【问题标题】:JavaFX Container Structure ScrollpaneJavaFX 容器结构滚动窗格
【发布时间】:2019-11-07 20:06:55
【问题描述】:

我的 GameBoard 所需的 GridPane(它应该包含我的模拟器地形所具有的“图块”数量)不适合 ScrollPane。

改变层次结构并使用彩色容器来识别问题无助于解决问题本身。

包含 GameBoard 的主容器 FXML


    <SplitPane dividerPositions="0.5" BorderPane.alignment="CENTER">
                    <items>
                        <AnchorPane>
                            <children>
                                <TextArea layoutX="1.0" layoutY="-14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                            </children>
                        </AnchorPane>
                      <ScrollPane prefWidth="800" prefHeight="500" hbarPolicy="ALWAYS" vbarPolicy="ALWAYS" >

                      <GameBoardCC fx:id="gameBoard" > 

                      </ScrollPane>
                    </items>
                </SplitPane>

自定义控件本身:


<fx:root xmlns:fx="http://javafx.com/fxml/1" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.221">

  <GridPane fx:id="gameBoard"
            style="-fx-background-color: green">
  </GridPane>

</fx:root>

基本上是添加这些项目的代码,我很确定我从 Stackoverflow 获得了大部分代码

 for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                // create node
                TerrainNode node = new TerrainNode ("Item " + i + "/" + j, i * 100, j *100, 100, 100);
                node.setOpacity (0.5);
                // add node to group
                gameBoard.getChildren ( ).add (node);
            }
        }

滑块行为的图片,出于某种原因,这些节点没有添加到网格窗格中,而是添加到网格窗格之外?

Pictures of the Slider Situation

我希望将滑块“卡”在 50%(尽管这不是我现在主要关心的问题),并且由于我的模拟应该具有可变的网格大小和固定的瓷砖尺寸,滚动条应该出现在例如 20x20 网格或将来客户端变得太小时。

【问题讨论】:

  • 能否提供Minimal, Reproducible Example。我对代码有点不清楚,因为您没有将列/行索引设置为节点。
  • link 目标是每次更改网格大小时都能创建新的网格窗格。每个网格元素都将由存储在 2D 数组中的值表示,但是一旦 GUI 工作正常,我会处理这个问题。
  • 修改translate 属性离开GridPane 认为不变的地方。您(可能)在这里所做的是将所有这些边界包含在(0,0)处的“单元格”中,然后仅调整渲染子项的位置。无论如何GridPane 通常负责分配职位本身。专注于获得正确的尺寸,使用GridPane.add(Node, int, int) 方法添加子代而不是getChildren().add(...) 并让GridPane 处理其余部分......顺便说一句:链接(或屏幕截图)不足以提供必要的代码。发布文本。
  • @fabian 非常感谢,这基本上是我必须做的唯一改变,使其行为相应。你有一个愉快的周末! :)

标签: java javafx fxml


【解决方案1】:

正如@fabian 指定的那样,让 GridPane 完成它的工作。 JavaFX 提供的每个布局窗格都有一个特定的功能。我建议您浏览不同类型的布局窗格并了解它们的基本用途。请参阅下图中的所有绿色框 :)

当然,您选择的布局(GridPane)是正确的。但执行不正确。 GridPane 根据提供的列/行索引对其子项进行布局。您不需要处理那里的布局定位。

下面是这个想法的简单示例:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import java.util.stream.Stream;

public class GameBoardDemo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        ToggleGroup tg = new ToggleGroup();
        RadioButton size1 = new RadioButton("5 X 5");
        RadioButton size2 = new RadioButton("5 X 10");
        RadioButton size3 = new RadioButton("10 X 10");
        RadioButton size4 = new RadioButton("10 X 15");
        RadioButton size5 = new RadioButton("15 X 15");
        Stream.of(size1, size2, size3, size4, size5).forEach(rb -> {
            rb.setToggleGroup(tg);
            rb.setId(rb.getText());
        });
        GridPane options = new GridPane();
        options.setHgap(10);
        options.addRow(0, size1, size2, size3, size4, size5);

        GridPane board = new GridPane();
        board.setPrefSize(800, 500);
        ScrollPane scrollBoard = new ScrollPane(board);
        VBox.setVgrow(scrollBoard, Priority.ALWAYS);

        tg.selectedToggleProperty().addListener((obs, old, val) -> {
            RadioButton rb = (RadioButton) val;
            double rows, columns;
            switch (rb.getText()) {
                case "5 X 5":
                    rows = 5;
                    columns = 5;
                    break;
                case "5 X 10":
                    rows = 5;
                    columns = 10;
                    break;
                case "10 X 10":
                    rows = 10;
                    columns = 10;
                    break;
                case "10 X 15":
                    rows = 10;
                    columns = 15;
                    break;
                default:
                    rows = 15;
                    columns = 15;
            }
            board.getChildren().clear();
            for (int rowIndex = 0; rowIndex < rows; rowIndex++) {
                for (int columnIndex = 0; columnIndex < columns; columnIndex++) {
                    Rectangle node = new Rectangle(100, 100);
                    node.setFill(Color.LIGHTBLUE);
                    node.setStroke(Color.BLACK);
                    StackPane terrainNode = new StackPane(node, new Label("Item " + rowIndex + "-" + columnIndex));
                    board.add(terrainNode, columnIndex, rowIndex);
                }
            }
        });
        VBox root = new VBox();
        root.setPadding(new Insets(10));
        root.setSpacing(15);
        root.getChildren().addAll(options, scrollBoard);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setTitle("BoardGame");
        primaryStage.show();
    }
}

【讨论】:

  • 非常感谢您的示例,您的图形确实帮助我理解了层次结构,现在在我完成逻辑后,它只是稍微调整了大小。周末愉快!!
猜你喜欢
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-06
相关资源
最近更新 更多