我想编写一个应用程序,它有一些选项。用户可以在菜单中选择一个选项,并且应该创建一个选项卡,该选项卡从另一个fxml文件(也有另一个视图控制器)加载其视图。目前我的代码如下:
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();
希望你能帮助我,因为我得到以下例外:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
答案 0 :(得分:1)
就像@DVarga所说,您需要检查NewTabView.fxml
文件的位置。
以下是一个可以帮助您的示例:
firstView
FXML文件是包含TabPane
secondView
FXML文件包含我们将在第一个Tab
TabPane
内动态加载的内容
createTabDynamically()
方法中我们加载secondView
的FXML文件并设置其控制器,然后我们实例化一个新选项卡并将第二个View设置为其内容,我们最后添加它到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();
}
}