如果没有包装,JavaFX 标签不会居中
JavaFX Label doesn't center if not wrapped
我遇到了一组非常奇怪的情况,在 JavaFX 标签中文本换行和居中对齐。我确定我做错了什么或 ill-advised,但我似乎无法弄清楚我做错了什么。
基本上,我试图将标题放在拼贴窗格上,并使该标题居中。此外,当 window 调整大小时,我希望标题换行。当标题没有换行时(例如:一行),它就不再居中了,就会出现奇怪的情况。一旦它包裹起来,它就会再次居中。下面是一些产生效果的示例代码:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.apache.commons.lang.RandomStringUtils;
public class Foo extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(RandomStringUtils.randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-text-alignment: center -fx-border-color:black;");
title.minWidthProperty().bind(Bindings.add(-30, primaryStage.widthProperty()));
title.setTextAlignment(TextAlignment.CENTER);
VBox box = new VBox(title, panel);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
这是我所看到的屏幕截图。在第一个中,顶部的粗线居中并环绕。第二个,上面的粗线没有换行,是 left-aligned.
好吧,我尝试了一些不同的策略,我用常规 css 想通了。
您可以使用“-fx-alignment: center;”去做吧。有关使用哪种 css 的更多信息,请参阅 this link。标签的宽度也很重要,否则宽度将只是文本的长度而不会真正居中。
进行更改,您的代码将如下所示
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(RandomStringUtils.randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-alignment: center; -fx-border-color:black;");
title.setMinWidth(400); //This is important, else the width will just be the text's length
VBox box = new VBox(title, panel);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
如documentation所述,文本对齐方式控制多行文本的对齐方式。这正是指定的行为。
如果您想象一个包围所有文本的矩形,当文本有多行时,必须决定如何在该矩形内布置这些单独的行。这是由 textAlignment
属性 控制的。默认是将每行对齐到该框的左侧:您也可以居中、右对齐或对齐(展开每行以填充框)。另一种思考方式是 textAlignment
仅控制每行文本 相对于其他文本行 .
的位置
另一方面,alignment
属性 定义标签内容(文本和图形)在标签本身内的对齐方式,如果有更多 space标签比文本占据。因此,要将标签居中放置在 VBox
中,您首先需要确保标签填满 VBox
的整个宽度,然后您需要将 alignment
属性 设置为 CENTER
。您可以通过设置标签的 maxWidth
使其无限增长,并将 VBox
的 fillWidth()
属性 设置为 true
来实现前者。
使用 Java 这看起来像
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-border-color:black;");
title.setPadding(new Insets(5));
title.setAlignment(Pos.CENTER);
title.setMaxWidth(Double.MAX_VALUE);
title.setTextAlignment(TextAlignment.CENTER);
VBox box = new VBox(title, panel);
box.setFillWidth(true);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
如果您愿意,可以在 CSS 中设置这些属性:
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-border-color:black;"
+ "-fx-text-alignment: center; -fx-alignment: center; -fx-max-width:Infinity; -fx-padding: 5;");
VBox box = new VBox(title, panel);
box.setFillWidth(true); // or box.setStyle("-fx-fill-width: true ;")
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
我遇到了一组非常奇怪的情况,在 JavaFX 标签中文本换行和居中对齐。我确定我做错了什么或 ill-advised,但我似乎无法弄清楚我做错了什么。
基本上,我试图将标题放在拼贴窗格上,并使该标题居中。此外,当 window 调整大小时,我希望标题换行。当标题没有换行时(例如:一行),它就不再居中了,就会出现奇怪的情况。一旦它包裹起来,它就会再次居中。下面是一些产生效果的示例代码:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.apache.commons.lang.RandomStringUtils;
public class Foo extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(RandomStringUtils.randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-text-alignment: center -fx-border-color:black;");
title.minWidthProperty().bind(Bindings.add(-30, primaryStage.widthProperty()));
title.setTextAlignment(TextAlignment.CENTER);
VBox box = new VBox(title, panel);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
这是我所看到的屏幕截图。在第一个中,顶部的粗线居中并环绕。第二个,上面的粗线没有换行,是 left-aligned.
好吧,我尝试了一些不同的策略,我用常规 css 想通了。 您可以使用“-fx-alignment: center;”去做吧。有关使用哪种 css 的更多信息,请参阅 this link。标签的宽度也很重要,否则宽度将只是文本的长度而不会真正居中。
进行更改,您的代码将如下所示
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(RandomStringUtils.randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-alignment: center; -fx-border-color:black;");
title.setMinWidth(400); //This is important, else the width will just be the text's length
VBox box = new VBox(title, panel);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
如documentation所述,文本对齐方式控制多行文本的对齐方式。这正是指定的行为。
如果您想象一个包围所有文本的矩形,当文本有多行时,必须决定如何在该矩形内布置这些单独的行。这是由 textAlignment
属性 控制的。默认是将每行对齐到该框的左侧:您也可以居中、右对齐或对齐(展开每行以填充框)。另一种思考方式是 textAlignment
仅控制每行文本 相对于其他文本行 .
另一方面,alignment
属性 定义标签内容(文本和图形)在标签本身内的对齐方式,如果有更多 space标签比文本占据。因此,要将标签居中放置在 VBox
中,您首先需要确保标签填满 VBox
的整个宽度,然后您需要将 alignment
属性 设置为 CENTER
。您可以通过设置标签的 maxWidth
使其无限增长,并将 VBox
的 fillWidth()
属性 设置为 true
来实现前者。
使用 Java 这看起来像
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-border-color:black;");
title.setPadding(new Insets(5));
title.setAlignment(Pos.CENTER);
title.setMaxWidth(Double.MAX_VALUE);
title.setTextAlignment(TextAlignment.CENTER);
VBox box = new VBox(title, panel);
box.setFillWidth(true);
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}
如果您愿意,可以在 CSS 中设置这些属性:
@Override
public void start(Stage primaryStage) throws Exception
{
TilePane panel = new TilePane();
panel.setTileAlignment(Pos.CENTER_LEFT);
for (int i = 0; i < 25; i++)
{
panel.getChildren().add(new Label(randomAlphabetic(10)));
}
Label title = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
title.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-wrap-text:true; -fx-border-color:black;"
+ "-fx-text-alignment: center; -fx-alignment: center; -fx-max-width:Infinity; -fx-padding: 5;");
VBox box = new VBox(title, panel);
box.setFillWidth(true); // or box.setStyle("-fx-fill-width: true ;")
box.setPadding(new Insets(10));
primaryStage.setScene(new Scene(box, 400, 400));
primaryStage.show();
}