java 如何在JavaFX的Grid的每个单元格中输入鼠标上的GridPane行和列ID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31095954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:06:23  来源:igfitidea点击:

How to get GridPane Row and Column IDs on Mouse Entered in each cell of Grid in JavaFX?

javajavafxjavafx-8

提问by Sujit Devkar

I am trying out JFX Drag and Drop feature in my application (later connecting the objects in a sequence). I could not find any easy way to drag and drop my ImageView/Button at suitable position in my pane, hence I am planning to apply use of GridPane. The GridPane would be a large canvas with more than (50x50) cells.

我正在我的应用程序中尝试 JFX 拖放功能(稍后按顺序连接对象)。我找不到任何简单的方法将我的 ImageView/Button 拖放到我的窗格中的合适位置,因此我计划应用 GridPane。GridPane 将是一个包含多个 (50x50) 单元格的大画布。

If I specify in my code that I need to drag and drop by ImageView at, let's say, (2,2) cell, I am able to do it. But, I need to give that access to my user. User could move the pointer in grid and would drop the ImageView/Button at any cell in the grid.

如果我在我的代码中指定我需要通过 ImageView 拖放到 (2,2) 单元格,我就可以做到。但是,我需要将该访问权限授予我的用户。用户可以在网格中移动指针,并将 ImageView/Button 放在网格中的任何单元格上。

Now, I would like to find out rowID and columnID of the cell on mouse entered in a particular cell of the GridPane.

现在,我想找出在 GridPane 的特定单元格中输入的鼠标单元格的 rowID 和 columnID。

I am handling mouse event in my Controller as follows:

我在我的控制器中处理鼠标事件如下:

package sample;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable{
Stage stage;

@FXML
private GridPane gridPane;

public void setStage(Stage primaryStage){
    stage = primaryStage;
}

@Override
public void initialize(URL location, ResourceBundle resources) {
    System.out.println("initialize");
}


@FXML
private void handleMouseEntered(MouseEvent event){
    System.out.println("MouseEntered");
}

}

When enters in the gridpane, I get "MouseEntered" only once. Besides, I am not able to get any RowID and ColumnID, hence, I have not written any function in the function.

当进入网格窗格时,我只得到一次“MouseEntered”。此外,我无法获得任何 RowID 和 ColumnID,因此,我没有在函数中编写任何函数。

My interface looks like following: enter image description here

我的界面如下所示: 在此处输入图片说明

I would like to know two things:

我想知道两件事:

[] How to detect mouse entry in each cell of the gridpane?

[] 如何在网格窗格的每个单元格中检测鼠标输入?

[] How to find out row and column IDs of the particular cell?

[] 如何找出特定单元格的行和列 ID?

Thanks in advance.

提前致谢。

回答by James_D

You can get the values by calling GridPane.getColumnIndex(node)and GridPane.getRowIndex(node).

您可以通过调用GridPane.getColumnIndex(node)和来获取值GridPane.getRowIndex(node)

You haven't shown what you're putting in the grid pane, and even whether you are populating it in FXML or in Java, but here's some basic functionality. Here I (tediously) populate the GridPanein FXML, it might be better to populate it in Java (i.e. in the controller), depending on your use case. (That way, the handler gets a bit cleaner too.)

您还没有显示您在网格窗格中放置的内容,甚至您是使用 FXML 还是 Java 填充它,但这里有一些基本功能。在这里,我(乏味地)填充了GridPaneFXML,根据您的用例,最好使用 Java(即在控制器中)填充它。(这样,处理程序也会变得更干净一些。)

Controller class:

控制器类:

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;


public class GridPaneTrackingController {

    @FXML
    private void mouseEntered(MouseEvent e) {
        Node source = (Node)e.getSource() ;
        Integer colIndex = GridPane.getColumnIndex(source);
        Integer rowIndex = GridPane.getRowIndex(source);
        System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
    }
}

If you don't want to define the contents of the cells in FXML, then you can just define them in the controller. That makes things cleaner, as you can just register the listener when you define them:

如果你不想在 FXML 中定义单元格的内容,那么你可以在控制器中定义它们。这使事情变得更清晰,因为您可以在定义侦听器时注册它们:

import javafx.fxml.FXML;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;


public class GridPaneTrackingController {

    @FXML
    private GridPane grid ;

    public void initialize() {
        int numCols = 4 ;
        int numRows = 4 ;

        for (int i = 0 ; i < numCols ; i++) {
            ColumnConstraints colConstraints = new ColumnConstraints();
            colConstraints.setHgrow(Priority.SOMETIMES);
            grid.getColumnConstraints().add(colConstraints);
        }

        for (int i = 0 ; i < numRows ; i++) {
            RowConstraints rowConstraints = new RowConstraints();
            rowConstraints.setVgrow(Priority.SOMETIMES);
            grid.getRowConstraints().add(rowConstraints);
        }

        for (int i = 0 ; i < numCols ; i++) {
            for (int j = 0; j < numRows; j++) {
                addPane(i, j);
            }
        }
    }

    private void addPane(int colIndex, int rowIndex) {
        Pane pane = new Pane();
        pane.setOnMouseEntered(e -> {
            System.out.printf("Mouse enetered cell [%d, %d]%n", colIndex, rowIndex);
        });
        grid.add(pane, colIndex, rowIndex);
    }

}

FXML:

文件格式:

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

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

<GridPane xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="GridPaneTrackingController" 
    fx:id="grid" gridLinesVisible="true">

</GridPane>

Application:

应用:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class GridPaneTrackingExample extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        GridPane root = FXMLLoader.load(getClass().getResource("GridPaneTrackingExample.fxml"));
        primaryStage.setScene(new Scene(root, 800, 800));
        primaryStage.show();
    }

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