0

在 JavaFX 中,如何对以下内容进行建模:

我在场景中显示客户列表。左侧有一个表格,右侧 ( contentPane ) 显示当前选择的客户的详细信息。

(相关部分)主控制器:

@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
    }
} 

当我填写完新客户的详细信息后,我单击另一个按钮(调用 ok())并将其保存到数据库中。

我现在要做的是关闭表单并将其替换为详细信息表单。

类似于在主控制器中调用受保护的方法,例如:

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

当然不会工作。(将抛出运行时异常,因为子/表单控制器中没有内容窗格(即使我将其设为保护)

在 Qt (C++) 中,我会使用信号/插槽并相应地连接它们。

似乎在 JavaFX 中没有类似的东西。我应该如何分享这些信息?

我需要为 contentPane 创建一个“超级控制器”吗?

4

1 回答 1

0

(我不知道 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);
}
于 2015-09-08T19:04:57.833 回答