แนวทางที่แนะนำ
คำตอบนี้แจกแจงกลไกต่าง ๆ สำหรับการส่งพารามิเตอร์ไปยังตัวควบคุม FXML
สำหรับแอปพลิเคชันขนาดเล็กฉันขอแนะนำให้ส่งพารามิเตอร์โดยตรงจากผู้เรียกไปยังคอนโทรลเลอร์ - มันเป็นเรื่องง่ายตรงไปตรงมาและไม่จำเป็นต้องใช้เฟรมเวิร์กเพิ่มเติม
สำหรับแอพพลิเคชั่นที่มีขนาดใหญ่และซับซ้อนมากขึ้นมันจะคุ้มค่าที่จะตรวจสอบว่าคุณต้องการใช้การฉีดอ้างอิงหรือEvent Busหรือไม่กลไกการภายในแอปพลิเคชันของคุณหรือไม่
การส่งผ่านพารามิเตอร์โดยตรงจากผู้เรียกไปยังคอนโทรลเลอร์
ส่งผ่านข้อมูลที่กำหนดเองไปยังตัวควบคุม FXML โดยดึงตัวควบคุมจากอินสแตนซ์ของตัวโหลด FXML และเรียกวิธีการบนตัวควบคุมเพื่อเริ่มต้นมันด้วยค่าข้อมูลที่จำเป็น
บางอย่างเช่นรหัสต่อไปนี้:
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 new FXMLLoader(location)
ใหม่จะถูกสร้างขึ้นตามที่แสดงในรหัสตัวอย่างเช่น ที่ตั้งเป็น URL และคุณสามารถสร้าง URL ดังกล่าวจากทรัพยากร FXML โดย:
new FXMLLoader(getClass().getResource("sample.fxml"));
ระวังอย่าใช้ฟังก์ชั่นโหลดแบบคงที่บน FXMLLoader ไม่เช่นนั้นคุณจะไม่สามารถรับตัวควบคุมจากอินสแตนซ์โหลดเดอร์ของคุณได้
อินสแตนซ์ FXMLLoader ไม่เคยรู้อะไรเกี่ยวกับวัตถุโดเมน คุณไม่ส่งวัตถุโดเมนเฉพาะแอปพลิเคชันไปยังตัวสร้าง FXMLLoader โดยตรงแทนคุณ:
- สร้าง FXMLLoader ตามมาร์กอัป fxml ณ ตำแหน่งที่ระบุ
- รับตัวควบคุมจากอินสแตนซ์ FXMLLoader
- เรียกใช้เมธอดบนตัวควบคุมที่ดึงมาเพื่อให้การอ้างอิงกับตัวควบคุมโดเมนวัตถุ
บล็อกนี้ (โดยนักเขียนอื่น) ให้เป็นทางเลือก แต่ที่คล้ายกันตัวอย่างเช่นตัวอย่างเช่น
การตั้งค่าคอนโทรลเลอร์บน FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
คุณสามารถสร้างคอนโทรลเลอร์ใหม่ในรหัสผ่านพารามิเตอร์ใด ๆ ที่คุณต้องการจากผู้โทรเข้าสู่คอนสตรัคเตอร์คอนโทรลเลอร์ เมื่อคุณสร้างคอนโทรลเลอร์แล้วคุณสามารถตั้งค่าบนอินสแตนซ์ FXMLLoader ก่อนที่คุณจะเรียกใช้load()
อินสแตนซ์เมธอด
ในการตั้งค่าคอนโทรลเลอร์บนโหลดเดอร์ (ใน JavaFX 2.x) คุณไม่สามารถกำหนด a fx:controller
แอตทริบิวต์ในไฟล์ fxml ของคุณได้
เนื่องจากข้อ จำกัด ในการ fx:controller
คำจำกัดความใน FXML ฉันชอบรับคอนโทรลเลอร์จาก FXMLLoader เป็นการส่วนตัวมากกว่าตั้งค่าคอนโทรลเลอร์ลงใน FXMLLoader
การมีตัวควบคุมดึงพารามิเตอร์จากวิธีการคงที่ภายนอก
วิธีนี้เป็นแบบสุดขั้วโดยคำตอบของ Sergey สำหรับJavafx 2.0 How-to Application.getParameters () ในไฟล์ Controller.javaในไฟล์
ใช้การฉีดพึ่งพา
FXMLLoader รองรับระบบฉีดพึ่งพาเช่น Guice, Spring หรือ Java EE CDI โดยอนุญาตให้คุณตั้งโรงงานควบคุมแบบกำหนดเองบน FXMLLoader สิ่งนี้จัดเตรียมการติดต่อกลับที่คุณสามารถใช้เพื่อสร้างอินสแตนซ์ของตัวควบคุมที่มีค่าที่ต้องพึ่งพาซึ่งถูกฉีดโดยระบบฉีดที่เกี่ยวข้อง
ตัวอย่างของแอปพลิเคชัน JavaFX และตัวควบคุมการพึ่งพาการฉีดกับสปริงมีให้ในคำตอบ:
วิธีการฉีดการพึ่งพาที่ดีและสะอาดนั้นเป็นแบบสุดขั้วโดยafterburner.fxด้วยตัวอย่างแอปพลิเคชัน air-hacksที่ใช้มัน afterburner.fx อาศัย JEE6 javax.injectเพื่อดำเนินการฉีดต่อเนื่อง
ใช้ Event Bus
Greg Brown ผู้สร้างข้อมูลจำเพาะ FXML ดั้งเดิมและผู้ดำเนินการมักแนะนำให้พิจารณาการใช้ Event Bus เช่น Guava EventBusเพื่อการสื่อสารระหว่าง FXML คอนโทรลเลอร์ที่สร้างอินสแตนซ์และแอปพลิเคชันอื่น ๆ
EventBus เป็น API การเผยแพร่ / สมัครสมาชิกที่เรียบง่าย แต่ทรงพลังพร้อมคำอธิบายประกอบที่ช่วยให้ POJO สื่อสารกับกันและกันได้ทุกที่ใน JVM โดยไม่ต้องอ้างถึงกันและกัน
ติดตามคำถาม & คำตอบ
ในวิธีแรกทำไมคุณถึงกลับสเตจ วิธีการอาจเป็นโมฆะเช่นกันเพราะคุณให้คำสั่งแสดง (); ก่อนกลับเวที; คุณวางแผนการใช้งานอย่างไรโดยส่งคืนสเตจ
มันเป็นวิธีการแก้ไขปัญหาการทำงาน สเตจจะถูกส่งคืนจากshowCustomerDialog
ฟังก์ชันเพื่อให้สามารถอ้างอิงการอ้างอิงกับคลาสภายนอกซึ่งอาจต้องการทำบางสิ่งเช่นซ่อนสเตจตามการคลิกปุ่มในหน้าต่างหลักในภายหลัง โซลูชันสำรองที่มุ่งเน้นวัตถุสามารถห่อหุ้มฟังก์ชันการทำงานและการอ้างอิงสเตจภายในวัตถุ CustomerDialog หรือให้ CustomerDialog ขยายสเตจได้ ตัวอย่างเต็มรูปแบบสำหรับอินเทอร์เฟซแบบเชิงวัตถุไปยังกล่องโต้ตอบแบบกำหนดเองที่ห่อหุ้ม FXML ข้อมูลคอนโทรลเลอร์และโมเดลอยู่นอกเหนือขอบเขตของคำตอบนี้ แต่อาจสร้างโพสต์บล็อกที่คุ้มค่าสำหรับใครก็ได้ที่ต้องการสร้าง
ข้อมูลเพิ่มเติมที่จัดทำโดยผู้ใช้ StackOverflow ชื่อ@dzim
ตัวอย่างการฉีดสปริงบูตพึ่งพา
คำถามที่ว่าจะทำอย่างไร "The Spring Boot Way" มีการสนทนาเกี่ยวกับ JavaFX 2 ซึ่งฉันได้รับการบอกกล่าวในลิงก์ถาวร วิธีการดังกล่าวยังคงใช้ได้และทดสอบในเดือนมีนาคม 2559 ใน Spring Boot v1.3.3 การปล่อย:
https://stackoverflow.com/a/36310391/1281217
บางครั้งคุณอาจต้องการส่งผลลัพธ์กลับไปยังผู้โทรซึ่งในกรณีนี้คุณสามารถตรวจสอบคำตอบสำหรับคำถามที่เกี่ยวข้อง: