Önerilen Yaklaşım
Bu yanıt, parametreleri FXML denetleyicilerine geçirmek için farklı mekanizmaları numaralandırır.
Küçük uygulamalar için parametreleri doğrudan arayandan denetleyiciye geçirmenizi önemle tavsiye ederim - basit, anlaşılır ve ekstra çerçeve gerektirmez.
Daha büyük, daha karmaşık uygulamalar için, uygulamanızda Bağımlılık Enjeksiyonu veya Olay Veri Yolu mekanizmalarını kullanmak isteyip istemediğinizi araştırmak faydalı olacaktır .
Parametreleri Doğrudan Arayandan Denetleyiciye Aktarma
Denetleyiciyi FXML yükleyici örneğinden alıp denetleyicide gerekli veri değerleriyle başlatmak için bir yöntem çağırarak özel verileri bir FXML denetleyicisine aktarın.
Aşağıdaki kod gibi bir şey:
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());
}
}
Örnek kodda gösterildiği gibi yeni bir FXMLLoader oluşturulur new FXMLLoader(location)
. Konum bir URL'dir ve böyle bir URL'yi şu şekilde bir FXML kaynağından oluşturabilirsiniz:
new FXMLLoader(getClass().getResource("sample.fxml"));
FXMLLoader'da statik yük fonksiyonu KULLANMAMAYA dikkat edin, aksi takdirde kumandanızı yükleyici durumunuzdan alamazsınız.
FXMLLoader örneklerinin kendileri etki alanı nesneleri hakkında hiçbir şey bilmez. Uygulamaya özgü etki alanı nesnelerini doğrudan FXMLLoader yapıcısına geçirmezsiniz, bunun yerine:
- Belirtilen bir konumda fxml işaretlemesine dayalı bir FXMLLoader oluşturma
- FXMLLoader örneğinden bir denetleyici alın.
- Denetleyiciye etki alanı nesnelerine başvurular sağlamak için alınan denetleyicideki yöntemleri çağırın.
Bu blog (başka bir yazar tarafından) alternatif, ancak benzer bir örnek sunmaktadır .
FXMLLoader'da Denetleyici Ayarlama
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
Arayandan istediğiniz parametreleri denetleyici yapıcısına ileterek kodda yeni bir denetleyici oluşturabilirsiniz. Bir denetleyici oluşturduktan sonra , örnek yöntemini çağırmadan önce onu bir FXMLLoader örneğinde ayarlayabilirsiniz .load()
Bir yükleyicide (JavaFX fx:controller
2.x'te ) bir denetleyici ayarlamak için fxml dosyanızda bir öznitelik tanımlayamazsınız .
fx:controller
FXML'deki tanımdaki sınırlama nedeniyle , denetleyiciyi FXMLLoader'a ayarlamak yerine kişisel olarak denetleyiciyi FXMLLoader'dan almayı tercih ederim.
Denetleyicinin Parametreleri Harici Statik Yöntemden Alması
Bu yöntem Sergey'in bir Controller.java dosyasındaki Javafx 2.0 How-to Application.getParameters () öğesine verdiği yanıtla örneklendirilmiştir .
Bağımlılık Enjeksiyonu Kullan
FXMLLoader, FXMLLoader'da özel bir kontrolör fabrikası kurmanıza izin vererek Guice, Spring veya Java EE CDI gibi bağımlılık enjeksiyon sistemlerini destekler. Bu, ilgili bağımlılık enjeksiyon sistemi tarafından enjekte edilen bağımlı değerlere sahip denetleyici örneği oluşturmak için kullanabileceğiniz bir geri arama sağlar.
JavaFX uygulaması ve Spring ile kontrolör bağımlılığı enjeksiyonuna bir örnek aşağıdaki cevapta verilmiştir:
Gerçekten güzel, temiz bir bağımlılık enjeksiyon yaklaşımı, onu kullanan örnek bir hava korsanlığı uygulamasıyla afterburner.fx çerçevesi tarafından örneklendirilir . afterburner.fx bağımlılık enjeksiyonunu yapmak için JEE6 javax.inject dosyasına güveniyor .
Etkinlik Otobüsü Kullanma
Orijinal FXML belirtim yaratıcısı ve uygulayıcısı olan Greg Brown, genellikle FXML somutlaştırılmış denetleyiciler ve diğer uygulama mantığı arasındaki iletişim için Guava EventBus gibi bir olay veri yolunun kullanılmasını öneriyor .
EventBus, POJO'ların birbirlerine başvurmak zorunda kalmadan JVM'de herhangi bir yerde birbirleriyle iletişim kurmalarına olanak tanıyan ek açıklamalara sahip basit ama güçlü bir yayınlama / abone olma API'sidir.
Takip Soru-Cevap
ilk yöntemde neden Sahne Alanı'na dönüyorsunuz? Şimdiden show () komutunu verdiğiniz için yöntem de geçersiz olabilir. dönüş aşamasından hemen önce; Sahne Alanı'na geri dönerek kullanımı nasıl planlıyorsunuz?
Bir soruna işlevsel bir çözümdür. Bir aşama, showCustomerDialog
işlevden daha sonra ana pencerede bir düğmeyi tıklatarak sahneyi gizlemek gibi bir şey yapmak isteyebilecek harici bir sınıf tarafından saklanabilmesi için işlevden döndürülür . Alternatif, nesne yönelimli bir çözüm, bir CustomerDialog nesnesi içindeki işlevselliği ve sahne referansını kapsayabilir veya bir CustomerDialog Sahne Alanı genişletebilir. FXML, denetleyici ve model verilerini kapsayan özel bir iletişim kutusuna nesne yönelimli arabirim için tam bir örnek bu yanıtın kapsamı dışındadır, ancak bir tane oluşturmaya eğilimli herkes için değerli bir blog gönderisi yapabilir.
@Dzim adlı StackOverflow kullanıcısı tarafından sağlanan ek bilgiler
Yay Önyükleme Bağımlılığı Enjeksiyonu Örneği
Bunun nasıl yapılacağı sorusu "The Spring Boot Way", ekli kalıcı bağlantıda cevapladığım JavaFX 2 hakkında bir tartışma vardı. Yaklaşım İlkbahar Boot v1.3.3.RELEASE üzerinde hala geçerli ve Mart 2016 yılında test edilmiştir:
https://stackoverflow.com/a/36310391/1281217
Bazen, sonuçları arayana geri aktarmak isteyebilirsiniz, bu durumda ilgili sorunun cevabını kontrol edebilirsiniz: