@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
initRootLayout();
showTabOverview();
}
/**
* Initializes the root layout.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("rootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Shows the Tab overview inside the root layout.
*/
public void showTabOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("tabLayout.fxml"));
TabPane TabOverview = (TabPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(TabOverview);
} catch (IOException e) {
e.printStackTrace();
}
}
它适用于我的tablab的FXML。
<TabPane xmlns:fx="http://www.w3.org/1999/XSL/Transform">
<tabs>
<Tab text="Untitled Tab 1">
</Tab>
<Tab text="Untitled Tab 2">
</Tab>
</tabs>
</TabPane>
但我尝试使用this link
上找到的这种方法添加每个标签FXML<Tab text="Untitled Tab 1">
<content>
<fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/>
</content>
</Tab>
当我为标签添加包含新来源的内容时,我会IllegalArgumentException: Unable to coerce javafx.scene.control.Tab@3885406e to class javafx.scene.Node.
如何让这些标签真正成为节点?是否有特定的方法来创建它们?
答案 0 :(得分:3)
Tab
不是Node
的子类,您可以从JavaDocs看到。这样做的原因是JavaFX的作者希望标签只在<{1}}中放置 :如果TabPane
是Tab
的子类,那么你可以做例如,Node
,这不是真的有意义(我怀疑JavaFX的作者并不想在防御上编码HBox anyContainer = new HBox(new Tab(...));
来处理这些场景。所以{{ 1}}是Tab
的子类,Tab
有Object
,您可以使用TabPane
访问。{/ p>
ObservableList<Tab>
通过使用(很多很多)反射来工作。这允许它动态创建对象,其类由fxml文件确定,当然编译器从未看到过。因此,getTabs()
没有对从FXML文件创建的对象类型进行编译时检查。因此,您为FXMLLoader
的灵活性支付的价格是类型安全性的损失;作为程序员,您可以确保在FXML文件中定义正确的类型以用于其预期用途。
因此,如果你有如下FXML代码:
FXMLLoader
这松散地转化为
FXMLLoader
由于setContent
预计为<Tab text="Untitled Tab 1">
<content>
<fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/>
</content>
</Tab>
,因此只有Tab tab = new Tab("Untitled Tab 1");
tab.setContent(FXMLLoader.load(getClass().getResource("fooTabPage.fxml")));
的根元素引用Node
时才会成功。
相反,如果fooTabPage.fxml
的根元素是Node
,那么您需要fooTabPage.fxml
出现在预期Tab
的地方。所以你可以<fx:include>
作为
Tab
然后再做
fooTabPage.fxml
但是,如果您不假设其层次结构将放置在选项卡窗格中,则您的<?xml version="1.0" encoding="UTF-8"?>
<!-- imports .... -->
<Tab fx:controller="..." xmlns:fx="http://javafx.com/fxml/1">
<content>
<!-- define content here... -->
</content>
</Tab>
文件可能会更具可重用性(尽管此级别的设计非常适合您)。因此,将<TabPane>
<tabs>
<fx:include source="fooTabPane.fxml" />
</tabs>
</TabPane>
fooTabPage.fxml
实例的根元素设置为更有用,例如
fooTabPage.fxml
并做(如您提供的链接):
Node