当前位置: 首页 > 知识库问答 >
问题:

响应式UI-在滚动窗格中使用TilePane进行设计

终安和
2023-03-14

我正试图缠绕我的头卷轴-和铁板atm机,我遇到了一个问题,我只是不能解决没有一个肮脏的黑客。

我有一个水平的TilePane有8个瓷砖,我将它设置为有4列,结果是有4个瓷砖的2行。我放入了一个HBox,因为如果我把它放入一个StackPane中,它会拉伸TilePane的大小,使我的colum设置无效。有点奇怪的是,设置PrefColumns/Rows会重新计算TilePane的大小,而不是尝试设置列/行的实际数量,感觉更像是一个肮脏的黑客。

无论如何,将HBox直接放入滚动窗格也不会起作用,因为即使在第二行瓷砖被切断后滚动条也不会出现。在Stackpane中再次设置HBox,然后我将其放入ScrollPane中,这就完成了任务。至少在我将窗口的宽度调整到很小之前,tilepane必须重新对齐瓷砖,并且出现第三行或更多行。

下面是基本程序:

public class Main extends Application {

    @Override
    public void start(Stage stage) {

        TilePane tilePane = new TilePane();
        tilePane.setPadding(new Insets(5));
        tilePane.setVgap(4);
        tilePane.setHgap(4);
        tilePane.setPrefColumns(4);
        tilePane.setStyle("-fx-background-color: lightblue;");

        HBox tiles[] = new HBox[8];
        for (int i = 0; i < 8; i++) {
            tiles[i] = new HBox(new Label("This is node #" + i));
            tiles[i].setStyle("-fx-border-color: black;");
            tiles[i].setPadding(new Insets(50));
            tilePane.getChildren().add(tiles[i]);
        }

        HBox hbox = new HBox();
        hbox.setAlignment(Pos.CENTER);
        hbox.setStyle("-fx-background-color: blue;");
        hbox.getChildren().add(tilePane); 

        StackPane stack = new StackPane();
        stack.getChildren().add(hbox);

        ScrollPane sp = new ScrollPane();
        sp.setFitToHeight(true);
        sp.setFitToWidth(true);
        sp.setContent(stack);

        stage.setScene(new Scene(sp, 800, 600));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
public class Main extends Application {

    private boolean notFirstPassHeight;
    private boolean notFirstPassWidth;

    @Override
    public void start(Stage stage) {

        TilePane tilePane = new TilePane();
        tilePane.setPadding(new Insets(5));
        tilePane.setVgap(4);
        tilePane.setHgap(4);
        tilePane.setPrefColumns(4);
        tilePane.setStyle("-fx-background-color: lightblue;");
        // I took the value from ScenicView
        tilePane.prefTileWidthProperty().set(182);

        HBox tiles[] = new HBox[8];
        for (int i = 0; i < 8; i++) {
            tiles[i] = new HBox(new Label("This is node #" + i));
            tiles[i].setStyle("-fx-border-color: black;");
            tiles[i].setPadding(new Insets(50));
            tilePane.getChildren().add(tiles[i]);
        }

        ScrollPane sp = new ScrollPane();
        sp.setFitToHeight(true);
        sp.setFitToWidth(true);

        StackPane stack = new StackPane();

        VBox vbox = new VBox();
        vbox.setStyle("-fx-background-color: red");

        HBox hbox = new HBox();
        hbox.setAlignment(Pos.CENTER);
        hbox.setStyle("-fx-background-color: blue;");
        hbox.getChildren().add(tilePane);

        notFirstPassHeight = false;
        notFirstPassWidth = false;
        hbox.heightProperty().addListener((observable, oldValue, newValue) -> {
            if (oldValue.doubleValue() < newValue.doubleValue() && notFirstPassHeight) {
                tilePane.setPrefColumns(tilePane.getPrefColumns() - 1);
                stack.requestLayout();
            }
            notFirstPassHeight = true;
        });
        hbox.widthProperty().addListener((observable, oldValue, newValue) -> {
             if (oldValue.doubleValue() < newValue.doubleValue() && notFirstPassWidth && tilePane.getPrefColumns() <= 3
                     && (newValue.doubleValue() / (tilePane.getPrefColumns() + 1)) > tilePane.getPrefTileWidth()) {
                 tilePane.setPrefColumns(tilePane.getPrefColumns() + 1);
                 stack.requestLayout();
             }
             notFirstPassWidth = true;
        });

        vbox.getChildren().add(hbox);

        stack.getChildren().add(vbox);

        sp.setContent(stack);
        stage.setScene(new Scene(sp, 800, 600));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

如果你问我的话,这不是一个好方法。对于这么基本的东西来说太复杂的过程了。必须有一种更好、更简单的方法来实现滚动窗格中的TilePanes的完全可调整大小和所需的行为。

共有1个答案

后安民
2023-03-14

TilePane中设置首选列和/或行数将确定该平铺窗格的PrefWidtheightPrefHeight值的计算。如果要强制设置最大列数,只需使maxwidth等于计算的prefwidth:可以使用

tilePane.setMaxWidth(Region.USE_PREF_SIZE);

这意味着(只要将平铺窗格放置在管理布局的东西中),它就永远不会比pref宽度宽,计算pref宽度是为了允许首选的列数。当然,它可能比这个小。(注意,如果需要最小的列数,而不是最大的列数,则可以在setminwidth中使用相同的技巧。)

滚动窗格的FittoHeightFittoWidty属性在为true时将尝试调整内容的高度(分别为宽度),使其与滚动窗格视口的高度(宽度)相等。这些操作将优先于内容的首选高度(宽度),但将尝试尊重最小高度(宽度)。

我认为您的原始代码的以下版本基本上完成了您所要寻找的内容:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.TilePane;
import javafx.stage.Stage;

public class ScrollingTilePane extends Application {

    @Override
    public void start(Stage stage) {

        TilePane tilePane = new TilePane();
        tilePane.setPadding(new Insets(5));
        tilePane.setVgap(4);
        tilePane.setHgap(4);
        tilePane.setPrefColumns(4);
        tilePane.setStyle("-fx-background-color: lightblue;");

        // dont grow more than the preferred number of columns:
        tilePane.setMaxWidth(Region.USE_PREF_SIZE);

        HBox tiles[] = new HBox[8];
        for (int i = 0; i < 8; i++) {
            tiles[i] = new HBox(new Label("This is node #" + i));
            tiles[i].setStyle("-fx-border-color: black;");
            tiles[i].setPadding(new Insets(50));
            tilePane.getChildren().add(tiles[i]);
        }

        HBox hbox = new HBox();
        hbox.setAlignment(Pos.CENTER);
        hbox.setStyle("-fx-background-color: blue;");
        hbox.getChildren().add(tilePane); 

//        StackPane stack = new StackPane();
//        stack.getChildren().add(tilePane);
//        stack.setStyle("-fx-background-color: blue;");

        ScrollPane sp = new ScrollPane();
//        sp.setFitToHeight(true);
        sp.setFitToWidth(true);
        sp.setContent(hbox);

        stage.setScene(new Scene(sp, 800, 600));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

注意,如果需要更改滚动窗格内容外部空间的背景颜色,可以在外部样式表中使用以下内容:

css prettyprint-override">.scroll-pane .viewport {
  -fx-background-color: red ;
}
 类似资料:
  • 基于此注释https://stackoverflow.com/a/29530135/1387524,我添加了一个ScrollPane,以便在画布移到可见区域之外时使用滚动。

  • 问题我如何可以嵌入这个应用程序到SPlitPane,在左边将是另一个面板。 不幸的是,代码导致了错误的坐标,

  • 问题内容: 我在DotNetNuke的项目中使用了twitter bootstrap。我使用HTML,CSS,引导程序进行了设计和布局。当我在不同的移动设备上进行测试时,即使我调整浏览器窗口的大小,响应式设计也能正常工作。 由于运行良好,我将设计转换为DotNetNuke Skin。现在,仅当我调整浏览器窗口的大小而不是在移动设备上时,自适应设计才能正常工作。我了解DNN加载样式表的流程,并且已经

  • 嗨,伙计们,我要用这个拔头发了。 我不能让日期选择器JQUERY UI控件响应任何事情,上面的代码显示了警报,但无论我设置了什么值,日期选择器都只是默认设置。在下面的代码中,我只显示了一个月,并且没有设置默认日期: 作为最后一次尝试,我刚刚升级了JQUERY版本,但还是一样,没有什么区别。在我的应用程序中,我用datepicker设置值,它被广泛使用,一切都很好。这是我第一次需要对控件实例进行任何

  • 我希望能够向下滚动动态生成的电影列表。我尝试添加滚动窗格。 我在页面的开头有一个导航栏,中间有一个包含所有电影的jpanel。 您可以使用以下代码重新创建此示例: 我想做的是用我的鼠标滚轮向下滚动这个电影列表,而不看任何滚动条。它现在看起来应该和现在一模一样,但我希望能够向下滚动,看到所有的电影。 我不知道为什么它不起作用,这就是为什么我在这里问,希望有人能向我解释我做错了什么。

  • 如果我将单词换行设置为标签,并将其放在任何布局中--除非我将标签放在滚动窗格中,否则单词换行很好。下面是一个例子: 有什么方法可以使文字包装工作在滚动窗格?