经过几个小时的工作,我终于明白了如何使用javafx和胶粘场景生成器创建自定义组件。如何为该组件添加新属性,该属性将出现在“场景生成器属性”菜单中,以便在设计时输入属性值。
发布于 2017-12-08 08:35:11
您需要子类某些东西,很可能是Parent、Region或Pane的实现。从这里,您可以加载FXML,它是由您在Scene Builder中所做的任何操作生成的。
示例:
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的根节点。要防止出现这种情况,请使用FXMLLoader.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组合成一个类。你需要FXMLLoader.setController(this)。
好处是你可以直接接触到所有的东西。不好的是,有些人会说这违反了MVC。
https://stackoverflow.com/questions/47710056
复制相似问题