JavaFX UI-Thread und DB-Thread trennen um z.B. Ladebalken anzuzeigen

dior

Bekanntes Mitglied
Hi,

ich habe eine mittlerweile lauffähige Anwendung die je nachdem welchen Button ich anklicke eine SQL DB Abfrage macht und das Ergebnis in eine TableView schreibt.

Leider habe ich den UI und DB Thread ziemlich vermischt und weiß nicht wie ich die am besten trennen kann damit ich neben der Abfrage und dem befüllen der TableView die GUI mit einem Ladebalken oder einer anderen Animation ständig updaten kann bis alles fertig ist.

TreeView mit der Auswahl der einzelnen Abfragen:
Java:
.
.
public static ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();
  public static ObservableList<String> row = FXCollections.observableArrayList();
.
.
@FXML
  TableView tableview1;
.
.
public void BuildTreeView() {
.
.
************************************************************************************************** */
         treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {

             @Override
             public void changed(ObservableValue observable, Object oldVal, Object newVal) {
                 System.out.println(oldVal + " neuer: " + newVal);

                 switch (newVal.toString()) {
case "TreeItem [ value: USW ]":
                         sqlDatei = "USW.txt";
                         xlsxSheetName = sqlDatei.substring(0, sqlDatei.lastIndexOf('.'));
                         pIVisible();
                         AuswahlClicked();
                         buildData();
                         break;
case "TreeItem [ value: GHA ]":
                         sqlDatei = "gha.txt";
                         AuswahlClicked();
                         buildData();
                         break;
.
.
.

pIVisible()
Java:
public void pIVisible() {

        Platform.runLater(new Runnable() {
            public void run() {
                progressBarStatus.setVisible(true);
                labelStatus.setText("loading...");
            }
        });
    }

AuswahlClicked()
Hier lade ich das jeweilige SQL Statement aus einer Textdatei

buildData(); // -> DB-Abfrage und TableView updaten...

Java:
public void buildData() {
      tableview1.getItems().clear();
      tableview1.getColumns().clear();
       System.out.println("index: " + data.indexOf(c));
        try {
            c = DB._DB_Connection.getConnection();
            System.out.println("real SQL: " + SQL);
            ResultSet rs = c.createStatement().executeQuery(SQL);
            TableColumn col = new TableColumn();
            for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
                //making dynamic table
                final int j = i;
                col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
                col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
                    public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
                      //  System.out.println("param.getValue(): " + param.getValue().toString());
                        return new SimpleStringProperty(param.getValue().get(j).toString());
                    }
                });
                int rowNr = i + 1;
                System.out.println("Column [" + rowNr + "] " + rs.getMetaData().getColumnName(rowNr));
                tableview1.getColumns().addAll(col);
            }
            /* Data added to ObservableList */
            while (rs.next()) {
                //Iterate Row
                row = FXCollections.observableArrayList();
                for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                    Object o = rs.getObject(i);
                    row.add(o == null ? "" : o.toString()); // wenn ein NULL Value gefunden wird, wird dieser durch "" ersetzt
                }
                data.addAll(row);
                System.out.println("row: " + row.get(0));
            }
            Platform.runLater(() -> tableview1.setItems(data));
           
            ausgabe1.setText("" + data.size());
            System.out.println("Anzahl der Zeilen: " + data.size());
            // RechtsklickMenü in TableView initialisieren!
            RechtsKlickMenue();

            rs.close();
            c.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Error on Building Data");
        }

    }


Wie kann ich die buildData() so anpassen das der progressBar updated während die Abfrage noch läuft? Und dann nat. fertig ist wenn die Abfrage und das befüllen der TableView fertig ist.

ich hoffe ich habe das Problem halbwegs verständlich erklärt
danke im Voraus für eure Hilfe,
 

dzim

Top Contributor
Im Prinzip überall wo du etwas an der GUI manipulierst, was direkt angezeigt werden würde, muss dies per Platform#runLater ausgelöst werden (siehe dein Lambda-Ausdruck im anderen Thread).

ABER: Das setzt voraus, dass du die DB-Operation vorher bereits auf einem anderen Thread gemacht hast.

