外部jar FXML加载异常

时间:2014-08-28 19:08:13

标签: javafx classloader fxml fxmlloader

我尝试使用classloader加载位于外部jar中的类。课程" FXMLbase"加载确定,但FXMLdocument.fxml尝试实例化FXMLDocumentController时会触发错误。但是当" FXMLbase"通过JavaFXApplication5.java(位于外部jar)实例化它可以正常工作。有任何想法吗?

类加载器

 File file = new File("C:/Users/Os/Dropbox/CODE_OS/JavaFXApplication5/dist/JavaFXApplication5.jar");
 URLClassLoader clazzLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
 Class c = clazzLoader.loadClass("javafxapplication5.FXMLbase");
 PluginInterface fXMLbase = (PluginInterface) c.newInstance();
 Parent loadScreen = fXMLbase.getRoot();

FXMLbase.java - 外部jar -

public Parent getRoot() {
    Parent root = null;
    try {
        System.out.println("Class Name:" + getClass().getName());           
        root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    } catch (IOException ex) {            
        Logger.getLogger(FXMLbase.class.getName()).log(Level.SEVERE, null, ex);
    }
    return root;
}

FXMLdocument.fxml - 外部jar -

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"  fx:controller="javafxapplication5.FXMLDocumentController">
<children>
    <Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me! app5" />
    <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
</children>

FXMLDocumentController.java - 外部jar -

public class FXMLDocumentController implements Initializable{    
@FXML
private Label label;    
@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    label.setText("Hello World!");
}

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

JavaFxApplication5.java - 外部jar -

public void start(Stage stage) throws Exception {        
    FXMLbase fXMLbase=new FXMLbase();
    Parent root = fXMLbase.getRoot();
    Scene scene = new Scene(root);        
    stage.setScene(scene);
    stage.show();
}

错误:

ago 28, 2014 2:26:16 PM javafxapplication5.FXMLbase getRoot
SEVERE: null
javafx.fxml.LoadException: 
file:/C:/Users/Os/Dropbox/CODE_OS/JavaFXApplication5/dist/JavaFXApplication5.jar!/javafxapplication5/FXMLDocument.fxml:9
 ....
Caused by: java.lang.ClassNotFoundException: javafxapplication5.FXMLDocumentController

1 个答案:

答案 0 :(得分:3)

某些时候FXMLLoader必须从FXML文件根元素中fx:controller属性的值加载控制器类。看起来它正在使用系统类加载器来执行此操作:我认为这是因为系统类加载器找到FXMLLoader类并加载它,而不是用于加载FXMLBase类的类加载器。

我能找到的唯一解决方法是从FXMLbase类显式设置控制器类,而不是在FXML中指定它。这有点令人不满意;也许有一种更好的方式我会失踪。

更新了FXMLbase课程:

public Parent getRoot() {
    Parent root = null;
    try {
        System.out.println("Class Name:" + getClass().getName());           
        FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
        loader.setController(new FXMLDocumentController());
        root = loader.load();
    } catch (IOException ex) {            
        Logger.getLogger(FXMLbase.class.getName()).log(Level.SEVERE, null, ex);
    }
    return root;
}

,您需要从FXML文件中删除fx:controller属性。