我正在尝试创建一个组件,该组件在线条的父级上注册监听器,并且当它更改时,它会在线条的父级上添加/删除矩形。
您可以看到下面的代码。 基本上我有 2 个按钮
- 添加 > 将行添加到 demoPane
- 删除 > 从 demoPane 中删除该行
正如我已经解释的那样,我还在父行上注册了一个监听器。
当我单击“添加”按钮时,一切正常...添加了线条,随后也添加了矩形。
当我按删除时,该行将从 demoPane 中删除,但在删除矩形时,会引发以下异常:
-Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = AnchorPane[id=demoPane]
at javafx.scene.Parent$2.onProposedChange(Unknown Source)
at com.sun.javafx.collections.VetoableListDecorator.remove(Unknown Source)
at demo.Delete.lambda$2(Delete.java:63)
这发生在第 63 行,这是我从 demoPane 中删除矩形的地方
private static void mountDemo(AnchorPane demoPane) {
Button buttonAdd = new Button("Add");
Button buttonRemove = new Button("Remove");
Line line = new Line(100, 100, 400, 100);
Rectangle rectangle = new Rectangle(20, 20);
demoPane.getChildren().add(buttonAdd);
demoPane.getChildren().add(buttonRemove);
buttonAdd.setOnMouseClicked((event)->demoPane.getChildren().add(line));
buttonRemove.setOnMouseClicked((event)->demoPane.getChildren().remove(line));
line.parentProperty().addListener((observable, oldParent, newParent)->{
if(newParent != null)
((Pane)newParent).getChildren().add(rectangle);
else
((Pane)oldParent).getChildren().remove(rectangle);
});
}
有人可以帮我吗?我做错了什么?
最佳答案
既然我知道你想做什么,我建议创建一个新类。假设您想要在两点之间有一个水平箭头:
public class Arrow extends Path {
private static Double ARROW_HEAD_SIZE = 10D;
private Point2D startPoint;
private Point2D endPoint;
public Arrow(Point2D start, Point2D end) {
super();
setStrokeWidth(1);
startPoint = start;
endPoint = end;
draw();
}
public void draw() {
getElements().clear();
// Goto start point
MoveTo startMove = new MoveTo();
startMove.setX(startPoint.getX());
startMove.setY(startPoint.getY());
getElements().add(startMove);
// Horizontal line from start point to end point
HLineTo line = new HLineTo();
line.setX(endPoint.getX());
getElements().add(line);
// First line for the arrow
LineTo firstArrow = new LineTo();
firstArrow.setX(endPoint.getX() - ARROW_HEAD_SIZE);
firstArrow.setY(endPoint.getY() - ARROW_HEAD_SIZE);
getElements().add(firstArrow);
// Return to end point
MoveTo lastMove = new MoveTo();
lastMove.setX(endPoint.getX());
lastMove.setY(endPoint.getY());
getElements().add(lastMove);
// Second line for the arrow
LineTo secondArrow = new LineTo();
secondArrow.setY(endPoint.getY() + ARROW_HEAD_SIZE);
secondArrow.setX(endPoint.getX() - ARROW_HEAD_SIZE);
getElements().add(secondArrow);
}
}
这样,您只需从主类中添加/删除一个实例即可:
Point2D startPoint = new Point2D(50, 50);
Point2D endPoint = new Point2D(100, 50);
Arrow arrow = new Arrow(startPoint, endPoint);
buttonAdd.setOnMouseClicked((event) -> root.getChildren().add(arrow));
buttonRemove.setOnMouseClicked((event) -> root.getChildren().remove(arrow));
此外,您可以让新类扩展某种 Pane ,而不是使用路径,只需在其中加入几行,或者一条直线和一个三角形或其他什么。
关于JavaFX pane.getChildren().remove(child) 抛出 IllegalArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32026419/