JavaFX Concurrency Update UI

izoards

Bekanntes Mitglied
Hallo,

Ich möchte ein JavaFX UI von einem Background Thread aktualisieren. Ich habe mich an folgendem Codebeispiel orientiert:
JavaFX Concurrency Example | Examples Java Code Geeks - 2021

Jedoch ist mein UI mit einer Controller Klasse und einem *.fxml - File aufgesetzt.
Ich möchte also das label über das controller objekt ansprechen. Aber genau hier, stürzt mein Programm ab.

Hier mein angepasster Code:
[CODE lang="java" title="Update UI via controller class" highlight="81"]
public class FxConcurrencyExample3 extends Application
{

private Stage primaryStage;
private MainWindowController controller = new MainWindowController();

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

@Override
public void start(Stage primaryStage) {

this.primaryStage = primaryStage;



try {
FXMLLoader loader = new FXMLLoader(FxConcurrencyExample3.class.getResource("MainWindow.fxml"));
AnchorPane pane = loader.load();

primaryStage.setMinHeight(400);
primaryStage.setMinWidth(500);

// MainWindowController mainWindowController = loader.getController();
// mainWindowController.setMain(this);

Scene scene = new Scene(pane);

primaryStage.setScene(scene);
primaryStage.show();


startTask();

} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}




public void startTask()
{
// Create a Runnable
Runnable task = new Runnable()
{
public void run()
{
runTask();
}
};

// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();

}

public void runTask()
{
try
{
// Get the Status


// Update the Label on the JavaFx Application Thread
Platform.runLater(new Runnable()
{
@Override
public void run()
{
controller.ofActuelContent.setText("test");
System.out.println("run");
}
});


Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

[/CODE]


Die Fehlermeldung ist:

Java:
Feb 09, 2021 11:43:06 AM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 15.0.1 by JavaFX runtime of version 8.0.202-ea
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at tutorial.FxConcurrencyExample3$2.run(FxConcurrencyExample3.java:100)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)


Was mache ich falsch?
Wie sollte das Grundgerüst aussehen für mein Vorhaben?
Danke für eine Hilfe....
 

Flown

Administrator
Mitarbeiter
Du übernimmst deinen Controller nicht - daher auch nicht initialisiert - und hast deswegen auch den Controller nicht initialisiert (der gehört beim Loader hinzugefügt).

Zeile: controller.ofActuelContent.setText("test");
 

izoards

Bekanntes Mitglied
Wow, danke für die rasche Rückmeldung.
hm, also muss ich in der Controller Klasse die initialisation machen? Also in einem Konstruktor?
Oder wie genau muss ich den Controller initialisieren?

Sorry, befasse mich das erste Mal mit GUI und Threads...
 
K

kneitzel

Gast
Also wenn man mit fxml arbeitet, dann kann man im fxml File angeben, welche Klasse der Controller ist. Und dann erzeugt der Loader den Controller und initialisiert auch Variablen und so ...

Der auskommentierte Part könnte also durchaus schon der korrekte Ansatz sein, d.h. mittels getController den Controller zu bekommen. (Setzt aber voraus, dass das im fxml korrekt gesetzt wurde)

Wenn der Thread zum Windwos gehört, dann würde ich den aber auch innerhalb des Controllers starten. Dann kann er auch deutlich leichter auf den Controller zugreifen.
 

Flown

Administrator
Mitarbeiter
Normalerweise macht man sowas:
Code:
FXMLLoader loader = FXMLLoader(....);
loader.load();
this.controller = loader.getController(); // This is where the magic happens
 

izoards

Bekanntes Mitglied
Das wars :) Perfekt Danke vielmals, ich habe schon x-stunden gesucht....

Also mein Ziel ist es, das GUI primär als Anzeige zu verwenden.
Der Background thread, beinhaltet dann einen watchService für zwei Ordner und wird somit "endlos" laufen... und sollte einfach verschiedene Labels im GUI anpassen.

Später sollen dann noch die zu überwachenden Ordner übers GUI gesetzt werden.

Ich hoffe ich bin mit diesem Ansatz auf dem richtigen Weg für meine geplante Applikation...

Was ich noch nicht genau verstehe, ist, wo ich den controller erstellen und initialisieren muss?
Also wenn ich z.B. später in einer WorkerThread - Klasse das gui über den controller anpassen will.
So müsste ich doch in dieser Klasse den controller instanzieren und auch dort initialisieren?

Wenn ich das jedoch machen will, kann er "loader" nicht auflösen:

Java:
public class WorkerThread extends Thread{
    

    MainWindowController controller = new MainWindowController();
    controller = loader.getController();


    public WorkerThread() {
        setDaemon(true);

    }

    @Override
    public void run() {


        while (!this.isInterrupted()) {

            // UI updaten
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    // entsprechende UI Komponente updaten
                    controller.ofActuelContent.setText("------");

                }
            });

            // Thread schlafen
            try {
                // fuer 3 Sekunden
                sleep(TimeUnit.SECONDS.toMillis(3));
            } catch (InterruptedException ex) {
                Logger.getLogger(WorkerThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }


    }


Wie wäre hier die richtige Vorgehensweise, damit auch aus einer anderen Klasse auf die Labels zugegriffen werden kann?

Danke euch vielmals für die Hilfe :)
 

Flown

Administrator
Mitarbeiter
Ich will jetzt kein Spielverderber sein, aber ....

... es gibt FileWatcher die das für dich übernehmen können
... wenn du Fragen musst, wie du das mit dem richtigen Scoping/Threading/Initialisierung hinbekommst, dann ist UI Entwicklung noch ein wenig zu hoch und du solltest einen Schritt zurücksteigen
... Du kannst das Property ja eh auf der obersten Ebene halten (MyController controller;) und dann beim Laden eben zuweisen (this.controller = loader.getController())
... Man arbeitet in JavaFX mit Tasks und schon lange greift man keine Threads mehr selbst an (https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm)
 

izoards

Bekanntes Mitglied
Dachte mir schon, dass so eine Antwort kommt.
Ich bin tatsächlich noch überhaupt nicht erfahren.
Ich habe jedoch bis jetzt die Funktion, welche im Background laufen sollte hingekriegt und Sie läuft als Windows Service schon ganz gut.
Ich habe mit WatchService gearbeitet... Ich denke das ist dieser FileWatcher? Oder gibt es noch etwas spezifischeres?

