我已经运行了掌握FXML示例、如何在JavaFX 2.0中使用FXML创建自定义组件并尝试了这个站点中的其他各种解决方案,但我仍然没有找到一个简单的示例,说明如何设置一个定制控件,而这个控件并不是GUI的唯一部分。既然这个问题还在冒出来,看来我们需要一个更简单的例子。
我正在尝试创建一个简单的控件,包括一个垂直的SplitPane,顶部有一个按钮,下层有一个标签。然后,我想将这个SplitPane控件的实例放在一个TabPane中的多个选项卡中。要么控件不会出现,要么我会陷入各种错误,这取决于我试图遵循的示例。因此,我将回溯一点,只需简单地问一句:如何将SplitPane分离出来成为自定义控件?
以下是FXML文档:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<TabPane prefHeight="256.0" prefWidth="477.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="customcontroltest.FXMLDocumentController">
<tabs>
<Tab>
<content>
<SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="114.0" prefWidth="160.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button fx:id="button" onAction="#handleButtonAction" text="Click Me!" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label fx:id="label" minHeight="16" minWidth="69" />
</children>
</AnchorPane>
</items>
</SplitPane>
</content>
</Tab>
</tabs>
</TabPane>
控制器类:
package customcontroltest;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLDocumentController implements Initializable
{
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event)
{
label.setText("Hello World!");
}
@Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
}
}
而主要的测试课程:
package customcontroltest;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class CustomControlTest extends Application
{
@Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
我创建了一个新的FXML文件,并剪切/粘贴了整个SplitPane标记及其所有内容。我将FXML文档中的SplitPane标记替换为<packageName.ControlClassName />
。然后,我创建了控制器类来扩展SplitPane。我尝试在FXML标记和/或控制器类中指定控制器,但始终没有正确。一个知之甚少的人会愿意花几分钟的时间来展示这方面的工作例子吗?我猜更多的人会觉得这样的例子非常有用。因此,SplitPane应该是新的自定义控件,然后您可以在默认情况下将其加载到TabPane的第一个选项卡中。然后,我将编写代码将更多实例添加到后续选项卡中。
非常感谢您提前。
更新:--我已经将SplitPane
分解为自己的FXML和控制器类。下面是FXML (CustomSplitPane.fxml):
<fx:root type="javafx.scene.control.SplitPane" dividerPositions="0.5" orientation="VERTICAL" prefHeight="114.0" prefWidth="160.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="customcontroltest.CustomSplitPaneController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button fx:id="button" onAction="#handleButtonAction" text="Click Me!" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label fx:id="label" minHeight="16" minWidth="69" />
</children>
</AnchorPane>
</items>
</fx:root>
控制器类(CustomSplitPaneController.java):
package customcontroltest;
public class CustomSplitPaneController extends AnchorPane
{
@FXML
private Label label;
private SplitPane mySplitPane;
public CustomSplitPaneController()
{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("CustomSplitPane.fxml"));
try
{
fxmlLoader.load();
} catch (IOException exception)
{
throw new RuntimeException(exception);
}
}
@FXML
private void handleButtonAction(ActionEvent event)
{
label.setText("Hello World!");
}
}
原来的主FXML现在看起来如下所示:
<TabPane prefHeight="256.0" prefWidth="477.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="customcontroltest.FXMLDocumentController">
<tabs>
<Tab>
<content>
<customcontroltest.CustomSplitPaneController />
</content>
</Tab>
</tabs>
</TabPane>
fxmlLoader.load()
中的CustomSplitPaneController
似乎导致了一个java.lang.StackOverflowError。也许现在对这里的人来说我错过了什么更明显了?
再次感谢。
发布于 2017-01-11 01:48:16
您的自定义控件类应该扩展Parent
类之一,例如Region
或Pane
。如果您懒得做布局工作,只需扩展高级窗格(如GridPane
)即可。
然后,您的自定义控件类应该加载一个包含SplitPane
及其子控件的FXML。FXML的控制器可以是这个自定义控件类,也可以将它与它的个人控制器类分开。应该将SplitPane
节点添加为自定义控件类的子节点;这意味着您的自定义控件(它是Parent
类型)必须处理某些布局逻辑。此时,您的自定义控件已经完成。
此控件可以在FXML中使用。但是,如果要在场景生成器中使用它,则需要将其打包到JAR文件中,并将其添加到场景生成器中。请注意,为了使场景生成器工作,您的自定义控件类必须定义一个无参数构造函数。
https://stackoverflow.com/questions/41579752
复制相似问题