2014-02-07 2 views
2

javaFX에서 이벤트 중에 UI 요소에 영향을 주려고합니다.JavaFX - 이벤트 중 동작

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

"jBoss.restart()"동작은 JBoss가 다시 시작될 때까지 대기합니다.

문제 :

"restarting - ..."텍스트가 표시되지 않습니다. 응용 프로그램은 JBoss가 다시 시작될 때까지 대기 한 다음 텍스트 "JBoss가 성공적으로 다시 시작되었습니다"를 표시합니다.

내 생각 : 이벤트가 완료된 후 장면이 새로 고침됩니다. 따라서 첫 번째 레이블 변경은 발생하지 않습니다.

이벤트 중에 정보 메시지를 표시하려면 어떻게해야합니까?

답변

3

FX 스레드가 안전한 작업을하지 못하는 것이 문제입니다. 그래서 저는 jBoss.restart()에 많은 시간을 할애하고 있다고 생각합니다. 따라서이 명령을 서비스에 넣어야합니다. 또한 나는 당신에게 오랜 작업을하고있는 사용자에게 보여주는 진행률 표시기를 권장합니다.

여기 예를 들자면 Concurrency in 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(); 
    } 
} 
+0

확실히. JavaFX 응용 프로그램 스레드는 그래픽 사용자 인터페이스를 업데이트하고 조작하는 데에만 사용되므로 무언가를 처리하는 데 사용해서는 안됩니다. 나는 너의 대답에 완전히 동의한다. :) – Loa