Nun muss jedoch doch ein UI hin, darum bin ich nun daran, mich hier schlau zu machen...

Denke, auch, dass ich das mit den Tasks machen sollte mit der javafx.concurrent framework, richtig?
 

izoards

Bekanntes Mitglied
Trotzdem danke für die Antworten, für ideen, tutorials und beispielcode, bin ich immer sehr froh darüber...
 
K

kneitzel

Gast
Also generell sollte es so aussehen:
Du hast die Business-Logik mit irgendwelchen Daten unabhängig von jeder Oberfläche. Und dann wird ein Thread nur Daten anpassen im Model und sonst nichts.

Wenn Du dann eine Oberfläche erstellst, dann kümmert die sich nur um das Anzeigen und das Auslösen von Aktionen und so. Aber sie greift nur auf das Model zurück.

Das Model kann z.B. eine Art Event haben, wenn sich Daten ändern (Observer-Pattern). Da könnte dann ein Controller drauf reagieren um z.B. über runLater die Oberfläche anzupassen. Aber die eigentliche Funktionalität solltest Du erst einmal ohner Oberfläche entwickeln (und z.B. über Unit Tests testen).

Und bei der Oberflächen-Entwicklung gibt es dann diverse Pattern: MVC ist das, worauf einige Standard-Bezeichnungen schon hin deuten:Du hast das Model (Business-Logik mit Daten), die View und den Controller. Wobei ich das für Oberflächen als unpassend empfinde - da neige ich eher zum MVVMPattern (mit mvvmFX), aber das geht jetzt hier etwas zu weit. Aber ich hoffe, dass ich Dir ein paar Anregungen liefern konnte.
 

izoards

Bekanntes Mitglied
Besten Dank, das hilft auf jedenfall.
Also als Model meinst Du die Business logik?

Ich habe es mir eben ein bisschen weniger komplex vorgestellt:

Mein Programm läuft bereits ohne Oberfläche.

Nun habe ich mir ein Beispiel genommen und mir testweise eine kleine Oberfläche gemacht, also mit den bekannten JavaFX Struktur: main, controller und fxml.

Dort rufte ich mein eigentliches Programm auf und wollte die labels anpassen, jedoch friert das GUI ein..
Daher versuche ich nun diese ganze Geschichte mit den beiden Threads..

Ich finde es jedoch schwierig herauszufinden, wie die Verlinkung geschehen muss... Falls es hier ein Beispiel gäbe, um das ganze Grundgerüst zu erkunden, wäre das extrem hilfreich..
Ansonsten setzte ich mich an die Tutorials und werde mir deine Tipps (Observer Pattern) noch genauer ansehen..


PS: Zu beginn, bastelte ich mir einfach ein java swing gui, welches eigentlich soweit die labels anpasst, ohne Controller klasse etc. jedoch war ich mit der ganzen GUI Oberflächen Gestaltung bisschen am hadern, daher wollte ich es jetzt mit javafx und dem scene builder machen...

Macht meine Entscheidung sinn? Oder wäre java swing auch I.O. für mein anliegen?
 
K

kneitzel

Gast
Also die verwendete Technologie (JavaFX, Swing, SWT, ...) tut sich nichts. Die sind vom Prinzip her relativ ähnlich. Daher ist ein Wechsel eher kontraproduktiv (Da ich davon ausgehe, dass Du einige Punkte bereits verstanden hast. Zumindest hast Du diese gelesen und die Chance ist hoch, dass Du diese dann einordnen kannst, wenn du es brauchst....).

Der Hauptunterschied ist, dass Du jetzt nicht mehr auf irgendwas selbst wartest. Der Benutzer soll machen, was er will und nur bei bestimmten Dingen (Ein Click, ein bestimmter Tastendruck, ...) wirst du kurz (!!) aktiv. Denn die Ausführung macht nur ein Thread und wenn der steht, dann steht alles.

Das ist aber ok, denn in der Regel gibt es nur kurze Dinge zu tun. Und wenn etwas länger dauern könnte: Dann gibst Du das einfach weiter und läßt machen (Du bist sozusagen Boss! Feuerwehr-Einsatz und Du bist Chef! Wenn Du anfängst selbst irgendwas zu machen, dann entgehen Dir wichtige Dinge. Daher nur kurze Dinge machen und ggf. schnell Entscheidungen treffen ....)

Ansonsten kann ich Dir nur empfehlen, uns ruhig ein paar mehr Details mitzuteilen. Ich bin sicher, dass Du hier viele gute Ideen bekommst, wie du bestimmte Dinge machen kannst. Und so entsteht dann evtl. auch schnell ein kleines Beispiel, wie es gehen könnte. Also wenn z.B. das, was derzeit bei Dir hängt, nicht zu groß ist: Poste es doch einmal.
 

izoards

Bekanntes Mitglied
Das ist aber ok, denn in der Regel gibt es nur kurze Dinge zu tun. Und wenn etwas länger dauern könnte: Dann gibst Du das einfach weiter und läßt machen (Du bist sozusagen Boss! Feuerwehr-Einsatz und Du bist Chef! Wenn Du anfängst selbst irgendwas zu machen, dann entgehen Dir wichtige Dinge. Daher nur kurze Dinge machen und ggf. schnell Entscheidungen treffen ....)
hmm, also in meinem Fall ist es eben ein WatchService, so wie ich ihn gemacht habe, läuft der die ganze Zeit. Also nicht nur kurz was machen und wieder warten bis der User was macht. Wie bereits geschrieben, der User interagiert eigentlich fast nie mit dem GUI, ausser er will die Pfade ändern. Sonst soll das Gui Status Meldungen, Fehlermeldungen und logs anzeigen...

Ansonsten kann ich Dir nur empfehlen, uns ruhig ein paar mehr Details mitzuteilen. Ich bin sicher, dass Du hier viele gute Ideen bekommst, wie du bestimmte Dinge machen kannst. Und so entsteht dann evtl. auch schnell ein kleines Beispiel, wie es gehen könnte. Also wenn z.B. das, was derzeit bei Dir hängt, nicht zu groß ist: Poste es doch einmal.

Sehr gerne, ich bereite mal was vor und stelle es hier rein :) Das hilft mir auf jedenfall sehr...
 
