2017-06-16 89 views
-1

我MainApp:爲什麼此JavaFX選項卡窗格示例不起作用?

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:\J2EE\MultiTabPane\dist\run679227950\MultiTabPane.jar using platform C:\Program Files\Java\jdk1.8.0_60\jre/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 

文件:/ D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/multitabpane/view/fooTabPage.fxml:9 file:/ D:/J2EE/MultiTabPane/dist/run679227950/MultiTabPane.jar!/ multitabpane/view/MainController .fxm L: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 
+1

例外情況是說在'MainController.fxml'中使用'fx:id =「fooTabPage」'的元素是一個'AnchorPane':你試圖通過'@ FXML'注入將它賦值給一個變量鍵入'FooTabPage'。 –

+0

對不起,我根本看不到我需要做的事情。 – Rusty

+0

這是否意味着在MainApp類中coderootLayout =(AnchorPane)loader.load();是錯的? – Rusty

回答

0

我已經解決了這個問題,通過更改基於'tab1'和'tab2'的更有意義的名稱在示例代碼中的'foo'引用。

主控制器宣告標籤引用:

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> 

在選項卡控制器類中,爲選項卡創建參考,併爲用戶定義的選項卡工作區域的任何其他控件引用。在我的解決方案有在每個翼片控制層次結構的按鈕以及用於按鍵收聽者「打開操作」命令:

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> 

總之,有一個MainApp,三個控制器類和3個相應的FXML視圖。

0

我大概想這個問題,因爲在類MainController,你聲明fooTabPage作爲FooTabPage的實例,但在MainController.fxml,您使用<AnchorPane fx:id="fooTabPage">,總之,你聲明fooTabPage的差異類型在fxml和java類中。

代碼

"@FXML private FooTabPage fooTabPage;" 

只是改變

"@FXML private AnchorPane fooTabPage;" 
在MainController

,這個問題將得到解決。 因爲在你的「fooTabPage.fxml」中,它的根元素是AnchorPane,所以你應該在fxml根窗格中聲明與你使用的類型相同的類型。

+0

不幸的是,這個週末不幸在這個週末橫跨各大洲旅行,但當我回到我的辦公桌時,我會這樣做。 – Rusty

+0

<標籤文本= 「標籤1」> <標籤的文本=」 標籤2" > <! - 註釋掉,直到我能得到上面的工作 - > Rusty

+0

可以你也發佈了fooTabPage.fxml的內容嗎?因爲我想問題在於fooTabPage.fxml的根元素。 – yab

相關問題