1

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

类加载器

 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
4

1 回答 1

3

有时必须从 FXML 文件的根元素中FXMLLoader的属性值加载控制器类。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;
}

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

于 2014-08-29T01:51:59.363 回答