K

kneitzel

Gast
So ein Service wäre dann ein eigenständiger Thread. Wie man diesen am besten implementiert müsste man sich überlegen. Die meisten Frameworks haben einen Background Worker im Angebot, der sich für sowas oft anbietet. (Bei JavaFX wäre Task wohl die Klasse die sich hier anbieten würde.)
 

izoards

Bekanntes Mitglied
Ich muss mich mal noch mit diesem Background Worker befassen...
Melde mich mit Code gerne, nachdem ich mich nochmals Schlau gemacht habe...
 

izoards

Bekanntes Mitglied
Oder vielleicht zeige ich mal, was ich vorhabe:

Das ist die Main Routine, welche das Gui startet. In der Methode mainWindow() wird am Schluss dieser Background-"Task" gestartet, welcher in einem eigenen Task (Thread) laufen sollte. MIt dieser Lösung ist jedoch mein GUI komplett eingefrohren:

[CODE lang="java" title="Main: startet GUI und "Background-Runner""]package myPackage;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.io.IOException;
import java.nio.file.*;

public class Main extends Application {

private Stage primaryStage;



@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
mainWindow();
}

public void mainWindow() {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml"));
AnchorPane pane = loader.load();

primaryStage.setMinHeight(400);
primaryStage.setMinWidth(500);

MainWindowController mainWindowController = loader.getController();
mainWindowController.setMain(this);

Scene scene = new Scene(pane);

primaryStage.setScene(scene);
primaryStage.show();

Runner runBackground = new Runner();
runBackground.run(mainWindowController);



} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}





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

}
}
[/CODE]


in meiner "Runner" Klasse, wird dann der WatchService aufgerufen:
Im Moment übergebe ich hier das mainWindowController Objekt, damit ich die Labels auf dem GUI setzen könnte(?!)
(ist vermutlich falsch? Oder wäre das denkbar, falls dieser Runner im Hintergrund auf einem neuen Thread läuft?)

Java:
package myPackage;

import java.nio.file.*;

public class Runner {




    public void run(MainWindowController controller) throws Exception {


            XML_TCP runnerApp = new XML_TCP();

            runnerApp.tryToConnect();


            WatchService watchService = FileSystems.getDefault().newWatchService();
            Path pathIn = Paths.get("C:\\xml\\In");
            Path pathOut = Paths.get("C:\\xml\\Export");

            pathIn.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
            pathOut.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);

            WatchKey key;

            // Hier müssen dann noch die Pfade abgefragt werden! Falls gleich i.o. falls nicht, neuer Watch Service!
            while ((key = watchService.take()) != null) {
                if (key.watchable().equals(pathIn)) {
                    for (WatchEvent<?> event : key.pollEvents()) {
                        runnerApp.watchEventOne(controller);
                    }
                    key.reset();
                } else if (key.watchable().equals(pathOut)) {
                    for (WatchEvent<?> event : key.pollEvents()) {
                        runnerApp.watchEventTwo();
                    }
                    key.reset();
                }

            }
        }


    }


Also das Ziel wäre, Schlussendlich in der Klasse XML_TCP, die GUI Texte anzupassen...

(Das mit den Pfade setzen per GUI überlege ich mir später dann später... wenn ich das Gründgerüst zusammen habe....


Wäre es möglich, diese Runner Klasse in einen neuen Thread (Task) zu packen?
Oder ist diese Struktur bereits nicht so bestPractice?
 
K

kneitzel

Gast
Also mit
Java:
            Runner runBackground = new Runner();
            runBackground.run(mainWindowController);
erzeugst Du keinen neuen Thread.

Da solltest Du also entweder Task nutzen (der dann mit Thread gestartet werden sollte) oder einen Service. Das wird z.B. hier kurz erläutert:

Im Moment übergebe ich hier das mainWindowController Objekt, damit ich die Labels auf dem GUI setzen könnte(?!)
Also technisch ist das möglich und daher würde ich da nicht von falsch reden. Aber es ist ungeschickt, da du so unnötige Abhängigkeiten einbindest. Du kannst dies aber relativ einfach entkoppeln, daher ist dies nicht zu problematisch.
 

izoards

Bekanntes Mitglied
Hallo kneitzel,
Dass ich damit keinen nuene Thread starte, ist mir bewusst, das wollte ich nur andeuten, dass ich hier den thread starten möchte ;-)

Oh der Artikel über Task und Services ist super...
Habe soeben versucht diesen in mein Beispiel zu übernehmen, aber klappt nicht so richtig :-(
Meiner Meinung habe ich dasselbe "Setup" wie im Beispiel Code des Artikels.
Jedoch findet er z.B. die start Methode nicht, diese ist ebenfalls nicht ersichtlich im Code des Artikels...

Hier mein Versuch...

[CODE lang="java" title="Main"]package myPackage;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.io.IOException;
import java.nio.file.*;

public class Main extends Application {

private Stage primaryStage;


@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
mainWindow();

RunnerService runner = new RunnerService(this);
runner.start();


}

public void mainWindow() {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml"));
AnchorPane pane = loader.load();

primaryStage.setMinHeight(400);
primaryStage.setMinWidth(500);

MainWindowController mainWindowController = loader.getController();
mainWindowController.setMain(this);

Scene scene = new Scene(pane);

primaryStage.setScene(scene);
primaryStage.show();


// Runner runBackground = new Runner();
// runBackground.run(mainWindowController);



} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}





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

}
}
[/CODE]

[CODE lang="java" title="RunnerService"]package myPackage;

import javafx.concurrent.Task;

import javax.xml.ws.Service;
import java.nio.file.*;


public class RunnerService extends Service<Void> {

private Main mainApp;

public RunnerService(Main mainApp) {
this.mainApp = mainApp;
}

@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {

WinFTM_XML_TCP runnerApp = new WinFTM_XML_TCP();

runnerApp.tryToConnect();


WatchService watchService = FileSystems.getDefault().newWatchService();
Path pathIn = Paths.get("C:\\xml\\In");
Path pathOut = Paths.get("C:\\xml\\WinFTM_Export");

pathIn.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
pathOut.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);

WatchKey key;

// Hier müssen dann noch die Pfade abgefragt werden! Falls gleich i.o. falls nicht, neuer Watch Service!
while ((key = watchService.take()) != null) {
if (key.watchable().equals(pathIn)) {
for (WatchEvent<?> event : key.pollEvents()) {
runnerApp.watchEventOne(null);
}
key.reset();
} else if (key.watchable().equals(pathOut)) {
for (WatchEvent<?> event : key.pollEvents()) {
runnerApp.watchEventTwo();
}
key.reset();
}
return null;
}
return null;
}
};
}
}[/CODE]
 

izoards

Bekanntes Mitglied
Also technisch ist das möglich und daher würde ich da nicht von falsch reden. Aber es ist ungeschickt, da du so unnötige Abhängigkeiten einbindest. Du kannst dies aber relativ einfach entkoppeln, daher ist dies nicht zu problematisch.

Das ding läuft :) jedoch mit dem updaten des GUI's bin ich noch am Rätseln und zwar, habe ich es nun mit der Übergabe des Controllers versucht zu machen.
Dann in der Klasse welche nun im Background-thread läuft, folgende Methode hinzugefügt:

Java:
    private void updateGui(String text, MainWindowController controller) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                controller.setOfActuelContent(text);
            }
        });
    }


Leider bleibt das Programm dann mit folgendem Fehler hängen:

Java:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at myPackage.MainWindowController.setOfActuelContent(MainWindowController.java:43)
    at myPackage.WinFTM_XML_TCP$1.run(WinFTM_XML_TCP.java:459)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)


Daher meine Frage, wie kann ich das entkoppeln? Hast Du mir hier vielleicht einen Tipp?
 
K

kneitzel

Gast
Kannst du den Code einmal im Detail zeigen? Wie bringst Du den MainWindowController denn da rein? Und was ist in der Methode setOfActuelContent? Speziell Zeile 43 - denn da kommt die NPE.
 

izoards

Bekanntes Mitglied
hmm, stimmt, ich bringe den MainWindowController da gar nicht rein...
Habe eine instanz des MainWindowsController gemacht, und übergeben, jedoch funzt das so irgendwie nicht...

Nun,
Gemäss dem Artikel muss das also über eine ObservableList gemacht werden.
Kann ich das so verstehen, dass in meinem Fall im Background Task, diese Liste mit den zu aktualisierenden Texten gefüllt wird, und ich diese dann im "gui" - thread abarbeiten muss?

Oder wie ist das ganze zu verstehen?
 
K

kneitzel

Gast
Es gibt verschiedene Wege. Der Weg, das so über den Controller zu machen, kann funktionieren, nur eben musst Du die Instanz des Controllers haben. Unabhängig, wie Du die Teile genau verbindest: Du must diese irgendwie miteinander verknüpfen. Daher würde ich als erstes das generelle Problem mit dem aktuellen Ansatz lösen um dann ggf. etwas zu verändern.

Ist eine Art Event, auch ein Methodenaufruf? Oder was versteht man unter Event?
Aus meiner Sicht steht das einfach nur für eine Art Pattern, bei dem beliebige Dritte sich registrieren, informiert zu werden über irgendwelche Dinge. Und ja - unter dem Strich sind das dann einfach nur, dass eine Menge an Elementen gespeichert wird, auf denen bei Bedarf etwas aufgerufen wird. Beispiele sind die typischen Events in der GUI a.la. Methoden wie addXXXListener(XXXEvent)... Gerade mit funktionalen Interfaces kann man da einiges sehr schön machen ....
 

izoards

Bekanntes Mitglied
Danke für deine rasche Hilfe, so macht es ziemlich spass :)
Habe es mit deiner Hilfe nun hingebracht und zwar wie folgt:

[CODE lang="java" title="Main" highlight="25-26"]@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
mainWindow();

}

public void mainWindow() {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml"));
AnchorPane pane = loader.load();

primaryStage.setMinHeight(400);
primaryStage.setMinWidth(500);

MainWindowController mainWindowController = loader.getController();
mainWindowController.setMain(this);

Scene scene = new Scene(pane);

primaryStage.setScene(scene);
primaryStage.show();


RunnerService runner = new RunnerService(this, mainWindowController);
runner.start();
[/CODE]

Danach weiter hier:


[CODE lang="java" title="RunnerService"]public class RunnerService extends Service<Void> {

private Main mainApp;
private MainWindowController controller;

public RunnerService(Main mainApp, MainWindowController controller) {
this.mainApp = mainApp;
this.controller = controller;

}

@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {


XML_TCP runnerApp = new XML_TCP();
runnerApp.start(controller);


return null;
}
};
}[/CODE]


[CODE lang="java" title="HIer läuft dann das ganze mit WatchService etc...."]public void start(MainWindowController controller) throws Exception {

...
....
....
...
updateGui("Läuft!", controller);


...
....
....

}


private void updateGui(String text, MainWindowController controller) {
Platform.runLater(new Runnable() {
@Override
public void run() {
controller.setOfActuelContent(text);
}
});[/CODE]



Puh, habe das Gefühl, dass dies einfacher gehen könnte.....
Oder kann ich das so stehen lassen?

Also die updateGui Methode ist nun noch überhaupt nicht universell einsetzbar. Das funktioniert nun erst mit einem Label...
Hier muss ich nochmals überlegen, wie ich das Universell machen kann....

Aber ich wäre froh, um ein Feedback, ob ich so o.k. unterwegs bin, oder ob dies ein "no go" ist....

Danke :)
 
K

kneitzel

Gast
Erst einmal schön, dass Du es soweit zum laufen bekommen hast. Das ist auf jeden Fall ein wichtiger Schritt, ehe man es dann ggf. umstrukturieren könnte.

Eine erste Sache, die ich verschieben / ändern würde:
Java:
            RunnerService runner = new RunnerService(this, mainWindowController);
            runner.start();

1. Zum einen wird der erste Parameter nicht verwendet, daher kann der weg. (Oder habe ich da etwas übersehen?)

