Saya ingin menangani acara panggung (yaitu bersembunyi) dari kelas pengontrol saya. Jadi yang harus saya lakukan adalah menambahkan pendengar melalui
((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);
tetapi masalahnya adalah inisialisasi dimulai tepat setelahnya
Parent root = FXMLLoader.load(getClass().getResource("MyGui.fxml"));
dan sebelumnya
Scene scene = new Scene(root);
stage.setScene(scene);
jadi .getScene () mengembalikan null.
Satu-satunya solusi yang saya temukan sendiri adalah dengan menambahkan listener ke myPane.sceneProperty (), dan jika sudah tidak null saya mendapatkan scene, tambahkan ke .windowProperty () my! Goddamn! penanganan pendengar yang akhirnya saya ambil tahap. Dan itu semua diakhiri dengan pengaturan pendengar yang diinginkan ke acara panggung. Saya pikir ada terlalu banyak pendengar. Apakah ini satu-satunya cara untuk menyelesaikan masalah saya?
load()
metode. (Juga, javadoc digetController
terdengar seperti seharusnya aktifsetController
.)Yang Anda butuhkan hanyalah memberikan
AnchorPane
ID, dan kemudian Anda bisa mendapatkanStage
dari itu.@FXML private AnchorPane ap; Stage stage = (Stage) ap.getScene().getWindow();
Dari sini, Anda dapat menambahkan
Listener
yang Anda butuhkan.Sunting: Seperti yang dinyatakan oleh EarthMind di bawah ini, itu tidak harus menjadi
AnchorPane
elemen; dapat berupa elemen apa pun yang Anda tentukan.sumber
element
dapat setiap elemen denganfx:id
di jendela bahwa:Stage stage = (Stage) element.getScene().getWindow();
. Misalnya, jika Anda hanya memiliki denganButton
denganfx:id
di jendela Anda, gunakan itu untuk mendapatkan panggung.getScene()
masih kembalinull
.bgimage.sceneProperty().addListener((observableScene, oldScene, newScene) -> { if (oldScene == null && newScene != null) { bgimage.fitWidthProperty().bind(newScene.widthProperty()); ... } });
Saya tahu itu bukan jawaban yang Anda inginkan, tetapi IMO solusi yang diusulkan tidak baik (dan cara Anda sendiri adalah). Mengapa? Karena mereka bergantung pada status aplikasi. Di JavaFX, kontrol, pemandangan, dan panggung tidak bergantung satu sama lain. Artinya, kontrol bisa hidup tanpa ditambahkan ke adegan dan adegan bisa ada tanpa terikat ke panggung. Dan kemudian, pada saat t1, kontrol dapat dilampirkan ke sebuah adegan dan pada saat t2, adegan itu dapat ditambahkan ke sebuah panggung (dan itu menjelaskan mengapa mereka merupakan properti yang dapat diamati satu sama lain).
Jadi, pendekatan yang menyarankan untuk mendapatkan referensi pengontrol dan memanggil metode, meneruskan tahapan ke sana akan menambahkan status ke aplikasi Anda. Ini berarti Anda perlu menjalankan metode itu pada saat yang tepat, tepat setelah tahapan dibuat. Dengan kata lain, Anda harus mengikuti perintah sekarang: 1- Buat dekor 2- Lewati dekor yang dibuat ini ke pengontrol melalui sebuah metode.
Anda tidak dapat (atau tidak seharusnya) mengubah urutan ini dalam pendekatan ini. Jadi Anda kehilangan kewarganegaraan. Dan dalam perangkat lunak, secara umum, negara itu jahat. Idealnya, metode tidak memerlukan urutan panggilan apa pun.
Jadi apa solusi yang tepat? Ada dua alternatif:
1- Pendekatan Anda, dalam properti pengontrol mendengarkan untuk mendapatkan panggung. Saya pikir ini adalah pendekatan yang tepat. Seperti ini:
pane.sceneProperty().addListener((observableScene, oldScene, newScene) -> { if (oldScene == null && newScene != null) { // scene is set for the first time. Now its the time to listen stage changes. newScene.windowProperty().addListener((observableWindow, oldWindow, newWindow) -> { if (oldWindow == null && newWindow != null) { // stage is set. now is the right time to do whatever we need to the stage in the controller. ((Stage) newWindow).maximizedProperty().addListener((a, b, c) -> { if (c) { System.out.println("I am maximized!"); } }); } }); } });
2- Anda melakukan apa yang perlu Anda lakukan di mana Anda membuat
Stage
(dan bukan itu yang Anda inginkan):Stage stage = new Stage(); stage.maximizedProperty().addListener((a, b, c) -> { if (c) { System.out.println("I am maximized!"); } }); stage.setScene(someScene); ...
sumber
pane
ke adegan yang sudah dilampirkan ke panggung, ini tidak akan berhasil, bukan? Bukankah seharusnya ada tanda centang disceneProperty
listener dan hanya menambahkanstageProperty
listener jika stage masih null? Jika tidak, lakukan saja apa yang perlu saya lakukan sekarang juga?Cara termudah untuk mendapatkan objek panggung dalam pengontrol adalah:
Tambahkan metode tambahan di kelas pengontrol yang dibuat sendiri seperti (ini akan menjadi metode penyetel untuk mengatur bidang di kelas pengontrol),
private Stage myStage; public void setStage(Stage stage) { myStage = stage; }
Dapatkan pengontrol dalam metode start dan setel panggung
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyFXML.fxml")); OwnController controller = loader.getController(); controller.setStage(this.stage);
Sekarang Anda dapat mengakses dekor dalam pengontrol
sumber
stage
seperti ini.Tetapkan fx: id atau deklarasikan variabel ke / dari sembarang node: anchorpane, button, dll. Kemudian tambahkan event handler padanya dan di dalam event handler itu masukkan kode yang diberikan di bawah ini:
Semoga berhasil untuk Anda !!
sumber
Platform.runLater berfungsi untuk mencegah eksekusi hingga inisialisasi selesai. Dalam hal ini, saya ingin menyegarkan tampilan daftar setiap kali saya mengubah ukuran lebar jendela.
dalam kasus Anda
sumber
Anda bisa mendapatkan dengan
node.getScene
, jika Anda tidak menelepon dariPlatform.runLater
, hasilnya adalah nilai null.contoh nilai null:
contoh tidak ada nilai nol:
Platform.runLater(() -> { node.getScene().addEventFilter(KeyEvent.KEY_PRESSED, event -> { //your event }); });
sumber