如何确保具有不同标题长度的Javafx对话框的标头宽度?

问题描述 投票:0回答:1

最好使用:

标头的固定宽度,并使用省略号截断长标题?

pad带有空间的较短标题与均匀的长度相匹配?

    其他推荐技术以确保一致性? 我将感谢在Javafx中解决此问题的任何指导,示例或最佳实践。
  1. 运行示例:
  2. 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); } }
  3. 上述输出:

enter image description here

enter image description here

我们必须推断OP希望拥有@james_d建议的内容。 为了使窗口使用适合最宽的标头文本的宽度,然后将其保持在该尺寸的宽度,而不管显示如何。 但是,这直接与所提供的示例代码相矛盾,该代码根据当前值的长度显式地大小。 它花费了大量的努力来做到这一点,这使得OP的要求降低了。 enter image description here在查看解决方案之前,最好解决原始代码的某些问题...

主布局类是一个。 由于某种原因,将
javafx
1个回答
0
投票
放入一个

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 inStackPaneOriginal code operation.

最重要的是,每个them的属性仍然设置为

Labels

,因此布局管理器将继续为他们创造空间,即使它们不可见。  这可以确保窗户足够宽,以达到最长的
visible

。 看起来像这样:

和此:

这实现了效果,而无需直接操纵布局的大小。
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.