JavaFX 2:包含文本的可resize的矩形

我想显示一个包含文本/标签的矩形。 为此,我创建了一个堆栈窗格,并为其添加了一个矩形和一个标签。 但是文本/标签未正确居中。 它位于矩形之外(左侧)。 这是我目前使用的代码:

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) } 

我已经尝试绑定矩形的xProperty()和yProperty(),更改stackpane(setAlignment(Pos.CENTER))和其他东西的对齐方式,但没有成功。

当我使用固定的矩形大小(例如新的矩形(30,30))并且不使用绑定时,标签在矩形内正确居中。 但是,矩形的大小需要根据标签大小进行调整:

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

对于标注尺寸的背景

只需在Label上直接使用CSS,就不需要任何其他节点。

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

填充可用于调整标签周围的矩形背景区域的大小。

固定标签

对于可resize的背景

您不需要Rectangle节点,将标签放在StackPane中并在StackPane上设置背景:

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

居中的标签

可执行样本

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

注意:此答案中的内联样式仅用于演示目的,最佳做法是使用CSS样式表进行CSS样式定义。

我还想使用其他形状(尤其是圆角矩形和圆形)而不是普通的矩形。 这可以通过在答案中提出的堆叠窗格或标签本身的样式来实现吗?

是的,任何派生自Region的东西(包括StackPane等布局窗格和Label等控件)都可以通过CSS进行相当广泛的设计。

要获得圆角背景,可以使用-fx-background-radius

要获得任意形状的背景,您可以使用fx-shape ,但您可能会发现将文本放置在任意形状的背景中很棘手。

你也可以在代码中编写一个形状,并使用绑定来使你的东西适合你最初在你的问题中尝试。

如果需要进行大量的微调,那么你可以对region进行子类化并覆盖layoutChildren方法,为该方法中的所有子进程执行精确的布局计算(这是大多数内置JavaFX控件处理布局的方式)在他们的皮肤类)。

无论如何,一个看似简单的问题并不总是有一个简单的答案,因为在你可以做的事情的方式和你可能想要做的许多微妙的差异,如如何处理包装文本,结束了许多变化,插件,是否要超出最小尺寸的文本等。

但是,对于矩形或圆角矩形背景的最常见任务,我只是坚持在标签上直接使用CSS样式。 通过使用样式表,您可以轻松完全更改标签的应用程序样式。

这是一个更广泛的,矫枉过正的样本:

lotsastyles

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

标签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; } 

如果您对进一步的样品非常热衷,请查看QuoteMaker应用程序处理可resize的标签背景样式的方式。