1

So, I'm doing a JavaFX multiview GUI application.

Below is the code so that you can refer to it, don't read through it to find an error yet, I'll explain the problem underneath first ;)

I have a main - which starts the application

 public class MyFXMLMain extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Wireframe.fxml"));
        stage.setTitle("My Fitness App");
        Scene mainScene = new Scene(root,805,809);
        stage.setScene(mainScene);
        stage.show();
    }

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

ScreensController - that controls loading/setting screens.

public class ScreensController extends StackPane {

private HashMap<String, Node> screens = new HashMap<>(); 

public ScreensController() {
    super();
}

public void addScreen(String name, Node screen) { 
       screens.put(name, screen); 
   } 

public Node getScreen(String name) {
    return screens.get(name);
}

public boolean loadScreen(String name, String resource) {
     try { 
       FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
       Parent loadScreen = (Parent) myLoader.load(); 
       ControlledScreen myScreenController = ((ControlledScreen)                       myLoader.getController());
       myScreenController.setScreenParent(this); 
       addScreen(name, loadScreen); 
       return true; 
     }catch(Exception e) { 
       System.out.println(e.getMessage()); 
       return false; 
     } 
   }

   public boolean setScreen(final String name) {       
        if (screens.get(name) != null) {   //screen loaded
            final DoubleProperty opacity = opacityProperty();

            if (!getChildren().isEmpty()) {    //if there is more than one screen
                Timeline fade = new Timeline(
                        new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)),
                        new KeyFrame(new Duration(1000), new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent t) {
                        getChildren().remove(0);                    //remove the displayed screen
                        getChildren().add(0, screens.get(name));     //add the screen
                        Timeline fadeIn = new Timeline(
                                new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
                                new KeyFrame(new Duration(800), new KeyValue(opacity, 1.0)));
                        fadeIn.play();
                    }
                }, new KeyValue(opacity, 0.0)));
                fade.play();

            } else {
                setOpacity(0.0);
                getChildren().add(screens.get(name));       //no one else been displayed, then just show
                Timeline fadeIn = new Timeline(
                        new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
                        new KeyFrame(new Duration(2500), new KeyValue(opacity, 1.0)));
                fadeIn.play();
            }
            return true;
        } else {
            System.out.println("screen hasn't been loaded!!! \n");
            return false;
        }
   }

   public boolean unloadScreen(String name) {
        if (screens.remove(name) == null) {
            System.out.println("Screen didn't exist");
            return false;
        } else {
            return true;
        }
    }
}

A screen framework - that links the screens to the FXML files.

public class ScreensFramework extends Application { 

public static String MAIN_SCREEN = "MyFXMLController"; 
public static String MAIN_SCREEN_FXML = "Wireframe.fxml"; 
public static String calendarScreen = "CalendarscreenController"; 
public static String calendarScreenFXML = "Calendarscreen.fxml"; 
public static String guideScreen = "GuideScreenController"; 
public static String guideScreenFXML ="Guidescreen.fxml"; 

@Override 
public void start(Stage primaryStage) { 

  ScreensController mainContainer = new ScreensController(); 
  mainContainer.loadScreen(ScreensFramework.MAIN_SCREEN, ScreensFramework.MAIN_SCREEN_FXML); 
  mainContainer.loadScreen(ScreensFramework.calendarScreen,ScreensFramework.calendarScreenFXML); 
  mainContainer.loadScreen(ScreensFramework.guideScreen,ScreensFramework.guideScreenFXML); 

  mainContainer.setScreen(ScreensFramework.MAIN_SCREEN); 

  Group root = new Group(); 
  root.getChildren().addAll(mainContainer); 
  Scene scene = new Scene(root); 
  primaryStage.setScene(scene); 
  primaryStage.show(); 
} 
}

An FXML controller - which links to the FXML files and tells FXML what to do when something is clicked.

public class MyFXMLController implements ControlledScreen{

@FXML private TextField givenName;
@FXML private Text targetText;
//@FXML private static TableView<Mass> theTable;
//@FXML private static TableColumn<Mass, String> dateCol;
//@FXML private static TableColumn<Mass, String> massCol;
@FXML private static LineChart<Number,Number> weightChart;
@FXML private static NumberAxis axisX;
@FXML private static NumberAxis axisY;
@FXML private static Label myLabel;
//private static User theUser = new User();
private static ScreensController myController;

@Override
public void setScreenParent(ScreensController screenPage) {
    myController = screenPage;
}
@FXML protected void handlePressedCalendarButtonAction(ActionEvent event){
    System.out.println("Hello");
}   
@FXML protected void mouseclickedcal(MouseEvent mec){
    myController.setScreen(ScreensFramework.calendarScreen);
}

}

A controlledscreen - that does this:

   public interface ControlledScreen {

    public void setScreenParent(ScreensController screenPage);

    }

And a CalendarScreenController - that controls one of the multi screens

   public class CalendarScreenController implements Initializable, ControlledScreen {

    ScreensController myController; 

     @Override
     public void initialize(URL url, ResourceBundle rb) { 

         } 

     public void setScreenParent(ScreensController screenParent){ 
        myController = screenParent; 
     } 

     @FXML 
     private void goToMain(ActionEvent event){ 
       myController.setScreen(ScreensFramework.MAIN_SCREEN); 
     } 

    } 

PROBLEM BELOW

When I run my program it works fine, but then if I click on a button that activates the calendar onclick code here:

  @FXML protected void mouseclickedcal(MouseEvent mec){
        myController.setScreen(ScreensFramework.calendarScreen);
    }

which should set the screen to CalendarScreen.fxml,one of my multi screens but instead, it causes an error below:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$ClickGenerator.postProcess(Unknown Source)
    at javafx.scene.Scene$ClickGenerator.access$8600(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access$1900(Unknown Source)
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyMouse(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    ... 31 more
Caused by: java.lang.NullPointerException
    at myfxml.MyFXMLController.mouseclickedcal(MyFXMLController.java:125)
    ... 40 more

Line 125 is the code:

@FXML protected void mouseclickedcal(MouseEvent mec){
    myController.setScreen(ScreensFramework.calendarScreen);
    }

Thank you so much for having a look at this. I can't seem to find the error ;(

1 Answers1

-1

Turns out I had 2 mains and they were conflicting and also in my xml code I was calling something that didn't exist in its controller.