我会想象您的问题是:如何通过单击线条的两个像素内的任意位置来选择线条?
在下面的示例输出中,用户刚刚在非常靠近三角形右侧的线处单击,导致该线被突出显示。
下面的代码通过测试窗格中的每个形状并查看该形状是否与鼠标按下位置两侧 2 像素的矩形框相交来工作。该解决方案与解决方案中使用的解决方案非常相似:Checking Collision of Shapes with JavaFX。
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.*;
import javafx.stage.Stage;
public class LinePicker extends Application {
public static void main(String[] args) { Application.launch(LinePicker.class); }
@Override public void start(final Stage stage) throws Exception {
final Pane pane = new Pane();
pane.getChildren().setAll(
new Line( 10, 150, 50, 10),
new Line( 10, 150, 100, 150),
new Line(100, 150, 50, 10)
);
pane.setPrefSize(
200, 200
);
Scene scene = new Scene(addPickHandler(pane));
stage.setScene(scene);
stage.show();
}
private Pane addPickHandler(final Pane pane) {
pane.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
final Rectangle hotspot = new Rectangle(
event.getX() - 2,
event.getY() - 2,
4,
4
);
for (Node child : pane.getChildren()) {
if (child instanceof Shape) {
final Shape shape = (Shape) child;
Shape intersect = Shape.intersect(shape, hotspot);
if (intersect.getBoundsInLocal().getWidth() != -1) {
shape.setStyle("-fx-stroke: red;");
} else {
shape.setStyle("-fx-stroke: black;");
}
}
}
}
});
return pane;
}
}
评论
为什么 shved90 无法在他的应用程序中为他提供上述解决方案,这让我有点困惑。
Shev 评论说:“在 Line 中,据我了解,它会检查所有边界,如果线有某个角度,它的边界会像矩形,因此我检查是否发现了它(不仅在线和最近的点)。但我需要几何运算。
然而,这里提出的解决方案是基于几何的解决方案,因为点击热点必须与实际线相交,而不是与包围线的矩形边界相交。这是因为解决方案中使用的Shape.intersect方法适用于所涉及的实际形状的交集,而不是所涉及的形状的边界。
但是请注意,在 shved90 的原始问题中,他使用的是Node intersects方法而不是该Shape.intersect
方法。Node intersects 的文档指出“此函数的默认行为只是检查给定坐标是否与局部边界相交。”,从他的评论来看,这显然不是 shved90 想要的。
Shev 确实注意到“我在 javaFx 中找到了 Line2d 类,就像在 Java2D 中一样,我转换为这条线并使用它的交集”。我不建议使用与 JavaFX 捆绑在一起的Line2D类,因为它是一个私有的 com.sun api,不能保证在未来的 JavaFX 版本中存在或具有二进制向后兼容的 API。