Pendekatan yang Disarankan
Jawaban ini menyebutkan mekanisme berbeda untuk memberikan parameter ke pengontrol FXML.
Untuk aplikasi kecil, saya sangat merekomendasikan melewati parameter langsung dari pemanggil ke controller - itu sederhana, mudah dan tidak memerlukan kerangka kerja tambahan.
Untuk aplikasi yang lebih besar dan lebih rumit, ada baiknya menyelidiki jika Anda ingin menggunakan Dependency Injection atau Event Bus mekanisme dalam aplikasi Anda.
Melewati Parameter Langsung Dari Pemanggil ke Pengontrol
Berikan data khusus ke pengontrol FXML dengan mengambil pengontrol dari instance loader FXML dan memanggil metode pada pengontrol untuk menginisialisasi dengan nilai data yang diperlukan.
Sesuatu seperti kode berikut:
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(
(Pane) loader.load()
)
);
CustomerDialogController controller =
loader.<CustomerDialogController>getController();
controller.initData(customer);
stage.show();
return stage;
}
...
class CustomerDialogController {
@FXML private Label customerName;
void initialize() {}
void initData(Customer customer) {
customerName.setText(customer.getName());
}
}
FXMLLoader baru dibuat seperti yang ditunjukkan dalam contoh kode yaitu new FXMLLoader(location)
. Lokasi adalah URL dan Anda dapat menghasilkan URL seperti itu dari sumber daya FXML dengan:
new FXMLLoader(getClass().getResource("sample.fxml"));
Berhati-hatilah JANGAN menggunakan fungsi beban statis pada FXMLLoader, atau Anda tidak akan bisa mendapatkan controller dari instance loader Anda.
Instance FXMLLoader sendiri tidak pernah tahu apa-apa tentang objek domain. Anda tidak secara langsung mengirimkan objek domain khusus aplikasi ke konstruktor FXMLLoader, sebagai gantinya Anda:
- Bangun FXMLLoader berdasarkan marka fxml di lokasi yang ditentukan
- Dapatkan pengontrol dari instance FXMLLoader.
- Aktifkan metode pada pengontrol yang diambil untuk memberikan pengontrol dengan referensi ke objek domain.
Blog ini (oleh penulis lain) memberikan alternatif, tetapi serupa, contoh .
Mengatur Pengontrol pada FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
Anda dapat membuat pengontrol baru dalam kode, meneruskan parameter apa pun yang Anda inginkan dari pemanggil ke konstruktor pengontrol. Setelah Anda membuat kontroler, Anda bisa mengaturnya pada instance FXMLLoader sebelum Anda memanggil metode load()
instance .
Untuk mengatur pengontrol pada loader (dalam JavaFX 2.x) Anda TIDAK BISA juga mendefinisikan fx:controller
atribut dalam file fxml Anda.
Karena batasan pada fx:controller
definisi dalam FXML, saya pribadi lebih suka mendapatkan pengontrol dari FXMLLoader daripada mengatur pengontrol ke dalam FXMLLoader.
Memiliki Pengendali Mengambil Parameter dari Metode Statis Eksternal
Metode ini dicontohkan oleh jawaban Sergey untuk Javafx 2.0 How-to Application.getParameters () dalam file Controller.java .
Gunakan Injeksi Ketergantungan
FXMLLoader mendukung sistem injeksi ketergantungan seperti Guice, Spring atau Java EE CDI dengan memungkinkan Anda untuk mengatur pabrik pengontrol khusus di FXMLLoader. Ini memberikan panggilan balik yang dapat Anda gunakan untuk membuat instance controller dengan nilai-nilai dependen yang diinjeksi oleh sistem injeksi dependensi masing-masing.
Contoh aplikasi JavaFX dan injeksi ketergantungan pengontrol dengan Spring disediakan dalam jawaban untuk:
Suatu pendekatan injeksi ketergantungan yang benar-benar baik dan bersih dicontohkan oleh kerangka kerja afterburner.fx dengan contoh aplikasi air-hacks yang menggunakannya. afterburner.fx bergantung pada JEE6 javax.inject untuk melakukan injeksi ketergantungan.
Gunakan Bus Acara
Greg Brown, pembuat dan implementasi spesifikasi FXML asli, sering menyarankan untuk mempertimbangkan penggunaan bus peristiwa, seperti Guava EventBus , untuk komunikasi antara pengontrol instantiated FXML dan logika aplikasi lainnya.
EventBus adalah sederhana, tetapi kuat menerbitkan / berlangganan API dengan anotasi yang memungkinkan POJO untuk berkomunikasi satu sama lain di mana pun dalam JVM tanpa harus merujuk satu sama lain.
T&J tindak lanjut
pada metode pertama, mengapa Anda mengembalikan Stage? Metode ini dapat dibatalkan juga karena Anda sudah memberikan perintah show (); sebelum kembali panggung ;. Bagaimana Anda merencanakan penggunaan dengan mengembalikan Stage
Ini adalah solusi fungsional untuk suatu masalah. Tahap dikembalikan dari showCustomerDialog
fungsi sehingga referensi ke sana dapat disimpan oleh kelas eksternal yang mungkin ingin melakukan sesuatu, seperti menyembunyikan panggung berdasarkan klik tombol di jendela utama, di lain waktu. Alternatif, solusi berorientasi objek dapat merangkum fungsionalitas dan referensi tahap di dalam objek CustomerDialog atau memiliki Tahap memperpanjang CustomerDialog. Contoh lengkap untuk antarmuka berorientasi objek ke dialog khusus yang merangkum FXML, pengontrol, dan data model berada di luar cakupan jawaban ini, tetapi dapat membuat posting blog yang bermanfaat bagi siapa pun yang cenderung membuatnya.
Informasi tambahan disediakan oleh pengguna StackOverflow bernama @dzim
Contoh untuk Injeksi Ketergantungan Boot Musim Semi
Pertanyaan tentang bagaimana melakukannya "The Spring Boot Way", ada diskusi tentang JavaFX 2, yang saya jawab di permalink terlampir. Pendekatan ini masih valid dan diuji pada Maret 2016, pada Spring Boot v1.3.3.RELEASE:
https://stackoverflow.com/a/36310391/1281217
Kadang-kadang, Anda mungkin ingin meneruskan hasil kembali ke pemanggil, dalam hal ini Anda dapat memeriksa jawaban untuk pertanyaan terkait: