Forum Stats

  • 3,839,329 Users
  • 2,262,481 Discussions
  • 7,900,934 Comments

Discussions

Javafx- Display fxml document in BorderPane of another

Hello guys,

I have gone mad because of this issue. I want to design a desktop app where I have a main window with side pane containing buttons. When a button is clicked another fxml document displays in the center of the main window (which is basically a Border Pane). Another thing, how can I put a close button on the sub window to close the displayed fmxl document? The code runs and displays the main window content, but crashes when I click on the button to display Page1. This is very basic code. I don't need complex solutions please.

Two pictures of what I need to design are attached.

Here is the code in my Main Class:

package main;import java.io.IOException;import javafx.application.Application;import javafx.fxml.FXMLLoader;import javafx.scene.Scene;import javafx.stage.Stage;public class Main extends Application {    private Stage primaryStage;    @Override    public void start(Stage primaryStage) throws Exception {        this.primaryStage = primaryStage;        showRootStage();    }    public static void main(String[] args) {        launch(args);    }    private void showRootStage() throws IOException {        FXMLLoader loader = new FXMLLoader();        loader.setLocation(Main.class.getResource("Stage.fxml"));        Scene scene = new Scene(loader.load());        primaryStage.setScene(scene);        primaryStage.show();    }

This is the code in the main window controller (Stage document)

package main;import java.io.IOException;import java.net.URL;import java.util.ResourceBundle;import javafx.event.ActionEvent;import javafx.fxml.FXML;import javafx.fxml.FXMLLoader;import javafx.fxml.Initializable;import javafx.scene.layout.BorderPane;public class Stage implements Initializable {    @FXML    private BorderPane rootStage;        @FXML    private void handleButtonAction(ActionEvent event) throws IOException {        FXMLLoader loader = new FXMLLoader();        loader.setLocation(javafx.stage.Stage.class.getResource("Page1.fxml"));        BorderPane newScene = loader.load();        rootStage.setCenter(newScene);    }        @Override    public void initialize(URL url, ResourceBundle rb) {        // TODO    }        }

01.jpg02.jpg

Answers

  • bouye-JavaNet
    bouye-JavaNet Member Posts: 394 Silver Badge
    edited May 2, 2017 11:26PM

    Usually when there is a crash there is an errror, an error which can help you...

    Your issue comes from the fact that you unfortunately named your controller Stage instead of StageController. And then you almost immediately mixed it with the javafx.stage.Stage class.

    So when you are doing:

    loader.setLocation(javafx.stage.Stage.class.getResource("Page1.fxml"));  

    Things do not go really well as the resource resolution attempts to figure out where is your FXML file... in the javafx.stage package... where it is not... leading to a null URL passed to the loader... and thus ending with an IllegalStateException wrapped into an InvocationTargetException wrapped into a RuntimeException...

    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:49)    at javafx.event.Event.fireEvent(Event.java:198)    at javafx.scene.Node.fireEvent(Node.java:8413)    at javafx.scene.control.Button.fire(Button.java:185)   [...]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:498)   [...]Caused by: java.lang.IllegalStateException: Location is not set.    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)   [...]
  • jsmith
    jsmith Member Posts: 2,856
    edited May 3, 2017 3:12PM

    Some sample resources that may assist you:

    javafx - Loading new fxml in the same scene - Stack Overflow

    https://gist.github.com/jewelsea/6460130

    user interface - How to have menus in java desktop application - Stack Overflow

    Though you may not need them as bouye already pointed out the immediate issue with your code.Just ignore the linked resources if they are not helpful or confuse you.

    To implement the close button, it depends upon what you want in the center when the close button is pressed.  If it just an empty pane, the action of your close button can be something like parentBorderPane.setCenter(new Pane()).  If you need to get a reference to the parent border pane into your child document FXML controller, you can use a technique from: Passing Parameters JavaFX FXML - Stack Overflow.

This discussion has been closed.