简体   繁体   中英

JavaFX Gluon Scene Builder custom component with external dependency

I have two projects: Components and MyApp.

Components project have two files:

mycomponents/MyComponent.fxml
mycomponents/MyComponent.java

MyComponent.fxml uses ikonli, and ikonli-core-1.9.0.jar , ikonli-javafx-1.9.0.jar and ikonli-material-pack-1.9.0.jar are included in project (I think for compiling project ikonli-javafx-1.9.0.jar is enough)

MyComponent.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import org.kordamp.ikonli.javafx.FontIcon?>


<fx:root type="javafx.scene.layout.AnchorPane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111">
   <children>
      <Button mnemonicParsing="false">
         <graphic>
            <FontIcon iconLiteral="gmi-check-circle" iconSize="24" />
         </graphic>
      </Button>
   </children>
</fx:root>

MyComponent.java:

package mycomponents;

import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;

public class MyComponent extends AnchorPane {
    public MyComponent() {
        FXMLLoader loader = new FXMLLoader(MyComponent.class.getResource("MyComponent.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
}

The project compiles successfully and I can open MyComponent.fxml in Scene Builder (because I import three ikonli jars into Scene Builder (via repository search)). After compiling Components project I import Components.jar into Scene Builder, and situation in Library Manger is:

Library Manager screenshot

MyApp project have three files:

myapp/FXMLDocument.fxml
myapp/FXMLDocumentController.java
myapp/MyApp.java

FXMLDocument.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import mycomponents.MyComponent?>

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="myapp.FXMLDocumentController">
    <children>
        <MyComponent />
    </children>
</AnchorPane>

FXMLDocumentController.java:

package myapp;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;

public class FXMLDocumentController implements Initializable {
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    
}

MyApp.java:

package myapp;

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

public class MyApp extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }    
}

I included three ikonli jars and Components.jar . Projects compiles fine and I can run application and everything works.

But when I want to open FXMLDocument.fxml with Scene Builder I get this error:

java.io.IOException: javafx.fxml.LoadException: 
/C:/Users/user/Documents/NetBeansProjects/MyApp/src/myapp/FXMLDocument.fxml:9

    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMLoader.load(FXOMLoader.java:92)
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.<init>(FXOMDocument.java:82)
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.<init>(FXOMDocument.java:97)
    at com.oracle.javafx.scenebuilder.kit.editor.EditorController.updateFxomDocument(EditorController.java:2384)
    at com.oracle.javafx.scenebuilder.kit.editor.EditorController.setFxmlTextAndLocation(EditorController.java:664)
    at com.oracle.javafx.scenebuilder.app.DocumentWindowController.loadFromFile(DocumentWindowController.java:385)
    at com.oracle.javafx.scenebuilder.app.SceneBuilderApp.performOpenFiles(SceneBuilderApp.java:634)
    at com.oracle.javafx.scenebuilder.app.SceneBuilderApp.access$200(SceneBuilderApp.java:84)
    at com.oracle.javafx.scenebuilder.app.SceneBuilderApp$1.invalidated(SceneBuilderApp.java:496)
    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.ReadOnlyBooleanPropertyBase.fireValueChangedEvent(ReadOnlyBooleanPropertyBase.java:72)
    at javafx.beans.property.ReadOnlyBooleanWrapper.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:103)
    at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
    at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
    at com.oracle.javafx.scenebuilder.kit.library.user.UserLibrary.lambda$updateFirstExplorationCompleted$7(UserLibrary.java:324)
    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: javafx.fxml.LoadException: 
/C:/Users/user/Documents/NetBeansProjects/MyApp/src/myapp/FXMLDocument.fxml:9

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2425)
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMLoader.load(FXOMLoader.java:89)
    ... 22 more
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: 
file:/C:/Users/user/AppData/Roaming/Scene%20Builder/Library/Components.jar!/mycomponents/MyComponent.fxml

    at mycomponents.MyComponent.<init>(MyComponent.java:15)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1009)
    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)
    ... 24 more
Caused by: javafx.fxml.LoadException: 
file:/C:/Users/user/AppData/Roaming/Scene%20Builder/Library/Components.jar!/mycomponents/MyComponent.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2848)
    at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2692)
    at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2661)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at mycomponents.MyComponent.<init>(MyComponent.java:13)
    ... 34 more
Caused by: java.lang.ClassNotFoundException: org.kordamp.ikonli.javafx.FontIcon
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916)
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2905)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846)
    ... 40 more

Hi Im facing the same problem, as a workaround I'm extracting de .jar dependencies and including then im my Component.jar.

I use gradle to build, this is a snipet of the build.gradle where the things happen.

The 'XXX' is my library name;

...
dependencies {
...
   compile 'br.com.emorgado:XXX:1.0.0-SNAPSHOT'
...
}

task extractTransitiveDependencies(type: Copy) {
    into "$buildDir/classes/main"
    from {
        configurations.compile.filter{
            it.name.startsWith('XXX')
        }
        .collect {
            zipTree( it )
        }
    }
}

jar.dependsOn extractTransitiveDependencies

jar {
    doFirst {    
    copy{
       from("$buildDir/output/lib/br/com/emorgado/"){
        exclude 'META-INF'
       }
       into("/br/com/emorgado/") // <- this is my component folder
}
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM