java binding javafx javafx-2

JavaFX 2: rectángulo redimensionable que contiene texto



binding javafx-2 (1)

Para un fondo clasificado en la etiqueta

Simplemente use CSS directamente en la etiqueta, no necesita ningún otro nodo.

Label label = new Label("Sally collects seashells on the seashore"); label.setStyle("-fx-background-color: coral; -fx-padding: 10px;");

El relleno se puede usar para ajustar el tamaño del área de fondo rectangular alrededor de la etiqueta.

Para un fondo redimensionable

No necesita un nodo Rectangle, coloque la etiqueta en un StackPane y establezca un fondo en el StackPane:

Label label = new Label("Sally collects seashells on the seashore"); StackPane centeredLabel = new StackPane(label); centeredLabel.setStyle("-fx-background-color: coral;");

Muestra ejecutable

import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class LabelBackground extends Application { @Override public void start(Stage stage) throws Exception { Label label = new Label("Sally collects seashells on the seashore"); StackPane centeredLabel = new StackPane(label); centeredLabel.setStyle("-fx-background-color: coral;"); StackPane root = new StackPane(centeredLabel); root.setPadding(new Insets(10)); stage.setScene(new Scene(root)); stage.show(); } public static void main(String[] args) { Application.launch(args); } }

Nota: Los estilos en línea en esta respuesta son solo para fines de demostración fácil, la mejor práctica es usar una hoja de estilo CSS para las definiciones de estilo CSS.

También quiero usar otras formas (especialmente rectángulos y círculos redondeados) en lugar de rectángulos simples. ¿Se puede lograr esto al diseñar el stackpane o la etiqueta como se propone en su respuesta?

Sí, todo lo que se deriva de la región (que incluye paneles de diseño como StackPane y controles como Label), se puede diseñar de manera bastante extensiva a través de CSS.

Para obtener un fondo redondeado, puede usar -fx-background-radius .

Para obtener un fondo en forma arbitraria, puede usar fx-shape , aunque puede resultarle difícil colocar el texto dentro del fondo con forma arbitraria.

También puede escribir una forma en el código y usar enlaces para que las cosas quepan dentro de ella como lo intentó originalmente en su pregunta.

Si las cosas necesitan un gran ajuste, puede subcategorizar la región e ignorar el método layoutChildren para realizar cálculos de diseño precisos para todos los elementos dentro de ese método (esta es la forma en que la mayoría de los controles JavaFX integrados manejan los diseños en sus clases de piel).

De todos modos, una pregunta aparentemente simple no siempre tiene una respuesta simple, ya que hay muchas variaciones en la manera en que se pueden hacer las cosas y muchas diferencias sutiles en lo que se podría querer hacer, como por ejemplo, cómo manejar el texto ajustado. inserciones, ya sea para eludir el texto más allá de un tamaño mínimo, etc.

Sin embargo, para las tareas más comunes de fondos rectangulares rectangulares o redondeados, me limitaría a usar estilos CSS directamente en las etiquetas. Al usar hojas de estilo, puede cambiar completamente el estilo de la aplicación para sus etiquetas.

Aquí hay una muestra más extensa y exagerada:

LabelBackground.java

import javafx.application.Application; import javafx.beans.binding.DoubleBinding; import javafx.geometry.*; import javafx.scene.*; import javafx.scene.control.Label; import javafx.scene.layout.*; import javafx.scene.shape.Ellipse; import javafx.stage.Stage; public class LabelBackground extends Application { @Override public void start(Stage stage) throws Exception { Pane starLabel = labelOnStyledBackground( "Practical Principles of Plain and Perfect Pronunciation.", "star-label" ); StackPane labelOnResizableBackground = labelOnStyledBackground( "Sally collects seashells on the seashore", "resizable-background" ); labelOnResizableBackground.setPrefHeight(60); Label squareLabel = createLabel( "Betty Botter bought a bit of butter.", "square-label" ); Label roundedLabel = createLabel( "Peter Piper picked a peck of pickled peppers.", "rounded-label" ); Node ellipticalLabel = createEllipticalLabel( "Round and round the rugged rock the ragged rascal ran.", "elliptical-label" ); VBox root = new VBox( 10, starLabel, labelOnResizableBackground, squareLabel, roundedLabel, ellipticalLabel ); VBox.setVgrow(labelOnResizableBackground, Priority.SOMETIMES); root.setAlignment(Pos.TOP_CENTER); root.setPadding(new Insets(10)); Scene scene = new Scene(root); scene.getStylesheets().add( LabelBackground.class.getResource( "label-styles.css" ).toExternalForm() ); stage.setScene(scene); stage.setTitle("Resize me!"); stage.show(); } private Label createLabel(String text, String styleClass) { Label label = new Label(text); label.getStyleClass().add(styleClass); return label; } private StackPane labelOnStyledBackground(String text, String styleClass) { Label label = new Label(text); StackPane container = new StackPane(label); container.getStyleClass().add(styleClass); return container; } private Group createEllipticalLabel(String text, String styleClass) { final double INSET = 20; Label label = new Label(text); Ellipse ellipse = new Ellipse(); ellipse.getStyleClass().add("ellipse"); DoubleBinding halfWidth = label.widthProperty().divide(2).add(INSET); DoubleBinding halfHeight = label.widthProperty().divide(4).add(INSET); ellipse.radiusXProperty().bind(halfWidth); ellipse.radiusYProperty().bind(halfHeight); ellipse.centerXProperty().bind(halfWidth); ellipse.centerYProperty().bind(halfHeight); label.setLayoutX(INSET); label.layoutYProperty().bind(halfHeight.subtract(label.heightProperty().divide(2))); Group group = new Group(ellipse, label); group.getStyleClass().add(styleClass); return group; } public static void main(String[] args) { Application.launch(args); } }

label-styles.css

.root { -fx-font-size: 16px; } .rounded-label { -fx-background-color: cadetblue; -fx-padding: 10px; -fx-background-radius: 10px; } .square-label { -fx-background-color: plum; -fx-padding: 10px; } .star-label { -fx-background-color: gold; -fx-padding: 120px; /* shape courtesy of Smiffy''s star place: http://www.smiffysplace.com/stars.html */ -fx-shape: "M 0.000 20.000 L 23.511 32.361 L 19.021 6.180 L 38.042 -12.361 L 11.756 -16.180 L 0.000 -40.000 L -11.756 -16.180 L -38.042 -12.361 L -19.021 6.180 L -23.511 32.361 L 0.000 20.000"; } .resizable-background { -fx-background-color: coral; } .elliptical-label .ellipse { -fx-fill: lightpink; }

Si está muy interesado en obtener más ejemplos, observe la forma en que la aplicación QuoteMaker maneja el estilo de los fondos de etiquetas de tamaño variable .

Quiero mostrar un rectángulo que contiene un texto / etiqueta. Para este propósito creé un stackpane y agregué un rectángulo y una etiqueta a él. Sin embargo, el texto / etiqueta no está centrado correctamente. Se coloca fuera del rectángulo (a la izquierda). Este es el código que estoy usando actualmente:

createRectangle(String name) { pane = new StackPane(); text = new Label(name); rect = new Rectangle(); // bind rectangle width to text width and add 10 rect.widthProperty().bind(text.widthProperty().add(10)); rect.heightProperty().bind(text.heightProperty().add(10)); // add to stackpane pane.getChildren().addAll(rect,text); // display stackpane getChildren().add(pane) }

He intentado enlazar el xProperty () y yProperty () del rectángulo, cambiando la alineación del panel de distribución (setAlignment (Pos.CENTER)) y otras cosas, pero sin éxito.

Cuando uso un tamaño de rectángulo fijo (por ejemplo, un nuevo rectángulo (30,30)) y no utilizo los enlaces, la etiqueta se centra correctamente dentro del rectángulo. Sin embargo, el tamaño del rectángulo debe ajustarse según el tamaño de la etiqueta:

// label is placed correctly in the center of the rectangle createRectangle(String name) { pane = new StackPane(); text = new Label(name); rect = new Rectangle(30,30); // add to stackpane pane.getChildren().addAll(rect,text); // display stackpane getChildren().add(pane) }