【问题标题】:GroupBox / TitledBorder in JavaFX 2?JavaFX 2 中的 GroupBox / TitledBorder?
【发布时间】:2013-01-29 10:28:24
【问题描述】:

JavaFX 2 上是否有类似 GroupBoxTitledBorder 的东西?

感谢任何提示:-)

【问题讨论】:

    标签: layout javafx-2 groupbox titled-border


    【解决方案1】:

    没有这样的标准控件,但很容易创建自己的控件。这是一个示例实现:

    /** Places content in a bordered pane with a title. */
    class BorderedTitledPane extends StackPane {
      BorderedTitledPane(String titleString, Node content) {
        Label title = new Label(" " + titleString + " ");
        title.getStyleClass().add("bordered-titled-title");
        StackPane.setAlignment(title, Pos.TOP_CENTER);
    
        StackPane contentPane = new StackPane();
        content.getStyleClass().add("bordered-titled-content");
        contentPane.getChildren().add(content);
    
        getStyleClass().add("bordered-titled-border");
        getChildren().addAll(title, contentPane);
      }
    }
    

    以及它随附的 css:

    .label {
      -fx-font: 28px Vivaldi;
    }
    
    .bordered-titled-title {
      -fx-background-color: white;
      -fx-translate-y: -16;
    }
    
    .bordered-titled-border {
      -fx-content-display: top;
      -fx-border-insets: 20 15 15 15;
      -fx-background-color: white;
      -fx-border-color: black;
      -fx-border-width: 2;
    }
    
    .bordered-titled-content {
      -fx-padding: 26 10 10 10;
    }
    

    代码来自我创建的example,以响应Oracle JavaFX 论坛帖子"Equivalent to BorderFactory.createTitledBorder"

    示例程序的输出如下所示。

    【讨论】:

    • 太棒了,谢谢!你有没有想过一个可以完全使用 FXML 的版本,因此可以在 FXML 中设置标题和内容?
    • 获得了 FXML 版本,请参阅下面的答案。但是我需要一个正常/较小的字体,在这种情况下,标题没有居中(垂直!)到边框 - 对此有任何提示吗?解决了,请看下面我的回答。
    • jewelsea,能否请您将 Oracle 论坛的链接添加回此线程(对于 FXML 版本)?
    • hmm 标题较长的问题,请参阅下面的答案。对此有任何提示吗? ): 将 cotnent 宽度绑定到标签宽度 + 一些偏移量左右?
    • @jewelsea 是否可以创建带有与其他 JavaFX 组件完全相同样式(大小、颜色)的边框和平铺的标题窗格?
    【解决方案2】:

    我将TitledPanesetCollapsible(false) 一起使用。它看起来比使用 CSS 样式更一致。这是结果

    【讨论】:

    • 真的很简单方便
    【解决方案3】:

    jewelsea 回答的 FXML 版本:

    TitledBorder(我将 BorderedTitledPane 重命名为 TitledBorder)

    package com.example.controls;
    
    import javafx.geometry.Pos;
    import javafx.scene.Node;
    import javafx.scene.control.Label;
    import javafx.scene.layout.StackPane;
    
    public class TitledBorder extends StackPane 
    {
        private Label titleLabel = new Label();
        private StackPane contentPane = new StackPane();
        private Node content;
    
    
    
        public void setContent(Node content)
        {
            content.getStyleClass().add("bordered-titled-content");
            contentPane.getChildren().add(content);
        }
    
    
        public Node getContent()
        {
            return content;
        }
    
    
        public void setTitle(String title)
        {
        titleLabel.setText(" " + title + " ");
        }
    
    
        public String getTitle()
        {
            return titleLabel.getText();
        }
    
    
    
        public TitledBorder() 
        {
            titleLabel.setText("default title");
            titleLabel.getStyleClass().add("bordered-titled-title");
            StackPane.setAlignment(titleLabel, Pos.TOP_CENTER);
    
            getStyleClass().add("bordered-titled-border");
            getChildren().addAll(titleLabel, contentPane);
          }
    
    }
    

    FXML 用法:

    <?import com.example.controls.*?>
    
    <TitledBorder title="title" >       
        <Label text="label with text" />        
    </TitledBorder>   
    

    不要忘记样式表!

    将此 CSS 用于普通字体:

    .bordered-titled-title {
      -fx-background-color: white;
      -fx-translate-y: -10; /* play around with this value when changing the title font to get a vertically centered title */
    }
    
    .bordered-titled-border {
      -fx-content-display: top;
      -fx-border-insets: 20 15 15 15;
      -fx-background-color: white;
      -fx-border-color: black;
      -fx-border-width: 2;
    }
    
    .bordered-titled-content {
      -fx-padding: 26 10 10 10;
    }
    

    使用这个 CSS,它现在看起来像这样:

    更新: 标题长于内容时的问题:

    有什么提示可以解决这个问题吗?

    【讨论】:

    • setContent() 方法有什么用? FxmlLoader 解析 fxml 文档时从不调用它!
    • 我一直在寻找这个 :)- 但它没有在 Scene bulider 中打开
    • @stefan 你可以使用省略号字符串来解决你的问题,如果你能找到一种方法使标题标签的最大长度成为容器的长度。
    • 在那年后 ;) 也许像我这样的人仍在寻找它。我使用了类似的解决方案,并从标签的左侧和右侧添加了一些边距。
    【解决方案4】:

    这是一个可以加载到具有类似功能的 SceneBuilder 的 FXML 文档:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane style="-fx-border-insets: 8 0 0 0; -fx-background-color: #FFFFFF; -fx-border-color: black;">
        <children>
            <Label alignment="TOP_LEFT" layoutX="14.0" style="-fx-padding: 0 5; -fx-background-color: inherit;" text="Title" />
            <AnchorPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="10.0" />
        </children>
    </AnchorPane>
    

    如果您需要使标签文本/边框尺寸更大,您只需要编辑子 AnchorPane 的 CSS 和 topAnchor 以及父 AnchorPane 的 -fx-border-insets 的第一个参数。

    【讨论】:

      【解决方案5】:

      GroupBox - 据我所知,这是通常的组布局。

      TitledBorder - 看起来像 TitledPane(通常是 Accordion 的一个组件,但也可以是单独存在的控件)。

      JavaFX-2 类似物看起来与您的不同(但不明显),并且像往常一样,您可以使用不同的控件外观更改方式:css、控件的皮肤替换等

      【讨论】:

        【解决方案6】:

        这是一个基于 TitledPane 的 GroupBox 实现。它提供了三种方法来设置 GroupBox 的标题、内容和内容填充。

        public final class GroupBox extends Parent {
        
            private StackPane _stackPane;
            private TitledPane _titledPane;
        
            public GroupBox() {
                _stackPane = new StackPane();
                _titledPane = new TitledPane();
                setContentPadding(new Insets(10));
                _titledPane.setCollapsible(false);
                _titledPane.setContent(_stackPane);
                super.getChildren().add(_titledPane);
            }
        
            public GroupBox(String title, Node content) {
                this();
                setText(title);
                setContent(content);
            }
        
            public GroupBox(String title, Node content, Insets contentPadding) {
                this(title, content);
                setContentPadding(contentPadding);
            }
        
            public void setText(String value) {
                _titledPane.setText(value);
            }
        
            public void setContent(Node node) {
                _stackPane.getChildren().add(node);
            }
        
            public void setContentPadding(Insets value) {
                _stackPane.setPadding(value);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-05
          • 1970-01-01
          • 1970-01-01
          • 2011-08-10
          • 2020-12-28
          • 1970-01-01
          • 2012-11-12
          • 1970-01-01
          相关资源
          最近更新 更多