2. Und dann würde ich das in den Controller verschieben. Dann verschwindet der Code in mainWindow, das den Service startet. (mainWindow ist ein schlechter Name für eine Methode. Da sollte immer ein Verb dabei sein. createMainWindow oder so. Und dann gehört da das Erstellen und Starten eines solchen Services schlicht nicht rein.

3. Wenn die Abhängigkeiten raus sind, dann würde ich Daten vernünftig modellieren. Die können im Service stecken und der Service verändert diese lediglich. Oder er gibt die Daten regelmäßig nach außen...

4. Dann fliegt der Controller aus dem Service raus. Der Service braucht keinen Controller. Der funktioniert ja so. Statt dessen gibt es sowas wie einen Receiver, der Daten empfängt. Das kann ein funktionales Interface sein und dann kann der Controller nach Erzeugung des Services da eine Methode entsprechend bereitstellen. (Das wäre dann z.B. die Nutzung von https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/Consumer.html)

Alternative zu 4: Der Controller fliegt raus und der Service hat die Daten intern und diese können von außen zugegriffen werden. Dann gibt es lediglich eine Information nach außen, dass sich die Daten verändert haben. (Also so wie oben, nur die Daten werden nicht mitgegeben beim Aufruf. Statt dessen muss sich der Controller die Daten dann aktiv holen. Dabei ist aber ggf. auf gleichzeitige Zugriffe zu achten! Daher ist die erste Variante schöner.)

Das wären so auf Anhieb die Änderungen, die ich einfließen lassen würde. Und beide Versionen von 4 sind relativ einfach, wenn man voraussetzt, dass es maximal einen Empfänger gibt. Dann braucht man nur ein Consumer<Datenklasse> target; als Instanzvariable mit Setter im Service und immer wenn eine Instanz der Datenklasse erzeugt wurde, wird target.accept(daten) aufgerufen. Im Controller gibt es eine beliebige Methode, die Datenklasse als Parameter hat und die einmalig eingetragen wird (service.setTarget(this::methodeMitBeliebigemNamen); oder wenn Methodenreferenz nicht gewünscht ist, dann halt service.setTarget(d -> methodeMitBeliebigemNamen(d)); ...)

Das einfach einmal als kurze Liste zum Abschluss des Tages ... :)
 

izoards

Bekanntes Mitglied
guten Morgen kneitzel,
Ich danke dir vielmals für die grosse Hilfe...
werde mich nun an die Punkte setzen, die Du mir zur Verbesserung aufgeführt hast & und moch ggf. wieder melden, ok?

Du hast recht, der Parameter (this) mainApp, wird nicht gebraucht, der ist noch so drin vom Artikel, den du mir geschickt hast...

Im artikel werden ja auch daten vom Service übergeben, stimmt es, dass deine idee hier nochmals anders ist...

Muss mich da in aller ruhe noch an deine Punke setzen :)
 

izoards

Bekanntes Mitglied
Hallo kneitzel,
Ich habe seit gestern noch nichts geändert, jedoch könnte es sein, dass die System.out.println - Meldungen, mit dieser Variante nicht mehr ausgegeben werden?!
Bin an einem anderen Laptop zur Zeit und hier beobachte ich nun solche Probleme.. Das Label wird hier auch nicht zuverlässig angepasst.

Könnte es gestern nur Zufall gewesen sein, dass es gar noch nicht zuverlässig läuft?
Oder was könnten die Gründe sein, dass die KonsolenMeldungen nicht mehr ausgegeben werden..
Ansonsten wird der Code abgearbeitet...
Danke für die Hilfe...
 

izoards

Bekanntes Mitglied
Hallo kneitzel,
Ich habe seit gestern noch nichts geändert, jedoch könnte es sein, dass die System.out.println - Meldungen, mit dieser Variante nicht mehr ausgegeben werden?!
Bin an einem anderen Laptop zur Zeit und hier beobachte ich nun solche Probleme.. Das Label wird hier auch nicht zuverlässig angepasst.

Könnte es gestern nur Zufall gewesen sein, dass es gar noch nicht zuverlässig läuft?
Oder was könnten die Gründe sein, dass die KonsolenMeldungen nicht mehr ausgegeben werden..
Ansonsten wird der Code abgearbeitet...
Danke für die Hilfe...
hat sich erübrigt...
 

izoards

Bekanntes Mitglied
Hallo Kneitzel,

Ich mach mich jetzt mal an die Änderung, wie ich die Daten aus meinem Service ans GUI schicke, ohne den Controller als Parameter zu übergeben.

Du hast dieses hier bereits erklärt:
Das wären so auf Anhieb die Änderungen, die ich einfließen lassen würde. Und beide Versionen von 4 sind relativ einfach, wenn man voraussetzt, dass es maximal einen Empfänger gibt. Dann braucht man nur ein Consumer<Datenklasse> target; als Instanzvariable mit Setter im Service und immer wenn eine Instanz der Datenklasse erzeugt wurde, wird target.accept(daten) aufgerufen. Im Controller gibt es eine beliebige Methode, die Datenklasse als Parameter hat und die einmalig eingetragen wird (service.setTarget(this::methodeMitBeliebigemNamen); oder wenn Methodenreferenz nicht gewünscht ist, dann halt service.setTarget(d -> methodeMitBeliebigemNamen(d)); ...)

Nun nochmals zu meinem besseren Verständnis:

Ist es richtig, dass ich in meinem Hintergrund thread (Service), eben diesen Consumer erstelle. Also so etwas:

Java:
Consumer<String> myGuiData = (String x) -> setGui(x);    //setGui(String x) ist eine Methode vom Controller(?) geht das so?

oder so:?

Java:
Consumer<String> myGuiData = mainWindowController::setGui;     //?geht das so?



Danach, würde ich sobald Daten auf dem GUI aktualisiert werden, diese wie folgt "senden":

Java:
myGuiData.accept(meineStringVariable);

