Java FX ProgressIndicator dreht sich nicht

eclipseworker

Bekanntes Mitglied
Ich habe ein kleines Programm (erstes GUI-Programm), das für gewisse Sachen etwas länger braucht und um zeigen, dass das Programm arbeitet habe ich einen kleinen ProgressIndicator eingebaut und meine Idee wäre eigentlich gewesen, dass er sich so drehen müsste:
Java:
procircle.setProgress(-1F); /*bzw. er wird mit 
-1 inzialisert und normaler Weise versteckt also
procircle.setVisible(true); */

//tue Arbeit

procircle.setProgress(0); //procircle.setVisible(false);
Aber da dreht sich nichts auch wenn mein Programm für eine Minute still steht, wie kann ich das ausbessern?
 
Das Problem ist das diese Arbeit nicht wirklich in eine eigene Klasse auslagerbar ist.
Oh PS: und Exceptions können da auch auftreten.
Ok ich habe es bei einer Aufgabe geschaft circa so:
Java:
...
procircle.setVisible(true);
new RunableWorker(...).run();
procircle.setVisible(false);
...
Funktioniert auch nur wird der Kreis weiterhin nicht angezeigt.
 
Ok ich habe es bei einer Aufgabe geschaft circa so:
Java:
...
procircle.setVisible(true);
new RunableWorker(...).run();
procircle.setVisible(false);
...
Funktioniert auch nur wird der Kreis weiterhin nicht angezeigt.

Naja, was erwartest du, wenn du die Sichtbarkeit direkt nach dem auf true setzten wieder auf false setzt?
 
Naja, was erwartest du, wenn du die Sichtbarkeit direkt nach dem auf true setzten wieder auf false setzt?
Dass die Arbeit (die etwas länger dauert zuerst gemacht wird, das ist auch der Grund bin ich ja zu erst ja auch nicht drauf kommen, dass mit einem separaten Thread zu machen.) Habe es schon mit einem wait() versucht, gab aber eine unschöne Expedition, wie mache ich das korrekt?
 
Hi,
hier mal ein kleines Beispiel:
Java:
package application;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ProgressIndicatorTest extends Application{
    private Task<Void> task;
    private Button startButton;
    private Button cancelButton;
    private ProgressIndicator progressIndicator;
 
    public static void main(String[] args) {
        Application.launch(args);
    }
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("ProgressIndicator Example");
        Group root = new Group();
        Scene scene = new Scene(root, 350, 100, Color.WHITE);

        BorderPane mainPane = new BorderPane();
        root.getChildren().add(mainPane);

        final Label label = new Label("Progress: ");
        progressIndicator = new ProgressIndicator(0);

        final HBox hb = new HBox();
        hb.setSpacing(10);
        hb.setAlignment(Pos.CENTER);
        hb.getChildren().addAll(label, progressIndicator);
        mainPane.setTop(hb);

        startButton = new Button("Start");
        cancelButton = new Button("Stop");
        final HBox hb2 = new HBox();
        hb2.setSpacing(10);
        hb2.setAlignment(Pos.CENTER);
        hb2.getChildren().addAll(startButton, cancelButton);
        mainPane.setBottom(hb2);
     
        startButton.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent actionEvent) { 
                startButton.setDisable(true);
                progressIndicator.setProgress(0);
                cancelButton.setDisable(false);

                task = createTask();
                progressIndicator.progressProperty().bind(task.progressProperty());

                task.messageProperty().addListener(new ChangeListener<String>() {
                    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                        System.out.println(newValue);
                    }
                });

                task.setOnSucceeded(event -> {
                    System.out.println("fertig");
                    startButton.setDisable(false);
                    cancelButton.setDisable(true);
                    progressIndicator.progressProperty().unbind();
                });
             
                task.setOnCancelled(event -> {
                    System.out.println("angehalten.");
                    startButton.setDisable(false);
                    cancelButton.setDisable(true);
                    progressIndicator.progressProperty().unbind();
                });
             
                new Thread(task).start();
            }
        });
        cancelButton.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                task.cancel(true);
            }
        });
        primaryStage.setScene(scene);
        primaryStage.show();
    }
 

    public Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(1000);
                    updateMessage(i * 1000 + " ms");
                    updateProgress(i + 1, 10);
                }
                return null;
            }
        };
    }
}
... ist nicht perfekt, aber zeigt mal wie so etwas funktionieren könnte...😉
 
Zuletzt bearbeitet:
1)
Schau mal hier: Da habe ich ein Beispiel für so etwas gebaut (hab keine Lust den Code noch einmal zu posten):

http://www.java-forum.org/thema/mei...erden-nicht-aktualisiert.172464/#post-1086826

2)
Ok ich habe es bei einer Aufgabe geschaft circa so:
Java:
...
procircle.setVisible(true);
new RunableWorker(...).run();
procircle.setVisible(false);
...
Funktioniert auch nur wird der Kreis weiterhin nicht angezeigt.

Kurz noch eine etwas detailiertere Begründung, warum das vermutlich nicht funktioniert:
Variante 1) Du erstellst eine Runnable, nennst sie RunnableWorker und rufst die #run() Methode direkt auf. Dadruch wird kein Thread abgespalten und dein UI friert genauso wie vorher ein. Nur dass die Arbeit diesmal sauberer in einer eigenen Klasse stattfindet.

Variante 2) Unwahrscheinlich, aber wenn doch ein Thread abgespaltet werden sollte, dann würde #run() diesen lediglich starten, aber unabhängig davon, ob die Arbeit noch läuft, oder nicht, sofort wieder procircle.setVisible(false); aufrufen.

Die erste Variante ist meiner Einschätzung nach dein Fehler. Da die UI aufgrund der Arbeit einfriert, siehst du keinen sich drehenden ProgressBar.
Du musst deine Runnable in einem Thread laufen lassen. Dann aber muss entweder am Ende der Thread-Arbeit dieser selbst den ProgrBar wieder unsichtbar machen, oder aber wenn du den in unseren Code-Beispielen genannten Task verwendest, das mittelst eines Callbacks erledigen, das automatisch am Ende der Arbeit aufgerufen wird.
Lies dir die Beispiele von @knilch und mir mal in Ruhe durch und versuch dich mal daran.
 

Zurück
Oben