Schau dir dazu bitte die Klasse Task an:
https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html

Und hier noch etwas Doku/Tutorial dazu:
http://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm

Das sollte eigentlich genügen, um das Problem angehen zu können. Wenn nicht... Fragen!
 

dior

Bekanntes Mitglied
Danke für die Tips.

Ich habe jetzt folgendes versucht (bin nicht sicher ob das Zielführend ist...)
2 Tasks definiert. In einem wird die DB Abfrage gemacht, im anderen der ProgressIndicator angezeigt.

Java:
Task buildDatatask = new Task<Void>() {
        @Override
        public Void call() {
            System.out.println("Abfrage gestartet:");
            buildData();
            return null;
        }
    };
    Thread thBuildDatatask = new Thread(buildDatatask);

    Task pIVisibletask = new Task<Void>() {
        @Override
        public Void call() {
            System.out.println("Abfrage gestartet:");
            pIVisible();
            return null;
        }
    };
    Thread thPIVisibletask = new Thread(pIVisibletask);

beim klick auf das den Button starte ich die Threads:
Java:
thPIVisibletask.start();
thBuildDatatask.start();

Gut ist das am Ende das Ergebnis in der TableView angezeigt wird und auch der ProgressIndicator gleich beim klick gestartet wird, aber es kommt auch nach jeder Column eine Fehlermeldung:
Column [1] Name
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:145)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updatePlaceholderRegionVisibility(TableViewSkinBase.java:836)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updateVisibleColumnCount(TableViewSkinBase.java:799)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.lambda$new$71(TableViewSkinBase.java:302)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.FXCollections$UnmodifiableObservableListImpl.lambda$new$52(FXCollections.java:929)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
at javafx.scene.control.TableView.updateVisibleLeafColumns(TableView.java:1634)
at javafx.scene.control.TableView.access$200(TableView.java:355)
at javafx.scene.control.TableView$5.onChanged(TableView.java:634)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
Column [2] WERT1
at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:102)
at javafx.collections.ObservableListBase.addAll(ObservableListBase.java:245)
at FX.FXMLDocumentController.buildData(FXMLDocumentController.java:163)
at FX.FXMLDocumentController$1.call(FXMLDocumentController.java:119)
at FX.FXMLDocumentController$1.call(FXMLDocumentController.java:115)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updatePlaceholderRegionVisibility(TableViewSkinBase.java:838)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updateVisibleColumnCount(TableViewSkinBase.java:799)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.lambda$new$71(TableViewSkinBase.java:302)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.FXCollections$UnmodifiableObservableListImpl.lambda$new$52(FXCollections.java:929)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
at javafx.scene.control.TableView.updateVisibleLeafColumns(TableView.java:1634)
at javafx.scene.control.TableView.access$200(TableView.java:355)
at javafx.scene.control.TableView$5.onChanged(TableView.java:634)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:102)
at javafx.collections.ObservableListBase.addAll(ObservableListBase.java:245)
at FX.FXMLDocumentController.buildData(FXMLDocumentController.java:163)
at FX.FXMLDocumentController$1.call(FXMLDocumentController.java:119)
at FX.FXMLDocumentController$1.call(FXMLDocumentController.java:115)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updatePlaceholderRegionVisibility(TableViewSkinBase.java:838)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updateVisibleColumnCount(TableViewSkinBase.java:799)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.lambda$new$71(TableViewSkinBase.java:302)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.FXCollections$UnmodifiableObservableListImpl.lambda$new$52(FXCollections.java:929)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
at javafx.scene.control.TableView.updateVisibleLeafColumns(TableView.java:1634)
at javafx.scene.control.TableView.access$200(TableView.java:355)
at javafx.scene.control.TableView$5.onChanged(TableView.java:634)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
.
.
.
.
.

Fehler taucht beim befüllen der tableview auf:
Java:
tableview1.getColumns().addAll(col);
 

dzim

Top Contributor
Die Antwort steht vor dir:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread;
Dann ist auch klar, das es in der Zeile auftritt:
Java:
tableview1.getColumns().addAll(col);
Du musst diese Zeile in ein Lamdda und Platform#runLater wrappen:
Java:
Platform.runLater(() -> tableview1.getColumns().addAll(col));

Edit: Ungestetet, natürlich ;)
 

dior

Bekanntes Mitglied
Aber, ich habe das so gelöst... keine Ahnung ob das gut ist, aber es funktioniert zumindest.

Java:
TableColumn finalCol = col;
                Platform.runLater(() -> tableview1.getColumns().addAll(finalCol));
 

dior

Bekanntes Mitglied
Ich dachte jetzt hätte ich es, aber wenn ich jetzt eine 2. Abfrage starte kommt:
Exception in thread "JavaFX Application Thread" java.lang.IllegalThreadStateException

at java.lang.Thread.start(Thread.java:705)
at FX.FXMLDocumentController$4.changed(FXMLDocumentController.java:391)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:102)
at javafx.scene.control.MultipleSelectionModelBase.lambda$new$34(MultipleSelectionModelBase.java:67)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyIntegerPropertyBase.fireValueChangedEvent(ReadOnlyIntegerPropertyBase.java:72)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:102)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.MultipleSelectionModelBase.select(MultipleSelectionModelBase.java:404)
at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:356)
at javafx.scene.control.TreeView$TreeViewBitSetSelectionModel.clearAndSelect(TreeView.java:1477)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:256)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:220)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
 

dior

Bekanntes Mitglied
Beim 2. mal starten ist der Task (getState()) -> "Terminated" und lässt sich nicht nochmal starten.
Java:
Task buildDatatask = new Task<Void>() {
        @Override
        public Void call() {
           // System.out.println("Abfrage gestartet:");
           // System.out.println("ThreadStatus_buildDatatask: " + buildDatatask.getState().toString());
            buildData();
            return null;
        }
    };

was muss ich tun damit das doch geht bzw. wie kann ich den wieder "reseten" das es ein 2., 3., 4., .. mal geht?
 
K

kneitzel

Gast
Was spricht dagegen, wieder einen neuen Task zu erstellen? Die Idee eines Tasks ist nun einmal, dass dieser einmal abgearbeitet wird. Also immer, wenn Du den Task ausführen willst, läuft der Code mit Task buildTask = new Task<Void>() { .... erneut durch.
 

dior

Bekanntes Mitglied
Kann ich machen, ich wollte halt ein paar Codezeilen einsparen und den Task nicht immer neu schreiben.
Ich habe jetzt einen neuen Task erstellt und starte diesen dann mit:
Java:
Task buildDatatask2 = new Task<Void>() {
        @Override
        public Void call() {
           // System.out.println("Abfrage gestartet:");
           // System.out.println("ThreadStatus_buildDatatask: " + buildDatatask.getState().toString());
            buildData();
            return null;
        }
    };
                        Thread thBuildDatatask2 = new Thread(buildDatatask2);
                        thBuildDatatask2.start();

Es wird das Ergebnis in der TableView angezeigt, aber es kommt noch ein Fehler:
Exception in thread "Thread-8" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-8
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:145)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updatePlaceholderRegionVisibility(TableViewSkinBase.java:836)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.updateVisibleColumnCount(TableViewSkinBase.java:799)
at com.sun.javafx.scene.control.skin.TableViewSkinBase.lambda$new$71(TableViewSkinBase.java:302)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.FXCollections$UnmodifiableObservableListImpl.lambda$new$52(FXCollections.java:929)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
at javafx.scene.control.TableView.updateVisibleLeafColumns(TableView.java:1634)
at javafx.scene.control.TableView.access$200(TableView.java:355)
at javafx.scene.control.TableView$5.onChanged(TableView.java:634)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:157)
at FX.FXMLDocumentController.buildData(FXMLDocumentController.java:152)
at FX.FXMLDocumentController$5$1.call(FXMLDocumentController.java:412)
at FX.FXMLDocumentController$5$1.call(FXMLDocumentController.java:407)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)
 
K

kneitzel

Gast
Ach so, vom Task musst Du natürlich keine neue Instanz erzeugen sondern es müsste ein neuer Thread reichen.
Und den Punkt mit der "Not on FX application thread" hast Du ja gelöst - wollte dazu gerade auf die angegebene Lösung in diesem Thread hinweisen.
 

