layout javafx-2 groupbox titled-border

layout - GroupBox/TitledBorder en JavaFX 2?



javafx-2 titled-border (6)

¿Hay algo como un GroupBox o TitledBorder disponible en JavaFX 2?

Gracias por cualquier pista :-)


Aquí hay un documento FXML que se puede cargar en SceneBuilder que tiene una funcionalidad similar:

<?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>

Si necesita aumentar el tamaño del texto / borde de la etiqueta, solo debe editar el CSS y el Anclaje superior del AnchorPane secundario y el primer argumento de -fx-border-ints del AnchorPane padre.


Aquí hay una implementación de GroupBox basada en TitledPane. Proporciona tres métodos para establecer el título, el contenido y el relleno de contenido de 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); } }


GroupBox: ese es el diseño de grupo habitual, por lo que veo.

TitledBorder: parece un TitledPane (que por lo general es un componente de Accordion, pero podría ser un control que existe por separado).

Los análogos de JavaFX-2 se ven diferentes a los suyos (pero no significativamente), y como de costumbre, puede usar diferentes formas de cambio de aspecto de control: css, reemplazo de piel de control, etc.


No existe dicho control estándar, pero es fácil crear uno propio. Aquí hay una implementación de ejemplo:

/** 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); } }

Y el css que lo acompaña:

.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; }

El código proviene de un example que creé en respuesta a una publicación de hilo del foro Oracle JavaFX "Equivalente a BorderFactory.createTitledBorder" .

La salida del programa de ejemplo es como se muestra a continuación.


Utilicé TitledPane con setCollapsible(false) . Parece más consistente que usar estilos CSS. Aquí está el resultado


Versión FXML de la respuesta de jewelsea:

TitledBorder (renombré BorderedTitledPane a 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); } }

Uso de FXML:

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

¡No olvides la hoja de estilo!

Use este CSS para una fuente normal:

.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; }

El uso de este CSS ahora se ve así:

Actualización: problemas cuando el título es más largo que el contenido:

¿Alguna pista para solucionar este problema?