Im Controller gibt es eine beliebige Methode, die Datenklasse als Parameter hat und die einmalig eingetragen wird (service.setTarget(this::methodeMitBeliebigemNamen)
Dann im Controller die Methode so(?):

Java:
public void setGui(String x) {
        label.setText(x);
}

Ich verstehe leider nicht, was das bedeutet:
...die einmalig eingetragen wird (service.setTarget(this::methodeMitBeliebigemNamen)

Auch bin ich mir noch nicht ganz im klaren, was du mit:

....und immer wenn eine Instanz der Datenklasse erzeugt wurde, wird target.accept(daten) aufgerufen.
Die Datenklasse ist in meinem Fall jetzt "myGuiData" richtig?

Danke viemals für die Hilfe...
 
Zuletzt bearbeitet:

izoards

Bekanntes Mitglied
Komme irgendwie nicht weiter :-(

Das wären so auf Anhieb die Änderungen, die ich einfließen lassen würde. Und beide Versionen von 4 sind relativ einfach, wenn man voraussetzt, dass es maximal einen Empfänger gibt.
Meinst Du mit Empfänger, ein "label" auf dem GUI, oder eine controller klasse?


was ich bis jetzt gemacht habe:

Im Background-Task den Consumer "eingerichtet":

Java:
Consumer<String> myGuiData = (String x) -> setGui(x); // Als Klassenvariable definiert.



myGuiData.accept("Test"));    //Sobald ein Label des Gui's angepasst werden soll,
                            //es gibt verschiedene Labels die angepasst werden müssen



private void setGui(String x) {

        System.out.println("Aktueller String vom Consumer: " + x);

    }

So und wie bringe ich das jetzt in meinen Controller?

Im Controller gibt es eine beliebige Methode, die Datenklasse als Parameter hat...

Java:
    @FXML
    public void beliebigeMethode (String x) {            //String ist meine Datenklasse
        

    }


...und die einmalig eingetragen wird (service.setTarget(this::methodeMitBeliebigemNamen); oder wenn Methodenreferenz nicht gewünscht ist, dann halt service.setTarget(d -> methodeMitBeliebigemNamen(d)); ...)

Wo wird das eingetragen? Wäre riesig dankbar, wenn mir hier jemand auf die Sprünge helfen kann...
 

izoards

Bekanntes Mitglied
Bin jetzt soweit, dass ich in meinem Background Task folgende setter Methode habe:

Java:
private void setGui(String x) {

        System.out.println("Aktueller String vom Consumer: " + x);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                newController.setOfActuelContent(x);

            }
        });
    }

Ich erstelle also eine Instanz des controllers im Task und möchte dann dort, über Platform.runLater die Methode des controllers aufrufen.

So vermeide ich die Übergabe des controllers als Parameter....
Denke es wäre auch möglich, hier noch mehrere Parameter zu übergeben, so dass ich im Controller dann entscheiden kann, welches feld aktualisiert werden soll.

Leider stürzt das teil mit einer nullpointer exception ab.

Java:
  @FXML
    public void setOfActuelContent(String text) {
        System.out.println("inside setOfActuelContent: " + text);
        field1.setText(text);
    }


Java:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at myPackage.MainWindowController.setOfActuelContent(MainWindowController.java:93)
    at myPackage.WinFTM_XML_TCP$1.run(WinFTM_XML_TCP.java:502)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)


Bin ich so auf dem richtigen weg? Also dass ich halt einen controller im Background task erstelle, damit ich so auf die Methoden des controllers zugreifen kann? Oder ist das nicht die richtige Umsetzung der Idee mit dem consumers?
 
K

kneitzel

Gast
Ich erstelle also eine Instanz des controllers im Task
Das hört sich so nicht korrekt an. Der Controller, den Du im Task erzeugst, ist ja nicht verbunden. An den Controller kommst Du über mehrere Wege:
a) Wenn Du den Task innerhalb des Controllers erzeugst, dann hast Du den Controller in this.
b) Wenn Du mit fxml arbeitest (das @FXML deutet darauf hin), dann kannst Du entweder nach dem Laden den Controller vom FXMLLoader abfragen oder Du erzeugst den Controller und gibst diesen an den Loader. Ich hatte da Probleme mit setController, da ich im fxml auch einen controller angeben möchte. Daher arbeite ich in dem Fall mit setControllerFactory. Das wäre dann sozusagen mehr Richtung Model View Presenter Pattern. Da baut der Controller im Konstruktor auch die Stage:
Java:
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("MyWindow.fxml"));
        loader.setControllerFactory((Class<?> controllerType) -> this);
        Parent root = loader.load();

        // Setup new Window.
        Stage stage = new Stage();
        Scene scene = new Scene(root);
        stage.setTitle(title);
        stage.setScene(scene);
        stage.show();
(Alles etwas verkürzt. title ist ein Parameter für den Fenstertitel. Das Gute bei dem Ansatz: Man kann dem Controller direkt Parameter mitgeben und arbeitet nicht mit setUserObject / getUserObject. Wobei das natürlich auch alles gehen würdemit dem Abfragen des Controllers vom FXMLLoader nach dem Laden des fxml.)

Noch zu der Exception, die Du bekommst:
Die NPE dürfte kommen, da in dem Controller, den Du selbst erzeugt hast, field1 nicht gesetzt ist. Das dürfte ja vom FXMLLoader initialisiert werden und da Du eine neue Instanz erstellt hast, ist das einfach eine weitere Instanz, die mit dem Fenster nichts zu tun hat.
 
K

kneitzel

Gast
Ach so ja: Aber prinzipiell ist der Ansatz so richtig - Du musst halt nur dafür sorgen, dass Du die richtige Controller Instanz in die Variable von Deinem Task bekommst.
 

looparda

Top Contributor
Wo wird das eingetragen? Wäre riesig dankbar, wenn mir hier jemand auf die Sprünge helfen kann...
Würde es eher andersrum machen, dass dein Service einen Consumer vom Controller übergeben bekommt. Bei Änderungen wird der Consumer aufgerufen.

Java:
private final Consumer<String> changeConsumer;

public RunnerService(Consumer<String> changeConsumer) {
    this.changeConsumer = changeConsumer;
}

...

@Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                              setGui("new value"); 
                              return null;
                        }
                 };
         }    
...

private void setGui(String x) {

        System.out.println("Aktueller String vom Consumer: " + x);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                changeConsumer.accept(x)
            }
        });
    }

