2015-12-25 58 views
4

我通过扩展现有控件创建了一个新控件,并且我想在我的JavaFX场景中使用这个新控件。我希望能够使用Scene Builder编辑我的场景,但是在将新控件添加到FXML文件后,打开Scene Builder时遇到了ClassNotFoundException场景生成器中的自定义控件ClassNotFoundException

例如,这里是我做了一个类扩展TextField

RegexLimitingTextField.java

public class RegexLimitingTextField extends TextField { 

    private String regexLimiter = ".*"; 

    public void setRegexLimiter(String regex) { 
     this.regexLimiter = regex; 
    } 

    @Override 
    public void replaceText(int start, int end, String text) { 
     if (text.matches(regexLimiter)) 
      super.replaceText(start, end, text); 
    } 

    @Override 
    public void replaceSelection(String replacement) { 
     if (replacement.matches(regexLimiter)) 
      super.replaceSelection(replacement); 
    } 
} 

增加这个控制我的FXML文件后...

sample.fxml

<?import javafx.scene.layout.GridPane?> 
<?import sample.RegexLimitingTextField?> 
<GridPane fx:controller="sample.Controller" 
      xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10"> 
    <RegexLimitingTextField fx:id="textField" text="Test" /> 
</GridPane> 

...我得到这个错误,当l Oading Scene Builder 2.0:

Caused by: java.lang.ClassNotFoundException: sample.RegexLimitingTextField 
    at java.lang.ClassLoader.findClass(ClassLoader.java:530) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2920) 
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2909) 
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2850) 
    ... 23 more 

为什么Scene Builder不能找到我的新控件?为了找到并能够使用我的新控件,我需要做些什么?

这里,如果需要的是其他的文件:

Main.java

public class Main extends Application { 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setScene(new Scene(root, 200, 200)); 
     primaryStage.show(); 
    } 
} 

Controller.java

public class Controller implements Initializable { 
    public RegexLimitingTextField textField; 

    @Override 
    public void initialize(URL url, ResourceBundle resourceBundle) { 
     textField.setRegexLimiter("\\w*"); 
    } 
} 
+0

可能是http://stackoverflow.com/questions/30063792/adding-a-custom-component-to-scenebuilder-2-0 –

+1

@James_D的副本工作,谢谢。虽然我有点恼火。为什么他们会删除'scenebuilder-classpath-element'标签?这似乎意味着我每次改变我的课程时,都必须重新构建jar并重新导入它。有没有更简单的方法来做到这一点? –

回答

2

如果有人仍然有SceneBuilder不加载自己的自定义组件,只需传递一个烦恼ClassLoader为我解决了这个问题。

try { 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("CustomComponent.fxml")); 
    loader.setRoot(this); 
    loader.setController(this); 
    loader.setClassLoader(getClass().getClassLoader()); 
    loader.load(); 
} catch (IOException e){ 
    throw new RuntimeException(e); 
} 

积分为the miracle worker, thatjavaguy

2

所以...经过很多的斗争,我想我找到了解决这个问题。问题太蠢了,你不会相信。

此解决方案仅适用于thowse谁媒体链接都试过了,正确所做的一切,如:

  • 传递一个ClassLoader,当您为您的自定义组件控制器布拉德·塔瑞克说。
  • 使用FX:根构建您的.fxml

所以,似乎你在场景生成器得到ClassNotFoundException的同时,如果自定义组件(.fxml和它的Java控制器)是一个被命名为包以大写字母开头。看起来,所有包名称都必须以小写字母开头。可以肯定......只需使用小写来命名所有包。我注意到的另一件事是,控制器的类名也必须以大写字母开头。