2014-08-28 136 views
1

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

类装载器

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 - 外部罐 -

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 - 外部罐 -

<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> 

FXMLDocumentControlle r.java - 外部罐 -

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 - 外部罐 -

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 
+0

请编辑您的问题,以包括您所得到的确切例外。 – 2014-08-28 19:34:19

回答

2

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属性。

+0

对此解决方案感兴趣的是另一个问题,但是您是否知道如何处理onAction手柄不喜欢没有控制器组的问题。 – Gapp 2015-04-30 18:38:49

+0

我不明白这个问题。 – 2015-04-30 18:47:21

+0

感谢您的快速响应,问题仍然在为我抛出错误我以为这可能是因为一旦你删除控制器所有的onAction引用被标记为问题。但它看起来更像是css和图像引用。 – Gapp 2015-04-30 18:55:36