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

时间:2017-12-01 21:59:27

标签: javafx eventhandler onmouseclick

我想创建一组带有for循环的十个不同的圆圈,当鼠标光标悬停在其中一个上时,每个圆圈都会改变颜色,并且只需点击鼠标就可以将它们更改为第三种颜色。但是,只有一个圆圈 - 最后一个在圆圈中创建 - 具有颜色变化,无论哪个圆圈被点击或悬停。任何人都可以解释我为什么以及如何解决这个问题?我会非常感激的。 Hier是我的代码:

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

.....

enter image description here

3 个答案:

答案 0 :(得分:1)

circle是一个字段。运行事件处理程序时,将检索字段的值,在这种情况下,它包含最后分配给它的值,即最后创建的圆。

请注意,您可以从匿名类中访问周围范围内的final(对于java&gt; = 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
    }
}

答案 1 :(得分:0)

这是一个示例应用。这个应用程序使用lambda作为侦听器。

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

答案 2 :(得分:0)

这是我对它的看法,如果你想让它再次变黑,取消注释setOnMouseExited。

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

}