Reputation: 279
I'm trying to create a textfield with a title embedded in the field border like:
Following the solution posted here I've created a .java file called TitledBorder.java
within my src>main>java
directory. My FXML is in the src>main>resources
directory and I've added:
<?import TitledBorder?>
at the top and it shows no error like:
I then added this code to the FXML
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TitledBorder title="Email" >
<TextField fx:id="emailField" prefHeight="44.0" prefWidth="143.0" />
</TitledBorder>
</children>
</HBox>
and it shows no error either. I then launch my main method which is in a class also in src>main>java but it gets an error in the .fxml saying javafx.fxml.LoadException:
/C:/Users/ME/Documents/Automation/target/classes/demofxml.fxml
and
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
I'm not sure why it references "/target/classes/..." as opposed to "/src/main/java/...".
This is the only FXML example I've found so I'm confused why I'm getting an error upon compiling, yet no errors are shown prior? Removing all reference to TitledBorder
allows all my code to function/compile properly. Since its in the src package I use this code in FXML to connect w/ controller fx:controller="loadController">
. CSS is added properly too.
Thoughts?
Upvotes: 4
Views: 1281
Reputation: 49185
The line
<?import TitledBorder?>
implies that you put the TitledBorder.java
file to default package (i.e. no package declaration in source code of this file). However FXMLLoader
's source code checks the imports in FXML file and splits package path name and class name in loadType(...)
below, to load the imported class later with loadTypeForPackage()
:
private Class<?> loadType(String name, boolean cache) throws ClassNotFoundException {
int i = name.indexOf('.');
int n = name.length();
while (i != -1
&& i < n
&& Character.isLowerCase(name.charAt(i + 1))) {
i = name.indexOf('.', i + 1);
}
if (i == -1 || i == n) {
throw new ClassNotFoundException();
}
String packageName = name.substring(0, i);
String className = name.substring(i + 1);
Class<?> type = loadTypeForPackage(packageName, className);
if (cache) {
classes.put(className, type);
}
return type;
}
// TODO Rename to loadType() when deprecated static version is removed
private Class<?> loadTypeForPackage(String packageName, String className) throws ClassNotFoundException {
return getClassLoader().loadClass(packageName + "." + className.replace('.', '$'));
}
The imported class name is "TitledBorder" so the variable i
at the 1st line in loadType
method will be evaluated as name.indexOf('.') = -1
, and will throw ClassNotFoundException
in the next lines of code.
Generally it is bad practice to use default packages. Put the TitledBorder.java into some package and import it as
<?import my.some.package.TitledBorder?>
Upvotes: 1