0

I tried to find a solution on how to include custom javafx objects to a fxml file.

For example

package myExtendedObjects;

import javafx.scene.control.Label;

public class MyLabel extends Label interface connected{

    MyLabel(){
        super();
    }
  //Custom Code ...
}

into fxml

<?import myExtendedObjects.myLabel?>
<myLabel text="Name" />

I always get error codes from the type javafx.fxml.LoadException: Maybe there is a better solution then creating custom classes. But I need a Label with a custom Interface (connected). maybe a other solution would be to create a fxml file which includes only a label and set up a controller class for this with the interface.

EDIT:

try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/Viewer.fxml"));
        Parent root = fxmlLoader.load();
        Scene scene = new Scene(root);
        controller = fxmlLoader.getController();
        primaryStage.setScene(scene);
        primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }

EDITS 2: After changing Names, I was able to import the custom object without error, but when I try to insert

<MyLabel fx:id="myLabel"/>

in my xml date I get this error

javafx.fxml.LoadException: 
/C:/Users/TheOLGPC/Desktop/java/SolarimpactTelemety2/bin/fxml/Viewer.fxml:48

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1013)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
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.load(FXMLLoader.java:2409)
at application.Main.start(Main.java:24)
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(Unknown Source)
Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.ReflectUtil can not access a member of class myExtendedObjects.MyLabel with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1009)
... 15 more

Exception in Application start method

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Olgidos
  • 231
  • 1
  • 14
  • 1
    Hi, I se you don't follow the java's naming conventions, you have class and interface names with lowercase, but this inst the main problem. You have a class `myLabel` but its constructor is `myConnectedLabel()` so you surely get a compilation error if you are using any IDE. – Sunflame Jun 08 '17 at 15:04
  • ah jear failed to copy the right parts – Olgidos Jun 08 '17 at 15:10
  • But in the `.fxml` file is still the wrong label i think for me: `` and `` works. – Sunflame Jun 08 '17 at 15:16
  • I think you have problem at the load, please insert the code part where you load that `.fxml` – Sunflame Jun 08 '17 at 15:17
  • stackoverflow is your package? – Olgidos Jun 08 '17 at 15:21
  • Yes, it is my package, and in that package are my classes : `Main`, `Controller`, `Test.fxml` and the `MyLabel` – Sunflame Jun 08 '17 at 15:24
  • 1
    Capitalization may actually be the problem here. From the FXML [documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html#instance_declaration_elements): "an element's tag is considered an instance declaration if the tag begins with uppercase letter"; and later: "Elements whose tag names begin with a lowercase letter represent object properties.". So failing to follow proper naming conventions could well be confusing the `FXMLLoader`. But it's really impossible to tell what's wrong unless you include the complete stack trace in the question. – James_D Jun 08 '17 at 15:24
  • damn thank you =) it was the capitalization – Olgidos Jun 08 '17 at 15:27
  • but after importing a custom java object, i cant open the fxml files with scenbuilder any workaround? – Olgidos Jun 08 '17 at 15:43
  • I'm using the IntelliJ's SceneBuilder that opens the `.fxml` fine. When I try to open with the SceneBuilder app, I also get that exception, maybe @James_D has an idea for this. (morale: use IntelliJ :) ) – Sunflame Jun 08 '17 at 16:02
  • mhm maybe i give it a try .. at the moment i am using eclipse – Olgidos Jun 08 '17 at 16:08
  • just tried with scene builder from intelliJ and wont work – Olgidos Jun 08 '17 at 16:35

1 Answers1

2

Java has various naming conventions, including that class names should be capitalized, package names should be all lower case, and field and method names should begin lower case.

While the Java compiler and runtime regards these only as conventions, and will determine whether any entity is a class or property from the context, essentially regardless of name, the same is not true in FXML and for the FXMLLoader.

The FXML documentation states:

an element's tag is considered an instance declaration if the tag begins with uppercase letter

and later

Elements whose tag names begin with a lowercase letter represent object properties.

So if your classes fail to follow the usual naming conventions, they may fail to work correctly in FXML. Make sure the class and interface names are capitalized, property names are not capitalized, and package names are all lower case, and make sure they are used consistently in the Java code and in the FXML.

Additionally, the FXMLLoader will create an instance of your class by invoking (usually) the no-argument constructor. In order for that to work, the constructor must be public:

package myExtendedObjects;

import javafx.scene.control.Label;

public class MyLabel extends Label interface connected{

    public MyLabel(){
        super();
    }
  //Custom Code ...
}
James_D
  • 201,275
  • 16
  • 291
  • 322