首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重新访问JavaFX自定义控件

重新访问JavaFX自定义控件
EN

Stack Overflow用户
提问于 2017-01-10 22:43:08
回答 4查看 1.6K关注 0票数 3

我已经运行了掌握FXML示例如何在JavaFX 2.0中使用FXML创建自定义组件并尝试了这个站点中的其他各种解决方案,但我仍然没有找到一个简单的示例,说明如何设置一个定制控件,而这个控件并不是GUI的唯一部分。既然这个问题还在冒出来,看来我们需要一个更简单的例子。

我正在尝试创建一个简单的控件,包括一个垂直的SplitPane,顶部有一个按钮,下层有一个标签。然后,我想将这个SplitPane控件的实例放在一个TabPane中的多个选项卡中。要么控件不会出现,要么我会陷入各种错误,这取决于我试图遵循的示例。因此,我将回溯一点,只需简单地问一句:如何将SplitPane分离出来成为自定义控件?

以下是FXML文档:

代码语言:javascript
运行
复制
<?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>

控制器类:

代码语言:javascript
运行
复制
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
    }    
}

而主要的测试课程:

代码语言:javascript
运行
复制
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):

代码语言:javascript
运行
复制
<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):

代码语言:javascript
运行
复制
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现在看起来如下所示:

代码语言:javascript
运行
复制
<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。也许现在对这里的人来说我错过了什么更明显了?

再次感谢。

EN

Stack Overflow用户

发布于 2017-01-11 01:48:16

您的自定义控件类应该扩展Parent类之一,例如RegionPane。如果您懒得做布局工作,只需扩展高级窗格(如GridPane )即可。

然后,您的自定义控件类应该加载一个包含SplitPane及其子控件的FXML。FXML的控制器可以是这个自定义控件类,也可以将它与它的个人控制器类分开。应该将SplitPane节点添加为自定义控件类的子节点;这意味着您的自定义控件(它是Parent类型)必须处理某些布局逻辑。此时,您的自定义控件已经完成。

此控件可以在FXML中使用。但是,如果要在场景生成器中使用它,则需要将其打包到JAR文件中,并将其添加到场景生成器中。请注意,为了使场景生成器工作,您的自定义控件类必须定义一个无参数构造函数。

票数 1
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41579752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档