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

时间:2015-06-28 03:46:16

标签: java javafx javafx-8

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

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

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

我在Controller中处理鼠标事件如下:

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

}

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

我的界面如下所示: enter image description here

我想知道两件事:

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

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

提前致谢。

1 个答案:

答案 0 :(得分:5)

您可以致电GridPane.getColumnIndex(node)GridPane.getRowIndex(node)来获取值。

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

控制器类:

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

如果您不想在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>

应用:

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