Ich habe mal parallel ein Projekt aufgesetzt und das umgesetzt, was du vermutlich haben möchtest. Ich habe den Service jedoch im Controller erzeugt und binde die Properties des Service direkt an die Felder der UI (Service.html#messageProperty). Dabei sind mir folgende Fragen aufgekommen: Soll der Service immer laufen, oder nur aus einem Controller heraus gestartet werden? Teilen sich mehrere Controller einen Service? Gibt es nur eine Instanz des Service? All das beeinflusst wie (und wann) du deinen Controller und Service erstellst und wie du diese miteinander "verdrahtest", sodass diese miteinander kommunizieren können.
Der Versuch einen Controller im Service zu erstellen ist nicht zielführend. Wenn du Controller mit FXML-Files einsetzt muss man beachten, dass man diese nie per Hand via new erzeugt sondern diese durch die JavaFX Plattform erzeugt werden müssen. Hintergrund ist, dass nur dann die @FXML annotierten Felder initialisiert werden können, die Initialize-Methode des Controllers aufgerufen sowie Location und ResourceBundle gesetzt werden können.
 

izoards

Bekanntes Mitglied
Ach so ja: Aber prinzipiell ist der Ansatz so richtig - Du musst halt nur dafür sorgen, dass Du die richtige Controller Instanz in die Variable von Deinem Task bekommst.

Also mit dem Controller übergeben in den Background Task und dann über Platform run later funktionierts so wie ich es will. :)
Habe leider keine Zeit mehr, hier "bessere" Lösungen mehr zu entwickeln.
Schaue mir das vermutlich später nochmals in Ruhe an....