dior

Bekanntes Mitglied
OK, das versteh ich nicht ganz, bzw. das klapp nicht so wie ich mir das denke.

Ich habe den Task:
Java:
Task buildDatatask = new Task<Void>() {
        @Override
        public Void call() {
            // System.out.println("Abfrage gestartet:");
            // System.out.println("ThreadStatus_buildDatatask: " + buildDatatask.getState().toString());
            buildData();
            return null;
        }
    };

beim 1. Mal starte ich ihn mit:
Java:
Thread thBuildDatatask = new Thread(buildDatatask);
thBuildDatatask.start();

Wenn ich jetzt beim 2. Button die Abfrage starte mit:
Java:
Thread thBuildDatatask2 = new Thread(buildDatatask);
                        Platform.runLater(() -> thBuildDatatask2.start());

dann passiert gar nichts.....

wenn ich aber auch den Task neu mache, dann klappt alles:

Java:
Task buildDatatask2 = new Task<Void>() {
                            @Override
                            public Void call() {
                                // System.out.println("Abfrage gestartet:");
                                // System.out.println("ThreadStatus_buildDatatask: " + buildDatatask.getState().toString());
                                buildData();
                                return null;
                            }
                        };
                        Thread thBuildDatatask2 = new Thread(buildDatatask);
                        Platform.runLater(() -> thBuildDatatask2.start());
 
K

kneitzel

Gast
Hmm .... sorry für die Verwirrung. War da selbst etwas verwirrt, denn ein Task hat zwar die Möglichkeit, auch mehrfach ausgeführt zu werden aber beim run Aufruf ist dies nicht der Fall.

Task hat (von FutureTask) zwei Methoden, die betrachtet werden müssen:
a) run() - hier wird dann der Task ausgeführt und der Status wird gesetzt. Dadurch hast Du dann einen Endstatus und der Task kann kein zweites mal gestartet werden.
b) runAndReset() - hier wird der Task ausgeführt und danach dann aber in den Ursprungszustand zurückgesetzt. So lässt sich der Task dann auch mehrfach ausführen.

Daher ist es wohl für Dich am Einfachsten, auch den Task neu zu erstellen.
 

dzim

Top Contributor
Noch mal zu deinem Final-Feld zurück (deine erste Frage, nach meinem letzen Post). Es ist halt so, das ein Lambda am Ende "nur" eine optisch aufgehübschte Version einer Anonymen Klasse ist. Ich würde dir empfehlen, dich mit dem Thema Lambda und Methoden-Referenz zu beschäftigen - hab ich auch erst kürzlich getan und danach erst richtig verstanden, wie das intern klappt - ich kann es leider nur nicht gut genug erläutern. Sorry.

