notAquarius
@notAquarius
3 метра под уровнем грунта

Javafx, почему событие так (не)отрабатывает?

Я не могу изменять внешние переменные, intellij ругается.
Button button=new Button();
        String s;
        button.setOnAction(e->{
            s="";
        });


Говорит, что нужно вот так:
Button button=new Button();
        AtomicReference<String> s = null;
        button.setOnAction(e->{
            s.set("");
        });

Или так:
Button button=new Button();
        final String[] s = new String[1];
        button.setOnAction(e->{
            s[0] ="";
        });

Если же использовать FXML+контроллер, то проблем не возникает, я спокойно изменяю внешние переменные, почему это так работает?
Полагаю если я создам какой-то класс, унаследую его от EventHandler и переопределю метод события, а в button засуну этот самый класс как слушателя, то все тоже сработает.

Код:
Main.class
public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader fxmlLoader =new FXMLLoader(getClass().getResource("my.fxml"));
        Parent root= fxmlLoader.load();
        LoginWindowController loginWindowController= fxmlLoader.getController();
        loginWindowController.initialise(primaryStage);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }


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


myController.class
public class myController{
@FXML
 public void searchButtonPressed(MouseEvent mouseEvent) {
CreateNewWindow newWindow = new CreateNewWindow();
newWindow.create();    

}

}


public class CreateNewWindow{
create(){
Stage stage =new Stage();
Vbox v= new Vbox();
Button button =new Button("Press me");
v.getChildren().add(button);
stage.setScene(new Scene(v));
stage.show();

String str;
button.setOnAction(e->{
str="";  //Ругается
//Так - же отсюда я не могу вызвать никакой метод, который требует параметры;
});

}
}
  • Вопрос задан
  • 258 просмотров
Пригласить эксперта
Ответы на вопрос 1
jamakasi666
@jamakasi666
Просто IT'шник.
Недостаточно кода чтобы точно объяснить смысл поведения но в целом как то так.
- Не забывайте что javafx крутится в своем потоке.
- объявите ваш String как class member .
- касательно именно javafx то гляньте SimpleStringProperty и другие типы созданные специально удобства.

Ну а конкретно у вас следующая ситуация.
вы используете лямбду что в общем то обычный "вложенный анонимный класс" . В таких ситуациях любая переменная обязана быть final или иметь тип Atomic. Все это происходит из за проблем синхронизации.
Как вариант вы можете использовать немного другой подход и гдето внутри javafx(в случае с fxml) это работает примерно также:
String s;
private void doSome(){
 s="";
}
Button button=new Button();
button.setOnAction(e->{
  doSome();
});
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы