如何在循环上向按钮添加动作侦听器?

时间:2015-04-21 23:59:43

标签: java button javafx

我希望每次在我的4x4网格中按下按钮时,它会将moves递增1。这是创建4x4按钮布局。每次按下任何按钮,我都希望moves递增。基本上我是在创建记忆游戏,在那里你翻转卡片以相互匹配。我只需要计算玩家在解决这个难题时所做的moves总量。

private int moves = 0;

private GridPane makeGridPane(){
    ConcentrationModel c = new ConcentrationModel();
    GridPane grid = new GridPane();

    ColumnConstraints col1 = new ColumnConstraints();
    col1.setPercentWidth( 50 );

    grid.getColumnConstraints().addAll(col1, col1, col1, col1);
    RowConstraints row1 = new RowConstraints();
    row1.setPercentHeight( 50 );
    grid.getRowConstraints().addAll(row1, row1, row1, row1);


    for(int row = 0; row < 4; row ++){
        for(int col = 0; col < 4; col++){
            Button btn = new Button();
            ImageView image = new ImageView(c.getCards().get(0).getImage());
            image.setFitWidth(WIDTH/4);
            image.setFitHeight(HEIGHT/4);
            btn.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
            btn.setGraphic(image);
            grid.add(btn, col, row);


        }
    }
    return grid;
}

3 个答案:

答案 0 :(得分:2)

您可以创建单个事件处理程序并将其重用于所有按钮。既然您可能希望按钮也可以执行其他操作,我建议您将其添加为事件处理程序,而不是使用方便方法setOnAction(...)

EventHandler<ActionEvent> incrementMovesHandler = e -> moves++ ;

for(int row = 0; row < 4; row ++){
    for(int col = 0; col < 4; col++){
        Button btn = new Button();
        btn.addEventHandler(ActionEvent.ACTION, incrementMovesHandler);
        // ...
    }
}

答案 1 :(得分:1)

这实际上非常简单。您所要做的就是在grid.add(...)

之前添加这段代码
btn.setOnAction(new EventHandler<ActionEvent>() {
    @Override public void handle(ActionEvent event) {
        moves++;
    }
});

或者,相当于Java 8版本:

btn.setOnAction((ActionEvent e) -> {moves++;});

(我目前无法对此进行测试,但工作。如果没有,请知道并且我会尝试修复它。)

如果您关注内存,Christian points out below这会为每个按钮创建EventHandler的新实例。虽然这可能不是太可怕,但这可能是一个坏习惯。处理(没有双关语)的最佳方法是在for循环之前创建一个对象:

EventHandler<ActionEvent> eh = new EventHandler<>() {
    @Override public void handle(ActionEvent event) {
        moves++;
    }
};

然后,对于每个按钮,而不是最顶层的代码,您只需写下:

btn.setOnAction(eh);

这样,正在创建一个EventHandler并用于处理所有事件。如果你需要创建的不仅仅是几个按钮,你会想要使用这个按钮,因为它更快(不需要为每个对象分配内存)和更高的内存效率( ......它,呃,不需要为每个对象分配内存)。在这种情况下,我认为它非常微不足道,但是要知道它仍然很好。

答案 2 :(得分:-2)

您需要在班级中实施ActionListener界面。 然后在actionPerformed函数中,只需递增移动变量。 您只需为每个按钮调用btn.addActionListener(this);即可 你创造了。

public class Sample extends JFrame implements ActionListener {

  public Sample ()
  {

  }


  private GridPane makeGridPane()
  {
    ConcentrationModel c = new ConcentrationModel();
    GridPane grid = new GridPane();

    ColumnConstraints col1 = new ColumnConstraints();
    col1.setPercentWidth( 50 );

    grid.getColumnConstraints().addAll(col1, col1, col1, col1);
    RowConstraints row1 = new RowConstraints();
    row1.setPercentHeight( 50 );
    grid.getRowConstraints().addAll(row1, row1, row1, row1);


    for(int row = 0; row < 4; row ++){
        for(int col = 0; col < 4; col++){
            Button btn = new Button();
            ImageView image = new ImageView(c.getCards().get(0).getImage());
            image.setFitWidth(WIDTH/4);
            image.setFitHeight(HEIGHT/4);
            btn.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
            btn.setGraphic(image);
            btn.addActionListener(this);
            grid.add(btn, col, row);


        }
    }
    return grid;
  }


  public void actionPerformed(ActionEvent e) 
  {
    moves++;
  }  

}