2016-12-16 4 views
0

Я понимаю, как передать значение между двумя формами ala https://www.youtube.com/watch?v=HFAsMWkiLvgПередайте значение между двумя окнами JavaFX, которые настраиваются через fxml?

Проблема в том, как это делается в видео. (Быть статическим, что есть). Мне не удалось заставить FXMLLoaders работать, когда внутри статического метода используется метод getClass(). Он нестатический. 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. Успешно это делает. (Выше я есть мой @FXML крюк объявлен для loginButton)

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

Общепринятый способ обмена данных между двумя или более отдельными частями пользовательского интерфейса является использование типа подхода MVC/MVP. В этих шаблонах вы инкапсулируете данные в «модель» («М» в любом) таким образом, чтобы их можно было наблюдать и отправлять уведомления, если они меняются. Тогда одна часть пользовательского интерфейса может обновить модель, и другие части пользовательского интерфейса, которые ее наблюдают, будут уведомлены, если они будут изменены.

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 в authenticationState - true. Так как отключенное состояние пункта меню связано с (44) отрицательным значением свойства loggedIn, элемент меню автоматически включается. Если у вас есть кнопка «Выход», просто установите для нее loggedIn свойство false, и пункт меню снова будет отключен.

+0

Благодарим вас за подробное объяснение! – JosephCW

 Смежные вопросы

  • Нет связанных вопросов^_^