我通过扩展现有控件创建了一个新控件,我想在我的JavaFX场景中使用这个新控件。我希望能够使用Scene Builder编辑我的场景,但是在将新控件添加到FXML文件后,我在打开Scene Builder时遇到了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>
...加载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 :(得分:3)
如果有人因为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);
}
答案 1 :(得分:2)
所以......在经过多次努力之后,我想我找到了解决这个问题的方法。问题是如此愚蠢,你不会相信。
这个解决方案仅适用于那些已经尝试过所有事情并且正确完成所有事情的人,例如:
因此,如果自定义组件(.fxml和它的java控制器)位于以大写字母开头的名称包中,似乎在Scene Builder中也会出现ClassNotFoundException。似乎所有包名称都必须以小写字母开头。确保...只需使用小写来命名所有包。我注意到的另一件事是控制器的类名,必须以大写字母开头。
答案 2 :(得分:0)
自定义组件扩展了TextField
并导致Scene Builder在打开时冻结,我也从中获得了很多乐趣。
我添加到Scene Builder的jar
文件仅包含这一类。但是,我的自定义组件具有对控制器的引用-这就是重点。当我将两个类都导出到jar
时,一切都很好。
因此,如果您处于类似情况并寻找答案,请仔细查看相关性。没有Scene Builder的世界是不一样的。