最好使用:
标头的固定宽度,并使用省略号截断长标题?pad带有空间的较短标题与均匀的长度相匹配?
package dynamicDialogWidthExample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class DynamicDialogFixedWidthExample extends Application {
@Override
public void start(Stage primaryStage) {
// === Create Header (Top Section) ===
Label headerLabel = new Label("This is a Title");
headerLabel.setStyle("-fx-font-size: 16px; -fx-background-color: lightblue; -fx-padding: 10;");
// === Create a Text Object to Dynamically Measure Header Width ===
Text textMeasure = new Text(headerLabel.getText());
textMeasure.setStyle(headerLabel.getStyle());
// === Create Center (Content Section) ===
Label centerContent = new Label("Centered Content Goes Here");
centerContent.setStyle("-fx-font-size: 14px; -fx-background-color: lightgray; -fx-padding: 20;");
// === Create Footer (Bottom Section) ===
Label footerLabel = new Label("Footer");
footerLabel.setStyle("-fx-font-size: 14px; -fx-background-color: lightgreen; -fx-padding: 10;");
// === Assemble BorderPane ===
BorderPane borderPane = new BorderPane();
borderPane.setTop(headerLabel);
borderPane.setCenter(centerContent);
borderPane.setBottom(footerLabel);
// === AnchorPane to Embed BorderPane ===
AnchorPane rootAnchorPane = new AnchorPane();
rootAnchorPane.getChildren().add(borderPane);
// Anchor the BorderPane to all sides
AnchorPane.setTopAnchor(borderPane, 0.0);
AnchorPane.setBottomAnchor(borderPane, 0.0);
AnchorPane.setLeftAnchor(borderPane, 0.0);
AnchorPane.setRightAnchor(borderPane, 0.0);
// === Wrap Everything in a StackPane to Center ===
StackPane wrapperStackPane = new StackPane(rootAnchorPane);
wrapperStackPane.setStyle("-fx-background-color: #f0f0f0;");
// === Set Scene ===
Scene scene = new Scene(wrapperStackPane);
primaryStage.setScene(scene);
// === Adjust Width Dynamically ===
headerLabel.textProperty().addListener((observable, oldText, newText) -> {
textMeasure.setText(newText);
double computedWidth = textMeasure.getBoundsInLocal().getWidth() + 50; // Add padding
// Adjust both the BorderPane and Stage width
borderPane.setPrefWidth(computedWidth);
primaryStage.setWidth(computedWidth + 50); // Extra padding to prevent cutoff
});
// === Simulate Header Text Change for Testing ===
scene.setOnMouseClicked(event -> {
if (headerLabel.getText().equals("This is a Title")) {
headerLabel.setText("Short");
} else if (headerLabel.getText().equals("Short")) {
headerLabel.setText("An Extremely Long Header Title for Testing");
} else {
headerLabel.setText("This is a Title");
}
});
// === Set Stage Properties ===
primaryStage.setTitle("Dynamic Width Dialog Example");
primaryStage.show();
// === Ensure Initial Width Matches Title ===
textMeasure.setText(headerLabel.getText());
double initialWidth = textMeasure.getBoundsInLocal().getWidth() + 50;
borderPane.setPrefWidth(initialWidth);
primaryStage.setWidth(initialWidth + 50);
}
public static void main(String[] args) {
launch(args);
}
}
主布局类是一个。 由于某种原因,将
Label
中并锚定在
BorderPane
的每一侧。 BorderPane
中没有其他孩子。 以这种方式使用的
AnchorPane
不会为布局添加任何功能,并可能抑制封闭式AnchorPane
AnchorPane
的某些正常行为。next,锚固式锚定在stackpane中,并评论“居中”。 但是目前尚不清楚这是什么作用,因为代码的其余部分都试图将
AnchorPane
保持在基于BorderPane
的大小的大小。 因此,居中不应该是一个问题。
最终,原始代码使用的内容与
BorderPane/AnchorPane/StackPane
的内容相同,以重新计算布局所需的大小。 对于此问题来说,这通常不是一个好的/可靠的方法,您会更好地在涉及的节点的维度属性上使用绑定。从事我在Linux上调整场景/舞台/窗口的问题,所以我只是将它们放在它们的初始尺寸上,并在场景中应用了独特的颜色,因此很明显它是空的。
纯化,转换为kotlin,与原始代码相当的粗略看起来如下:
Stage
您可以看到,现在的布局实际上很简单,只有14行。 现在,通过将其值绑定到Label
。
跑步时,看起来像这样。
Text
的原始值使窗口很宽:如果目标是将布局的布局放在一个大小上,该布局足够大,以便于最长的标签,并且要保持尺寸,那么可以创建许多标签并将其放入stackpane中,一次只能通过操纵他们的
Label
属性:
class ConsistentWidth : Application() {
override fun start(primaryStage: Stage) {
val headerText : StringProperty = SimpleStringProperty("This is a Title oetahutnsaoehuaoeust aoestuhoesusau nst ueoatnshuaoesual")
val borderPane = BorderPane().apply {
top = Label().apply {
textProperty().bind(headerText)
style = "-fx-font-size: 16px; -fx-background-color: lightblue; -fx-padding: 10;"
widthProperty().subscribe { _ -> [email protected]() }
}
center = Label("Centered Content Goes Here").apply {
style = "-fx-font-size: 14px; -fx-background-color: lightgray; -fx-padding: 20;"
}
bottom = Label("Footer").apply {
style = "-fx-font-size: 14px; -fx-background-color: lightgreen; -fx-padding: 10;"
}
style = "-fx-font-size: 14px; -fx-background-color: pink; -fx-padding: 10;"
autosize()
}
primaryStage.title = "Dynamic Width Dialog Example"
primaryStage.show()
val scene = Scene(borderPane, Color.AQUA)
primaryStage.scene = scene.apply {
onMouseClicked = EventHandler {
if (headerText.value == "This is a Title") {
headerText.value = "Short"
borderPane.autosize()
} else if (headerText.value == "Short") {
headerText.value = "An Extremely Long Header Title for Testing"
borderPane.autosize()
} else {
headerText.value = "This is a Title"
borderPane.autosize()
}
}
}
}
}
fun main() {
Application.launch(ConsistentWidth::class.java)
}
herethe
Label
填充了一个
BorderPane.top
,然后用三个
StringProperty
填充了,每个StringProperty
都通过映射绑定到visible
,class ConsistentWidth : Application() {
override fun start(primaryStage: Stage) {
val whichLabel: IntegerProperty = SimpleIntegerProperty(0)
val borderPane = BorderPane().apply {
top = StackPane().apply {
children += Label("This is a Title").apply {
visibleProperty().bind(whichLabel.map { it == 0 })
style = "-fx-font-size: 16px; -fx-background-color: lightblue; -fx-padding: 10;"
}
children += Label("Short").apply {
visibleProperty().bind(whichLabel.map { it == 1 })
style = "-fx-font-size: 16px; -fx-background-color: lightblue; -fx-padding: 10;"
}
children += Label("An Extremely Long Header Title for Testing").apply {
visibleProperty().bind(whichLabel.map { it == 2 })
style = "-fx-font-size: 16px; -fx-background-color: lightblue; -fx-padding: 10;"
}
alignment = Pos.CENTER_LEFT
}
center = Label("Centered Content Goes Here").apply {
style = "-fx-font-size: 14px; -fx-background-color: lightgray; -fx-padding: 20;"
}
bottom = Label("Footer").apply {
style = "-fx-font-size: 14px; -fx-background-color: lightgreen; -fx-padding: 10;"
}
style = "-fx-font-size: 14px; -fx-background-color: pink; -fx-padding: 10;"
autosize()
}
primaryStage.title = "Dynamic Width Dialog Example"
primaryStage.show()
val scene = Scene(borderPane, Color.AQUA)
primaryStage.scene = scene.apply {
onMouseClicked = EventHandler {
val nextNum = if (whichLabel.value < 2) {whichLabel.value + 1} else 0
whichLabel.value = nextNum
}
}
}
}
fun main() {
Application.launch(ConsistentWidth::class.java)
}
,
BorderPane.top
.。
点击动作现在只需循环浏览0..2 inStackPane
.。
Labels
,因此布局管理器将继续为他们创造空间,即使它们不可见。 这可以确保窗户足够宽,以达到最长的
visible
。
看起来像这样:和此:
这实现了效果,而无需直接操纵布局的大小。