JavaFX 如何在更改文本后强制 Label 更新其 prefWidth?
JavaFX how to force Label to update its prefWidth after changing the text?
其实很简单:我希望我的 Label
更新它的 prefWidth
以在文本发生变化时使文本适应自身。
最初 Label
的文本是 null
而 prefWidth
是 -1.0
没有手动设置。因此,当 Label
s 文本在运行时更改时,prefWidth 仍然是 -1.0
并且 Label
显示“...”而不是设置文本,因为它太小了。
Label
在 HBox
内。 HBox
s prefWidth
绑定到其子 prefWidth
s 的总和,并且 HBox
有足够的 space 增长。
这是一些要重现的代码:
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
box.prefWidthProperty().bind(label.prefWidthProperty().add(button.prefWidthProperty()));
window.setScene(new Scene(new StackPane(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
如何让 Label
更新其宽度以适合其文本?
编辑:场景的根是 StackPane
而不是 Pane
。
尝试在 min/pref/max 大小的窗格上使用绑定来执行布局从来都不是一个好主意。 HBox
已经知道如何计算其首选宽度,并且默认情况下完全按照您的要求进行(简单版本是将其计算为其子节点的首选宽度之和,但实际上它更复杂,因为它考虑了间距、填充等)。
控件和布局窗格的 prefWidth
默认值是标记值 Region.USE_COMPUTED_SIZE
,它只是一个标志,告诉节点计算其首选大小,以便向正在放置的任何人报告出来。标签将通过检查显示其文本(和图形)所需的大小来计算其首选大小,类似于按钮,布局窗格将检查其子节点的首选大小。 Region.USE_COMPUTED_SIZE
is -1.0
的实际值,这就是为什么您在调用 getPrefWidth()
.
时总是看到该值的原因
HBox
被展开以填充堆栈窗格的原因是因为这正是 StackPane
的行为。来自 docs:
The stackpane will attempt to resize each child to fill its content area.
您可以通过使用不具有该行为的不同根窗格来防止这种情况(例如普通 Pane
或另一个 HBox
等):
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
window.setScene(new Scene(new HBox(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
或者将您的 HBox
包裹在另一个窗格中(因此包裹它的窗格将填充 StackPane
,但您的 box
不会填充其父窗格):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
window.setScene(new Scene(new StackPane(new HBox(box))));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
或者强制 box
不超过其首选大小,将其 maxWidth
设置为使用首选大小:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
box.setMaxWidth(Region.USE_PREF_SIZE);
window.setScene(new Scene(new StackPane(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
您没有在问题中说明 为什么 您想要使用 StackPane
作为 HBox
的父项。由于 StackPane
的唯一功能是按 z 顺序将其子节点堆叠在一起,如果您使用堆叠窗格,您可能会在其顶部或后面添加其他节点。因此,实际上可能根本没有必要阻止 HBox
调整大小(因为它不会影响堆叠),但也许仅仅确保 HBox
的对齐 属性 就足够了](以及 StackPane
的其他子节点)设置为与 StackPane
相同(默认情况下居中)。 IE。你可能只需要 box.setAlignment(Pos.CENTER)
.
其实很简单:我希望我的 Label
更新它的 prefWidth
以在文本发生变化时使文本适应自身。
最初 Label
的文本是 null
而 prefWidth
是 -1.0
没有手动设置。因此,当 Label
s 文本在运行时更改时,prefWidth 仍然是 -1.0
并且 Label
显示“...”而不是设置文本,因为它太小了。
Label
在 HBox
内。 HBox
s prefWidth
绑定到其子 prefWidth
s 的总和,并且 HBox
有足够的 space 增长。
这是一些要重现的代码:
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
box.prefWidthProperty().bind(label.prefWidthProperty().add(button.prefWidthProperty()));
window.setScene(new Scene(new StackPane(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
如何让 Label
更新其宽度以适合其文本?
编辑:场景的根是 StackPane
而不是 Pane
。
尝试在 min/pref/max 大小的窗格上使用绑定来执行布局从来都不是一个好主意。 HBox
已经知道如何计算其首选宽度,并且默认情况下完全按照您的要求进行(简单版本是将其计算为其子节点的首选宽度之和,但实际上它更复杂,因为它考虑了间距、填充等)。
控件和布局窗格的 prefWidth
默认值是标记值 Region.USE_COMPUTED_SIZE
,它只是一个标志,告诉节点计算其首选大小,以便向正在放置的任何人报告出来。标签将通过检查显示其文本(和图形)所需的大小来计算其首选大小,类似于按钮,布局窗格将检查其子节点的首选大小。 Region.USE_COMPUTED_SIZE
is -1.0
的实际值,这就是为什么您在调用 getPrefWidth()
.
HBox
被展开以填充堆栈窗格的原因是因为这正是 StackPane
的行为。来自 docs:
The stackpane will attempt to resize each child to fill its content area.
您可以通过使用不具有该行为的不同根窗格来防止这种情况(例如普通 Pane
或另一个 HBox
等):
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
window.setScene(new Scene(new HBox(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
或者将您的 HBox
包裹在另一个窗格中(因此包裹它的窗格将填充 StackPane
,但您的 box
不会填充其父窗格):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
window.setScene(new Scene(new StackPane(new HBox(box))));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
或者强制 box
不超过其首选大小,将其 maxWidth
设置为使用首选大小:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Spielwiese extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
Label label = new Label();
Button button = new Button("Fill Label");
button.setOnAction(e -> label.setText("Some Text"));
HBox box = new HBox(label, button);
box.setMaxWidth(Region.USE_PREF_SIZE);
window.setScene(new Scene(new StackPane(box)));
window.setWidth(800);
window.setHeight(600);
window.show();
}
}
您没有在问题中说明 为什么 您想要使用 StackPane
作为 HBox
的父项。由于 StackPane
的唯一功能是按 z 顺序将其子节点堆叠在一起,如果您使用堆叠窗格,您可能会在其顶部或后面添加其他节点。因此,实际上可能根本没有必要阻止 HBox
调整大小(因为它不会影响堆叠),但也许仅仅确保 HBox
的对齐 属性 就足够了](以及 StackPane
的其他子节点)设置为与 StackPane
相同(默认情况下居中)。 IE。你可能只需要 box.setAlignment(Pos.CENTER)
.