2014-10-24 20 views
7

Alles, was ich wollte, ist ein Etikett aktualisieren, wie mein Programm läuft. Ich lese einige Dateien und ich wollte, dass es den Namen der Datei anzeigt, die gelesen wurde.JavaFx - Aktualisierung GUI

Aber es zeigt nur die letzte Datei unter Verwendung des Codes (im Grunde GUI reagiert nicht, bis der gesamte Prozess abgeschlossen ist):

static Text m_status_update = new Text(); //I declared this outside the function so dont worry 
m_status_update.setText("Currently reading " + file.getName()); 

Ich habe um 4-5 Dateien und ich möchte nur zu Zeigen Sie den Namen an.

ich eine ähnliche Frage sah Displaying changing values in JavaFx Label empfahl die beste Antwort der folgende:

Label myLabel = new Label("Start"); //I declared this outside the function so dont worry 
myLabel.textProperty().bind(valueProperty); 

jedoch die Valueproperty ein String ist und ich einen String in einem String-Eigenschaft stecken zu konvertieren.

Auch sah ich diese Refresh label in JAVAFX, aber das OP könnte das Etikett basierend auf Aktion aktualisieren. Ich habe wirklich nichts zu tun?

+0

Das hört sich an, als wäre es ein Threading-Problem, aber es ist unmöglich, mit nur ein paar Code-Schnipsel zu erzählen. Kannst du ein [MCVE] (http://stackoverflow.com/help/mcve) von Grund auf erstellen, das das Problem demonstriert? –

+0

Aber ich habe nur einen einzigen Thread. In Ordung. Ill add more details – Indigo

+0

Wenn Sie den gesamten Prozess auf dem FX Application Thread ausführen, dann ist das das Problem. –

Antwort

15

Wenn Sie den gesamten Prozess für den FX-Anwendungs-Thread ausführen, ist dies (effektiv) derselbe Thread, der zum Anzeigen der Benutzeroberfläche verwendet wird. Wenn sowohl die Anzeige der Benutzeroberfläche als auch der Dateiiterationsprozess im selben Thread ausgeführt werden, kann nur einer gleichzeitig ausgeführt werden. So verhindern Sie, dass die Benutzeroberfläche aktualisiert wird, bis der Prozess abgeschlossen ist.

Hier ist ein einfaches Beispiel, wo ich einfach für 250 Millisekunden zwischen jeder Iteration pausieren (simulieren das Lesen einer ziemlich großen Datei). Eine Schaltfläche startet dies im FX-Anwendungs-Thread (beachten Sie, dass die Benutzeroberfläche während dieser Ausführung nicht reagiert - Sie können das Textfeld nicht eingeben). Die andere Schaltfläche verwendet eine Task, um es im Hintergrund auszuführen und Updates für die Benutzeroberfläche des FX-Anwendungsthreads ordnungsgemäß zu planen.

import javafx.application.Application; 
import javafx.concurrent.Task; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 


public class UpdateTaskDemo extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     Label label = new Label(); 
     Button runOnFXThreadButton = new Button("Update on FX Thread"); 
     Button runInTaskButton = new Button("Update in background Task"); 
     HBox buttons = new HBox(10, runOnFXThreadButton, runInTaskButton); 
     buttons.setPadding(new Insets(10)); 
     VBox root = new VBox(10, label, buttons, new TextField()); 
     root.setPadding(new Insets(10)); 

     runOnFXThreadButton.setOnAction(event -> { 
      for (int i=1; i<=10; i++) { 
       label.setText("Count: "+i); 
       try { 
        Thread.sleep(250); 
       } catch (InterruptedException exc) { 
        throw new Error("Unexpected interruption"); 
       } 
      } 

     }); 

     runInTaskButton.setOnAction(event -> { 
      Task<Void> task = new Task<Void>() { 
       @Override 
       public Void call() throws Exception { 
        for (int i=1; i<=10; i++) { 
         updateMessage("Count: "+i); 
         Thread.sleep(250); 
        } 
        return null ; 
       } 
      }; 
      task.messageProperty().addListener((obs, oldMessage, newMessage) -> label.setText(newMessage)); 
      new Thread(task).start(); 
     }); 

     primaryStage.setScene(new Scene(root, 400, 225)); 
     primaryStage.show(); 
    } 

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