Zum Einen: Wenn du den selben Task wieder und wieder verwendest, dann kannst du stattdessen auch einen Service implementieren (wenn man es so implementiert, wird immer ein neuer Task erstellt).
Auf der bereits geposteten Seite (http://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm) suche nach "The Service Class". Dort wird das erläutert.

Zum Anderen:
Java:
Platform.runLater(()-> thBuildDatatask2.start());
Das ist Käse! Mit dem Befehl führst du den Task wieder explizit auf dem UI-Thread auf und damit wird das UI wieder einfrieren. In den Lambdas von Platform#runLater darf nur Code stehen, der die GUI verändert!
 

dzim

Top Contributor
Nachtrag: Ok. Der Thread wird nicht explizit auf dem UI Thread laufen, nur vorn dort gestartet. Sorry. Hab übersehen, dass du noch einen Thread um den Task wrappst.
Aber: Du wirst dadurch trotzdem nichts gewinnen. Wichtig ist einfach, dass am Ende nur GUI-Updates darin ausgeführt werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Server/Client thread von GUI Trennen AWT, Swing, JavaFX & SWT 2
P thread nimmt veränderte boolean nicht AWT, Swing, JavaFX & SWT 7
N JFrame loescht alles, sobald der Thread zuende ist AWT, Swing, JavaFX & SWT 22
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
T Exception in thread "main" java.lang.NoClassDefFoundError AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28
H Event Handling Thread - Abruf der get-Methode AWT, Swing, JavaFX & SWT 5
J "Exception in thread "AWT-EventQueue-0"" Fehler AWT, Swing, JavaFX & SWT 3
G Thread starten Swing AWT, Swing, JavaFX & SWT 5
C Thread verwalten AWT, Swing, JavaFX & SWT 2
A Swing Exception in thread "AWT-EventQueue-0" AWT, Swing, JavaFX & SWT 1
S JavaFX Exception in thread "JavaFX Application Thread" AWT, Swing, JavaFX & SWT 3
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Alert Confirmation Dialog aus einem Service Thread AWT, Swing, JavaFX & SWT 8
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
D Swing SwingUtils / Thread Problem AWT, Swing, JavaFX & SWT 3
J Thread per Button starten AWT, Swing, JavaFX & SWT 10
J Thread kennt JButton nicht. AWT, Swing, JavaFX & SWT 11
T JavaFX Task / Thread / FXThread Komplikationen AWT, Swing, JavaFX & SWT 5
O Swing Event Dispatch Thread AWT, Swing, JavaFX & SWT 1
L JavaFX UI Thread block AWT, Swing, JavaFX & SWT 13
X Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 AWT, Swing, JavaFX & SWT 6
sandaime Swing Thread für CMD auslesen AWT, Swing, JavaFX & SWT 16
E JavaFX JavaFX Application in Thread ausführen AWT, Swing, JavaFX & SWT 1
T JavaFX Controller im extra Thread AWT, Swing, JavaFX & SWT 0
T Swing 2 Thread.sleep parallel laufen lassen AWT, Swing, JavaFX & SWT 4
L Zweites Fenster mit Thread AWT, Swing, JavaFX & SWT 0
E JavaFX Stage.show() in ursprünglichem Thread starten AWT, Swing, JavaFX & SWT 7
L Swing Frame in Thread wird nicht gezeichnet AWT, Swing, JavaFX & SWT 2
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
C Im ActionListener Buttons disablen, einen Thread starten, dann Buttons enablen AWT, Swing, JavaFX & SWT 2
C Thread-/ Simulations- Problem AWT, Swing, JavaFX & SWT 18
T Swing Button bleibt grau [=> UI hat sich aufgehängt, Aufgabe in Thread auslagern] AWT, Swing, JavaFX & SWT 3
M Thread-Frage in SWT AWT, Swing, JavaFX & SWT 1
Q GUI außerhalb GUI-Thread updaten - GUI friert ein AWT, Swing, JavaFX & SWT 18
C Thread in Klassen starten AWT, Swing, JavaFX & SWT 4
L exception in thread awt-eventqueue-0 java.lang.nullpointerexception AWT, Swing, JavaFX & SWT 2
S Swing Exception in thread "AWT-EventQueue-0" bei Jlabel AWT, Swing, JavaFX & SWT 4
D SWT SWT Elemente aus anderen Klassen aufrufen - Invalid thread access AWT, Swing, JavaFX & SWT 6
K JavaFX Tableview mit fxml ohne Aktualiserung trotz Thread AWT, Swing, JavaFX & SWT 13
K Event Handling 2 Buttons und Thread stop AWT, Swing, JavaFX & SWT 3
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
V JLabel bzw. GUI aus externen Thread ansteuern AWT, Swing, JavaFX & SWT 3
J Applet Paralleles Thread Handling AWT, Swing, JavaFX & SWT 3
H Swing JfreeChart aktualisieren - mit daten aus thread AWT, Swing, JavaFX & SWT 3
T Java Swing Main GUI Thread AWT, Swing, JavaFX & SWT 3
C Event Handling Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException AWT, Swing, JavaFX & SWT 43
T Table-Zeilen mit Thread einfärben AWT, Swing, JavaFX & SWT 15
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
V Nullpointerexception (etwas mit thread und jframe) AWT, Swing, JavaFX & SWT 3
P Problem Thread.sleep() und JProgressBar AWT, Swing, JavaFX & SWT 7
S SWT GUI-Thread AWT, Swing, JavaFX & SWT 11
A Thread und sleep(1000); AWT, Swing, JavaFX & SWT 7
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
S Timer oder Thread.sleep AWT, Swing, JavaFX & SWT 3
M Exception in thread "Thread-3" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 18
B Über SWT Button Thread beenden AWT, Swing, JavaFX & SWT 2
C SWT Gui Thread hängt sich auf AWT, Swing, JavaFX & SWT 3
lumo SWT Exception in thread "main" org.eclipse.swt.SWTError: No more handles AWT, Swing, JavaFX & SWT 3
Luk10 Swing Problem mit Zeichen-Thread AWT, Swing, JavaFX & SWT 8
G 2D-Grafik Von Thread aus Zeichnen AWT, Swing, JavaFX & SWT 5
U Swing JLabel bewegen mittels Thread AWT, Swing, JavaFX & SWT 3
M JProgressBar für einen Thread AWT, Swing, JavaFX & SWT 14
R JTable und Thread AWT, Swing, JavaFX & SWT 4
K Thread.sleep in GUI AWT, Swing, JavaFX & SWT 4
J Thread funktioniert nicht AWT, Swing, JavaFX & SWT 10
D JPanel mit Thread in JPanel AWT, Swing, JavaFX & SWT 4
F Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: null AWT, Swing, JavaFX & SWT 5
P Teil einer Swing GUI in eigenem Thread AWT, Swing, JavaFX & SWT 4
S Thread.sleep() in einer methode fürs zeichen AWT, Swing, JavaFX & SWT 3
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
P repaint während Thread läuft AWT, Swing, JavaFX & SWT 9
F SWT table refresh per Thread AWT, Swing, JavaFX & SWT 2
V Swing remove(Component) blockiert Thread sehr lange. AWT, Swing, JavaFX & SWT 6
J AWT Artefakte bei AWT-Rendering durch parallelen Thread AWT, Swing, JavaFX & SWT 4
H Thread-Problem mit der Darstellung beim Sperren des Fensters AWT, Swing, JavaFX & SWT 2
T Event Dispatch Thread und noch ein Thread AWT, Swing, JavaFX & SWT 7
Burny91 Swing Thread mit wait() und notify() steuern AWT, Swing, JavaFX & SWT 22
N SWT - über Thread Composite erstellen und Anhängen AWT, Swing, JavaFX & SWT 6
K Vom Gui aus auf einen Thread warten AWT, Swing, JavaFX & SWT 4
X Problem bei JTextArea und Thread.sleep() AWT, Swing, JavaFX & SWT 8
F Merkwürdiges Verhalten zeichnen sperater Thread AWT, Swing, JavaFX & SWT 13
B Swing Swing und Thread.sleep() AWT, Swing, JavaFX & SWT 6
N Exception Behandlung mit setDefaultUncaughtExceptionHandler, insbesondere im EventDispatcher Thread AWT, Swing, JavaFX & SWT 4
Q Neuer Thread zum Öffnen AWT, Swing, JavaFX & SWT 2
P Swing GUI im Thread? AWT, Swing, JavaFX & SWT 5
T GUI JFrame - neuer Thread AWT, Swing, JavaFX & SWT 2
data89 Was mache ich mit "Dispatched Event Thread"/Substance falsch? AWT, Swing, JavaFX & SWT 4
0x7F800000 Allg. Frage zum ev. dispatch thread, wie korrekt auf reaktion der Listener warten? AWT, Swing, JavaFX & SWT 4
S Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 7
T thread.sleep Sprung Problem AWT, Swing, JavaFX & SWT 24
N Server mit Thread und Statusbox AWT, Swing, JavaFX & SWT 3
S Objektverhalten in einen Thread legen AWT, Swing, JavaFX & SWT 4
G JProgressBar actionPerformedMethode und SwingUI thread AWT, Swing, JavaFX & SWT 36
E Komponenten in Event Dispatch Thread erzeugen? AWT, Swing, JavaFX & SWT 4
J Thread in GUI einbauen AWT, Swing, JavaFX & SWT 2
Lony AbstractTableModel Exception in thread "AWT-EventQueue- AWT, Swing, JavaFX & SWT 3
A Ticker als Thread AWT, Swing, JavaFX & SWT 3
G Auf Ergebnis vom Thread warten AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben