My MainApp:
package multitabpane;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class MainApp extends Application
{
private Stage primaryStage;
private AnchorPane rootLayout;
/** The horizontal offset for making the rootLayout movable */
private double xOffset = 0;
/** The vertical offset for making the rootLayout movable */
private double yOffset = 0;
public MainApp() {}
@Override
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
//Get rid of the windoze crap
primaryStage.initStyle(StageStyle.UNDECORATED);
initRootLayout();
//Make the screen movable by a drag and drop
rootLayout.setOnMousePressed((MouseEvent event) -> {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
});
rootLayout.setOnMouseDragged((MouseEvent event) -> {
primaryStage.setX(event.getScreenX() - xOffset);
primaryStage.setY(event.getScreenY() - yOffset);
});
}
/**
* Initializes the root layout.
*/
public void initRootLayout()
{
try
{
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
Loader.setLocation(MainApp.class.getResource("view/MainController.fxml"));
rootLayout = (AnchorPane)loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {}
}
/**
* Returns the main stage.
* @return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args){
launch(args);
}
}
以下是 MainController.java 和 MainController.xml
package multitabpane.view;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
public class MainController {
// Inject tab content.
@FXML private AnchorPane fooTabPage;
// Inject controller
@FXML private FooTabController fooTabPageController;
// Inject tab content. Keep Commented out until the above is working
// @FXML private BarTabPage barTabPage;
// Inject controller
// @FXML private BarTabController barTabPageController;
}
和
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
<TabPane id="tabPane" prefHeight="400.0" prefWidth="600.0">
<tabs>
<Tab text="Tab 1">
<content>
<fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/>
</content>
</Tab>
<Tab text="Tab 2">
<content>
<!-- commented out until I can get the above to work -->
<!-- fx:include fx:id="barTabPage" source="barTabPage.fxml"/ -->
</content>
</Tab>
</tabs>
</TabPane>
</AnchorPane>
这是FooTabController:
package multitabpane.view;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
class FooTabController {
@FXML private AnchorPane fooTabPage;
}
最后这是FooTabPage.java和xml:
package multitabpane.view;
class FooTabPage {}
和
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="fooTabPage" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="multitabpane.view.FooTabController" />
最后是我尝试运行构建项目时的转储:
Executing D:J2EEMultiTabPanedistrun679227950MultiTabPane.jar using platform C:Program FilesJavajdk1.8.0_60jre/bin/java
Jun 21, 2017 9:14:22 AM multitabpane.MainApp initRootLayout
Error in MainApp:initRootLayout()
SEVERE: null
file:/D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/multitabpane/view/fooTabPage.fxml:9
javafx.fxml.LoadException:
file:/D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/multitabpane/view/MainController.fxml:14
file:/D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/multitabpane/view/fooTabPage.fxml:9file:/D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/multitabpane/view/MainController.fxml:14
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:934)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.access$2700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1143)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at multitabpane.MainApp.initRootLayout(MainApp.java:58)
at multitabpane.MainApp.start(MainApp.java:35)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
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.IllegalAccessException: Class sun.reflect.misc.ReflectUtil can not access a member of class multitabpane.view.FooTabController with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
... 24 more
我想这个问题可能是因为在类 MainController 中,您将 fooTabPage 声明为 FooTabPage 的实例,但在 MainController.fxml 中,您使用 <AnchorPane fx:id="fooTabPage">
,简而言之,您在 fxml 和 java 类中声明了 fooTabPage 的不同类型。
只需更改代码
"@FXML private FooTabPage fooTabPage;"
自
"@FXML private AnchorPane fooTabPage;"
在主控制器中,问题将得到解决。因为在"fooTabPage.fxml"中,它的根元素是AnchorPane,所以你应该声明与fxml根窗格中使用的类型相同。
我已经通过将示例代码中的"foo"引用更改为基于"tab1"和"tab2"的更有意义的名称来解决这个问题。我现在运行构建项目时没有收到错误:
主控制器声明对选项卡的引用:
public class MainController {
@FXML private AnchorPane tab1Page;
@FXML private AnchorPane tab2Page;
}
在主控制器 fxml 中,将选项卡引用绑定到其文件源:
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="multitabpane.view.MainController">
<TabPane id="tabPane" prefHeight="400.0" prefWidth="600.0">
<tabs>
<Tab text="Tab 1">
<content>
<fx:include fx:id="tab1Page" source="Tab1Controller.fxml"/>
</content>
</Tab>
<Tab text="Tab 2">
<content>
<fx:include fx:id="tab2Page" source="Tab2Controller.fxml"/>
</content>
</Tab>
</tabs>
</TabPane>
</AnchorPane>
在选项卡中,控制器类为选项卡创建引用,并引用用户定义的选项卡工作区的任何其他控件。在我的解决方案中,每个选项卡控件层次结构中都有一个按钮和一个用于按钮"On Action"命令的侦听器:
public class Tab1Controller {
@FXML Tab tab1;
@FXML Button exitButton;
@FXML
public void exitApp()
{
System.exit(1);
}
}
和
public class Tab2Controller
{
@FXML Tab tab2;
@FXML Button resetButton;
@FXML
public void handleReset()
{
System.out.println("Does nothing");
}
}
选项卡控制器必须相应地引用其控制器:
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="multitabpane.view.Tab1Controller">
<children>
<Button fx:id="exitButton" layoutX="92.0" layoutY="136.0" mnemonicParsing="false" onAction="#exitApp" text="Button" />
</children>
</AnchorPane>
和
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="multitabpane.view.Tab2Controller">
<children>
<Button fx:id="resetButton" layoutX="78.0" layoutY="180.0" mnemonicParsing="false" onAction="#handleReset" text="Reset" />
</children>
</AnchorPane>
总之,有一个主应用程序,三个控制器类和3个相应的FXML视图。