Создание редактируемой (раскрашиваемой) сетки в JavaFX

В настоящее время существует 2 набора сеток. первый gridset представляет собой сетку 5x4 с изображениями карты. Кроме того, есть сетка, в которой есть все маленькие плитки для каждого из ячеек сетки 5x4.

Пример изображения сетки

Поэтому мне нужно иметь большие изображения в сетке 5x4 с мини-плитками 16x16 внутри каждой из этих плиток, и каждая мини-плитка должна быть раскрашиваемой (или иметь изображения) над основным изображением, которое существует на больших акрах.

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

<?import java.lang.String?>
<?import java.net.URL?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.StackPane?>

<BorderPane id="mainPane" fx:id="editorPane" prefHeight="500.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/null" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.michaelgatesdev.OldLeaf.gui.controllers.tabs.TabMapEditorController">

    <stylesheets>
        <URL value="@../../css/tabs/TabMapEditor.css"/>
        <URL value="@../../css/Flat.css"/>
        <URL value="@../../css/FlatColors.css"/>
    </stylesheets>

    <center>
        <ScrollPane id="map-editor-grid-container" fx:id="gridContainer" fitToHeight="true" fitToWidth="true" nodeOrientation="LEFT_TO_RIGHT" styleClass="content-pane">
            <content>
                <StackPane fx:id="stackPane">
                    <children>
                        <GridPane id="map-editor-grid-acres" fx:id="gridAcres">
                            <columnConstraints>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="192.0" minWidth="192.0" prefWidth="192.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="192.0" minWidth="192.0" prefWidth="192.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="192.0" minWidth="192.0" prefWidth="192.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="192.0" minWidth="192.0" prefWidth="192.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="192.0" minWidth="192.0" prefWidth="192.0"/>
                            </columnConstraints>
                            <rowConstraints>
                                <RowConstraints maxHeight="192.0" minHeight="192.0" prefHeight="192.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="192.0" minHeight="192.0" prefHeight="192.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="192.0" minHeight="192.0" prefHeight="192.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="192.0" minHeight="192.0" prefHeight="192.0" vgrow="ALWAYS"/>
                            </rowConstraints>
                        </GridPane>
                        <GridPane id="map-editor-grid-tiles" fx:id="gridTiles">
                            <columnConstraints>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                                <ColumnConstraints hgrow="ALWAYS" maxWidth="12.0" minWidth="12.0" prefWidth="12.0"/>
                            </columnConstraints>
                            <rowConstraints>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                                <RowConstraints maxHeight="12.0" minHeight="12.0" prefHeight="12.0" vgrow="ALWAYS"/>
                            </rowConstraints>
                        </GridPane>
                    </children>
                </StackPane>
            </content>
        </ScrollPane>
    </center>
    <left>
        <AnchorPane id="map-editor-tools-container" fx:id="toolsPane" prefHeight="200.0" prefWidth="200.0" styleClass="content-pane" BorderPane.alignment="CENTER">
            <children>
                <HBox id="map-editor-tools-search-pane" fx:id="toolsSearchPane" alignment="CENTER" prefHeight="50.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="00.0">
                    <children>
                        <ComboBox id="map-editor-tools-search" fx:id="toolsSearch" editable="true" prefHeight="25.0" prefWidth="185.0" promptText="Search.." styleClass="flat-combo-box"/>
                    </children>
                </HBox>
                <ScrollPane id="map-editor-tools-list-pane" fx:id="toolsListPane" fitToHeight="true" fitToWidth="true" prefHeight="328.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
                    <content>
                        <Accordion id="map-editor-tools-accordion" fx:id="toolsAccordion" prefWidth="185.0" styleClass="flat-accordion">
                            <panes>
                                <TitledPane animated="true" text="Empty">
                                    <content>
                                        <ListView prefHeight="200.0" prefWidth="200.0">
                                            <items>
                                                <FXCollections fx:factory="observableArrayList">
                                                    <String fx:value="Blank (0x00)"/>
                                                </FXCollections>
                                            </items>
                                        </ListView>
                                    </content>
                                </TitledPane>
                            </panes>
                        </Accordion>
                    </content>
                </ScrollPane>
            </children>
        </AnchorPane>
    </left>
