在显示窗口之前,如何在JavaFX中更改FXML控制器变量值?

在显示窗口之前,如何在JavaFX中更改FXML控制器变量值?,java,javafx-2,javafx,Java,Javafx 2,Javafx,我想在弹出的FXML窗口显示之前更改其标签和文本。之所以这样做是因为所有的帮助项目都非常相似,我想制作一个模板FXML,然后相应地更改标签和文本区域的值以减少编码 不过,我很惊讶在JavaFX中没有遇到模板方法。如果有更好的方法,请提出建议 对于手头的任务,我有以下几点: @FXML private void documentationAction(ActionEvent action) throws IOException { Stage dialogue = new Stage();

我想在弹出的
FXML
窗口显示之前更改其标签和文本。之所以这样做是因为所有的帮助项目都非常相似,我想制作一个模板
FXML
,然后相应地更改标签和文本区域的值以减少编码

不过,我很惊讶在
JavaFX
中没有遇到模板方法。如果有更好的方法,请提出建议

对于手头的任务,我有以下几点:

@FXML
private void documentationAction(ActionEvent action) throws IOException {
    Stage dialogue = new Stage();
    Parent root = null;
    FXMLLoader loader = new FXMLLoader();
    root = loader.load(getClass().getResource("dialogues/dialogue.fxml"));
    Scene scene = new Scene(root);
    /*
     * change text values in title (Label) and text (TextArea)
     * and change the behavior of the findMore button
     */
    dialogue.setTitle("Documentation");
    dialogue.setScene(scene);
    dialogue.show();
}
我希望能够更改
FXM
L文件中的变量,我在controller类中为其创建了
getters
setters
,但我不知道如何做到这一点

有办法吗?在多窗口应用程序中,在窗口之间更改信息似乎是必要的,因此我确信我缺少一些简单的东西

更新 控制器代码:

public class DialogueController implements Initializable {

    @FXML
    private Button more;
    @FXML
    private Button close;
    @FXML
    private TextArea text;
    @FXML
    private Label title;

    public TextArea getText() {
        return text;
    }

    public void setText(String text) {
        this.text.setText(text);
    }

    public Label getTitle() {
        return title;
    }

    public void setTitle(String text) {
        this.title.setText(text);
    }

    @FXML
    public void closeAction(ActionEvent action) {
        // get a handle to the stage
        Stage stage = (Stage) close.getScene().getWindow();
        // do what you have to do
        stage.close();
    }

    @FXML
    public void moreAction(ActionEvent action) {
    }

    @FXML
    public void makeDocumentation(ActionEvent action) {
        this.title.setText("Documentation");
    }

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }
}
public class DialogueController extends Stage implements Initializable{
    @FXML private Button more;
    @FXML private Button close;
    @FXML private TextArea text;
    @FXML private Label title;

    public DialogueController(Parent parent){
        FXMLLoader loader = new FXMLLoader(getClass().getResource("dialogues/dialogue.fxml"));
        fxmlLoader.setController(this);
        super.setTitle("Documentation");
        try{
            setScene(new Scene((Parent) loader.load()));
        }catch(IOException e){
            e.printStackTrace();        
        }
        /*
         * Change values here
         */     
    }   
}
@FXML
private void documantationAction(ActionEvent action) throws IOException{
    DialogueController controller = new DialogueController(null);
    controller.show();
}
完整对话FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" padding="$x1" prefHeight="500.0" prefWidth="400.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml" fx:controller="pdbpro.dialogues.DialogueController">
  <children>
    <GridPane alignment="CENTER" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <Label fx:id="title" alignment="CENTER_LEFT" prefWidth="-1.0" styleClass="title" text="Title" underline="false" visible="true" GridPane.columnIndex="0" GridPane.rowIndex="0">
          <GridPane.margin>
            <Insets fx:id="x1" />
          </GridPane.margin>
        </Label>
        <TextArea fx:id="text" editable="false" focusTraversable="false" prefWidth="200.0" wrapText="true" GridPane.columnIndex="0" GridPane.rowIndex="1">
          <GridPane.margin>
            <Insets bottom="24.0" left="15.0" right="15.0" />
          </GridPane.margin>
        </TextArea>
        <ToolBar GridPane.columnIndex="0" GridPane.rowIndex="2">
          <items>
            <Button fx:id="more" mnemonicParsing="false" text="Find more" />
            <Button fx:id="close" mnemonicParsing="false" onAction="#closeAction" text="Close" />
          </items>
          <GridPane.margin>
            <Insets bottom="14.0" />
          </GridPane.margin>
        </ToolBar>
      </children>
      <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
      </columnConstraints>
      <padding>
        <Insets fx:id="x1" />
      </padding>
      <rowConstraints>
        <RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" valignment="CENTER" vgrow="NEVER" />
        <RowConstraints maxHeight="1.7976931348623157E308" minHeight="50.0" prefHeight="0.0" vgrow="ALWAYS" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
      </rowConstraints>
    </GridPane>
  </children>
  <stylesheets>
    <URL value="@dialogue.css" />
  </stylesheets>
</AnchorPane>
试试这个:

root = (Parent) loader.load(getClass().getResource("dialogues/dialogue.fxml").openStream());
DialogueController dc = loader.getController();
dc.setTitle("title");
dc.setTextArea("text");
// and so on..
...
dialogue.show();
断言DialogueController dc不为null。假设“title”是fxml文件中带有
fx:id=titleLabel
的标签,它应该在控制器类中备份,如下所示:

