setOnAction в другом набореOnAction не работает для массивов кнопок в Javafx

77
5

Я действительно не уверен в названии, потому что не знаю, действительно ли это проблема. Я делаю это приложение, которое пользователь нажимает на кнопку "плюс" или "минус", чтобы получить количество людей, затем для каждого человека есть еще две кнопки "плюс" и "минус", чтобы получить еще один номер, который нужно умножить на 15, и результат показано в TextField. я не знаю, почему мой код дает мне эту ошибку: "Локальная переменная i, определенная в охватывающей области, должна быть окончательной или фактически окончательной". Я прокомментировал код, где отображается ошибка.

Любая помощь будет очень оценена.

Огромное спасибо.

int arrayLength;
int counter = 1;
double bc = 15.00;

Button[] baggagePlus;
Button[] baggageMinus;
Label[] baggageCounter;
Label[] costBaggage;
CheckBox[] checkReturn;

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {

stage = primaryStage;
stage.setTitle("");
stage.setResizable(false);

pane = new BorderPane();
pane.setStyle("-fx-background: #CEF6D8;");

centerPane1 = new Pane();

GridPane mainGrid = new GridPane();
mainGrid.setPadding(new Insets(150, 0, 0, 100));
mainGrid.setVgap(50);

noPassGrid = new GridPane();
noPassGrid.setHgap(10);

adultPlus = new Button("+");
adultPlus.setMinWidth(50);
adultPlus.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(adultPlus, 1, 0);

adultPlus.setOnAction(e -> {
plus(adultCounter);
getArraySize();
});

adultCounter = new Label("1");
adultCounter.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(adultCounter, 2, 0);

adultMinus = new Button("-");
adultMinus.setMinWidth(50);
adultMinus.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(adultMinus, 3, 0);

adultMinus.setOnAction(e -> {
minus(adultCounter);
getArraySize();
});

noPassGrid.getChildren().addAll(adultPlus, adultCounter, adultMinus);

GridPane.setConstraints(noPassGrid, 0, 2);

mainGrid.getChildren().addAll(noPassGrid);

search = new Button("SEARCH");
search.setPrefSize(300, 100);
search.setFont(new Font("Verdana", 30));
passengersGrid = new GridPane();
search.setOnAction(e -> {

passengersGrid.setPadding(new Insets(150, 0, 0, 450));
passengersGrid.setVgap(20);
passengersGrid.setHgap(20);

for(int i=0; i<arrayLength; i++) {

baggagePlus[i] = new Button("+");
baggagePlus[i].setMinWidth(50);
baggagePlus[i].setFont(Font.font("Verdana", 20));
GridPane.setConstraints(baggagePlus[i], 5, i);

baggageCounter[i] = new Label("0");
baggageCounter[i].setFont(Font.font("Verdana", 20));
GridPane.setConstraints(baggageCounter[i], 6, i);

baggagePlus[i].setOnAction(
new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
plus(baggageCounter[i]); //The "i" is underlined showing error
doublePrice(checkReturn[i], costBaggage[i], bc, baggageCounter[i]);
}
});

baggageMinus[i] = new Button("-");
baggageMinus[i].setMinWidth(50);
baggageMinus[i].setFont(Font.font("Verdana", 20));
GridPane.setConstraints(baggageMinus[i], 7, i);

baggageMinus[i].setOnAction(
new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
minus(baggageCounter[i]); //The "i" is underlined showing error
doublePrice(checkReturn[i], costBaggage[i], bc, baggageCounter[i]);
}
});

checkReturn[i] = new CheckBox();
checkReturn[i].setFont(Font.font(20));
GridPane.setConstraints(checkReturn[i], 10, i);

checkReturn[i].setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
//The "i" is underlined showing error
doublePrice(checkReturn[i], costBaggage[i], bc, baggageCounter[i]);
}
});

costBaggage[i] = new Label("€0.00");
costBaggage[i].setFont(Font.font("Verdana", 25));
GridPane.setConstraints(costBaggage[i], 18, i);

passengersGrid.getChildren().addAll(baggagePlus[i], baggageCounter[i], baggageMinus[i], checkReturn[i], costBaggage[i]);

}
});

centerPane1.getChildren().addAll(mainGrid, passengersGrid);
pane.setCenter(centerPane1);

bottom1 = new AnchorPane(search);
bottom1.setPadding(new Insets(0, 0, 100, 0));
AnchorPane.setRightAnchor(search, 150.0);
pane.setBottom(bottom1);

scene = new Scene(pane, 1200, 600);
stage.setScene(scene);
stage.show();

}

public void getArraySize() {
arrayLength = counter;

baggagePlus = new Button[arrayLength];
baggageMinus = new Button[arrayLength];
baggageCounter = new Label[arrayLength];
costBaggage = new Label[arrayLength];
checkReturn = new CheckBox[arrayLength];
}

public void plus(Label l) {
if(counter < 8) {
counter++;
l.setText("" + counter);
}
}

public void minus(Label l) {
if(counter > 1) {
counter--;
l.setText("" + counter);
}
}

public void doublePrice(CheckBox cb, Label ll, double bc, Label l) {
if(cb.isSelected()) {
ll.setText("€" + df.format(2 * bc * (Double.parseDouble(l.getText()))));
}
else {
ll.setText("€" + df.format(bc * (Double.parseDouble(l.getText()))));
}
}

}

спросил(а) 2021-01-25T19:20:52+03:00 4 месяца, 4 недели назад
1
Решение
88

Ошибка - это именно то, что она говорит: я должен быть окончательным (или фактически окончательным, что означает, что компилятор должен иметь возможность вывести, что переменная никогда не изменится.

В вашем случае i меняю (от 0 до 10), поэтому он не "эффективно финал".

То, что вы хотите сделать, это добавить переменную для хранения текущего моментального снимка i и сохранить его в конечной переменной; например, в верхней части цикла добавьте:

final int snapshot = i;

Если вы думаете об этом, это поведение Java очень логично - к тому моменту, когда какой-либо из слушателей срабатывает, цикл, о котором идет речь, закончен, поэтому нет такой вещи, как текущее значение i. Вместо этого есть моментальный снимок значения i, сделанного во время итерации, когда слушатель был установлен.

ответил(а) 2021-01-25T19:20:52+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема