JavaFX — действие во время события

я пытаюсь повлиять на элемент пользовательского интерфейса во время события в javaFX.

void buttonClicked(ActionEvent e) {
    labelInfo.setText("restarting - might take a few seconds");
    jBoss.restart();
    labelInfo.setText("JBoss successfully restarted");
}

Действие "jBoss.restart()" ожидает перезапуска JBoss.

Проблема:

текст "перезагрузка -..." не отображается. Приложение ожидает перезапуска JBoss, а затем показывает текст «JBoss успешно перезапущен».

Мои мысли: сцена обновляется ПОСЛЕ завершения события. Так что первой смены ярлыка не произойдет.

Как я могу показать информационное сообщение во время события?


person user3282709    schedule 07.02.2014    source источник


Ответы (1)


Проблема в том, что у FX Thread нет безопасных операций. Так что я предполагаю, что jBoss.restart() это займет много времени. Поэтому вы должны поместить эту команду в Service. Также я рекомендую вам индикатор прогресса, чтобы показать пользователю, что вы делаете длинную операцию.

Вот пример, но я рекомендую вам перейти к Параллелизм в JavaFX и внимательно изучите его. Может быть, есть другие вещи, которые могут вам помочь.

import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Test extends Application {

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

    private Label labelInfo;
    private Button button;
    private ProgressIndicator progressIndicator;

    @Override
    public void start(Stage stage) throws Exception {
        VBox vbox = new VBox(5);
        vbox.setAlignment(Pos.CENTER);
        labelInfo = new Label();
        button = new Button("Restart");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                buttonClicked(event);
            }
        });
        progressIndicator = new ProgressIndicator(-1);
        progressIndicator.setVisible(false);
        vbox.getChildren().addAll(labelInfo, progressIndicator, button);

        Scene scene = new Scene(vbox, 300, 200);
        stage.setScene(scene);
        stage.show();
    }

    void buttonClicked(ActionEvent e) {
        Service<Void> service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        updateMessage("restarting - might take a few seconds");
                        // Here the blocking operation
                        // jBoss.restart();
                        Thread.sleep(10000);
                        updateMessage("JBoss successfully restarted");
                        return null;
                    }
                };
            }
        };
        // Make the progress indicator visible while running
        progressIndicator.visibleProperty().bind(service.runningProperty());
        // Bind the message of the service to text of the label
        labelInfo.textProperty().bind(service.messageProperty());
        // Disable the button, to prevent more clicks during the execution of
        // the service
        button.disableProperty().bind(service.runningProperty());
        service.start();
    }
}
person Antonio J.    schedule 07.02.2014
comment
Конечно. Мы должны помнить, что поток приложения JavaFX используется только для обновления и управления графическим пользовательским интерфейсом и никогда не должен использоваться для какой-либо обработки. Я полностью согласен с вашим ответом. :) - person Loa; 07.02.2014