Сетка GanePane с пробелами внутри ScrollPane отображается неправильно - PullRequest
0 голосов
/ 23 мая 2018

Я хочу иметь прямоугольную сетку с квадратными ячейками, которую можно увеличивать и масштабировать (как на карте).Поэтому я поместил его в ScrollPane, хотя он ведет себя довольно странно при определенных размерах.Размер сетки будет меняться динамически.

На картинке изображена сетка размером 20х20.Grid of size 20x20

  1. Не все пробелы показаны внутри сетки. Обратите внимание, что это должно быть 20 квадратов, но это не так.Значение Vgap и Hgap равно 1.
  2. Сама сетка больше, чем содержимое , что нехорошо, поскольку при ее увеличении я могу перетащить за пределы сетки.
  3. Я бы хотел центрировать GridPane внутри ScrollPane , когда он меньше, чем область прокрутки.(Gridpane alignment="CENTER" явно ничего не делает)

Пример минимального, завершенного и проверяемого

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.GridPane?>

<ScrollPane hbarPolicy="NEVER" hvalue="0.5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" pannable="true" prefHeight="400.0" prefWidth="600.0" vbarPolicy="NEVER" vvalue="0.5" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="bug.app.Bug">
    <GridPane fx:id="gridPane" alignment="CENTER" hgap="1.0" style="-fx-background-color: red;" vgap="1.0">
    </GridPane>
</ScrollPane>

Controller + Main:

package bug.app;

import javafx.application.Application;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Bug extends Application {
    private static final int HEIGHT = 20;
    private static final int WIDTH = 20;
    private static final double MIN_CELL_SIZE = 2;
    @FXML private GridPane gridPane;
    private DoubleProperty zoomRatio = new SimpleDoubleProperty(5);

    @FXML
    private void initialize() {
        final DoubleBinding cellSizeBinding = zoomRatio.multiply(MIN_CELL_SIZE);

        List<Node> cells = new ArrayList<>(HEIGHT * WIDTH);
        for (int row = 0; row < HEIGHT; row++) {
            for (int col = 0; col < WIDTH; col++) {
                final Pane cell = new Pane();
                cell.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY)));

                cell.setMinSize(MIN_CELL_SIZE, MIN_CELL_SIZE);
                cell.setMaxWidth(Region.USE_PREF_SIZE);
                cell.setMaxHeight(Region.USE_PREF_SIZE);
                cell.prefWidthProperty().bind(cellSizeBinding);
                cell.prefHeightProperty().bind(cellSizeBinding);

                GridPane.setConstraints(cell, col, row, 1, 1);

                cells.add(cell);
            }
        }
        gridPane.getChildren().clear();
        gridPane.getChildren().addAll(cells);
    }

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

    @Override
    public void start(Stage primaryStage) throws IOException {
        Parent root = FXMLLoader.load(
                getClass().getResource("/view/bugView.fxml"));
        final Scene scene = new Scene(root, 600, 400);

        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

NB: Я выбрал панель в качестве ячейки, потому что хочу разделить ее на подклассы и в конечном итоге заполнить ее (возможно, фигурами?) Разными цветами, разделив квадрат на1-4 части.Представьте себе два или четыре треугольника, образующих квадрат.Я также хотел бы изменить это элегантно (AFAIK Shapes не изменяемого размера), возможно, каким-то образом привязка размера внутренних Shapes к размеру Panes сделает волшебство.Я еще не так далеко, но не стесняйтесь давать советы и по этому вопросу.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Проблемы 1 и 2

Я нашел обходной путь для проблем 1. и 2. с пропуском Vgap и Hgap, потому что, очевидно, он глючит.

Вместо использования свойства gap GridPane я устанавливаю поле для каждой ячейки:

GridPane.setMargin(cell, new Insets(0.5));

Однако это округляет поле до 1 из-за значения по умолчанию snapToPixel="true" в GridPane и, таким образом, приводит кпробелы 2px.Это неудобно, потому что я хочу, чтобы квадраты были размером 2x2px, поэтому разрыв в 2px слишком велик.Я, вероятно, установлю snapToPixel на false на GridPane.Требуется дополнительное тестирование.

Задача 3

Я попытался обернуть GridPane в StackPane, как предложено @Silas Gyeme.

Просто обернуть его в StackPane не удалосьдостаточно. Мне нужно было установить оба значения fitToHeight="true" & fitToWidth="true" на ScrollPane.

Также пришлось привязать minSize ячейки к cellSizeBinding, потому что он уменьшал размеры квадратов, когда я уменьшал окно меньше.

cell.minWidthProperty().bind(cellSizeBinding);
cell.minHeightProperty().bind(cellSizeBinding);

РЕДАКТИРОВАТЬ: Я попытался опустить StackPane, и на самом деле он мне не нужен!Достаточно только установить fitToHeight и fitToWidth, GridPane будет хорошо растягиваться.

0 голосов
/ 23 мая 2018

оборачивает область сетки внутри области стека, это будет центрировать область сетки

...