遍历包含 mouseEvent 操作的 for 循环时发生异常

Exception occurred when iterating though for loop that includes mouseEvent action

当我使用包含通过 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 设为实例变量。 IE。你有这样的东西:

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

}

这里 iDemo 实例(即调用 start() 的应用程序实例)的 属性。在 start() 方法中, i 被初始化为 0 ,然后在每次迭代 for 循环时递增。当i不再小于array.length(即3)时for循环退出,所以当for循环退出时,i==3 .

因此,当您按下其中一个按钮时,代码

System.out.println(array[i].getText());

被执行。 i 的值在 for 循环完成后没有改变,所以这等同于

System.out.println(array[3].getText());

并抛出 IndexOutOfBoundsException,因为数组中的值索引是 012。事实上,完整的错误信息是

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 循环的首选形式。

这是代码的 fully-cleaned 和工作版本:

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

}