我想在点击事件时获取 GridPane 的索引

I want to get GridPane's index when I act click event

我想在执行MouseClickEvent 时获取GridPane 的索引。 我在 GridPane 中的 AnchorPane 上创建了 clickevent。 单击后,我成功地将 mainmenu.fxml 更改为 koreanfood.fxml。 但我想获取 GridPane 的索引 因为我想在一个 .fxml 上做同样的事情 当我在 GridPane 中单击另一个 AnchorPane 时。

我试过了this method and and

但是 getRowIndex() 和 getColumnIndex() 总是返回 null

Main.java:

package application;

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


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root=FXMLLoader.load(getClass().getResource("mainmenu.fxml"));
            primaryStage.setScene(new Scene(root));         
            primaryStage.setTitle("recipe");
            primaryStage.show();
//          primaryStage.setResizable(false);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

Controller.java:

package application;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Controller {
    @FXML
    private Label food;
    @FXML
    private void clickmainmenu(MouseEvent event) {

        try {
            Parent koreanfood = FXMLLoader.load(getClass().getResource("koreanfood.fxml"));
            Scene scene = new Scene(koreanfood);
            Stage primaryStage = (Stage)((Node) event.getSource()).getScene().getWindow();

            Integer row = GridPane.getRowIndex((Node)event.getSource() );
            int column=GridPane.getColumnIndex((Node)event.getSource() );
            System.out.println("r : "+row+"c : "+column);
            if(row==0) {
                switch(column) {
                case 0:
                    food.setText("한식");
                    break;
                case 1:
                    food.setText("중식");
                    break;
                case 2:
                    food.setText("일식");
                    break;
                case 3:
                    food.setText("양식");
                    break;      
                }
            }
            else if(row==1) {
                switch(column) {
                case 0:
                    food.setText("분식");
                    break;
                case 1:
                    food.setText("야식");
                    break;
                case 2:
                    food.setText("랜덤");
                    break;
                case 3:
                    food.setText("ㅋ");
                    break;      
                }
            }           

            primaryStage.setScene(scene);
            primaryStage.setTitle("recipe");
        } catch(Exception e) {
            e.printStackTrace();
        }

    }
    @FXML
    private void clickfoodmenu(MouseEvent event) {
        try {
            Parent cookingrecipe = FXMLLoader.load(getClass().getResource("cookingrecipe.fxml"));
            Scene scene = new Scene(cookingrecipe);

            Stage primaryStage = (Stage)((Node) event.getSource()).getScene().getWindow();

            primaryStage.setScene(scene);
            primaryStage.setTitle("recipe");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    @FXML
    private void clickBackMain(MouseEvent event) {
        try {
            Parent koreanfood = FXMLLoader.load(getClass().getResource("mainmenu.fxml"));
            Scene scene = new Scene(koreanfood);

            Stage primaryStage = (Stage)((Node) event.getSource()).getScene().getWindow();

            primaryStage.setScene(scene);
            primaryStage.setTitle("recipe");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    @FXML
    private void clickBackKor(MouseEvent event) {
        try {
            Parent mainmenu = FXMLLoader.load(getClass().getResource("koreanfood.fxml"));
            Scene scene = new Scene(mainmenu);

            Stage primaryStage = (Stage)((Node) event.getSource()).getScene().getWindow();

            primaryStage.setScene(scene);
            primaryStage.setTitle("recipe");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

mainmenu.fxml:

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

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="600.0" prefWidth="800.0" style="-fx-background-color: yellow;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
   <children>
      <GridPane hgap="30.0" layoutX="70.0" layoutY="200.0" prefHeight="320.0" prefWidth="682.0" vgap="30.0">
        <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <AnchorPane onMouseClicked="#clickmainmenu" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;">
               <children>
                  <ImageView fitHeight="101.0" fitWidth="103.0" layoutX="27.0" layoutY="7.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@../../../resources/iconfinder_Food_C226_2427886.png" />
                     </image></ImageView>
                  <Label layoutX="54.0" layoutY="119.0" text="한식">
                     <font>
                        <Font size="21.0" />
                     </font></Label>
               </children>
            </AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
               <children>
                  <Button layoutY="1.0" mnemonicParsing="false" onMouseClicked="#clickmainmenu" prefHeight="123.0" prefWidth="119.0" style="-fx-background-color: white;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                  <ImageView fitHeight="114.0" fitWidth="116.0" layoutX="14.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@../../../resources/dim-sum.png" />
                     </image>
                  </ImageView>
                  <Label layoutX="54.0" layoutY="119.0" text="중식">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children>
            </AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="2">
               <children>
                  <Label layoutX="51.0" layoutY="121.0" text="일식">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
                  <ImageView fitHeight="128.0" fitWidth="122.0" layoutX="13.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@../../../resources/iconfinder_Food_C212_2427856.png" />
                     </image>
                  </ImageView>
               </children>
            </AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="3">
               <children>
                  <ImageView fitHeight="114.0" fitWidth="114.0" layoutX="17.0" pickOnBounds="true" preserveRatio="true" />
                  <Label layoutX="51.0" layoutY="121.0" text="양식">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children></AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.rowIndex="1">
               <children>
                  <ImageView fitHeight="114.0" fitWidth="114.0" layoutX="17.0" pickOnBounds="true" preserveRatio="true" />
                  <Label layoutX="51.0" layoutY="114.0" text="분식">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children></AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="1" GridPane.rowIndex="1">
               <children>
                  <ImageView fitHeight="114.0" fitWidth="114.0" layoutX="21.0" pickOnBounds="true" preserveRatio="true" />
                  <Label layoutX="51.0" layoutY="114.0" text="야식">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children></AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="2" GridPane.rowIndex="1">
               <children>
                  <ImageView fitHeight="114.0" fitWidth="114.0" layoutX="17.0" pickOnBounds="true" preserveRatio="true" />
                  <Label layoutX="51.0" layoutY="114.0" text="랜덤">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children></AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="3" GridPane.rowIndex="1">
               <children>
                  <ImageView fitHeight="114.0" fitWidth="130.0" layoutX="11.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@../../../resources/food.png" />
                     </image></ImageView>
                  <Label layoutX="10.0" layoutY="119.0" text="너만의 레시피">
                     <font>
                        <Font size="21.0" />
                     </font>
                  </Label>
               </children></AnchorPane>
         </children>
      </GridPane>
      <Label layoutX="300.0" layoutY="47.0" prefHeight="94.0" prefWidth="220.0" text="뭐먹어">
         <font>
            <Font size="72.0" />
         </font>
      </Label>
   </children>
</AnchorPane>

koreanfood.fxml:

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

<?import javafx.scene.image.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="600.0" prefWidth="800.0" style="-fx-background-color: yellow;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
   <children>
      <Label fx:id="food" layoutX="327.0" layoutY="14.0" prefHeight="99.0" prefWidth="146.0">
         <font>
            <Font size="70.0" />
         </font>
      </Label>
      <GridPane hgap="20.0" layoutX="61.0" layoutY="121.0" prefHeight="448.0" prefWidth="678.0" vgap="20.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <AnchorPane onMouseClicked="#clickfoodmenu" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;">
               <children>
                  <ImageView fitHeight="99.0" fitWidth="121.0" layoutX="17.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true" />
                  <Label layoutX="54.0" layoutY="104.0" prefHeight="29.0" prefWidth="58.0" text="111" />
               </children>
            </AnchorPane>
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.rowIndex="1" />
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.rowIndex="2" />
            <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" GridPane.columnIndex="1" />
         </children>
      </GridPane>
      <ImageView fitHeight="72.0" fitWidth="132.0" layoutX="32.0" layoutY="24.0" onMouseClicked="#clickBackMain" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@../../../resources/reply%20(2).png" />
         </image>
      </ImageView>
   </children>
</AnchorPane>

错误:

java.lang.NullPointerException
    at application.Controller.clickmainmenu(Controller.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
    at javafx.scene.Scene$ClickGenerator.access00(Scene.java:3398)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
    at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent3(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null7(WinApplication.java:177)
    at java.lang.Thread.run(Unknown Source)

我该怎么办? 有人可以帮帮我吗??

rowIndex/columnIndexnull,除非你初始化这个属性。没有必要指定这些属性,因为 GridPane 默认将它们视为 0

另请注意,MouseEvent.source 包含添加事件处理程序的节点,因此

  • 您添加事件处理程序的第一个节点位于单元格 (0, 0) 并且为了减小 fxml 大小,SceneBuilder 没有指定值,因为布局上的效果是相同的,导致值null.
  • 您添加事件处理程序的第二个节点不是 GridPane 的子节点,而是 GridPane 的子节点的子节点,因此 rowIndex也没有指定 columnIndex。 (此外,对于 Buttons,最好使用 onAction 事件;不过这是一个 ActionEvent。)

您仍然可以通过

处理这些问题
  1. 向上遍历场景结构,直到找到 GridPane 的子项。
  2. null 视为 0
private static int toIndex(Integer value) {
    return value == null ? 0 : value;
}
@FXML
private GridPane grid;
<GridPane fx:id="grid" hgap="30.0" layoutX="70.0" layoutY="200.0" prefHeight="320.0" prefWidth="682.0" vgap="30.0">
Node node = (Node) event.getSource();
Parent p = node.getParent();

while (p != grid) {
    node = p;
    p = p.getParent();
}

int row = toIndex(GridPane.getRowIndex(node));
int column = toIndex(GridPane.getColumnIndex(node));