...
@FXML private Label titleLabel;
...
public void setTitle(String txt) {
    titleLabel.setText(txt);
}
...

我看到的一种方法是使您的控制器实现可初始化并实现initialize方法。当fxml加载程序创建控制器时,将自动调用initialize方法。当调用initialize方法时,所有声明的fxml对象都应该初始化并准备好进行自定义

[编辑] 看完报纸,, 它表示,如果创建了一个名为initialize(不带参数)的方法,那么fxml加载程序将自动调用该方法。所以据我所知,您不需要实现initializable。只需创建一个没有参数的initialize方法


如果需要,可以在中找到更多信息。

我建议您将所有FXML加载代码隐藏到控制器。为此,可以扩展阶段类:

控制器:

public class DialogueController implements Initializable {

    @FXML
    private Button more;
    @FXML
    private Button close;
    @FXML
    private TextArea text;
    @FXML
    private Label title;

    public TextArea getText() {
        return text;
    }

    public void setText(String text) {
        this.text.setText(text);
    }

    public Label getTitle() {
        return title;
    }

    public void setTitle(String text) {
        this.title.setText(text);
    }

    @FXML
    public void closeAction(ActionEvent action) {
        // get a handle to the stage
        Stage stage = (Stage) close.getScene().getWindow();
        // do what you have to do
        stage.close();
    }

    @FXML
    public void moreAction(ActionEvent action) {
    }

    @FXML
    public void makeDocumentation(ActionEvent action) {
        this.title.setText("Documentation");
    }

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }
}
public class DialogueController extends Stage implements Initializable{
    @FXML private Button more;
    @FXML private Button close;
    @FXML private TextArea text;
    @FXML private Label title;

    public DialogueController(Parent parent){
        FXMLLoader loader = new FXMLLoader(getClass().getResource("dialogues/dialogue.fxml"));
        fxmlLoader.setController(this);
        super.setTitle("Documentation");
        try{
            setScene(new Scene((Parent) loader.load()));
        }catch(IOException e){
            e.printStackTrace();        
        }
        /*
         * Change values here
         */     
    }   
}
@FXML
private void documantationAction(ActionEvent action) throws IOException{
    DialogueController controller = new DialogueController(null);
    controller.show();
}
请致电您的控制器:

public class DialogueController implements Initializable {

    @FXML
    private Button more;
    @FXML
    private Button close;
    @FXML
    private TextArea text;
    @FXML
    private Label title;

    public TextArea getText() {
        return text;
    }

    public void setText(String text) {
        this.text.setText(text);
    }

    public Label getTitle() {
        return title;
    }

    public void setTitle(String text) {
        this.title.setText(text);
    }

    @FXML
    public void closeAction(ActionEvent action) {
        // get a handle to the stage
        Stage stage = (Stage) close.getScene().getWindow();
        // do what you have to do
        stage.close();
    }

    @FXML
    public void moreAction(ActionEvent action) {
    }

    @FXML
    public void makeDocumentation(ActionEvent action) {
        this.title.setText("Documentation");
    }

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }
}
public class DialogueController extends Stage implements Initializable{
    @FXML private Button more;
    @FXML private Button close;
    @FXML private TextArea text;
    @FXML private Label title;

    public DialogueController(Parent parent){
        FXMLLoader loader = new FXMLLoader(getClass().getResource("dialogues/dialogue.fxml"));
        fxmlLoader.setController(this);
        super.setTitle("Documentation");
        try{
            setScene(new Scene((Parent) loader.load()));
        }catch(IOException e){
            e.printStackTrace();        
        }
        /*
         * Change values here
         */     
    }   
}
@FXML
private void documantationAction(ActionEvent action) throws IOException{
    DialogueController controller = new DialogueController(null);
    controller.show();
}

我在setTitle行上得到了一个空指针异常。原因:pdbpro.MainController.documentationAction(MainController.java:84)@Kylamus处的java.lang.NullPointerException。您是否在dialogue.fxml中定义了fx:controller属性?那个控制器的初始化方法在加载dialogue.fxml时运行了吗?它似乎都被正确初始化了,并且控制器已经被完全定义。@Kylamus。那么您的DialogueController在dc.setTitle(“title”);行不应为空;。我想NPE来自setTitle()。我可以至少看到getter/setter控制器类的代码吗?请参阅update.reduced code::
public类DialogueController实现可初始化的{@FXML private Button more;@FXML private Button close;@FXML private TextArea text;@FXML private Label title;public TextArea getText(){return text;}public void setText(字符串文本){this.text.setText(text);}public void setTitle(String text){this.title.setText(text);}@Override public void initialize(URL-URL,ResourceBundle-rb){}
控制器已经初始化,但在本例中,initialize方法为空:@Override public void initialize(URL,ResourceBundle rb){}如果我想编辑类的字段,我尝试了Uluk的建议,但是我得到了一个空指针。你能扩展一下你的意思吗?谢谢!在这个方法中,你可以进行你想要的自定义。你可以调用你的getter和setter,做一切事情来更改标签,以及从ini开始在控制器中需要做的任何事情tialize方法已经在它里面了。我应该传递给初始化器什么来指示我在初始化过程中要设置什么值?或者我应该如何向该方法添加另一个参数(比如字符串)来指示我要初始化什么值?你不能传递另一个参数。我要做的是为控制器创建一个模型并传递然后在控制器的initialize方法中,它将与模型对话,以获得所需的值