Alex Webb
Alex Webb

Reputation: 18

InvocationTargetException and NullPointerException JavaFX

I am using SceneBuilder to create a GUI to get information from the user via text feilds. I get this InvocationTargetException and stack trace when I click the calcPremiumButton button.

> Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
    at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$355(GlassViewEventHandler.java:388)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
    ... 31 more
Caused by: java.lang.NullPointerException
    at PremiumCalculator.calculatePremiumAction(PremiumCalculator.java:52)
    ... 41 more

I have traced the NullPointerException back to the setOnMouseClicked method.

    import java.lang.*;
    import java.util.*;
    import java.awt.*;
    import javafx.event.Event;
    import javafx.event.EventHandler;
    import javafx.scene.input.MouseEvent;
    import javafx.fxml.FXML;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;

    /*** PremiumCalculator ***/
    public class PremiumCalculator extends LifeInsurancePolicy
    {   
       @FXML
       private static TextField coverage;

      @FXML
      private static TextField number;

      @FXML
      private static TextField lName;

      @FXML
      private static TextField a;

      @FXML
      private static TextField fName;

      @FXML
      private static TextField s;

      @FXML
      private static TextField pName;

      @FXML
      private static Label outputLabel;

      @FXML
      private static Button calcPremiumButton;

      @FXML
      private static TextField w;

      @FXML
      private static TextField h;

      @FXML
      private void calculatePremiumAction()
      {
          /*** setOnMouseClicked ***/     
          PremiumCalculator.calcPremiumButton.setOnMouseClicked(new EventHandler<MouseEvent>()
          {
             /*** handle ***/
             public void handle(MouseEvent mouseEvent)
             {
                /*** Get information from the GUI text boxes ***/
                String number = PremiumCalculator.number.getText();
                String pName = PremiumCalculator.pName.getText();
                String fName = PremiumCalculator.fName.getText();
                String lName = PremiumCalculator.lName.getText();
                String a = PremiumCalculator.a.getText();
                String s = PremiumCalculator.s.getText();
                String h = PremiumCalculator.h.getText();
                String w = PremiumCalculator.w.getText();
                String coverage = PremiumCalculator.coverage.getText();

                /*** Convert Strings ***/
                int num = Integer.parseInt(number);
                int ag = Integer.parseInt(a);
                double he = Double.parseDouble(h);
                double we = Double.parseDouble(w);
                double c = Double.parseDouble(coverage);
                double lifeInsurance = Double.parseDouble(lifeInsurancePolicyString);

                /*** Instantiate a new LifeInsurancePolicy object ***/
                LifeInsurancePolicy customer = new LifeInsurancePolicy(num, pName, fName, lName, ag, s, he, we);

                /*** Call an instance of the LifeInsurancePolicy object to get the life insurance cost ***/
                double lifeInsuranceAmount = customer.calculateLifeInsurance(s, bmi);

                /*** Display the life insurance cost ***/
                outputLabel.setText("Life Insurance Cost: " + lifeInsuranceAmount);
             }   
             /*** End handle ***/
          });
          /*** End setOnMouseClicked ***/        
       }                
    }
    /*** End PremiumCalculator ***/

I am not sure if I am getting the exception because of the setOnMouseClicked method or if it is caused by something else. Any help would be much appreciated!

Upvotes: 0

Views: 1788

Answers (2)

plastique
plastique

Reputation: 1204

First make your life easier with SceneBuilder. It will create FXML for you.

Secondly use SceneBuilder's 'On Action' field in code section to name button's handling method in controller directly without clumsy setOnMouseClicked() call with anonymous class as parameter. It should look like this in FXML:

<Button onAction="#onBtnClicked" text="Text on button" />

In controller:

@FXML
void onBtnClicked(ActionEvent event) {
   // your handling code goes here
}

Then the FXMLLoader may be used to load your javaFx Node from *.fxml and to inject all @FXML annotated fields into instance of your UI controller.

URL fxmlLocation = new URL("url to your fxml");
FXMLLoader loader = new FXMLLoader(fxmlLocation);
PremiumCalculator controller = new PremiumCalculator();
loader.setController(controller);
// now load and inject  
Node javafxNode = loader.load();

Add javafxNode to your scene to make it part of visible scene graph. This should do the trick. Plus your code in controller will be way simpler and easier to understood.

Upvotes: 1

A.V
A.V

Reputation: 26

SceneBuilder allows someone to edit FXML files. Those files describe a view, an interface, just like a HTML file would do it for a web page.

The problem is that you are trying to put an Event on your button inside the function private void calculatePremiumAction(). But this function is already an Event function (because it has @FXML on top of it), you just have to bind it with your button in SceneBuilder.

Here an example of how you should do it.

Upvotes: 1

Related Questions