2016-12-16 159 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

相關問題