2016-06-12 70 views
0

我开始研究JavaFX FXML应用程序技术。JavaFX FXML访问成功使用lookup()方法,但不使用@FXML注释

我使用主类中访问的一个主舞台Main.getStage(),它在应用程序开始时使用重写方法public void start(Stage stage)调用。在内部有两个public static Scene以在切换它们时保持持久性。

@Override 
public void start(Stage stage) throws Exception { 
    STAGE = stage; 
    LOGIN = new Scene(FXMLLoader.load(getClass().getResource("Login.fxml"))); 
    REGISTER = new Scene(FXMLLoader.load(getClass().getResource("Register.fxml"))); 

    STAGE.setScene(LOGIN); 
    STAGE.setTitle("FXApplication"); 
    STAGE.show(); 
} 

public static Stage getStage() { 
    return STAGE; 
} 

这两个场景都有相同的控制器类,称为MainController。使用:

  • 按键采用fx:id="buttonLoginRegister"REGISTER场景
  • 按键采用fx:id="buttonRegisterBack"回去给LOGIN之一。

并且两者具有相同的onClick事件handleButtonAction(ActionEvent event)。 TextFields是用于登录/注册用户名的字段。

​​

我的目标是将值从LOGIN文本字段复制到一个在REGISTER现场。它使用上面的代码很好用。然而,首先我尝试访问另一个场景中的元素:

fieldRegisterUsername.setText(fieldLoginUsername.getText()); 

这是错误的。确切地说,fieldRegisterUsernamenull

为什么在lookup(String id)方法中发现某些元素而不是@FXML注释?

+0

通常不鼓励用于不同FXML(视图)的共享控制器。如果你只是从JavaFX开始,我特别建议不要这样做。看看[这个问题](http://stackoverflow.com/questions/17914254/javafx-multiple-fxml-and-1-shared-controller)。 – Itai

+0

这是有争议的,很多开发人员使用这种方式,并且相同的数字是最简单的。就我个人而言,在2个小场景中我看不出共享控制器的坏处。我之前已经阅读过这个链接的问题,但是这与我的持久性需求相冲突。 –

+0

不知道我明白你的意思是“需要坚持”。查看我的答案,解释为什么'lookup'在你的情况下起作用。请记住,除非你为'FXMLLoader'设置了控制器,否则每次调用'load'都会创建一个控制器类的新实例。 – Itai

回答

2

正如我的评论中提到的,在不同视图之间共享控制器并不是一个好主意,我强烈建议您为每个视图制作一个单独的控制器。

至于你的问题本身 - 你有两个控制器类的实例,每调用一次FXMLLoader.load。据推测,一个视图具有fieldLoginUsername TextField,而另一个视图具有fieldRegisterUsername
如果满足if声明的条件,则表示活动场景是登录场景,因此处理它的控制器是具有fieldLoginUsername的控制器,因此fieldRegisterUsername自然会为空。

但在if子句中更改活动现场向登记册之一,所以,当你打电话的时候scene#lookup你指的是其控制器的注册控制器,一个是确实有fieldRegisterUsername现场的第一线。

如果您在更改活动场景之前调用scene#lookup,您会发现它也会返回null。

如果您必须对控制器使用相同的类,那么您可能希望确保只有该类的一个实例。这将需要使用FXMLLoader#setController

+0

感谢您的解释。如果在不同的Scanes之间使用一个控制器是一个坏主意,您是否会建议我使用两个分离的控制器来实现相同效果?我不知道如何轻松传递价值。 –

+0

Arjan在对原始问题的评论中链接了两个优秀的答案。 – Itai