JavaFX-for循环创建的不同对象上的事件处理程序

JavaFX-for循环创建的不同对象上的事件处理程序,javafx,eventhandler,onmouseclick,Javafx,Eventhandler,Onmouseclick,我想用for循环创建一组10个不同的圆,当鼠标光标悬停在其中一个圆上时,使每个圆都改变颜色,并通过鼠标单击使它们改变为第三种颜色。但是,无论单击或悬停在哪个圆上,只有一个圆(在循环中创建的最后一个圆)的颜色会发生变化。有人能解释一下我为什么要解决这个问题吗?我会非常高兴的。这是我的代码: public class View extends Parent{ BorderPane gameScreen; Group hexaBlock; ArrayList<Circle> circleL

我想用for循环创建一组10个不同的圆,当鼠标光标悬停在其中一个圆上时,使每个圆都改变颜色,并通过鼠标单击使它们改变为第三种颜色。但是,无论单击或悬停在哪个圆上,只有一个圆(在循环中创建的最后一个圆)的颜色会发生变化。有人能解释一下我为什么要解决这个问题吗?我会非常高兴的。这是我的代码:

public class View extends Parent{
BorderPane gameScreen;
Group hexaBlock;
ArrayList<Circle> circleList = new ArrayList<>(); 
Circle circle;
...
public View(){
        gameScreen = new BorderPane();
        hexaBlock = new Group(); 
        ...
        for(int y=0; y<2; y++ ){
            for(double x=0; x<5; x++){
                circle = new Circle(xPosition(hexagon width*x), yPosition(hexagon height*4*y), radius);
                circleList.add(circle);
                circle.setFill(Color.BLACK);
                circle.setOnMousePressed(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        circle.setFill(Color.CYAN);
                    }
                });
                circle.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>(){
                    @Override
                    public void handle(MouseEvent t) {
                        circle.setFill(Color.RED);
                    }
                });
                circle.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>(){
                     @Override
                        public void handle(MouseEvent t) {
                         circle.setFill(Color.BLACK);
                        }
                });
}
this.getChildren().add(gameScreen);
... 
gameScreen.setCenter(hexaBlock);
...
hexaBlock.getChildren().addAll(circleList);
公共类视图扩展父类{
边界窗格游戏屏幕;
组块;
ArrayList circleList=新的ArrayList();
圆圈;
...
公众观点(){
gameScreen=新建边框窗格();
hexaBlock=新组();
...

对于(int y=0;y,这里是一个示例应用程序。此应用程序使用lambdas作为侦听器

import java.util.Random;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication54 extends Application
{

    @Override
    public void start(Stage primaryStage)
    {
        Random random = new Random();

        AnchorPane root = new AnchorPane();

        for (int i = 0; i < 5; i++)
        {
            int x1 = random.nextInt(300);
            System.out.println("l: " + x1);
            int y1 = random.nextInt(250);
            int radius = random.nextInt(10) + 3;
            root.getChildren().add(getCircle(x1, y1, radius));
        }

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

    Circle getCircle(int x1, int y1, int radius)
    {
        Circle tempCircle = new Circle(x1, y1, radius);
        tempCircle.setFill(Color.BLACK);

        tempCircle.setOnMousePressed(me -> tempCircle.setFill(Color.CYAN));
        tempCircle.setOnMouseEntered(me -> tempCircle.setFill(Color.RED));
        tempCircle.setOnMouseExited(me -> tempCircle.setFill(Color.BLACK));

        return tempCircle;
    }
}
import java.util.Random;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.stage.stage;
/**
*
*@author blj0011
*/
公共类JavaFXApplication54扩展了应用程序
{
@凌驾
公共无效开始(阶段primaryStage)
{
随机=新随机();
锚烷根=新锚烷();
对于(int i=0;i<5;i++)
{
int x1=随机的nextInt(300);
系统输出println(“l:+x1”);
int y1=随机的下一个(250);
int半径=随机。nextInt(10)+3;
root.getChildren().add(getCircle(x1,y1,半径));
}
场景=新场景(根,300,250);
setTitle(“你好,世界!”);
初级阶段。场景(场景);
primaryStage.show();
}
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args)
{
发射(args);
}
圆getCircle(整数x1,整数y1,整数半径)
{
圆tempCircle=新圆(x1,y1,半径);
tempCircle.setFill(颜色:黑色);
tempCircle.setOnMousePressed(me->tempCircle.setFill(Color.CYAN));
tempCircle.setonMouseCenter(me->tempCircle.setFill(Color.RED));
tempCircle.setOnMouseExited(me->tempCircle.setFill(Color.BLACK));
返回圈;
}
}

这是我对它的看法,如果希望它再次变黑,请取消对setonmouseexted的注释

import java.util.Random;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class CircleColours extends Application {

    private final Random random = new Random();

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

    @Override
    public void start(Stage primaryStage) {
        AnchorPane pane = new AnchorPane();
        Scene scene = new Scene(pane, 600, 400);
        addCircles(pane, 10, 50);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public void addCircles(AnchorPane pane, int amount, int radius) {
        for (int i = 0; i < amount; i++) {
            Circle circle = new Circle(random.nextInt((int) pane.getWidth()), random.nextInt((int) pane.getHeight()), radius);
            circle.setOnMouseEntered(event -> circle.setFill(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255))));
            circle.setOnMouseClicked(event -> circle.setFill(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255))));
            //circle.setOnMouseExited(event -> circle.setFill(Color.BLACK));
            pane.getChildren().add(circle);
        }
    }

}
import java.util.Random;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.stage.stage;
公共类圆环颜色扩展了应用程序{
私有最终随机=新随机();
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
锚烷窗格玻璃=新锚烷();
场景=新场景(窗格,600400);
添加圆(窗格,10,50);
初级阶段。场景(场景);
primaryStage.show();
}
公共虚空添加圆(锚形窗格,整数数量,整数半径){
对于(int i=0;icircle.setFill(Color.rgb(random.nextInt(255)、random.nextInt(255)、random.nextInt(255));
circle.setOnMouseClicked(事件->circle.setFill(Color.rgb(random.nextInt(255)、random.nextInt(255)、random.nextInt(255));
//circle.setonmouseexed(事件->circle.setFill(Color.BLACK));
pane.getChildren().add(圆圈);
}
}
}

圆圈
是一个字段。运行事件处理程序时,将检索该字段的值,在本例中,该字段包含上次分配给它的值,即上次创建的圆圈

请注意,您可以从匿名类中访问周围作用域中的
final
(对于java>=8)局部变量。我建议删除
circle
字段并声明
circle
,在此处为其赋值:

for(int y=0; y<2; y++ ){
    for(double x=0; x<5; x++){
        final Circle circle = new Circle(xPosition(hexagon width*x), yPosition(hexagon height*4*y), radius);

        ...
        // init circle handlers/properties
    }
}

用于(int y=0;yI在代码中看不到问题所在。您应该创建一个。出于某种原因,您将
圆圈
声明为一个字段。因此处理程序总是引用该字段,该字段具有最后分配的值。改为在循环中本地声明。我没有捕捉到这一点。谢谢您的回答!当我执行该语句时“…getChildren().add(circle);”在循环中,对于每个循环,它都可以工作!不幸的是,我仍然需要一个列表,因为这些循环不是在场景中引用的类中创建的。你的确切意思是什么?为什么不能将它们添加到列表中。