鼠标单击多个节点上的事件

时间:2016-07-19 07:09:13

标签: java javafx

在练习中,单击矩形时,会在矩形边界中显示一个圆。但是当在圆圈上按下鼠标右键时,它应该被删除。我使用了ArrayList来存储正在添加的圆圈。但是我怎么知道点击了哪个圆圈?然后应该为该圆圈调用Click事件以将其删除。

package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.control.Label;
import java.util.ArrayList;
import javafx.scene.text.Font;
import javafx.scene.layout.Pane;

public class Main extends Application {

    private ArrayList < Circle > circles = new ArrayList<>();
    private Rectangle rectangle = new Rectangle( 200, 100, 1000, 600 );

    private Label[] label = new Label[2];
    private int counter = 0;

    private Pane pane = new Pane();

    @Override
    public void start( Stage stage ) throws Exception {
        rectangle.setFill( Color.WHITE );
        rectangle.setStroke( Color.BLACK );
        rectangle.setStrokeWidth( 1 );

        rectangle.setOnMouseClicked( e -> {
            if( e.getButton() == MouseButton.PRIMARY ) {
                // e.getX and e.getY will place the circle at the location of cursor click
                AddCircle( e.getX(), e.getY() );
            }
        });

        // will format the labels to be added on the pane
        formatLabels();

        pane.getChildren().addAll( label[0], label[1], rectangle );
        Scene scene = new Scene( pane, 1200, 650, Color.ANTIQUEWHITE );
        stage.setScene( scene );
        stage.setTitle( "Add and Remove Circles" );
        stage.show();
    }

    public void AddCircle( double X, double Y ) {
        Circle circle = new Circle( X, Y, 10 );
        circle.setFill( Color.WHITE );
        circle.setStroke( Color.BLACK );
        circle.setStrokeWidth( 1 );

        // adds circle object at value of counter
        circles.add( counter, circle );
        // setting id for object
        circles.get( counter ).setId( "" + counter );
        // adding circle from list into the pane
        pane.getChildren().add( circles.get( counter ) );

        // incrementing the counter after circle object is added
        ++counter;
    }

    private void formatLabels() {
        label[0] = new Label();
        label[0].setTranslateX( 20 );
        label[0].setTranslateY( 20 );
        label[0].setText( "Press Left Mouse key to add a circle" );
        label[0].setFont( Font.font( "Calibri", FontWeight.BLACK, FontPosture.REGULAR, 15 ) );

        label[1] = new Label();
        label[1].setTranslateX( 20 );
        label[1].setTranslateY( 40 );
        label[1].setText( "Press Right key on a circle to remove it" );
        label[1].setFont( Font.font( "Calibri", FontWeight.BLACK, FontPosture.REGULAR, 15 ) );
    }

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

1 个答案:

答案 0 :(得分:0)

将圆圈存储在列表中对我来说似乎没有必要,因为您唯一一次读取对它的访问就是当您获得对刚刚添加到列表中的圆圈的引用时circle已经包含该引用( AddCircle方法)。

要将圆圈移除,只需向其添加onMouseClicked处理程序即可。 Circle可用作事件目标:

private final EventHandler<MouseEvent> removeHandler = evt -> {
    if (evt.getButton() == MouseButton.SECONDARY) {
        // remove clicked node (the circle) as child of pane
        this.pane.getChildren().remove(evt.getTarget());
    }
};

public void AddCircle(double X, double Y) {
    Circle circle = new Circle(X, Y, 10);
    circle.setFill(Color.WHITE);
    circle.setStroke(Color.BLACK);
    circle.setStrokeWidth(1);

    // setting id for object
    circle.setId("" + counter);

    // allow circle removal via mouse click
    circle.setOnMouseClicked(removeHandler);

    // adding circle into the pane
    pane.getChildren().add(circle);

    // incrementing the counter after circle object is added
    ++counter;
}

请注意,主鼠标按钮和辅助鼠标按钮可能不是鼠标左键和右键,例如如果鼠标设置将鼠标更改为左手鼠标。