Tim plugin untuk mengonfigurasi komponen JavaFX dalam aplikasi desktop

Selalu menyenangkan untuk berbicara dengan aplikasi yang mengingat kebiasaan Anda dan seolah-olah merasakan Anda, apa yang Anda inginkan. Pustaka atau platform UI apa pun hanya memiliki fungsionalitas dasar dan sekumpulan komponen. Misalnya, jika kolom dalam tabel tidak bergerak atau tidak dapat disortir olehnya, maka aplikasi seperti itu yang digunakannya hampir tidak bisa disebut ramah. Untungnya, hari ini Anda tidak akan mengejutkan siapa pun dengan fungsi seperti itu. Namun, tidak setiap program akan mengingat posisi kolom ini dan pada sesi berikutnya akan menampilkannya di tempat yang sama. Mungkin mengganggu untuk mengatur posisi pemisah setiap kali di SplitPane atau untuk memasukkan parameter filter yang sama. Sebagai aturan, fasilitas tersebut harus disediakan oleh pengembang sendiri.


Ada banyak contoh perbaikan yang tampaknya kecil, tetapi solusi yang ditawarkan oleh platform hanya dua, dan pada dasarnya mereka serupa: buat komponen Anda sendiri berdasarkan pangkalan, buat Kulit Anda ke komponen pangkalan, ubah perilaku. Tidak satu pun dari metode ini yang mudah diimplementasikan, apalagi masing-masing komponen harus menulis komponen adaptornya sendiri. Saya bertemu beberapa orang yang dengannya metode ini lebih akrab dan dimengerti.


Tapi dia jauh dari satu-satunya. Bagaimana jika kita mengambil kapabilitas platform yang mendukung templat peramban untuk Node child, dan ketika menambahkan atau menghapus subgraf Node , jalankan melalui satu set plugins, masing-masing yang terlibat dalam pekerjaan spesifiknya sendiri? Satu dapat mengingat dan mengembalikan semuanya selama sesi kedua, yang lain - komponen yang ditentukan diubah oleh menu konteks, menambahkan fungsi menyalin teks. Beberapa dari mereka menambahkan tiga titik di akhir teks jika tidak pas, dan ketika Anda mengarahkan mouse, itu akan menampilkan petunjuk dengan teks lengkap, hanya jika tidak cocok. Yang terpenting, tidak masalah dari perpustakaan mana komponen ini berada, apakah kita dapat mewarisinya dan mendefinisikan kembali perilaku yang kita butuhkan. Yang kita butuhkan dalam hal ini adalah mengajarkan plugin untuk bekerja dengan komponen yang diperlukan dengan cara yang berbeda, jika perlu.


Ini bisa menjadi pendengar untuk koleksi anak-anak:


private final ListChangeListener changeListener = (ListChangeListener<Node>) (ListChangeListener.Change<? extends Node> c) -> { if (c.next()) { c.getAddedSubList().forEach(this::applySettingsForNodeAndAddListenerForItsChild); } }; 

Itu akan menjadi kode pemrosesan untuk setiap Node yang dimodifikasi:


 private void applySettingsForNodeAndAddListenerForItsChild(Node n) { if (!checkApplySettings(n)) { apply(n); ObservableList<Node> children = getChildren(n); if (children != null) { addListnerForUpdateChildren(children); } markNodePropertyApplied(n); } } 

Dan begitulah kode yang langsung memanggil plugin itu sendiri, yang terdaftar pada jenis komponen ini:


 public Node apply(Node node) { List<SettingsPlugin> settingsPlugins = settingsMap.get(Node.class); if (settingsPlugins != null) { for (SettingsPlugin plugin : settingsPlugins) { node = plugin.apply(node, userSettings.getSettings()); } } List<SettingsPlugin> settingList = settingsMap.get(node.getClass()); if (settingList != null) { for (SettingsPlugin plugin : settingList) { node = plugin.apply(node, userSettings.getSettings()); } } return node; } 

Ini adalah antarmuka dari plugin itu sendiri:


 public interface SettingsPlugin { public Node apply(Node node, Map<String, Object> userSettings); } 

Hanya perlu mendaftarkan pendengar sekali pada koleksi elemen Root anak dari elemen Scene , dan pada sisa subgraph, itu akan mendaftar sendiri ...


Baru-baru ini, saya menggambar analogi tentang kemampuan platform untuk aplikasi desktop dan web. Akan menarik untuk mengetahui bagaimana fungsionalitas tersebut dapat diimplementasikan pada kerangka kerja yang berbeda.

Source: https://habr.com/ru/post/id422693/


All Articles