2016-12-16 111 views
0

我明白如何传递两种形式之间的值ala https://www.youtube.com/watch?v=HFAsMWkiLvg通过fxml设置的两个JavaFX窗口之间传递值?

问题在于它在视频中的做法。 (作为静态)。由于使用了getClass()方法,我无法在静态方法内部使FXMLLoaders工作。它只是非静态的。 getClass().getResource("myFile.fxml")

这里是我怎么装我的第二个形式。

try { 
     FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("LoginForm.fxml")); 
     Parent root1 = (Parent) fxmlLoader.load(); 
     Stage stage = new Stage(); 
     stage.initModality(Modality.APPLICATION_MODAL); 
     stage.setTitle("HWI - Login"); 
     stage.setResizable(false); 
     stage.setScene(new Scene(root1)); 
     stage.showAndWait(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

在scenebuilder里面我设置了要运行的方法,它在本质上是检查用户名/密码的数据库。所有这些都是在我的loginController类中完成的。一旦成功,它会这样做。 (以上我有申报loginButton我@FXML钩)

Stage stage = (Stage) loginButton.getScene().getWindow(); 
stage.close(); 

当前的方式我有程序的设置是,所有的菜单都设置为禁用用户在签署之前,我有一个非静态方法已经设置为重新启用一切,但我无法调用它,因为我无法在关闭第二个窗口之前弥补静态/非静态之间的差距。

谢谢,

+1

'getResource'方法可以在静态的方式来使用:'ExampleClass.class.getResource'但也有比静态控制器类更好的方法。见http://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml和http://stackoverflow.com/questions/40117925/javafx-many-static-fxml-controllers – Omid

+0

这通常是一个非常糟糕的主意,使控制器中的任何东西(除了常量)都是静态的。我不清楚你想要做什么:你想从登录控制器到主控制器进行通信,反之亦然? (第二个很容易,第一个有点棘手,所以如果是第一个,请确切地说明*你想要沟通什么)。 –

回答

2

普遍接受的方式来共享UI的两个或更多个不同的部分之间的数据是使用MVC/MVP型方法。在这些模式中,您可以将数据封装在“模型”(两者中的“M”)中,以便可以观察数据并在发送更改时发送通知。然后,用户界面的一部分可以更新模型,并且观察它的用户界面的其他部分会在其更改时得到通知。

的JavaFX使这一特别是通过执行observable properties对你来说,这只是包装价值和可以很容易地添加,如果他们改变通知听众容易。

因此,在这个例子中,你可以这样做:

public class AuthenticationState { 

    private final BooleanProperty loggedIn = new SimpleBooleanProperty(false); 

    public BooleanProperty loggedInProperty() { 
     return loggedIn ; 
    } 

    public final boolean isLoggedIn() { 
     return loggedInProperty().get(); 
    } 

    public final void setLoggedIn(boolean loggedIn) { 
     loggedInProperty().set(loggedIn); 
    } 

    private final StringProperty userName = new SimpleStringProperty(); 

    public StringProperty userNameProperty() { 
     return userName ; 
    } 

    public final String getUserName() { 
     return userNameProperty().get(); 
    } 

    public final void setUserName(String userName) { 
     userNameProperty().set(userName); 
    } 

    // other properties as needed, e.g. IntegerProperty logInAttempts , etc. 
} 

现在你的主控制器可以这样做:

public class MainController { 

    @FXML 
    private final MenuItem deleteAllDataMenuItem ; 

    private AuthenticationState authenticationState ; 

    public void initialize() { 

     authenticationState = new AuthenticationState(); 

     deleteAllDataMenuItem.disableProperty() 
      .bind(authenticationState.loggedInProperty().not()); 

    } 

    @FXML 
    public void logIn() { 
     try { 
      FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("LoginForm.fxml")); 
      Parent root1 = (Parent) fxmlLoader.load(); 

      LoginController loginController = fxmlLoader.getController(); 
      loginController.setAuthenticationState(authenticationState); 

      Stage stage = new Stage(); 
      stage.initModality(Modality.APPLICATION_MODAL); 
      stage.setTitle("HWI - Login"); 
      stage.setResizable(false); 
      stage.setScene(new Scene(root1)); 
      stage.showAndWait(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

和你的登录控制器可以看起来像:

public class LoginController { 

    private AuthenticationState authenticationState ; 

    public void setAuthenticationState(AuthenticationState authenticationState) { 
     this.authenticationState = authenticationState ; 
    } 

    @FXML 
    public void login() { 
     // check login: 
     boolean loginSuccessful = ... ; 

     authenticationState.setLoggedIn(loginSuccessful); 

     // ... 
    } 
} 

现在,当用户登录时,登录控制器将设置loggedIn属性authenticationStatetrue。由于菜单项的禁用状态绑定到loggedIn属性(的负值),因此菜单项会自动启用。如果你有一个“退出”按钮,只是它的loggedIn属性设置为false,菜单项将被再次禁用。

+0

谢谢你的详细解释! – JosephCW

相关问题