在javafx中绘制多边形

在javafx中绘制多边形,java,javafx,javafx-8,Java,Javafx,Javafx 8,我试图在javafx中绘制一个多边形,并将其添加到鼠标点坐标数组中。我的问题是,当我用鼠标左键单击其他东西时,我不知道如何使它停止 Polygon polygon = new Polygon(); rootPane.setOnMouseClicked((MouseEvent mouseEvent) -> { do { polygon.getPoints().addAll(mouseEvent.getX(),mouseEvent.getY()); } whil

我试图在javafx中绘制一个多边形,并将其添加到鼠标点坐标数组中。我的问题是,当我用鼠标左键单击其他东西时,我不知道如何使它停止

Polygon polygon = new Polygon();
rootPane.setOnMouseClicked((MouseEvent mouseEvent) -> {
    do {
        polygon.getPoints().addAll(mouseEvent.getX(),mouseEvent.getY());
    } while(mouseEvent.getButton().equals(mouseEvent.isSecondaryButtonDown()));    
});
rootPane.getChildren().add(polygon);

可以创建对多边形的参照。如果是第一次单击,则多边形将为空,因此创建一个新多边形并将其添加到窗格中。然后继续添加点,直到右键单击为止,此时只需将多边形设置回null,以便下一次左键单击再次启动新多边形

SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;

public class DrawPolygon extends Application {

    private Polygon currentPolygon ;

    @Override
    public void start(Stage primaryStage) {
        Pane rootPane = new Pane();
        rootPane.setMinSize(600, 600);
        rootPane.setOnMouseClicked(e -> {
            if (e.getButton() == MouseButton.PRIMARY) {
                if (currentPolygon == null) {
                    currentPolygon = new Polygon();
                    currentPolygon.setStroke(Color.BLACK);
                    rootPane.getChildren().add(currentPolygon);
                }
                currentPolygon.getPoints().addAll(e.getX(), e.getY());
            } else {
                currentPolygon = null ;
            }
        });
        Scene scene = new Scene(rootPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
您可以围绕这一点发挥各种想法,以获得不同的用户体验,例如

    rootPane.setOnMouseClicked(e -> {
        if (e.getButton() == MouseButton.PRIMARY) {
            if (currentPolygon == null) {
                currentPolygon = new Polygon();
                currentPolygon.getPoints().addAll(e.getX(), e.getY());
                currentPolygon.setStroke(Color.BLACK);
                rootPane.getChildren().add(currentPolygon);
            }
            currentPolygon.getPoints().addAll(e.getX(), e.getY());
        } else {
            currentPolygon = null ;
        }
    });
    rootPane.setOnMouseMoved(e -> {
        if (currentPolygon != null) {
            currentPolygon.getPoints().set(currentPolygon.getPoints().size()-2, e.getX());
            currentPolygon.getPoints().set(currentPolygon.getPoints().size()-1, e.getY());
        }
    });

问题是,您的代码被卡在一个事件中。即使移动鼠标或释放鼠标按钮,您正在使用的事件实例的值也不会更改

将事件视为单一状态。当您的案例中发生重要事件时,单击鼠标按钮,javafx将使用鼠标状态的MouseEvent实例调用您的mouseEventHandler。再次单击时,javafx将使用新值创建一个新实例,并再次调用eventHandler

为了使这项工作,您需要一个不同的鼠标事件或稍微修改它,使其仅在一次鼠标点击上设置一个点。您需要丢失无限while循环,因为它既阻塞了EventThread,又无法处理您需要它做的事情。所以像这样的事情可能会更好一些

// this will add a point for every (secondary)mousebutton click
rootPane.setOnMouseClicked((MouseEvent me) -> {
    if(me.isSecondaryButtonDown())
        polygon.getPoints().addAll(me.getX(),me.getY());
     });

// this will add a point for every mousemovement while the secondary mousebutton is down.
rootPane.setOnMouseMoved((MouseEvent) me -> {
    if(me.isSecondaryButtonDown())
        polygon.getPoints().addAll(me.getX(),me.getY());
});
现在有了MouseDragEvent,但它主要用于移动图像和文件等数据,但我不推荐它。在您的情况下,它没有多大用处,而且它的行为仍然很糟糕


我希望这有助于您朝着正确的方向前进。

为了澄清这一点,您传递给事件处理程序(如onMouseClicked)的代码将在每次事件发生时执行。这里不需要循环。