Sai*_*dem 5 javafx splitpane flowpane
如果内容具有多行 FlowPane,我会遇到 SplitPane 分隔符的问题。如果 FlowPane 在一行中呈现,则没有问题。如果 FlowPane 有多于一行,则内容部分会发生变化。
行数越多,移位越大。
为了演示这个问题,下面是一个快速演示。该演示包含三个垂直 splitPane,其中每个 SplitPane 都有不同编号的 FlowPane。行数。(第一个 splitPane - 1 行,第二个 SplitPane - 2 行,第三个 SplitPane - 3 行)
当使用 1 个 FlowPane 行调整 splitPane 大小时,没有问题,一切正常。然而,如果我调整第二个 splitPane 的大小,内容就会从所需的位置移动,从而在 SplitPane 中留下空白空间。当调整第三个 splitPane 的大小时,空间甚至更大。
我相信这应该是 SplitPane-FlowPane 计算中的一些问题(或者我也可能是错的)。但在这个阶段,我不是试图找出根本原因(这将在 JavaFX 源代码中的某个地方),而是更迫切地想通过一些解决方法来解决这个问题。
我尝试了几种方法,例如绑定高度、设置一些区域常量等,但都没有奏效。FlowPane的所有高度计算确实是正确的。
你们中的任何人对我如何解决这个问题有任何建议吗?
注意:该问题可以在所有版本的 JavaFX 中重现
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SuppressWarnings("javadoc")
public class SplitPaneDividerIssueDemo extends Application {
/**
* FlowPane for debugging purpose.
*/
class SimpleFlowPane extends FlowPane {
@Override
protected double computeMaxHeight(final double width) {
final double height = super.computeMaxHeight(width);
// Debugging the first FlowPane in each SplitPane
if (isFirst()) {
System.out.println("Computed max height for " + getId() + " :: " + height);
}
return height;
}
@Override
protected double computeMinHeight(final double width) {
final double height = super.computeMinHeight(width);
if (isFirst()) {
System.out.println("Computed min height for " + getId() + " :: " + height);
}
return height;
}
@Override
protected double computePrefHeight(final double width) {
final double height = super.computePrefHeight(width);
if (isFirst()) {
System.out.println("Computed pref height for " + getId() + " :: " + height);
}
return height;
}
private boolean isFirst() {
return getId().endsWith("-1");
}
}
private int splitId = 1;
private int flowId = 1;
public static void main(final String... a) {
Application.launch(a);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final HBox root = new HBox(buildSplitPane(10), buildSplitPane(20), buildSplitPane(30));
root.setSpacing(10);
final Scene scene = new Scene(root, 1250, 700);
primaryStage.setScene(scene);
primaryStage.setTitle("SplitPane Divider Issue");
primaryStage.show();
}
private VBox buildContent(final int count) {
final Button button = new Button("Button");
final FlowPane flowPane = new SimpleFlowPane();
flowPane.setId("flow-" + splitId + "-" + flowId);
flowPane.setVgap(5);
flowPane.setHgap(5);
for (int i = 0; i < count; i++) {
flowPane.getChildren().add(new Button("" + i));
}
final ScrollPane scroll = new ScrollPane();
VBox.setVgrow(scroll, Priority.ALWAYS);
final ToolBar toolBar = new ToolBar();
toolBar.getItems().add(new Button("Test"));
final VBox pane = new VBox();
pane.setPadding(new Insets(5));
pane.setSpacing(5);
pane.setStyle("-fx-background-color:yellow;-fx-border-width:1px;-fx-border-color:red;");
pane.getChildren().addAll(button, flowPane, scroll, toolBar);
pane.parentProperty().addListener((obs,old,content)->{
if(content!=null){
content.layoutYProperty().addListener((obs1,old1,layoutY)->{
System.out.println("LayoutY of content having "+flowPane.getId()+" :: "+layoutY);
});
}
});
flowId++;
return pane;
}
private SplitPane buildSplitPane(final int count) {
final SplitPane splitPane = new SplitPane();
splitPane.setStyle("-fx-background-color:green;");
splitPane.setOrientation(Orientation.VERTICAL);
splitPane.setDividerPositions(.36, .70);
splitPane.getItems().addAll(buildContent(count), buildContent(count), buildContent(count));
HBox.setHgrow(splitPane, Priority.ALWAYS);
splitId++;
flowId = 1;
return splitPane;
}
}
Run Code Online (Sandbox Code Playgroud)
问题出在 FlowPane 的 minHeight 内,因为它是水平方向的,使得 minHeight 非常动态。它的设计似乎是随着宽度的增长和缩小而改变 minHeight 的。根据文档,当您垂直压缩父级时,VBox 会将其 minHeight 计算为“顶部/底部插图加上每个子级的最小高度加上每个子级之间的间距之和”。显然存在一些问题,FlowPane 的父级无法解释其 minHeight。
HBox 将其 minHeight 计算为“顶部/底部插图加上最大的子项最小高度”。因此,如果将 FlowPane 包装在 HBox 中,则该 HBox minHeight 将绑定到 FlowPane 的高度,然后将该 HBox 放置在 FlowPane 应该所在的 VBox 中。
HBox flowPaneContainer = new HBox();
flowPaneContainer.getChildren().add(flowPane);
pane.getChildren().addAll(button, flowPaneContainer, scroll, toolBar);
Run Code Online (Sandbox Code Playgroud)
编辑:如果你的舞台尺寸是固定的,这很好。如果您的应用程序可调整大小,则需要做更多工作,因为 flowPane minHeight 将发生变化,从而更改 HBox minHeight,然后会导致相同的问题,因为每个 VBox 内的所有内容都没有足够的空间。
对于可调整大小的应用程序,我通常通过将 SplitPane 的每个部分包装在 ScrollPane 中来处理此问题。
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |