按下按钮上的变量访问

时间:2017-03-12 00:44:51

标签: java javafx

我正在使用javafx编写一个小型棋盘游戏,并且我已经为每个单元格创建了一个网格'在董事会上。

但是,按下单元格按钮时,我在更改单元格颜色方面遇到了一些问题。

这是我遇到的错误之一: "错误:(44,45)java:从内部类引用的局部变量必须是最终的或有效的最终版本"

但是,我不能使变量最终 - 因为变量是for循环的一部分,如图所示:

for (int columns = 0; columns < 8; columns++) {
        for (int rows = 0; rows < 8; rows++) {
            positions[columns][rows] = new Button();

            positions[columns][rows].setText("X:" + columns + " Y:" + rows); // current location text (temp)

            positions[columns][rows].setMinHeight(cellDimensions);
            positions[columns][rows].setMaxHeight(cellDimensions);
            positions[columns][rows].setMinWidth(cellDimensions);
            positions[columns][rows].setMaxWidth(cellDimensions);

            String zoneColour = getColourBoard(columns, rows);
            positions[columns][rows].setStyle("-fx-background-color: " + zoneColour + "; ");

            positions[columns][rows].setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                            positions[columns][rows].setStyle("-fx-background-color: #FFA500; ");
                        }
                    });

            grid.add(positions[columns][rows], columns, rows);

        }
    }

这里真正的问题是我需要向一个按钮添加一个事件处理程序,该按钮是一组按钮的一部分,但似乎无法访问所述按钮数组的计数器变量。

4 个答案:

答案 0 :(得分:2)

您遇到此问题是因为columnsrows在整个循环中发生了变化。您可以创建这些的最终实例,但在监听器中创建要引用的final Button会更有意义。

for (int columns = 0; columns < 8; columns++) {
    for (int rows = 0; rows < 8; rows++) {
        positions[columns][rows] = new Button();
        positions[columns][rows].setText("X:" + columns + " Y:" + rows); // current location text (temp)
        positions[columns][rows].setMinHeight(cellDimensions);
        positions[columns][rows].setMaxHeight(cellDimensions);
        positions[columns][rows].setMinWidth(cellDimensions);
        positions[columns][rows].setMaxWidth(cellDimensions);

        String zoneColour = getColourBoard(columns, rows);
        positions[columns][rows].setStyle("-fx-background-color: " + zoneColour + "; ");

        final Button b = positions[columns][rows];
        // final int c = columns, r = rows;
        positions[columns][rows].setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                // Could use c and r above if needed.
                // positions[c][r]
                b.setStyle("-fx-background-color: #FFA500; ");
            }
        });
        grid.add(positions[columns][rows], columns, rows);
    }
}

答案 1 :(得分:0)

最简单的方法是在每次迭代时立即将循环计数器设置为最终变量。

for (int columns = 0; columns < 8; columns++) {
    final int columnNum = columns;
    for (int rows = 0; rows < 8; rows++) {
        final int rowNum = rows;
        // now use columnNum and rowNum
    }
}

答案 2 :(得分:0)

如果问题是关于handle方法中的位置[columns] [rows]引用,你可以尝试用event.getSource()替换它,将它强制转换为正确的类型,以删除对那里位置的引用。

答案 3 :(得分:0)

这可能是一种奇怪的方式,但你可以创建一个单独的类

public class PositionEventHandler extends EventHandler<ActionEvent> {

    private final Button button;

    public PositionEventHandler(Button b) {
        this.button = b;
        b.setOnAction(this);
    }

    @Override
    public void handle(ActionEvent event) {
        this.button.setStyle("-fx-background-color: #FFA500; ");
    }
}

如果您将"#FFA500"作为参数传递给String clickColor

,那会更有意义

然后,在循环中。

final Button b = new Button();

b.setText("X:" + columns + " Y:" + rows);

new PositionEventHandler(b); // One line to define the action onto itself. 

positions[columns][rows] = b;