Besten Dank für alle Hilfe, ist der Hammer!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Juelin starten maven javafx programm ohne netbeans AWT, Swing, JavaFX & SWT 24
Juelin javax.swing in javafx AWT, Swing, JavaFX & SWT 1
MiMa JUnit5 im JavaFX Projekt AWT, Swing, JavaFX & SWT 2
Juelin in javafx Event auslösen AWT, Swing, JavaFX & SWT 4
MiMa Fonts, Icons, Bilder in JavaFX Anwendung AWT, Swing, JavaFX & SWT 5
MiMa SwingFXUtils in JavaFX 20 AWT, Swing, JavaFX & SWT 6
MiMa JavaFX Fenstertitel zu klein. AWT, Swing, JavaFX & SWT 1
MiMa JavaFX JAR unter Windows ausführen schlägt fehl? AWT, Swing, JavaFX & SWT 5
I JavaFX JavaFx-Anwendung für die Erstellung einer Windows-Anwendung? AWT, Swing, JavaFX & SWT 6
Hatsi09 Javafx MediaPlayer spielt nicht immer AWT, Swing, JavaFX & SWT 3
Hatsi09 Javafx Neuladen von ImageView und MediaView AWT, Swing, JavaFX & SWT 3
Maxim6394 JavaFX Umlaute in JavaFX GUI AWT, Swing, JavaFX & SWT 12
Maxim6394 JavaFX Scene Builder - Crash bei eigener Komponente AWT, Swing, JavaFX & SWT 2
Ernesto95 JavaFX JavaFX GUI mit sehr vielen Update requests AWT, Swing, JavaFX & SWT 4
Telisti Javafx Image wird nicht richtig integiert AWT, Swing, JavaFX & SWT 8
J Netbeans die JavaFX-Anwendung wird nicht ausgeführt AWT, Swing, JavaFX & SWT 16
MartinNeuerlich Kann mir jemand, der einen Mac mit einem m1 oder m2-Chip hat, eine POM geben mit der Javafx-Fullscreen beim Mac mit m-Chip funktioniert? AWT, Swing, JavaFX & SWT 1
tommybalbor JavaFx Anwendung klappt nicht für macOs Nutzern, wenn ich zwei dependecies bei maven hinzufüge AWT, Swing, JavaFX & SWT 6
JavaSchmecktLecker JavaFX JavaFX Ordner automatisch verlinken AWT, Swing, JavaFX & SWT 2
melaniemueller Taschenrechner JavaFX AWT, Swing, JavaFX & SWT 4
R auto. Importanweisungen für javafx funktioniert in Eclipse nicht mehr AWT, Swing, JavaFX & SWT 4
thor_norsk JavaFX Anwendung stürzt ab AWT, Swing, JavaFX & SWT 4
berserkerdq2 Skalieren sich javafx objekte automatisch auf die Bildschirmgröße AWT, Swing, JavaFX & SWT 6
berserkerdq2 Wie füge ich ein Bild in javafx mit dem Scenebuilder ein, das automatisch mitgezogen wird, wenn das Fenster vergrößert wird oder Vollbildmodus AWT, Swing, JavaFX & SWT 6
B Java Projekt mit JavaFX und jfoenix ausführbar machen AWT, Swing, JavaFX & SWT 46
H JavaFX wie JavaFX Projekt aufsetzen? AWT, Swing, JavaFX & SWT 10
thor_norsk JavaFX - Grafikkarte AWT, Swing, JavaFX & SWT 7
MiHimbert Rückmeldung an den aufrufenden JAVAFX-Dialog AWT, Swing, JavaFX & SWT 1
MiMa JavaFX Runtime components are Missing??? AWT, Swing, JavaFX & SWT 3
J JavaFx PDF in einem Element in einem Fenster anzeigen. AWT, Swing, JavaFX & SWT 11
B JavaFX Sprachumschaltung mit Button auf der HMI AWT, Swing, JavaFX & SWT 6
H JavaFX Fehlende JavaFX Package AWT, Swing, JavaFX & SWT 10
K JavaFX unterschiedliche (mehrere Fenster) in seperater Main Methode AWT, Swing, JavaFX & SWT 26
_user_q Kann man ein 2. JavaFX-Fenster auch beenden (exit) statt schließen (close) lassen? AWT, Swing, JavaFX & SWT 8
G JavaFX Line Chart mit Farbverlauf/Gradient in Linie AWT, Swing, JavaFX & SWT 1
thor_norsk JavaFX, FXML und SceneBuilder AWT, Swing, JavaFX & SWT 6
_user_q Über installDist exportiertes Programm wirft "Unsupported JavaFX configuration" AWT, Swing, JavaFX & SWT 0
CodingBerlin JavaFX Programm läuft nur unter Eclipse AWT, Swing, JavaFX & SWT 1
H Fehler: Zum Ausführen dieser Anwendung benötigte JavaFX-Runtime-Komponenten fehlen AWT, Swing, JavaFX & SWT 44
temi JavaFX "Frames" in JavaFx - passende Komponente? AWT, Swing, JavaFX & SWT 13
G JavaFX Steuerung bzw. Test von externer JavaFX Anwendung (liegt nur als jar vor) AWT, Swing, JavaFX & SWT 9
_user_q [JavaFX] Spinner so einstellen, dass er nicht leer bleiben darf? AWT, Swing, JavaFX & SWT 6
S Javafx getResource-Pfad wird nicht erkannt AWT, Swing, JavaFX & SWT 7
A JavaFX exportierte Jar ohne beim starten die Libs hinzufügen? AWT, Swing, JavaFX & SWT 2
J JavaFX Schiffe versenken mit JavaFX und Scene builder AWT, Swing, JavaFX & SWT 3
Encera ArrayList mit eigenen Objekten in JavaFX sortieren und ausgeben AWT, Swing, JavaFX & SWT 50
L JavaFx Textformatierung mittels Datenbank und Funktion anpassen AWT, Swing, JavaFX & SWT 5
sserio Wie funktioniert ein Controller bei JavaFx? AWT, Swing, JavaFX & SWT 1
sserio Kann man bei JavaFx ein Fenster aufkommen lassen? AWT, Swing, JavaFX & SWT 1
Jose05 JavaFx Fxml: GUI aus einer anderen Klasse starten AWT, Swing, JavaFX & SWT 1
Tassos JavaFX/Problem mit der Maussteuerung in Stackpane AWT, Swing, JavaFX & SWT 7
S Ich bringe Code mit JavaFX unter Apache NetBeans IDE 12.6 nicht zum laufen. AWT, Swing, JavaFX & SWT 14
K Bekomme (u.a) javafx.fxml.LoadException trotz "korrektem" Code AWT, Swing, JavaFX & SWT 8
S JavaFX: voneinander abhängige TextFields AWT, Swing, JavaFX & SWT 33
M Gluon will JavaFX in den Browser stecken AWT, Swing, JavaFX & SWT 0
H javafx application does not exist AWT, Swing, JavaFX & SWT 16
A JavaFX Controller Problem AWT, Swing, JavaFX & SWT 1
izoards JavaFX TableView mit Array Inhalt füllen AWT, Swing, JavaFX & SWT 1
M Javafx versuch Bibliothek zu erstellen AWT, Swing, JavaFX & SWT 0
N JavaFX Javafx intelij Projekt zu ausführbaren jar Datei Machen AWT, Swing, JavaFX & SWT 1
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
izoards JavaFX TextFlow - Sonderzeichen AWT, Swing, JavaFX & SWT 1
maximstein JavaFX WebView - java.lang.NoSuchMethodError: 'boolean com.sun.prism.ResourceFactory.isDisposed()' AWT, Swing, JavaFX & SWT 4
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
MiHimbert javaFX openfx (17) datepicker AWT, Swing, JavaFX & SWT 3
A Mit JavaFX einzelne Zeilen in TableView farbig markieren AWT, Swing, JavaFX & SWT 5
melaniemueller JavaFX Taschenrechner mit SceneBuilder AWT, Swing, JavaFX & SWT 12
Jose05 Javafx Label Höhe=Breite AWT, Swing, JavaFX & SWT 1
Jose05 JavaFX: eigene FXML-Datei für einen Button AWT, Swing, JavaFX & SWT 3
izoards JavaFX editierbare Tabelle AWT, Swing, JavaFX & SWT 4
N javafx Position der Bustaben finden label AWT, Swing, JavaFX & SWT 1
D Verschieden Scenen ansprechen mit dem Scene Builder und JavaFX (Eclipse) AWT, Swing, JavaFX & SWT 16
izoards JavaFX Background Task warten auf Knopfdruck AWT, Swing, JavaFX & SWT 4
M Zufallsgenerator bei JavaFx AWT, Swing, JavaFX & SWT 1
N Label Schriftart Ändern javafx AWT, Swing, JavaFX & SWT 2
L JavaFX JavaFX, MVVM und SceneBuilder AWT, Swing, JavaFX & SWT 4
S JavaFx Album AWT, Swing, JavaFX & SWT 137
I JavaFX - Pane wechseln über 2. Controller AWT, Swing, JavaFX & SWT 5
melaniemueller JavaFX Beispiel kann nicht ausgeführt werden AWT, Swing, JavaFX & SWT 4
T FXML Datei in Java Code einbinden: javafx.fxml.LoadException AWT, Swing, JavaFX & SWT 2
J JavaFX - Included FXML - Entfernen feststellen AWT, Swing, JavaFX & SWT 2
J JavaFX JavaFX/ Taskmenu / UML Klassendiagramm AWT, Swing, JavaFX & SWT 2
Davee JavaFX JavaFX Jar ausführbar jedoch nicht alle Stages AWT, Swing, JavaFX & SWT 3
2 JavaFX die ChoiceBox leitet den String nicht weiter oder es komm zu einem NullPointer AWT, Swing, JavaFX & SWT 8
C MouseEvent JavaFX AWT, Swing, JavaFX & SWT 4
L JavaFX javafx.fxml.LoadException bei einem Taschenrechner AWT, Swing, JavaFX & SWT 5
M4cM4rco0707 JavaFX Custom-Komponente mit Custom-Controller AWT, Swing, JavaFX & SWT 3
M Error occurred during initialization of boot layer java.lang.module.FindException: Module javafx.controls not found AWT, Swing, JavaFX & SWT 14
G javafx build.fxbuild in eclipse und ANT AWT, Swing, JavaFX & SWT 9
M Kollisionensbehandlung mit JavaFX AWT, Swing, JavaFX & SWT 1
N JavaFX - Toolkit not initialized AWT, Swing, JavaFX & SWT 6
G JavaFX , Duplicate erzeugt aber ich weis nicht wo AWT, Swing, JavaFX & SWT 4
K Javafx Plugin (javafx:jlink) mit moditect Plugin nutzen ... AWT, Swing, JavaFX & SWT 5
J Saubere Trennung Model, View, Controller Javafx AWT, Swing, JavaFX & SWT 10
G JavaFX BarChart während der Runtime aktualisieren AWT, Swing, JavaFX & SWT 4
Z JavaFX JavaFX Spinner AWT, Swing, JavaFX & SWT 1
N JavaFX Tableview nach Löschen von Element falscher Index AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28
T JavaFX DatePicker JavaFX AWT, Swing, JavaFX & SWT 14
G ObjectOutPutStream mit Javafx GUI Elementen AWT, Swing, JavaFX & SWT 14

Ähnliche Java Themen

Neue Themen


Oben