EDIT (Show the real problem instead of a sample code Annotation code)
I created my own way of loading fxml
files in Javafx 8 by using Annotation
instead of using the fx:controller
tag using this blog, Designing JavaFX Business Applications
I came up with this idea for dealing with Javafx fxml
files.
@Target(value = {ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FXMLConfig {
public String path();
}
So if I have a Javafx controller SampleController
, it would look like this
@FXMLConfig(path = "/path/to/SampleController.fxml")
public class SampleController implements Initializable { ... }
To load the GUI I used a class named JavafxWindow
public class JavafxWindow {
private Stage stage;
private Scene scene;
private FXMLLoader loader;
public void setup(Object controller) throws IOException {
FXMLConfig config = controller.getClass().getAnnotation(FXMLConfig.class);
this.loader = new FXMLLoader(controller.getClass().getClassLoader().getResource(config.path()));
this.loader.setController(controller);
Parent parent = (Parent) loader.load();
this.scene = new Scene(parent);
this.stage = new Stage();
}
public void show() {
this.stage.show();
}
}
Now the java.lang.NullPointerException
lies with in the lines
FXMLConfig config = controller.getClass().getAnnotation(FXMLConfig.class);
this.loader = new FXMLLoader(controller.getClass().getClassLoader().getResource(config.path()));
I tested the code and it worked fine but NPE
behavior occurs in the production which is a very annoying bug to users. Exception
is thrown at getAnnotation()
or config.path()
at times of heavy usage. But the production code is deployed using OSGi
, Apache Felix 4.6.0
across multiple bundles
. I am also using Reflection
on other parts but no NPE
is thrown.
Can you give me an implementation that comes with a level of checking to remove the abnormal java.lang.NullPointerException
behavior?
Thanks for the community's positive response.
Here is aa Minimal Complete Verifiable example. I haven't seen NPE of such type, so I'll post here the exact same way I always create my custom annotation for reference. Further questions welcome.
Custom Annotation Class(interface)
import java.lang.annotation.*;
@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface BasicBenefits {
String bId() default "B-101";
String bName() default "General Class A Employee";
}
Class using the custom annotation(no need of any imports):
@BasicBenefits(bId="B-400", bName="General Plus Class A Employee")
public class Employee {
String eId;
String eName;
public Employee(String eId, String eName){
this.eId = eId;
this.eName = eName;
}
public void getEmployeeDetails(){
System.out.println("Employee ID: "+eId);
System.out.println("Employee Name: "+eName);
}
}
Driver class to test out the above.
import java.lang.annotation.Annotation;
public class TestCustomAnnotationBasicBenefits {
public static void main(String[] args) throws Exception{
Employee emp = new Employee("E-100", "user3320018");
emp.getEmployeeDetails();
Class reflectedClass = emp.getClass();
Annotation hopeBenefitAnn = reflectedClass.getAnnotation(BasicBenefits.class);
BasicBenefits bBenefits = (BasicBenefits)hopeBenefitAnn;
System.out.println("Benefit ID: "+bBenefits.bId());
System.out.println("Benefit Name: "+bBenefits.bName());
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.