2017-12-01 15 views
0

forループで10個の異なる円のセットを作成し、マウスカーソルがそれらのいずれかの上を移動し、マウスをクリックすると3番目の色になります。ただし、ループ内で最後に作成されるサークルの1つのみが、どのサークルがクリックされたかどうかにかかわらず、色の変化があります。なぜ誰に教えてもらえますか?どうすればこの問題を解決できますか?私は非常に素晴らしいだろう。ハイアーは、私のコードです:JavaFX - forループによって作成された異なるオブジェクト上のイベントハンドラ

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

+0

どこに問題がある、私はあなたのコード内で見ることができません。 [最小、完全、かつ検証可能な例](https://stackoverflow.com/help/mcve)を作成する必要があります。 – Sedrick

+1

何らかの理由で 'circle 'をフィールドとして宣言しました。したがって、ハンドラは常にフィールドを参照します。フィールドには、割り当てられた最後の値があります。代わりにループ内でローカルに宣言してください。 –

+0

私はそれをキャッチしませんでした。 – Sedrick

答えて

0

は、サンプルアプリです。このアプリはリスナーにラムダを使用します。

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

} 
+0

ありがとうございました! ".... getChildren()。add(circle);"という文を実行すると、ループ内でローカルに、各サークルのために、それは動作します!不幸にも、サークルはシーンから参照されるクラスで作成されていないので、まだリストが必要です。 – Fernando

+0

正確にはどういう意味ですか?なぜリストに追加できないのですか? – Emrage

1

circleはフィールドです。イベントハンドラが実行された場合、フィールドの値が取得され、この場合には、それはすなわち、最後に作成された円の最後に割り当てられた値を、含まれています。

匿名クラスから周囲のスコープ内の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 
    } 
} 
関連する問題