Petua Java 61: Potong, salin, dan tampal di Java

Artikel ini akan memberi anda pemahaman yang baik tentang cara mengirim dan mendapatkan maklumat dari papan keratan di Java. Anda juga akan belajar bagaimana menangani pelbagai perisa data yang ada. Akhirnya, kami akan merangkumi pelbagai keperibadian papan keratan dan bagaimana mereka memberikan sokongan untuk lebih dari satu rasa data.

Java menawarkan dua jenis papan keratan: tempatan dan sistem. Papan klip tempatan hanya terdapat di dalam mesin maya yang digunakan oleh applet atau aplikasi anda. Namun, tidak seperti beberapa sistem operasi yang membataskan anda hanya pada satu papan keratan, Java membolehkan anda memiliki sebanyak mungkin papan keratan tempatan yang anda mahukan. Mengakses papan keratan tempatan semudah merujuknya dengan namanya.

Papan klip sistem dihubungkan secara langsung dengan sistem operasi sebaya, yang membolehkan aplikasi anda memindahkan maklumat antara aplikasi yang berjalan di bawah sistem operasi tersebut. Satu kelemahan menggunakan papan keratan sistem ialah anda hanya dapat memindahkan data teks. Jenis objek lain tidak disokong oleh papan keratan sistem. Dengan jayanya, masalah ini akan ditangani dalam siaran JDK yang akan datang.

Sebelum melangkah lebih jauh, mari kita lihat semua kelas yang terlibat dalam memanipulasi papan keratan. Kelas-kelas ini, yang disenaraikan dalam jadual di bawah, semuanya merupakan bahagian dari pakej java.awt.datatransfer .

Senarai semua kelas dalam pakej java.awt.datatransfer
Nama Jenis Penerangan
Clipboard Kelas Berurusan dengan semua yang boleh dipindah milik
ClipboardOwner Antara muka Setiap kelas yang berurusan dengan papan keratan mesti melaksanakan antara muka ini. Antaramuka ini digunakan untuk memberitahu ketika data yang awalnya diletakkan di papan keratan telah ditimpa
Dataflavor Kelas Merupakan semua jenis data yang menyokong sokongan yang boleh dipindah milik
StringSelection Kelas Satu jenis yang boleh dipindah milik yang dibekalkan dengan Java
Transferable Antara muka Balut ke objek yang dilalui ke papan keratan
UnsupportedFlavor Exception Kelas Pengecualian dilemparkan dengan pindah untuk rasa data yang tidak disokong

Lebih banyak lagi di kelas papan keratan

Mari selami penerokaan java.awt.datatransferpakej kami dengan lebih terperinci di setiap kelas.

Kelas Papan Keratan

The Clipboardkelas adalah link anda untuk mengakses papan klip. Ini merangkumi tiga kaedah, yang ditentukan dalam jadual berikut:

Kelas papan keratan
Kaedah Penerangan
String getName () Dapatkan nama papan keratan
void setContents (Transferable, ClipboardOwner) Tetapkan kandungan papan keratan bersama dengan objek pemilik
Transferable getContent (Object) Dapatkan isi papan keratan dalam bentuk objek yang Boleh Dipindahkan. Objek yang dilalui sebagai parameter adalah pemiliknya

Tiga Clipboardkaedah kelas di atas membolehkan anda menamakan papan keratan, menghantar maklumat kepadanya, atau mendapatkan maklumat darinya. Mengakses papan keratan sistem atau membuat papan keratan tempatan adalah berbeza dan memerlukan sedikit perbincangan. Untuk mengakses papan keratan sistem, berikan rujukan dari papan keratan sistem ke Clipboardkelas, seperti:

Clipboard clipboard = getToolkit ().getSystemClipboard ();

Sebaliknya, untuk membuat papan keratan tempatan anda hanya perlu membuat Clipboardobjek dengan nama yang ingin anda tetapkan kepadanya, misalnya:

Clipboard clipboard = new Clipboard ("My first clipboard");

Mengakses papan keratan sistem atau membuat papan keratan tempatan berbeza tetapi mudah.

Antara muka ClipboardOwner

Oleh kerana Java adalah bahasa multiplatform, dan karena sistem operasi berperilaku berbeda terhadap papan klip, pengarang bahasa Java harus membuat mekanisme untuk mengatasi perbedaan halus. Ini adalah sebab kehadiran ClipboardOwnerantara muka. Fungsi utamanya adalah untuk memberitahu pemilik papan keratan apabila datanya ditimpa oleh orang lain. Ini juga dapat memberi isyarat kepada aplikasi ketika melepaskan sumber yang berkaitan dengan data.

Dalam aplikasi nyata, lostOwnershipmetode ini dapat digunakan untuk menetapkan bendera yang memberitahu aplikasi Anda tentang ketersediaan data di papan keratan. Microsoft Word, walaupun tidak ditulis dalam Java, adalah contoh yang baik dari mekanisme ini di tempat kerja dalam aplikasi. Setiap kali anda meletakkan sesuatu di papan keratan di Word dan kemudian berhenti, kotak dialog muncul memaklumkan bahawa data ada di papan keratan. Anda kemudian akan ditanya sama ada anda mahu meninggalkan data di papan keratan.

Melaksanakan ClipboardOwnerantaramuka agak mudah kerana hanya ada satu kaedah untuk dilaksanakan. Kaedah ini akan menyebabkan program anda melepaskan pemilikan papan keratan.

Kelas DataFlavour

The DataFlavorkelas digunakan untuk mewakili jenis objek. Anda tidak terhad kepada satu rasa data (atau jenis) setiap objek. Dan, seperti kami, objek anda boleh mempunyai pelbagai keperibadian! Sebagai contoh, kelas gambar dapat ditunjukkan sebagai kelas Java atau sebagai susunan bit (GIF, JPEG, dan sebagainya). Pada hakikatnya, DataFlavorkelas adalah pembungkus untuk jenis MIME. Standard MIME luas, oleh itu hampir tidak ada batasan data yang dapat dipindahkan ke papan keratan. (Perbincangan mengenai standard MIME berada di luar ruang lingkup artikel ini, tetapi anda boleh mendapatkan maklumat tambahan di bahagian Sumber.)

Sebagai contoh rasa data, anda akan dapati bahawa StringSelectionkelas mempunyai dua perisa berdasarkan jenis MIME. Pada pelaksanaannya adalah "application / x-java-serialized-object", dan yang kedua adalah "text / plain; charset = unicode". Sebenarnya, pelaksanaan ini memberitahu kita bahawa kita dapat mengambil teks dari papan keratan sebagai Stringkelas ( application/x-java-serialized-object) atau sebagai teks biasa ( text/plain; charset=unicode).

Terdapat dua cara untuk membuat a DataFlavor. Anda boleh menulis:

public DataFlavor (representationClass, String humanRepresentationName)

Pembina ini akan mencipta rasa data baru yang mewakili kelas Java. Yang dikembalikan DataFlavorakan mempunyai representationClass = representationClassdan a mimeType = application/x-java-serialized-object. Sebagai contoh, berikut akan membuat DataFlavoruntuk java.awt.Button:

DataFlavor (Class.forName ("java.awt.Button"), "AWT Button");

Sekarang, pembina kedua ini

public DataFlavor (String mimeType, String humanRepresentationName)

akan membina DataFlavormenggunakan a MimeType. Yang dikembalikan DataFlavorakan berdasarkan pada MimeType. Sekiranya MimeTypeya application/x-java-serialized-object, hasilnya akan sama seperti jika anda memanggil pembina sebelumnya. Walaupun begitu, yang dikembalikan DataFlavorakan menjadi representationClass= InputStream and mimeType =mimeType. Sebagai contoh, panggilan berikut akan menimbulkan rasa teks biasa:

public DataFlavor ("text/plain; charset=unicode", "Unicode");

Jadual berikut menunjukkan kaedah DataFlavorkelas.

Kelas DataFlavour
Kaedah Penerangan
boolean equals (DataFlavor) Uji apakah DataFlavour yang diberikan sama dengan DataFlavour yang diwakili oleh kelas ini
String getHumanPresentableName () Kembalikan nama representasi manusia untuk format yang ditunjukkan oleh DataFlavour ini
void setHumanPresentableName (String) Tetapkan nama perwakilan manusia untuk DataFlavour ini
String getMimeType () Dapatkan rentetan jenis MIME yang diwakili oleh DataFlavour ini
Class getRepresentationClass () Kembalikan Kelas yang mewakili kelas ini

