Reputation: 69
I want to write an application, that has got a few options. The user can choose in a menu one option and a tab should be created, which loads its view from another fxml-file(, which has also another view-controller). Currently my code looks like:
Tab t = new Tab("My New Tab");
try {
t.setClosable(true);
t.setId("test");
t.setContent(FXMLLoader.
load(getClass().
getResource("/package/NewTabView.fxml")));
} catch (Exception e) {
}
tabPane.getTabs().add(t);
selectionModel.selectLast();
Hope you can help me, because I get the following Exception:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
Upvotes: 2
Views: 1033
Reputation: 216
Like what @DVarga said you need to check the location of your NewTabView.fxml
file.
Here is an example that could help you:
firstView
FXML file is the one that contains the TabPane
secondView
FXML file contains the content that we are going to load dynamically inside a new Tab
in the first TabPane
createTabDynamically()
method where we load the FXML file of the secondView
and set its controller, then we instantiate a new tab and set the secondView as its content and we finally add it to the TabPane
.FirstView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<BorderPane fx:id="container" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem fx:id="closeMI" mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Action">
<items>
<MenuItem fx:id="openTabMI" mnemonicParsing="false" text="Open the new tab" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="ALL_TABS">
<tabs>
<Tab fx:id="myTab" closable="false" text="MyTab">
<content>
<VBox>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
<children>
<Label text="Hello From the first view" />
</children>
</VBox>
</content>
</Tab>
</tabs>
</TabPane>
</center>
</BorderPane>
SecondView.FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox fx:id="container" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="secondInfoLbl" text="This is the second view">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
FirstViewController.java
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.VBox;
public class FirstViewController implements Initializable {
@FXML private MenuItem openTabMI, closeMI;
@FXML private TabPane tabPane;
private Tab myDynamicTab;
@Override
public void initialize(URL location, ResourceBundle resources) {
openTabMI.setOnAction((event)->{
createTabDynamically();
});
closeMI.setOnAction((event)->{Platform.exit();});
}
private void createTabDynamically() {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("secondView.fxml"));
loader.setController(new SecondViewController());
try {
Parent parent = loader.load();
myDynamicTab = new Tab("A Dynamic Tab");
myDynamicTab.setClosable(true);
myDynamicTab.setContent(parent);
tabPane.getTabs().add(myDynamicTab);
} catch (IOException e) {
e.printStackTrace();
}
}
}
SecondViewController.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class SecondViewController implements Initializable {
@FXML private Label secondInfoLbl;
@Override
public void initialize(URL url, ResourceBundle rb) {
secondInfoLbl.setText("Hello from the second view");
}
}
MainApp.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
public static void main(String [] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FirstView.fxml"));
FirstViewController firstViewController = new FirstViewController();
loader.setController(firstViewController);
Parent parent = loader.load();
Scene scene = new Scene(parent);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Upvotes: 2