Исключение произошло при повторении для l oop, которое включает действие mouseEvent - PullRequest
0 голосов
/ 06 августа 2020

следующее сообщение об исключении появляется, когда я выполняю итерацию с использованием NORMAL for-l oop, который включает действие mouseEvent через radioButtons.

Сообщение: исключение в потоке «JavaFX Application Thread» java .lang.ArrayIndexOutOfBoundsException

Но когда я повторяю, используя для каждого l oop, проблем нет!

пожалуйста, помогите мне, спасибо

Часть кода, относящаяся к делу:


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

1 Ответ

0 голосов
/ 06 августа 2020

Я предполагаю, так как ваш вопрос неполный, вы по какой-то причине сделали l oop index 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 l oop. for l oop выходит, когда i не меньше array.length (что составляет 3), поэтому, когда for l oop выходит, i==3.

Следовательно, при нажатии одной из кнопок выполняется код

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

. Значение i не изменилось с момента завершения for l oop, поэтому это эквивалентно

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

Вместо этого вам нужно использовать локальную переменную для индекса в l oop:

    for (int i = 0; i < array.length; i++) {

        array[i].setOnAction(e -> { /* ... */ });

    }

Теперь проблема в том, что лямбда-выражение в обработчике событий не может получить доступ к локальной переменной i, потому что она не final (или «фактически окончательная»). Решение этой проблемы состоит в том, чтобы «захватить» значение i на каждой итерации l oop в конечной переменной:

    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 l oop.

Вот полностью очищенная и рабочая версия кода:

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

}
...