动态加载指向由 FXML 构造的多边形
Dynamically loads point to a Polygon constructed by FXML
在这个 中,加载器 class 用于在构建 ComboBox
时动态加载它(没有 post 处理)。
我想使用与 pre-process 类似的技术并重用 Polygon ,但多边形不会公开 items
属性 或类似的。
我的解决方案是扩展 Polygon 并添加这样的 属性:
public class DPolygon extends javafx.scene.shape.Polygon{
public ObjectProperty<ObservableList<Double>> items =
new SimpleObjectProperty<>(this, "items");
public DPolygon() {
items.addListener(new ChangeListener<ObservableList<Double>>() {
@Override
public void changed(ObservableValue<? extends ObservableList<Double>>
observable, ObservableList<Double> oldValue,
ObservableList<Double> newValue) {
addPolyPoints();
}
});
}
private void addPolyPoints() { super.getPoints().setAll(items.get());}
public ObjectProperty<ObservableList<Double>>itemsProperty() { return items; }
public final ObservableList<Double> getItems() {return items.get(); }
public final void setItems(ObservableList<Double> value) {items.set(value); }
}
有装载机class供应点数:
public class PointsLoader5 {
private ObservableList<Double> items;
public ObservableList<Double> getItems() {
items = FXCollections.observableArrayList(
new Double[] {100.,0.,100., 100., 0., 0.});
return items;
}
}
在 FXML
文件中同时使用:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.Double?>
<?import javafx.xml_polygon.DPolygon?>
<DPolygon fx:id="triangle" fill="GREEN" stroke="RED" strokeType="INSIDE"
items="${pointsLoader.items}" xmlns:fx="http://javafx.com/fxml/1" >
</DPolygon>
并将它们放在一起进行测试:
public class DrawTrianle5 extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setTitle("Set points using loader");
Group group = new Group();
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
group.getChildren().add(grid);
FXMLLoader loader = new FXMLLoader(getClass().getResource("triangle/Triangle5.fxml"));
loader.getNamespace().put("pointsLoader", new PointsLoader5());
DPolygon triangle = loader.load();
grid.add(triangle, 0, 0);
Scene scene = new Scene(group, 450, 175);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
它没有问题。
我的问题是:这是正确的方法,还是有更好的方法动态加载指向由FXML
构造的Polygon
,避免post-处理?
唯一阻止您使用当前 Polygon
class 执行此操作的是 @NamedArg
annotation.
没有合适的构造函数参数
因此,一种方法是:
import java.util.List;
import javafx.beans.NamedArg;
import javafx.scene.shape.Polygon;
public class DPolygon extends Polygon {
public DPolygon(@NamedArg("points") List<Double> points) {
super(points.stream().mapToDouble(Double::doubleValue).toArray());
}
}
那么你只需要
<DPolygon xmlns:fx="http://javafx.com/fxml/1" points="$points" fill="GREEN" stroke="RED" strokeType="INSIDE" />
测试:
import java.util.Arrays;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
public class PolygonTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Polygon.fxml"));
loader.getNamespace().put("points", Arrays.asList(100.0,0.0,100.0,100.0,0.0,0.0));
Polygon poly = loader.load();
Scene scene = new Scene(new Group(poly), 450, 175);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
感觉应该有一种完全没有 subclass 的方法,但我找不到一个可行的方法。
在这个 ComboBox
时动态加载它(没有 post 处理)。
我想使用与 pre-process 类似的技术并重用 Polygon ,但多边形不会公开 items
属性 或类似的。
我的解决方案是扩展 Polygon 并添加这样的 属性:
public class DPolygon extends javafx.scene.shape.Polygon{
public ObjectProperty<ObservableList<Double>> items =
new SimpleObjectProperty<>(this, "items");
public DPolygon() {
items.addListener(new ChangeListener<ObservableList<Double>>() {
@Override
public void changed(ObservableValue<? extends ObservableList<Double>>
observable, ObservableList<Double> oldValue,
ObservableList<Double> newValue) {
addPolyPoints();
}
});
}
private void addPolyPoints() { super.getPoints().setAll(items.get());}
public ObjectProperty<ObservableList<Double>>itemsProperty() { return items; }
public final ObservableList<Double> getItems() {return items.get(); }
public final void setItems(ObservableList<Double> value) {items.set(value); }
}
有装载机class供应点数:
public class PointsLoader5 {
private ObservableList<Double> items;
public ObservableList<Double> getItems() {
items = FXCollections.observableArrayList(
new Double[] {100.,0.,100., 100., 0., 0.});
return items;
}
}
在 FXML
文件中同时使用:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.Double?>
<?import javafx.xml_polygon.DPolygon?>
<DPolygon fx:id="triangle" fill="GREEN" stroke="RED" strokeType="INSIDE"
items="${pointsLoader.items}" xmlns:fx="http://javafx.com/fxml/1" >
</DPolygon>
并将它们放在一起进行测试:
public class DrawTrianle5 extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setTitle("Set points using loader");
Group group = new Group();
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
group.getChildren().add(grid);
FXMLLoader loader = new FXMLLoader(getClass().getResource("triangle/Triangle5.fxml"));
loader.getNamespace().put("pointsLoader", new PointsLoader5());
DPolygon triangle = loader.load();
grid.add(triangle, 0, 0);
Scene scene = new Scene(group, 450, 175);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
它没有问题。
我的问题是:这是正确的方法,还是有更好的方法动态加载指向由FXML
构造的Polygon
,避免post-处理?
唯一阻止您使用当前 Polygon
class 执行此操作的是 @NamedArg
annotation.
因此,一种方法是:
import java.util.List;
import javafx.beans.NamedArg;
import javafx.scene.shape.Polygon;
public class DPolygon extends Polygon {
public DPolygon(@NamedArg("points") List<Double> points) {
super(points.stream().mapToDouble(Double::doubleValue).toArray());
}
}
那么你只需要
<DPolygon xmlns:fx="http://javafx.com/fxml/1" points="$points" fill="GREEN" stroke="RED" strokeType="INSIDE" />
测试:
import java.util.Arrays;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
public class PolygonTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Polygon.fxml"));
loader.getNamespace().put("points", Arrays.asList(100.0,0.0,100.0,100.0,0.0,0.0));
Polygon poly = loader.load();
Scene scene = new Scene(new Group(poly), 450, 175);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
感觉应该有一种完全没有 subclass 的方法,但我找不到一个可行的方法。