简体   繁体   English

在JavaFX中绘制多边形

[英]Draw a polygon in javafx

I'm trying to draw a polygon in javafx adding to its array of point the mouse coordinates. 我正在尝试在javafx中绘制一个多边形,以将鼠标坐标添加到其点数组中。 My problem is that I don't know how to make it stop when I click something else from the mouse left click. 我的问题是,当我从鼠标左键单击其他内容时,我不知道如何使其停止。

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);

You can create a reference to a polygon. 您可以创建对多边形的引用。 If it's the first click, then the polygon will be null , so create a new one and add it to your pane. 如果是第一次单击,则多边形将为null ,因此创建一个新的多边形并将其添加到您的窗格中。 Then keep adding points until you get a right click, at which point you just set the polygon back to null , so that the next left click starts a new polygon again. 然后继续添加点,直到右键单击为止,此时您只需将多边形设置回null ,以便下次单击鼠标左键即可再次启动一个新的多边形。

SSCCE: 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);
    }
}

You can play with various ideas around this to get different user experiences, eg 您可以围绕此进行各种构想,以获得不同的用户体验,例如

    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());
        }
    });

The problem is that your code gets stuck in one single event. 问题在于您的代码被卡在一个事件中。 Even when you move your mouse, or release the mouse button, the values of that event instance you are working with, are not going to change. 即使您移动鼠标或释放鼠标按钮,您正在使用的事件实例的值也不会改变。

Think of the event as a single state. 将事件视为单个状态。 When something important happens (in your case, a mousebutton is clicked), javafx will call your mouseEventHandler using a MouseEvent instance with the state of the mouse at that verry moment. 当发生重要事件时(在您的情况下,单击了鼠标按钮),javafx将使用具有该状态的MouseEvent实例的MouseEvent实例来调用mouseEventHandler。 When you click again javafx will create a new instance with new values, and call the eventHandler again. 再次单击时,javafx将创建一个具有新值的新实例,并再次调用eventHandler。

In order to make this work, you need a different mouse event (or modify it slightly so its only setting a point on a single mouse click). 为了使此工作有效,您需要一个不同的鼠标事件(或稍作修改,使其仅在单击一次鼠标时设置一个点)。 You need to lose the (infinite) while-loop as it is both blocking the EventThread, and not working for the stuff you need it to do. 您需要丢失(无限)while循环,因为它既阻塞了EventThread,又没有为您需要的事情工作。 So something like this might work a little better. 因此,这样的操作可能会更好一些。

// 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());
});

Now there is a MouseDragEvent, but thats mostly for moving data (like images and files), but I wouldnt recommend it. 现在有一个MouseDragEvent,但是多数情况下是用于移动数据(例如图像和文件)的,但是我不建议这样做。 In your case it isnt much usefull, and its behavior is quit buggy still. 在您的情况下,它不是很有用,并且它的行为仍然是越野车。

I hope this helped you in the right direction. 希望这对您朝正确的方向有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM