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

Java 多个节点上的鼠标单击事件,java,javafx,Java,Javafx,在本练习中,单击矩形时,将在矩形的边界中显示一个圆形。但当按下圆圈上的鼠标右键时,应将其移除。我使用了一个ArrayList来存储要添加的圆。但是我怎么知道哪个圆圈被点击了呢?然后,应该为该圆圈调用Click事件以将其删除 package sample; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.scene.Scene; import javafx.scene.in

在本练习中,单击矩形时,将在矩形的边界中显示一个圆形。但当按下圆圈上的鼠标右键时,应将其移除。我使用了一个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);
    }
}
包装样品;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.scene.scene;
导入javafx.scene.input.MouseButton;
导入javafx.scene.text.fontpostation;
导入javafx.scene.text.FontWeight;
导入javafx.stage.stage;
导入javafx.scene.shape.Rectangle;
导入javafx.scene.shape.Circle;
导入javafx.scene.paint.Color;
导入javafx.scene.control.Label;
导入java.util.ArrayList;
导入javafx.scene.text.Font;
导入javafx.scene.layout.Pane;
公共类主扩展应用程序{
私有ArrayListcircles=新ArrayList();
私有矩形=新矩形(2001001000600);
私有标签[]标签=新标签[2];
专用整数计数器=0;
私有窗格=新窗格();
@凌驾
public void start(Stage)引发异常{
矩形。设置填充(颜色为白色);
矩形。设定行程(颜色为黑色);
矩形。设置行程宽度(1);
矩形。setOnMouseClicked(e->{
如果(例如getButton()==MouseButton.PRIMARY){
//e.getX和e.getY将把圆放置在光标单击的位置
AddCircle(e.getX(),e.getY());
}
});
//将格式化要添加到窗格上的标签
格式化标签();
pane.getChildren().addAll(标签[0],标签[1],矩形);
场景=新场景(窗格,1200650,Color.ANTIQUEWHITE);
舞台场景;
stage.setTitle(“添加和删除圆圈”);
stage.show();
}
公共无效添加圆(双X,双Y){
圆=新的圆(X,Y,10);
圆形。设置填充(颜色为白色);
圆整定行程(颜色为黑色);
圆。设定行程宽度(1);
//在计数器的值处添加圆形对象
圆。添加(计数器,圆);
//设置对象的id
circles.get(counter.setId)(“+counter”);
//将列表中的圆圈添加到窗格中
pane.getChildren().add(circles.get(counter));
//添加圆对象后递增计数器
++计数器;
}
私有void formatLabels(){
标签[0]=新标签();
标签[0].setTranslateX(20);
标签[0].setTranslateY(20);
标签[0].setText(“按鼠标左键添加圆”);
标签[0].setFont(Font.Font(“Calibri”,FontWeight.BLACK,FontPositure.REGULAR,15));
标签[1]=新标签();
标签[1].setTranslateX(20);
标签[1].setTranslateY(40);
标签[1].setText(“按圆上的右键将其删除”);
标签[1].setFont(Font.Font(“Calibri”,FontWeight.BLACK,FontPositure.REGULAR,15));
}
公共静态void main(字符串[]args)
{
发射(args);
}
}

将圆圈存储在列表中对我来说似乎没有必要,因为只有当您获得对刚刚添加到列表中的圆圈的引用,并且
圆圈
已经包含该引用(
添加圆圈
方法)时,才可以读取该圆圈

要使圆可移动,只需向其添加一个
onMouseClicked
处理程序。
圆圈
可用作事件目标:

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;
}
private final EventHandler removeHandler=evt->{
if(evt.getButton()==MouseButton.SECONDARY){
//将单击的节点(圆)作为窗格的子节点删除
this.pane.getChildren().remove(evt.getTarget());
}
};
公共无效添加圆(双X,双Y){
圆=新的圆(X,Y,10);
圆形。设置填充(颜色。白色);
圆整定行程(颜色为黑色);
圆。设定行程宽度(1);
//设置对象的id
圆.setId(“+”计数器);
//允许通过鼠标单击删除圆
circle.setOnMouseClicked(removeHandler);
//将圆添加到窗格中
pane.getChildren().add(圆圈);
//添加圆对象后递增计数器
++计数器;
}

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

直接方法:从最新到最旧的循环,如果找到包含单击点的循环,则将其删除。重复:一个问题:为什么保留
计数器并在该索引处添加?从您的代码来看,似乎
circles.size()
也会这样做(如果在将圆添加到列表之前设置id,则id将为
circles.size()+1
)。