java - 在 JavaFX 中创建可编辑(可绘制)网格

标签 java css javafx fxml gridpane

目前有2组网格。第一个网格集是一个 5x4 网格,其中包含 map 图像。最重要的是,有一个网格,其中包含每个 5x4 网格框的所有小图 block 。

Example Grid Image

所以我需要有 5x4 网格图案的大图像,每个图 block 内有 16x16 迷你图 block ,并且每个迷你图 block 需要在存在于大英亩土地中的底层图像之上可绘制(或具有图像)。

<?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 访问网格图 block (列、行、数据等)组件?

最佳答案

创建自定义可绘制网格组件并将其放置在图像上。

代码

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);
}

截图

enter image description here

关于java - 在 JavaFX 中创建可编辑(可绘制)网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36369224/

相关文章:

java - 将带有按钮的新行添加到 javafx tableview

java - 如何在 JavaFX 中继续循环之前等待媒体结束?

java - JUnit 测试未在 Eclipse 中运行

css - 无法让外部 css 在动态 web 元素 spring 中工作

java - 跑表。数秒。 javafx

html - 如何使用剩余宽度?

html - 响应式设计无法正常工作 - 显示太多

java - Android 自定义 toast 消息不能在单独的类中工作

java - Android:将 View 放在与其他 View 相同的高度

java - 如何正确设置多配置文件 Maven 项目?