JavaFx - Eigene Komponente

Hi,

ich habe mir eine Komponente mit in JavaFX mit FXML zusammengebaut.
So diese lässt sich im gleichen Projekt auch super toll einbinden.

Nun muss ich aber in einem zweiten Projekt diese Komponente per URLClassLoader dazu laden.
Die FXML Datei wird auch gefunden, alles spitze nur bekomme ich eine Exception:

Root is not an instance of javafx.scene.layout.AnchorPane.

Mag ja sein das google die Antwort hat - nur finde ich sie nicht, ODER ABER ich kapiere nicht was der Autor mir sagen will.

Poste doch mal, wie Du deine FXML-Datei im java-code aufrufst. Und die FXML-Datei auch.
Dein Fehler klingt danach, als würde die Root-Klasse nicht dem entsprechen, was Du im FXML angibst.
Wenn das so aussieht:
[XML]
<fx:root xmlns:fx=“http://javafx.com/fxml” type=“AnchorPane”>
[/XML]
dann muss die Root auch eine AnchorPane sein.

public class Controller extends AnchorPane
{
     FXMLLoader loader  = new FXMLLoader(getClass().getResource("MyPanel.fxml"));
     loader.setRoot(this)
     .....

Hi,

erst einmal vielen Dank schon einmal für deine Mühe.

Hier meine fxml Datei:
[XML]

<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?>

<fx:root type=“javafx.scene.layout.AnchorPane” fx:id=“pnlMain” prefHeight=“350.0” prefWidth=“402.0” xmlns:fx=“http://javafx.com/fxml”>







</fx:root>
[/XML]

und hier ein Auszug aus meiner Java Datei:

public CalendarController()
    {
        FXMLLoader oFxmlLoader = new FXMLLoader(getClass().getResource("Calendar.fxml"));
        oFxmlLoader.setRoot(this);
        oFxmlLoader.setController(this);
        
        try
        {
            oFxmlLoader.load();
        }
        catch (IOException exception)
        {
           throw new RuntimeException(exception);
        }
    }

Wie gesagt im gleichen Projekt funktioniert die Geschichte, sobald ich aber per URLClassLoader diese Datei in ein anderes Projekt lade kommt die oben genannte Fehlermeldung.

[QUOTE=evilhomer]
und hier ein Auszug aus meiner Java Datei:

public CalendarController() { }
```[/QUOTE]

[QUOTE=Hobelhai;27566]
Wenn das so aussieht:
dann muss die Root auch eine AnchorPane sein.

public class Controller extends AnchorPane { }


mfg

Meine Klasse macht ein extends auf den AnchorPane.
Was ich gepostet habe ist mein Konstruktor, wie man eventuell an den Klammern sehen kann.

public class CalendarController extends AnchorPane implements controls.calendarController.Interface
....
    public CalendarController()
    {
        FXMLLoader oFxmlLoader = new FXMLLoader(getClass().getResource("Calendar.fxml"));
        oFxmlLoader.setRoot(this);
        oFxmlLoader.setController(this);
        
        try
        {
            oFxmlLoader.load();
        }
        catch (IOException exception)
        {
           throw new RuntimeException(exception);
        }
    }

Dann scheint es wohl am Laden der FXML zu scheitern. Leg die Datei mal bei die Klasse und probiere, ob es dann funktioniert. Sonst weiß ich auch nicht weiter.

O.K. mach ich - aber wie? :slight_smile:
Tut mir leid, aber sooooweit bin ich in Java jetzt leider nicht.

Danke aber schon einmal für den Tip!

Ich weiß ja nicht, wie und womit Du arbeitest, welche IDE Du verwendest usw., aber prinzipiell kopierst Du Dir die FXML-Datei in das Verzeichnis, in dem die Klasse liegt, die sie verwendet. Du darfst sie auch ganz woanders hin kopieren, dann musst Du aber beim Aufruf des FXMLLoaders den Pfad dementsprechend angleichen. Wenn Du in deinem Code nicht unbedingt auf eine Instanz deiner Klasse CalendarController zugreifen musst, kannst Du auch folgenden Weg gehen: Du definierst den Controller in der FXML-Datei selbst über seinen voll qualifizierten Namen
[XML]

[/XML]
Dann brauch CalendarController noch nicht mal mehr AnchorPane erweitern, Du musst aber eine initialize-Methode definieren

@FXML
private void initialize()
{
     .....
}

Ich vergaß noch folgendes mitzuteilen:
In deiner Application rufst Du das Ganze folgendermaßen auf

@Override
	public void start(Stage stage) throws IOException
	{
		Parent root = FXMLLoader.load(getClass().getResource("Calendar.fxml"));
		Scene scene = new Scene(root);
		stage.setScene(scene);
		stage.show();
	}

Auch hier wieder beim Aufruf des FXMLLoaders auf die Pfadangabe achten.

Ah ok - ich dachte man könnte die FXML im Source selbst irgendwie vergraben.
Da hatte ich was falsch verstanden.

So wie ich das Beispiel aber verstehe, wird da den AnchorPane über die FXML Datei als Stage geladen.

Wenn ich nun aber per URLClassLoader die das Modul als AnchorPane in ein anderes AnchorPane laden möchte, wie mache ich das.

Du kannst fxml-Dateien auch per include-Anweisung ineinander schachteln
[XML]
<fx:root xmlns:fx=“http://javafx.com/fxml” type=“AnchorPane”>

<fx:include source=“Calendar.fxml” AnchorPane.topAnchor=“12” AnchorPane.rightAnchor=“25.0”
fx:controller=“mein.eigenes.package.CalendarController”/>

</fx:root>
[/XML]
Auch hier wieder auf die Pfadangabe achten. Wenn Du der Übersichtlichkeit halber deine FXML-Dateien in einen gemeinsamen Ordner schieben möchtest, dann steht Dir das wie schon gesagt frei. Du musst Dich dann allerdings mit dem Thema Pfade auseinandersetzen.

Ah ok - das wusste ich auch nicht. :slight_smile:
Das klingt schon einmal gut.

Mein einziges Problem bei der Sache ist noch - wie bekomme ich das mit dem URLClassLoader zusammen hin.
Weil es geht da um eine Art Plugin Struktur…
…es sollen nur Elemente Geladen werden, die quasi auf den Rechner liegen.

Würde bedeuten: CalendarController.java liegt nicht auf dem Rechner also lade ich es auch nicht.

Oje, da fragst Du leider den Falschen. Wenn das Programm nur Resourcen auf dem eigenen Rechner verwenden darf, dann ist das so und du musst damit leben. Ansonsten kann man solche Dinge wohl dynamisch nachladen, aber wie genau das geht…?

Mit Swing Elementen scheint dies Unproblematischer zu sein, wie ich das sehe.
Danke in jedem Fall für die Hilfe!

Sollte jemand noch ein kreativen Schub bekommen und eine Idee dazu haben, würde ich mich freuen!

Verwechselst Du hier nicht Äpfel mit Birnen? Wo hast Du denn mit Swing die Möglichkeit, deine UI mit XML zusammenzubauen?

Verwechseln ist hier der falsche Ausdruck - vergleichen hätte eher gepasst. :wink:
Hast ja recht, man kann mit Swing nicht durch XML sein UI definieren.
Es war auch mehr ein Randbemerkung das dies doch wesentlich leichter zu gehen scheint.