Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaFx中为自定义组件创建属性?_Java_Javafx_Properties_Gluon - Fatal编程技术网

如何在JavaFx中为自定义组件创建属性?

如何在JavaFx中为自定义组件创建属性?,java,javafx,properties,gluon,Java,Javafx,Properties,Gluon,经过几个小时的工作,我终于了解了如何使用javafx和Gluons场景生成器创建自定义组件。 如何为将出现在场景生成器属性菜单中的组件添加新属性,以便在设计时输入属性值。您需要对某些内容进行子类化,最有可能是Parent、Region或Pane的实现。从那里,您可以加载FXML,该FXML由您在场景生成器中执行的任何操作生成 例如: public class MyComponent extends VBox { private final StringProperty foo = new

经过几个小时的工作,我终于了解了如何使用javafx和Gluons场景生成器创建自定义组件。
如何为将出现在场景生成器属性菜单中的组件添加新属性,以便在设计时输入属性值。

您需要对某些内容进行子类化,最有可能是
Parent
Region
Pane
的实现。从那里,您可以加载FXML,该FXML由您在
场景生成器中执行的任何操作生成

例如:

public class MyComponent extends VBox {
    private final StringProperty foo = new SimpleStringProperty();

    public MyComponent {
        final Parent root = (Parent) FXMLLoader.load(getClass().getResource(fxmlPath));

        getChildren().add(root);
    }

    public final StringProperty fooProperty() { return foo; }
    public final String getFoo() { return foo.get(); }
    public final void setFoo(String foo) { this.foo.set(foo); }
}
这可能会产生一个额外的容器,一个是
MyComponent
,另一个是FXML的根节点。要防止出现这种情况,请使用
fxmloader.setRoot()

更新 似乎您还有一个额外的障碍-具有主逻辑的控制器与
MyComponent
解耦

有很多方法可以做到这一点:

通过引用传递 您可以将
MyComponent
的引用传入控制器

public class MyController {
    /* Your controller stuff */

    private MyComponent component;

    public final void setComponent(MyComponent component) {
        // You can bind your controller properties to fooProperty here
    }
}
然后,在
MyComponent
中加载FXML时,您将获得控制器的引用并手动调用
setComponent()

通过公开控制器属性 此方法直接在
MyComponent

public class MyComponent extends VBox {
    // Other stuff

    private MyController controller;

    public MyComponent {
        // Original stuff

        this.controller = loader.getController();
    }

    public final StringProperty fooProperty() {
        assert controller != null; // If you loaded correctly this assertion should be valid

        return controller.fooProperty();
    }

    public final String getFoo() { return fooProperty().get(); }
    public final void setFoo(String foo) { fooProperty().set(foo); }
}
将控制器集成到组件中 此方法将
MyComponent
MyController
简单地组合到一个类中。您需要
fxmloader.setController(此)


优点是您可以直接访问所有内容。糟糕的是,有些人会说这违反了MVC。

只需为属性添加getter和setter。创建自定义组件时,最好使用
fx:root
来允许使用
fxmloader\setRoot()
。您的示例没有错,但它是不正确的。@mrmcwolf我确实指出了这一点,我想?这几乎让我达到了目的,但是我似乎无法从同一个包中的控制器文件访问getFoo()方法。有什么建议吗?@TonyWolff Updated。