</BorderPane>

Как видите, FXML очень запутанный и в целом кажется ненужным.

Итак, мой вопрос: Как я могу нарисовать все это, используя как можно меньше сеток или вообще не используя их, и в то же время предоставляя мне доступ к плиткам сетки (столбцам, строкам, данным и т. д.) через какой-либо удобный компонент bean?< /сильный>


person Michael Gates    schedule 02.04.2016    source источник


Ответы (2)


Создайте собственный компонент раскрашиваемой сетки и наложите его на изображения.

Код

Main.java

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    boolean showHoverCursor = true;

    int rows = 15;
    int columns = 20;
    double width = 800;
    double height = 600;

    ImageView imageView = new ImageView( new Image( "https://upload.wikimedia.org/wikipedia/commons/c/c7/Pink_Cat_2.jpg"));


    @Override
    public void start(Stage primaryStage) {
        try {
            StackPane root = new StackPane();

            // create grid
            Grid grid = new Grid( columns, rows, width, height);

            MouseGestures mg = new MouseGestures();

            // fill grid
            for (int row = 0; row < rows; row++) {
                for (int column = 0; column < columns; column++) {

                    Cell cell = new Cell(column, row);

                    mg.makePaintable(cell);

                    grid.add(cell, column, row);
                }
            }

            root.getChildren().addAll(imageView, grid);

            // create scene and stage
            Scene scene = new Scene(root, width, height);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();



        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    private class Grid extends Pane {

        int rows;
        int columns;

        double width;
        double height;

        Cell[][] cells;

        public Grid( int columns, int rows, double width, double height) {

            this.columns = columns;
            this.rows = rows;
            this.width = width;
            this.height = height;

            cells = new Cell[rows][columns];

        }

        /**
         * Add cell to array and to the UI.
         */
        public void add(Cell cell, int column, int row) {

            cells[row][column] = cell;

            double w = width / columns;
            double h = height / rows;
            double x = w * column;
            double y = h * row;

            cell.setLayoutX(x);
            cell.setLayoutY(y);
            cell.setPrefWidth(w);
            cell.setPrefHeight(h);

            getChildren().add(cell);

        }

        public Cell getCell(int column, int row) {
            return cells[row][column];
        }

        /**
         * Unhighlight all cells
         */
        public void unhighlight() {
            for( int row=0; row < rows; row++) {
                for( int col=0; col < columns; col++) {
                    cells[row][col].unhighlight();
                }
            }
        }
    }

    private class Cell extends StackPane {

        int column;
        int row;

        public Cell(int column, int row) {

            this.column = column;
            this.row = row;

            getStyleClass().add("cell");

//          Label label = new Label(this.toString());
//
//          getChildren().add(label);

            setOpacity(0.9);
        }

        public void highlight() {
            // ensure the style is only once in the style list
            getStyleClass().remove("cell-highlight");

            // add style
            getStyleClass().add("cell-highlight");
        }

        public void unhighlight() {
            getStyleClass().remove("cell-highlight");
        }

        public void hoverHighlight() {
            // ensure the style is only once in the style list
            getStyleClass().remove("cell-hover-highlight");

            // add style
            getStyleClass().add("cell-hover-highlight");
        }

        public void hoverUnhighlight() {
            getStyleClass().remove("cell-hover-highlight");
        }

        public String toString() {
            return this.column + "/" + this.row;
        }
    }

    public class MouseGestures {

        public void makePaintable( Node node) {


            // that's all there is needed for hovering, the other code is just for painting
            if( showHoverCursor) {
                node.hoverProperty().addListener(new ChangeListener<Boolean>(){

                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {

                        System.out.println( observable + ": " + newValue);

                        if( newValue) {
                            ((Cell) node).hoverHighlight();
                        } else {
                            ((Cell) node).hoverUnhighlight();
                        }

                        for( String s: node.getStyleClass())
                            System.out.println( node + ": " + s);
                    }

                });
            }

            node.setOnMousePressed( onMousePressedEventHandler);
            node.setOnDragDetected( onDragDetectedEventHandler);
            node.setOnMouseDragEntered(onMouseDragEnteredEventHandler);

        }

        EventHandler<MouseEvent> onMousePressedEventHandler = event -> {

            Cell cell = (Cell) event.getSource();

            if( event.isPrimaryButtonDown()) {
                cell.highlight();
            } else if( event.isSecondaryButtonDown()) {
                cell.unhighlight();
            }
        };

        EventHandler<MouseEvent> onMouseDraggedEventHandler = event -> {

            PickResult pickResult = event.getPickResult();
            Node node = pickResult.getIntersectedNode();

            if( node instanceof Cell) {

                Cell cell = (Cell) node;

                if( event.isPrimaryButtonDown()) {
                    cell.highlight();
                } else if( event.isSecondaryButtonDown()) {
                    cell.unhighlight();
                }

            }

        };

        EventHandler<MouseEvent> onMouseReleasedEventHandler = event -> {
        };

        EventHandler<MouseEvent> onDragDetectedEventHandler = event -> {

            Cell cell = (Cell) event.getSource();
            cell.startFullDrag();

        };

        EventHandler<MouseEvent> onMouseDragEnteredEventHandler = event -> {

            Cell cell = (Cell) event.getSource();

            if( event.isPrimaryButtonDown()) {
                cell.highlight();
            } else if( event.isSecondaryButtonDown()) {
                cell.unhighlight();
            }

        };

    }

}

приложение.css

.cell {
    -fx-border-color: dodgerblue;
    -fx-border-width: 1px;
}
.cell-highlight {
    -fx-background-color:derive(dodgerblue,0.9);
}
.cell-hover-highlight {
    -fx-background-color:derive(green,0.9);
}

Скриншот

введите здесь описание изображения

person Roland    schedule 02.04.2016
comment
Это именно то, что я ищу! К сожалению, я не могу сделать это исключительно в FXML, что я хотел бы сделать, но я думаю, что на данный момент недостаточно поддержки пользовательских компонентов. Вопрос: На моем изображении я также выделил жирным шрифтом линии фрагментов сетки карты 5x4, просто используя другую сетку. Есть ли способ сделать это, не рисуя вручную каждую линию/прямоугольник? - person Michael Gates; 02.04.2016
comment
Просто измените CSS для этого цель. Не надо ничего рисовать. - person Roland; 02.04.2016
comment
В итоге я наложил на него еще одну сетку, потому что не мог понять CSS для нее. У меня проблема, однако. Рисование сетки занимает ужасно много времени, а у меня мощный компьютер. Причина в том, что каждая ячейка делает ненужные вызовы отрисовки. Первое поле отображает 4 строки, второе поле должно отображать только низ, право, верх, то же самое с остальной частью строки. Следующая строка не должна отображать вершину, поскольку она уже была визуализирована. Как я могу избежать всех ненужных вызовов отрисовки? - person Michael Gates; 16.05.2016

Вот что я сделал с.

По сути, я отказался от сетки FXML, потому что она была ужасно медленной для того, что я пытался сделать. Вместо него я создал собственный холст и нарисовал собственные линии сетки. Это было здорово, потому что позволяло мне рисовать несколько слоев и при этом работать в десять раз быстрее, чем решение FX. Для грубой справки: решению FX потребовалось ~ 2 полных минуты, чтобы отрисовать одну сетку, решению Canvas требуется около ~ 75 мс, чтобы нарисовать 3 холста.

person Michael Gates    schedule 04.01.2020