我正在使用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);
}
}
这里真正的问题是我需要向一个按钮添加一个事件处理程序,该按钮是一组按钮的一部分,但似乎无法访问所述按钮数组的计数器变量。
答案 0 :(得分:2)
您遇到此问题是因为columns
和rows
在整个循环中发生了变化。您可以创建这些的最终实例,但在监听器中创建要引用的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;