2014-03-25 53 views
0

我是JavaFX的新手,嘗試創建一個確認對話框。 我已經知道,有沒有真正的建立在JavaFX的對話框,所以我創建了一個我自己是這樣的:JavaFX對話框通信

@FXML 
public void delBox() { 
    try { 
     Stage dialogStage = new Stage(); 
     AnchorPane root = FXMLLoader.load(getClass().getResource("Dialog.fxml")); 
     Scene scene = new Scene(root); 
     dialogStage.setScene(scene); 
     dialogStage.showAndWait(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

它看起來相當不錯了,但我不明白的是,如何將這些兩個階段可以相互溝通其他?我想將一個字符串傳遞給消息中顯示的對話框,當對話窗口中的某個按鈕被點擊時,我想對此作出相應的反應。

任何人都可以解釋我如何溝通階段的作品? btw:我使用.FXML文件和控制器類。

回答

2

您需要對該對話框的控制器的引用。爲此,請創建FXMLLoader的實例,而不是使用靜態FXMLLoader.load(URL)方法。

例如,假設你有一個類DialogController,所以你Dialog.fxml樣子:

<AnchorPane xmlns:fx="..." fx:controller="DialogController.fxml"> 
... 
</AnchorPane> 

然後你就可以在delBox()

Stage dialogStage = new Stage(); 
FXMLLoader loader = new FXMLLoader(getClass().getResource("Dialog.fxml")); 
AnchorPane root = (AnchorPane)loader.load(); 
DialogController controller = (DialogController) loader.getController(); 
Scene scene = new Scene(root); 
dialogStage.setScene(scene); 
dialogStage.showAndWait(); 

訪問DialogController上面現在你可以兩個控制器之間進行通信。例如,在DialogController可以定義一個message財產,並將其綁定到一個Label:在您的delBox

public class DialogController { 
    private final StringProperty message = new SimpleStringProperty(""); 
    public void setMessage(String message) { 
     this.message.set(message); 
    } 
    public String getMessage() { 
     return message.get(); 
    } 
    public StringProperty messageProperty() { 
     return message ; 
    } 

    @FXML 
    private Label label ; 

    public void initialize() { 
     label.textProperty().bind(message); 
     // ... 
    } 
} 

然後回()方法:

//... as before: 
     AnchorPane root = (AnchorPane)loader.load(); 
     DialogController controller = (DialogController) loader.getController(); 
     controller.setMessage("Hello World"); 
// ... 

同樣,您可以定義特性,這在對話框中按下控件時設置,並且觀察它們或在showAndWait()調用之後查詢它們。

還有一堆其他類似的技術。一些例子:

https://github.com/james-d/Shared-Data-Controller/tree/master/src

https://github.com/james-d/Dialog-FXML-Example/tree/master/src

https://github.com/james-d/Nested-Controller-Example/tree/master/src/nestedcontrollerexample

+0

非常感謝! –

1
<AnchorPane xmlns:fx="..." fx:controller="DialogController.fxml"> 
... 
</AnchorPane> 

FX控制器是一個java文件,所以它必須是DialogController和控制器的路徑應即包括,fx:controller="applicationPackageName.DialogController"
上面提到的fxml代碼不起作用。它導致
javafx.fxml.LoadException
java.lang.InstantiationException
的java.lang。NoSuchMethodException

原因:JVM中查找一個類的構造與0的參數來構建一個實例。爲了克服錯誤,則控制器文件需要在java的編碼功能被加載:
loader.setController(new ControllerName(""));

綜上所述(工作代碼):
FXML文件:

<BorderPane id="background" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="320.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" > 
    <bottom> 
     <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"> 
      <children> 
       <Button onAction="#close" text="OK" /> 
      </children>    
     </HBox> 
    </bottom> 
    <center> 
     <Label fx:id="messageLabel" /> 
    </center> 
</BorderPane> 

控制器文件:

public class PiPreferenceController { 
    private final String message ; 

     @FXML 
     private Label messageLabel ; 

     @FXML 
     void initialize() { 
      messageLabel.setText(message); 
     } 



     public PiPreferenceController(String message) { 
      this.message = message ; 
     } 



     @FXML 
     public void close() { 
      messageLabel.getScene().getWindow().hide(); 
     } 

} 



void dialogPreferences() throws IOException { 

     Stage dialogStage = new Stage(); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource(
       "PiPreference.fxml")); 

     loader.setController(new PiPreferenceController("")); 
     BorderPane root = (BorderPane) loader.load(); 
     Scene scene = new Scene(root); 
     dialogStage.setScene(scene); 
     dialogStage.showAndWait(); 

    }