Antara muka yang boleh dipindah milik

The Transferablemuka harus dilaksanakan oleh semua kelas yang anda ingin menghantar ke clipboard, maka Clipboardkelas hanya akan memahami kelas yang telah dibalut oleh Transferableantara muka. The Transferablemuka terdiri daripada tiga kaedah:

Antara muka yang boleh dipindah milik
Kaedah Penerangan
DataFlavor getTransferDataFlavor () Kembalikan array DataFlavour yang mewakili objek
boolean isDataFlavorSupported (DataFlavor) Uji sama ada DataFlavour yang disokong disokong
Object getTransferData (DataFlavor) Kembalikan objek yang diwakili oleh DataFlavor yang disediakan

Ini mengakhiri lawatan kami ke semua kelas yang terlibat dalam mengendalikan papan keratan. Kita telah melihat bahawa untuk mengakses papan keratan kita mesti membuat Clipboardobjek atau mendapatkan rujukan ke papan keratan sistem. Kerana papan keratan hanya menerima objek jenis Transferable, objek yang ingin anda hantar ke papan keratan mesti melaksanakan antara muka ini. Akhirnya, semua objek di papan keratan mempunyai rasa yang diwakili oleh DataFlavorkelas, yang pada hakikatnya adalah pembungkus untuk jenis MIME.

Pada bahagian seterusnya, kita akan mempraktikkan apa yang telah kita pelajari.

Resipi penggunaan papan keratan

Bagaimana pelbagai kelas ini mengakses papan keratan boleh membingungkan. Nasib baik, ada resipi mudah, yang merangkumi langkah-langkah berikut:

Langkah 1. Buat kelas yang dipanggil xxxxSelection . Di sini, xxx harus menamakan jenis yang ditunjukkan oleh rasa ini. Sebagai contoh, ImageSelectionakan menjadi nama yang baik untuk rasa gambar. Tentu saja konvensyen penamaan ini hanyalah cadangan. Saya mengikuti konvensyen penggunaan yang ditetapkan dengan yang StringSelectiondisediakan di JDK, tetapi anda boleh menamakan kelas ini apa sahaja yang anda mahukan. Penting untuk diingat bahawa objek ini mesti melaksanakan Transferabledan ClipboardOwnerantara muka. Sekiranya anda bercadang untuk memindahkan teks, StringSelectionkelas harus digunakan sebagai gantinya.

Langkah 2. Tentukan kelas untuk mengakses papan keratan . Untuk mengakses clipboard tempatan, menggunakan panggilan berikut: Clipboard clipboard = new Clipboard ("name"). Untuk mengakses sistem clipboard operasi rakan sebaya, menggunakan panggilan ini sebaliknya: Clipboard clipboard = getToolkit ().getSystemClipboard ().

Langkah 3. Tetapkan kandungan papan keratan . Untuk melakukan ini, gunakan setContentkaedah di Clipboardkelas, di mana parameter pertama adalah objek yang menerapkan Transferable( xxxxSelectionkelas dibuat pada Langkah 1), dan parameter kedua adalah rujukan kepada kelas yang memanggil kaedah ini.

Langkah 4. Dapatkan kandungan papan keratan . Gunakan getContentkaedah di Clipboardkelas. Kaedah ini akan mengembalikan kelas jenis Transferable.

Langkah 5. Laksanakan 'cut operasi' . Untuk melakukan ini, anda mesti memadamkan data secara manual setelah disalin ke papan keratan. Java tidak menyediakan pelaksanaan operasi pemotongan.

Selepas lawatan ringkas kelas yang melibatkan manipulasi papan keratan, kami akan mengikuti resipi yang dicadangkan untuk menulis applet mudah yang memindahkan teks ke papan keratan sistem.

Penyenaraian 1

Mari kita periksa applet ini:

Penyenaraian 1

Berikut ini adalah penjelasan mengenai baris kod tertentu dalam Penyenaraian 1.

Baris 9: Tentukan kelas applet1untuk melanjutkan Appletkelas dan melaksanakan ClipboardOwnerantara muka.

Baris 17: Tentukan objek papan keratan.

Baris 26: Tetapkan objek papan keratan ke papan keratan sistem operasi rakan sebaya.

Garis 45 hingga 47: Melaksanakan satu-satunya kaedah dalam antara muka ini. Dalam artikel ini kita tidak menggunakan lostOwnershipkaedah tetapi hanya mencetak mesej di konsol. Anda boleh bereksperimen dengan kaedah ini dengan menyalin beberapa teks ke papan keratan menggunakan applet ini, dan kemudian menyalin sesuatu yang lain dari aplikasi lain. Anda harus melihat pesan pemilikan yang hilang muncul di konsol Java, kerana data yang ditempatkan di papan keratan (menggunakan Java applet) ditimpa oleh aplikasi lain.

Baris 52: Tentukan kelas jenis StringSelectionyang menerapkan rasa data teks. Kami kemudian mendapat kandungan bidang teks sumber.

Baris 53: Tetapkan kandungan papan keratan ke fieldContentkelas yang kita tentukan pada baris sebelumnya. Perhatikan bahawa kita mesti menyediakan pemilik kelas ini, dalam kes ini, applet ini.

Baris 61: Tentukan objek jenis Transferableuntuk menerima kandungan papan keratan.

Baris 63: Mengesahkan dua perkara. Pertama, adakah papan keratan kosong? Kedua, adakah kandungan papan keratan itu rasa yang tepat? Dalam kes ini kita mencari a stringFlavor.

Baris 67: Dapatkan kandungan papan keratan dalam pemboleh ubah rentetan. Untuk melakukan ini, kami memanggil getTransferDatakaedah dengan rasa yang diperlukan. Dalam kes ini, kita memerlukan DataFlavor.stringFlavorjenis.

Baris 69: Tetapkan kandungan medan teks tujuan ke kandungan papan keratan.

Anda boleh bereksperimen dengan applet ini dengan memindahkan teks antara applet ini dan applet Java yang lain, atau antara applet Java dan program asli, seperti Notepad, bagi mereka yang menjalankan Microsoft Windows.

Penyenaraian 2

Dalam contoh kedua, kami akan menulis applet yang menyalin gambar ke papan keratan. Imej itu akan menerapkan rasa sendiri.

Penyenaraian 2

Berikut ini adalah penjelasan mengenai baris kod tertentu dalam Penyenaraian 2.

Baris 27: Buat objek papan keratan yang merujuk papan keratan tempatan.

Baris 41: Tetapkan sourImagekawalan ke Image.gif.

Garis 44 hingga 50: Laksanakan lostOwnershipkaedah. Kami hanya mencetak mesej di konsol Java.

Baris 6: Buat ImageSelectionobjek berdasarkan gambar dalam sourceImagekawalan.

Baris 57: Tetapkan kandungan papan keratan dengan ImageSelectionobjek.

Baris 66: Dapatkan kandungan papan keratan.

Baris 68: Pastikan kandungannya tidak kosong dan rasa yang kita cari disokong.

Baris 71: Dapatkan data mengikut citarasa yang sesuai.

Baris 72: Tetapkan destinationImagekawalan ke kandungan yang baru diperoleh.

Baris 90: Tentukan ImageSelectionkelas.

Baris 93: Tentukan susunan yang DataFlavordipanggil supportedFlavorsdengan satu elemen ( imageFlavor).

Baris 102: Buat rasa gambar. Rasa yang dibuat berdasarkan pada java.awt.Imagenama representasi "Gambar."

Garis 111 hingga 130: Laksanakan Transferablekaedah.

Baris 123: Kembalikan kandungan papan keratan dengan kaedah ini.

Baris 125: Mengesahkan rasa. Sekiranya rasa yang diminta disokong, maka objek gambar akan dikembalikan. Jika tidak, pengecualian dilemparkan.

Dalam Penyenaraian 1, kami menggunakan rasa data lalai ( StringSelection) untuk menghantar teks ke papan keratan sistem. Dalam Penyenaraian 2, kami melangkah lebih jauh dengan menerapkan rasa data kami sendiri java.awt.Image.