Javafx 在滚动窗格中使用TilePane的响应式UI设计
我正试图在Scroll-and-Tilepanes atm机上绞尽脑汁,我遇到了一个问题,如果没有一个肮脏的黑客,我是无法解决的 我有一个有8个平铺的水平平铺面板,我将其设置为有4列,结果是有4个平铺的2行。 我把那块瓷砖放在一个HBox里,因为如果我把它放在一个堆叠窗格里,它会拉伸瓷砖的大小,使我的立柱设置无效。有点奇怪,设置prefColumns/Rows会重新计算TilePane的大小,而不是试图设置实际的列/行数量,这更像是一个肮脏的黑客行为 无论如何,将HBox直接放入ScrollPane也不会起作用,因为即使在第二行分幅被切断后,滚动条也不会出现。在Stackpane中再次设置HBox,然后将其放在滚动窗格中。至少在我将窗口的宽度调整为如此之小之前,瓷砖面板必须重新对齐瓷砖,并显示第三行或更多行 以下是基本程序:Javafx 在滚动窗格中使用TilePane的响应式UI设计,javafx,javafx-2,javafx-8,scrollpane,Javafx,Javafx 2,Javafx 8,Scrollpane,我正试图在Scroll-and-Tilepanes atm机上绞尽脑汁,我遇到了一个问题,如果没有一个肮脏的黑客,我是无法解决的 我有一个有8个平铺的水平平铺面板,我将其设置为有4列,结果是有4个平铺的2行。 我把那块瓷砖放在一个HBox里,因为如果我把它放在一个堆叠窗格里,它会拉伸瓷砖的大小,使我的立柱设置无效。有点奇怪,设置prefColumns/Rows会重新计算TilePane的大小,而不是试图设置实际的列/行数量,这更像是一个肮脏的黑客行为 无论如何,将HBox直接放入ScrollPa
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类主扩展应用程序{
@凌驾
公众假期开始(阶段){
TilePane TilePane=新的TilePane();
tilePane.setPadding(新插图(5));
tilePane.setVgap(4);
tilePane.setHgap(4);
tilePane.setpref列(4);
tilePane.setStyle(“-fx背景色:浅蓝色;”);
HBox贴片[]=新HBox[8];
对于(int i=0;i<8;i++){
tiles[i]=新的HBox(新标签(“这是节点#“+i));
平铺[i].setStyle(“-fx边框颜色:黑色;”);
瓷砖[i]。设置填充(新插图(50));
tilePane.getChildren().add(tiles[i]);
}
HBox HBox=新的HBox();
hbox.设置校准(位置中心);
hbox.setStyle(“-fx背景色:蓝色;”);
hbox.getChildren().add(tilePane);
StackPane stack=新的StackPane();
stack.getChildren().add(hbox);
ScrollPane sp=新的ScrollPane();
sp.setFitToHeight(真);
sp.setFitToWidth(真);
sp.setContent(堆栈);
舞台场景(新场景(sp,800600));
stage.show();
}
公共静态void main(字符串[]args){
发射();
}
}
我设法实现了我想要的行为,但这更像是一个肮脏的黑客行为。我在包含TilePane的HBox的高度和宽度中添加了一个侦听器,并假设当高度改变时,由于宽度变小,一列被删除,一个新行被添加。为了做到这一点,我将HBox放在VBox中,这样它就不会随着滚动窗格的高度而增长。对于宽度,我只是简单地计算了是否有空间显示另一个柱(最多4个),以便执行此操作
以下是变化:
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();
}
}
public类主扩展应用程序{
私有布尔值非第一通行高度;
私有布尔notFirstPassWidth;
@凌驾
公众假期开始(阶段){
TilePane TilePane=新的TilePane();
tilePane.setPadding(新插图(5));
tilePane.setVgap(4);
tilePane.setHgap(4);
tilePane.setpref列(4);
tilePane.setStyle(“-fx背景色:浅蓝色;”);
//我从ScenicView中获取了值
tilePane.prefTileWidthProperty().set(182);
HBox贴片[]=新HBox[8];
对于(int i=0;i<8;i++){
tiles[i]=新的HBox(新标签(“这是节点#“+i));
平铺[i].setStyle(“-fx边框颜色:黑色;”);
瓷砖[i]。设置填充(新插图(50));
tilePane.getChildren().add(tiles[i]);
}
ScrollPane sp=新的ScrollPane();
sp.setFitToHeight(真);
sp.setFitToWidth(真);
StackPane stack=新的StackPane();
VBox VBox=新的VBox();
vbox.setStyle(“-fx背景色:红色”);
HBox HBox=新的HBox();
hbox.设置校准(位置中心);
hbox.setStyle(“-fx背景色:蓝色;”);
hbox.getChildren().add(tilePane);
notFirstPassHeight=false;
notFirstPassWidth=false;
hbox.heightProperty().addListener((可观察、旧值、新值)->{
if(oldValue.doubleValue(){
if(oldValue.doubleValue()
然而,这种方法要求我
1.了解瓷砖面板中瓷砖的宽度
2.考虑我计算中的瓦片填充和间隙是准确的,这在我的例子中不适用。
如果你问我的话,至少这不是一个好方法。对于这样一件基本的事情来说,这个过程太复杂了。必须有一种更好、更简单的方法来实现滚动窗格中TilePane的完全可调整性和所需行为。在
TilePane
中设置首选列数和/或行数决定了该平铺窗格的prefWidth
和prefHeight
值的计算。如果要强制最大列数,只需使maxWidth
等于计算的prefWidth
:您可以使用
tilePane.setMaxWidth(Region.USE_PREF_SIZE);
这意味着(只要平铺窗格位于管理布局的位置)
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();
}
}