【问题标题】:javaFX - how to use function or object of a controller from another controllerjavaFX - 如何从另一个控制器使用控制器的功能或对象
【发布时间】:2015-08-14 02:08:28
【问题描述】:

看过很多和我类似的问题,但是没弄清楚怎么解决我的问题,所以有我的代码:

我有一个简单的主要内容:

MainClassFXGui.java

public class MainClassFXGui extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));

        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Assicurazione");
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

和三个fxml文件,其中一个包含另外两个,由标签

<fx:include source="MyTab1.fxml" />

MyProgramMainGuiTab.fxml

...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
          <tabs>
              <Tab closable="false" text="MyTab1">
                   <content>
    <fx:include source="MyTab1.fxml" />
                   </content>
              </Tab>
              <Tab closable="false" text="MyTab2">
                   <content>
    <fx:include source="MyTab2.fxml" />
                   </content>
              </Tab>
          </tabs>
    </TabPane>
...

和三个控制器:

MyProgramMainGuiTabController.java

....
@FXML
private Label LeftSt;
/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    LeftSt.setText("");
}    

public void setLeftSt(String st){
    LeftSt.setText(st);
}
...

MyTab1Controller.java

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}

我是这样尝试的:

MyTab1Controller.java

private MyProgramMainGuiTabController controller;

@FXML
private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    FXMLLoader fxmlLoader = new
    FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
    try {
         fxmlLoader.load();            
    } catch (IOException exception) {
         throw new RuntimeException(exception);
    }
    controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}

但是我有一个空指针异常,或者如果我在 handleButtonAction 函数中移动对象“控制器”的实例化代码,我没有任何错误,但标签没有改变。

也许我可以在 MainClassFXGui.java 中创建一个静态场景和一个静态舞台? 但后来我不知道如何使用它们......

MainClassFXGui.java

public class MainClassFXGui extends Application {
    static private Scene scene;
    static private Stage stage;

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));

        this.scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Assicurazione");
        stage.show();
        this.stage = stage;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public static Scene getScene(){
        return AssicurazioneFXGui.scene;
    }

    public static Stage getStage(){
        return AssicurazioneFXGui.stage;
    }

}

我可以用 getScene() 或 getStage() 做点什么吗?有什么想法或建议吗?

谢谢大家

【问题讨论】:

  • 你能看看这个问题和我的回答是否有帮助吗?:stackoverflow.com/q/21995359/1396265 - 谢谢 - Rainer
  • 嗨 Rainer,是的,我已经看过这个问题,但对我没有帮助:当我尝试使用控制器时,如果我在“初始化”中插入代码,就会出现空指针异常,或者如果我将代码放入函数中,它什么也没有。 (也许我理解错了?)
  • 你能说出想要的场景吗?是否通过单击按钮更改标签文本?
  • 你在哪里加载 MyTab1Controller.fxml ?
  • 嗨卡利普斯。是的,当单击按钮或出现错误时,必须更改标签。对不起,我做错了,真的MyTab1Controller.fxml是MyTab1Controller.java:主加载的MyTab1Controller.fxml的控制器..

标签: javafx scene stage


【解决方案1】:

MyTab1Controller 中定义一个StringProperty,使用常用方法:

public class MyTab1Controller {

    private final StringProperty leftSt = new SimpleStringProperty();

    public StringProperty leftStProperty() { 
        return leftSt ;
    }

    public final String getLeftSt() {
        return leftStProperty().get();
    }

    public final void setLeftSt(String leftSt) {
        leftStProperty().set(leftSt);
    }

    // ...

    @FXML
    public void handleButtonAction() {
        setLeftSt(...);
    }

    // ...
}

现在将fx:id 属性分配给fx:include 标签:

<Tab closable="false" text="MyTab1">
    <content>
        <fx:include fx:id="myTab1" source="MyTab1.fxml" />
    </content>
</Tab>

这意味着您可以将 MyTab1.fxml控制器 注入到包含它的 FXML (MyProgramMainGuiTabController) 的控制器中:

public class MyProgramMainGuiTabController {

    @FXML
    private MyTab1Controller myTab1Controller ;

}

然后你可以观察属性并在标签发生变化时更新它:

public class MyProgramMainGuiTabController {

    @FXML
    private MyTab1Controller myTab1Controller ;

    @FXML
    private Label leftSt;

    public void initialize() {
        leftSt.setText("");
        myTab1Controller.leftStProperty().addListener((obs, oldValue, newValue) -> 
            leftSt.setText(newValue));
    }    
}

注意这里的规则是控制器的字段名称是 fx:id 属性的值,并附加了单词“Controller”:fx:id 中的 myTab1 解析为 myTab1Controller控制器被注入。请参阅NestedControllers 了解更多信息。

【讨论】:

    【解决方案2】:

    目前我已经以这种方式解决了。如果有人有更好的解决方案,请写信。也因为如果我需要执行一个功能,这并不能解决问题..谢谢

    MyProgramMainGuiTabController.fxml

    ...
    @FXML
    private Label LeftSt;
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        LeftSt.setText("");
    }  
    ...
    

    MyTab1Controller.fxml

    @FXML
    private Button myObject;
    
    private Scene scene;
    private Label lblDataLeft;
    
    @FXML
    private void handleButtonAction(ActionEvent event) {
            System.out.println("You clicked me!");
            setLeftSt("this works!");
    }
    
    public void setLeftSt(String st){
        if(this.scene == null)
            this.scene = myObject.getScene();
        if(this.lblDataLeft==null)
            this.lblDataLeft = (Label) scene.lookup("#LeftSt");
        if (this.lblDataLeft!=null) 
            this.lblDataLeft.setText(st); 
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-30
      • 2016-09-13
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2015-06-20
      相关资源
      最近更新 更多