2015-09-08 2 views
0

В JavaFX, как вы можете моделировать:Как сигнализировать/уведомлять суперконтроллер об изменении в субконтроллере?

Я показываю список клиентов в сцене. На левой стороне находится таблица с правой стороны (contentPane) отображаются текущие данные выбранного клиента.

(Соответствующая часть) Main-контроллер:

@jfxf.FXML 
protected def newButtonPressed(): Unit = 
{ 
    contentPane.getChildren.clear 
    contentPane.getChildren.add(FXMLLoader.load(GUILoader.load("customers/form.fxml"))) 
} 

Существует кнопка для добавления нового клиента. При нажатии этой кнопки вместо открытия всплывающего окна я заменяю «детали» - часть сцены и добавляю туда форму.

Теперь для этой формы (как и остальная часть GUI - в SceneBuilder и сохранена как .fxml) Я использую другой контроллер.

class Form extends Main with jfxf.Initializable 
{ 
    @jfxf.FXML 
    private var foreNameTextField: jfxsc.TextField = _ 
    @jfxf.FXML 
    private var lastNameTextField: jfxsc.TextField = _ 
    @jfxf.FXML 
    private var ageTextField: jfxsc.TextField = _ 

    override def initialize(url: URL, resourceBundle: ResourceBundle): Unit = 
    { 

    } 

    @jfxf.FXML 
    protected def ok(): Unit = 
    { 
     // TODO validation 
     val newPerson = new Person(-1, foreNameTextField.getText, lastNameTextField.getText, ageTextField.getText.toInt) 
     // Save to DB 
     // Close whole form 
    } 
} 

Когда я закончу с заполнением деталей нового клиента, я нажать на другую кнопку (что вызывает ОК()) и сохраните его в базу данных.

Теперь я хочу закрыть форму и заменить ее на детализированную форму.

Что-то вроде вызова защищенного метода в основном-контроллера, как:

protected def clearDetails(): Unit = 
{ 
    contentPane.getChildren.clear 
    contentPane.getChildren.add(savedOldDetails) 
} 

не будет работать, конечно. (Кинет во время выполнения-исключение, потому что нет ContentPane в суб/форм-контроллера (даже если я делаю это защищенный)

В Qt (C++) Я хотел бы использовать сигналы/слоты и подключить их соответствующим образом.

Похоже, в JavaFX нет ничего подобного. Как я должен делиться такой информацией?

Мне нужно, чтобы создать «супер-контроллер» для ContentPane ли?

ответ

1

(я не знаю, Scala, так что я напишу это на Java, надеюсь, что все в порядке).

Вы можете определить наблюдаемое свойство в контроллере Form, и наблюдать его при загрузке формы из главного контроллера:

public class Form implements Initializable { 

    private final ObjectProperty<Person> person = new SimpleObjectProperty<>(null); 

    public ObjectProperty<Person> personProperty() { 
     return person ; 
    } 

    public final Person getPerson() { 
     return personProperty().get(); 
    } 

    public final void setPerson(Person person) { 
     personProperty().set(person); 
    } 

    // ... code you had before... 

    @FXML 
    protected void ok() { 
     Person person = new Person(-1, foreNameTextField.getText(), lastNameTextField.getText(), ageTextField.getText()); 
     // save to DB... 
     personProperty().set(person); 
    } 
} 

Теперь в главном контроллере, загрузите форму следующим образом:

@FXML 
protected void newButtonPressed() { 
    contentPane.getChildren().clear(); 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("customers/form.fxml")); 
    Parent form = loader.load(); 
    Form formController = loader.getController(); 
    formController.personProperty().addListener((obs, oldPerson, newPerson) { 
     if (newPerson != null) { 
      // clear form, etc, e.g. 
      clearDetails(); 
     } 
    }); 
    contentPane.getChildren().add(form); 
} 
Смежные вопросы