for-loop - 迭代包含 mouseEvent 操作的 for 循环时发生异常
问题描述
当我使用包含通过radioButtons 的mouseEvent 操作的NORMAL for 循环进行迭代时,会出现以下异常消息。
消息:线程“JavaFX 应用程序线程”中的异常 java.lang.ArrayIndexOutOfBoundsException
但是当我使用for-each循环进行迭代时,没有问题!
请帮助我,谢谢
相关代码部分:
HBox p1 = new HBox();
RadioButton Red = new RadioButton("RED");
RadioButton Blue = new RadioButton("Blue");
RadioButton Black = new RadioButton("Black");
ToggleGroup tg = new ToggleGroup();
Red.setToggleGroup(tg);
Blue.setToggleGroup(tg);
Black.setToggleGroup(tg);
RadioButton [] array = {Red,Blue,Black};
p1.getChildren().addAll(Red,Blue,Black);
i = 0;
for(i = 0; i< array.length; i++){
array[i].setOnAction(e->{
System.out.println(array[i].getText());
});
}
解决方案
我猜,因为您的问题不完整,您将循环索引设置i
为实例变量,出于某种原因。即你有类似的东西:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Demo extends Application {
// Guessing:
private int i ;
@Override
public void start(Stage primaryStage) throws Exception {
HBox p1 = new HBox();
RadioButton red = new RadioButton("RED");
RadioButton blue = new RadioButton("Blue");
RadioButton black = new RadioButton("Black");
ToggleGroup tg = new ToggleGroup();
red.setToggleGroup(tg);
blue.setToggleGroup(tg);
black.setToggleGroup(tg);
RadioButton[] array = { red, blue, black };
p1.getChildren().addAll(red, blue, black);
i = 0;
for (i = 0; i < array.length; i++) {
array[i].setOnAction(e -> {
System.out.println(array[i].getText());
});
}
Scene scene = new Scene(p1, 400, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
这i
是Demo
实例的一个属性(即在其start()
上调用的应用程序实例)。在该start()
方法中,每次迭代循环时i
都会初始化并递增。当不再小于(即)时,循环退出,所以当循环退出时,。0
for
for
i
array.length
3
for
i==3
因此,当您按下其中一个按钮时,代码
System.out.println(array[i].getText());
被执行。自循环完成以来,的值i
没有改变for
,所以这相当于
System.out.println(array[3].getText());
这会抛出IndexOutOfBoundsException
, 因为数组中的值索引是0
,1
和2
。事实上,完整的错误信息是
Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
相反,您需要为循环中的索引使用局部变量:
for (int i = 0; i < array.length; i++) {
array[i].setOnAction(e -> { /* ... */ });
}
现在的问题是事件处理程序中的 lambda 表达式无法访问局部变量i
,因为它不是final
(或“实际上是最终的”)。解决方案是在最终变量中“捕获”i
循环每次迭代的值:
for (int i = 0; i < array.length; i++) {
final int index = i ;
array[i].setOnAction(e -> {
System.out.println(array[index].getText());
});
}
当然,您实际上并不需要索引;您只需要数组的元素,因此您可以捕获它:
for (int i = 0; i < array.length; i++) {
final RadioButton button = array[i] ;
button.setOnAction(e -> {
System.out.println(button.getText());
});
}
此代码与以下代码完全相同(在某种意义上,编译器将以下内容转换为相同的内容):
for (RadioButton button : array) {
button.setOnAction(e -> {
System.out.println(button.getText());
});
}
这是迄今为止for
循环的首选形式。
这是代码的完全清理和工作版本:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Demo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
HBox p1 = new HBox();
RadioButton red = new RadioButton("RED");
RadioButton blue = new RadioButton("Blue");
RadioButton black = new RadioButton("Black");
ToggleGroup tg = new ToggleGroup();
RadioButton[] buttons = { red, blue, black };
tg.getToggles().setAll(buttons);
p1.getChildren().addAll(buttons);
for (RadioButton button : buttons) {
button.setOnAction(e -> {
System.out.println(button.getText());
});
}
Scene scene = new Scene(p1, 400, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
推荐阅读
- php - PHP 查看来自同一用户的不同 $_SESSION
- r - r 中的 ymd() 出错:“所有格式都无法解析。未找到格式。”
- excel - 工作簿无法使用 VBA 打开
- c# - EntityFramework 核心 - 在不选择实体的情况下更新数据集合
- docker - 来自 asp.net core api 3.1 的 docker 容器上的 ssl/tls 握手失败
- spring-data-jpa - 用于测试的hsqldb动态配置
- c++ - 从 NuGet 包中使用 Lua 时的 LNK2019
- c# - c#方法的块方案
- python - 分类结果的加权准确度与验证和测试的未加权准确度相同
- flutter - 如何访问(填充)地图中的值,其中,值是一个列表