我编写了以下代码,用于通过鼠标事件添加和删除点或圆。下一步是在创建它们时创建一条线(创建多边形)。我完全陷入困境,不知道从哪里开始。我正在寻找文档,但是如果有人可以指出正确的方向,我将不胜感激。

package application;

//import all needed classes
import javafx.collections.ObservableList;
import javafx.scene.input.MouseButton;
import javafx.application.Application;
import javafx.scene.shape.Circle;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Node;

public class Main extends Application {

    // using the base class of layout panes
    Pane pane = new Pane();

    @Override
    public void start(Stage primaryStage) {

        // what to do when the mouse is clicked
        pane.setOnMouseClicked(e -> {
            double drawX = e.getX();// position of mouse in X axle
            double drawY = e.getY();// position of mouse in y axle

            if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
                Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
                pane.getChildren().add(circle);
            } else if (e.getButton() == MouseButton.SECONDARY) {
                deleteCircle(drawX, drawY);// using the deleteCircle function to delete the circle if right click on the circle
            }

        });

        // container to show all context in a 500px by 500px windows
        try {
            Scene scene = new Scene(pane, 500, 500);// size of the scene
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // method to draw the circle when left click
    private Circle makeCircle(double drawX, double drawY) {
        Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
        circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
        return circle;
    }

    // method to delete the circle using the ObservableList class
    private void deleteCircle(double deletX, double deleteY) {

        // loop to create my list of circles 'til this moment
        ObservableList<Node> list = pane.getChildren();
        for (int i = list.size() - 1; i >= 0; i--) {
            Node circle = list.get(i);

            // checking which circle I want to delete
            if (circle instanceof Circle && circle.contains(deletX, deleteY)) {
                pane.getChildren().remove(circle);
                break;
            }
        }
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

最佳答案

我将向窗格的子级添加一个更改侦听器,向该窗格添加一个多边形,如果有两个以上的Circle,则需要重绘该多边形:

public class Main extends Application {

    // using the base class of layout panes
    Pane pane = new Pane();
    Polygon polygon = new Polygon();

    @Override
    public void start(Stage primaryStage) {

        // what to do when the mouse is clicked
        pane.setOnMouseClicked(e -> {
            double drawX = e.getX();// position of mouse in X axle
            double drawY = e.getY();// position of mouse in y axle

            if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
                Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
                pane.getChildren().add(circle);
            } else if (e.getButton() == MouseButton.SECONDARY) {
                deleteCircle(drawX, drawY);// using the deleteCircle function to delete the circle if right click on the circle
            }

        });

        pane.getChildren().add(polygon);

        pane.getChildren().addListener(new ListChangeListener<Node>() {
            @Override
            public void onChanged(Change<? extends Node> c) {
                int numOfCircles = pane.getChildren().size() - 1;
                if ( numOfCircles >= 2 ) {
                    polygon.setStroke(Color.BLACK);
                    polygon.getPoints().clear();
                    for ( int i = 0; i <= numOfCircles; i++ ) {
                        Node node = pane.getChildren().get(i);
                        if ( node.getClass() == Circle.class ) {
                            polygon.getPoints().addAll(
                                    ((Circle) node).getCenterX(),
                                    ((Circle) node).getCenterY()
                            );
                        }
                    }
                    System.out.println(polygon.getPoints());
                }
            }
        });

        // container to show all context in a 500px by 500px windows
        try {
            Scene scene = new Scene(pane, 500, 500);// size of the scene
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // method to draw the circle when left click
    private Circle makeCircle(double drawX, double drawY) {
        Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
        circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
        return circle;
    }

    // method to delete the circle using the ObservableList class
    private void deleteCircle(double deletX, double deleteY) {

        // loop to create my list of circles 'til this moment
        ObservableList<Node> list = pane.getChildren();
        for (int i = list.size() - 1; i >= 0; i--) {
            Node circle = list.get(i);

            // checking which circle I want to delete
            if (circle instanceof Circle && circle.contains(deletX, deleteY)) {
                pane.getChildren().remove(circle);
                break;
            }
        }
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

}


您也不能使用更改侦听器,但是每当添加或删除圆时都调用重绘。此外,您还可以向每个圈子添加onclick侦听器,以调用delete函数并以更有效的方式进行删除:

public class Main extends Application {

    // using the base class of layout panes
    Pane pane = new Pane();
    Polygon polygon = new Polygon();

    @Override
    public void start(Stage primaryStage) {

        // what to do when the mouse is clicked
        pane.setOnMouseClicked(e -> {
            double drawX = e.getX();// position of mouse in X axle
            double drawY = e.getY();// position of mouse in y axle

            if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
                Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
                pane.getChildren().add(circle);
                circle.setOnMouseClicked( event -> {
                    deleteCircle(circle);
                    // consume event so that the pane on click does not get called
                    event.consume();
                });
                redrawPolygon();
            }

        });

        polygon = new Polygon();
        polygon.setFill(Color.TRANSPARENT);
        polygon.setStroke(Color.BLACK);
        pane.getChildren().add(polygon);

        // container to show all context in a 500px by 500px windows
        try {
            Scene scene = new Scene(pane, 500, 500);// size of the scene
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // method to draw the circle when left click
    private Circle makeCircle(double drawX, double drawY) {
        Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
        circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
        return circle;
    }

    private void redrawPolygon() {
        int numOfCircles = pane.getChildren().size() - 1;
        if ( numOfCircles > 0 ) {
            polygon.getPoints().clear();
            for ( int i = 0; i <= numOfCircles; i++ ) {
                Node node = pane.getChildren().get(i);
                if ( node.getClass() == Circle.class ) {
                    polygon.getPoints().addAll(
                            ((Circle) node).getCenterX(),
                            ((Circle) node).getCenterY()
                    );
                }
            }
        }
    }

    private void deleteCircle(Circle circle){
        pane.getChildren().remove(circle);
        redrawPolygon();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

}


如果您只想使用一键式处理程序,也可以这样操作:

   pane.setOnMouseClicked(e -> {

        if ( e.getTarget().getClass() == Circle.class ) {
            deleteCircle((Circle)e.getTarget());
        } else {
            Circle circle = makeCircle(e.getX(), e.getY());// using the makeCircle method to draw the circle where the mouse is at the click
            pane.getChildren().add(circle);
            redrawPolygon();
        }

    });

关于java - 与javaFX的连接点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36145084/

10-09 01:30