Ich weiß, dass diese Frage viele Male gestellt wird, aber ich kann keine Lösung finden, die für mich funktioniert (eigentlich kann ich nicht einmal sehen, was ich falsch mache).Laden mehrerer FXML-Dateien schlägt fehl, wenn Controller definiert sind
Die Grundidee besteht darin, bei Bedarf GUI-Komponenten zu laden. Also habe ich die GUI in verschiedene FXML-Dateien strukturiert und Controller-Klassen implementiert. Beide - FXML-Dateien und Klassen - sind im selben Paket gespeichert, aber es ist ein Paket für jede Komponente. Jede FXML-Datei wird geladen und der GUI hinzugefügt, solange ich die Controller-Klasse nicht in der FXML-Datei (fx: controller) definiere. Wenn es definiert ist, bekomme ich eine LoadException.
Zum besseren Verständnis hier ist mein Code (vereinfacht):
Main.java:
package application;
import application.a.ControllerA;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application
{
// Button aus MainLayout.fxml
@FXML
private Button button;
@Override
public void start(Stage primaryStage)
{
try
{
BorderPane root = new BorderPane();
Parent contentMain = FXMLLoader.load(getClass().getResource("MainLayout.fxml"));
ControllerA contentA = new ControllerA(root);
root.setTop(contentA.getContent());
root.setCenter(contentMain);
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
// Event-Handler für den Button -> funktioniert!
@FXML
public void buttonClicked(ActionEvent e)
{
if (!button.getText().equals("NEW"))
{
button.setText("NEW");
}
else
{
button.setText("OLD");
}
}
}
Diese Klasse ist auch eine Steuerung für das folgende Layout (und es funktioniert Flossen bisher):
MainLayout.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<Pane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Main">
<children>
<Button fx:id="button" mnemonicParsing="false" onAction="#buttonClicked" text="Button" />
</children>
</Pane>
In einem Teilpaket (genannt a) von 0.123.Sie diese finden:
ControllerA.java:
package application.a;
import java.net.URL;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
public class ControllerA
{
private Parent content;
@FXML
private Button buttonA;
public ControllerA(BorderPane root)
{
String sceneFile = "A.fxml";
URL url = null;
try
{
url = getClass().getResource(sceneFile);
content = FXMLLoader.load(url);
}
catch (Exception ex)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Parent getContent()
{
return content;
}
@FXML
public void clickedA(ActionEvent e)
{
buttonA.setText("Clicked already");
}
}
A.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.a.ControllerA">
<children>
<Button fx:id="buttonA" layoutX="274.0" layoutY="188.0" mnemonicParsing="false" onAction="#clickedA" text="A" />
</children>
</Pane>
Und das ist, wo alles schief gelaufen ist:
javafx.fxml.LoadException:
/Z:/BachelorArbeit/Projektdateien/Entwicklung/EclipseWorkspace/Sandbox/bin/application/a/A.fxml:8
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:932)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at application.a.ControllerA.<init>(ControllerA.java:26)
at application.Main.start(Main.java:35)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.InstantiationException: application.a.ControllerA
at java.lang.Class.newInstance(Class.java:427)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
... 23 more
Caused by: java.lang.NoSuchMethodException: application.a.ControllerA.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 25 more
I habe versucht mit dem Pfad-String herumzubasteln wie
- "./a/A.fxml"
- "/application/a/A.fxml"
- "A.fxml"
- "a/A.fxml"
- ...
aber nichts hat funktioniert. Ich wäre sehr erleichtert, wenn mich jemand mit diesem Problem hinhalten könnte.
Was ist Zeile 35 in 'Main.java'? –
Ups, Tut mir leid: 'ControllerA contentA = neuer ControllerA (root);' – Marco
und Zeile 26 in 'ControllerA.java'? –