JavaFX事件处理程序不再工作

JavaFX事件处理程序不再工作,javafx,event-handling,Javafx,Event Handling,在我的代码中,我创建了一个最初可以工作的事件处理程序;然而,在添加了更多的代码后,它停止了工作,所以我恢复到更改之前的状态,但仍然无法工作。我做错什么了吗?此外,如果eclipse有助于确定原因,我将使用eclipse Main.java: 包装申请 import java.util.ArrayList; import javafx.application.Application; import javafx.event.EventHandler; import javafx.fxml.FXM

在我的代码中,我创建了一个最初可以工作的事件处理程序;然而,在添加了更多的代码后,它停止了工作,所以我恢复到更改之前的状态,但仍然无法工作。我做错什么了吗?此外,如果eclipse有助于确定原因,我将使用eclipse

Main.java: 包装申请

import java.util.ArrayList;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.InputEvent;
import javafx.scene.input.MouseEvent;


public class Main extends Application {
    public Parent root;
    public ChessUtil chess = new ChessUtil();
    @Override
    public void start(Stage primaryStage) {
        try {
            root = FXMLLoader.load(getClass().getResource("/Chess.fxml"));
            Node peice;
            for(int x = 0; x < 16 ;x++)
            {
                peice = root.lookup("#" + chess.whiteID[x]);
                peice.addEventHandler(MouseEvent.MOUSE_CLICKED, peiceClick);
                peice = root.lookup("#" + chess.blackID[x]);
                peice.addEventHandler(MouseEvent.MOUSE_CLICKED, peiceClick);
            }
            disablePeicesToggle(chess.blackID, true);
            Scene scene = new Scene(root,740,740);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    EventHandler peiceClick = new EventHandler<InputEvent>() {
        public void handle(InputEvent event) {
            String id = ((Node) event.getSource()).getId();
            ArrayList<String> moves = chess.findPeiceMoves(id);
            System.out.println(moves.size());
            if(moves.size() > 0)
            {
                System.out.println(moves);
            }
            System.out.println("Handling event " + event.getEventType()); 
            event.consume();
        }
     };
    public void disablePeicesToggle(String[] idSet, boolean disable)
    {
        Node peice;
        for(int x = 0; x < 16 ;x++)
        {
            peice = root.lookup("#" + idSet[x]);
            peice.setDisable(disable);
        }

    }
    public static void main(String[] args) {
        launch(args);
    }
}
import java.util.ArrayList;
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.fxml.fxmloader;
导入javafx.stage.stage;
导入javafx.scene.Node;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.input.InputEvent;
导入javafx.scene.input.MouseEvent;
公共类主扩展应用程序{
公共父根;
公共ChessUtil chess=新ChessUtil();
@凌驾
公共无效开始(阶段primaryStage){
试一试{
root=FXMLLoader.load(getClass().getResource(“/Chess.fxml”);
节点位置;
对于(int x=0;x<16;x++)
{
peice=root.lookup(“#”+chess.whiteID[x]);
peice.addEventHandler(MouseEvent.MOUSE_单击,peiceClick);
peice=root.lookup(“#”+chess.blackID[x]);
peice.addEventHandler(MouseEvent.MOUSE_单击,peiceClick);
}
disablePeicesToggle(chess.blackID,true);
场景=新场景(根,740740);
scene.getStylesheets().add(getClass().getResource(“application.css”).toExternalForm());
初级阶段。场景(场景);
primaryStage.show();
}捕获(例外e){
e、 printStackTrace();
}
}
EventHandler peiceClick=neweventhandler(){
公共无效句柄(InputEvent事件){
字符串id=((节点)event.getSource()).getId();
ArrayList moves=chess.findPeiceMoves(id);
System.out.println(moves.size());
如果(moves.size()>0)
{
系统输出打印项次(移动);
}
System.out.println(“处理事件”+event.getEventType());
event.consume();
}
};
public void disablePeicesToggle(字符串[]idSet,布尔禁用)
{
节点位置;
对于(int x=0;x<16;x++)
{
peice=root.lookup(“#”+idSet[x]);
peice.setDisable(禁用);
}
}
公共静态void main(字符串[]args){
发射(args);
}
}
Chess.fxml:

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

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

<AnchorPane prefHeight="740.0" prefWidth="740.0" stylesheets="@application/application.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <AnchorPane id="chessboard" layoutX="10.0" layoutY="10.0" prefHeight="720.0" prefWidth="720.0" stylesheets="@application/application.css" />
      <AnchorPane id="board-spaces" layoutX="50.0" layoutY="50.0" prefHeight="640.0" prefWidth="640.0">
         <children>
            <Region id="b7" prefHeight="80.0" prefWidth="80.0" styleClass="bRook" />
            <Region id="b3" layoutX="160.0" prefHeight="80.0" prefWidth="80.0" styleClass="bBishop" />
            <Region id="b5" layoutX="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bKnight" />
            <Region id="b2" layoutX="240.0" prefHeight="80.0" prefWidth="80.0" styleClass="bQueen" />
            <Region id="b1" layoutX="320.0" prefHeight="80.0" prefWidth="80.0" styleClass="bKing" />
            <Region id="b4" layoutX="400.0" prefHeight="80.0" prefWidth="80.0" styleClass="bBishop" />
            <Region id="b6" layoutX="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="bKnight" />
            <Region id="b8" layoutX="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="bRook" />
            <Region id="b12" layoutX="240.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b10" layoutX="80.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b13" layoutX="320.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b16" layoutX="560.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b9" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b15" layoutX="480.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b11" layoutX="160.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="b14" layoutX="400.0" layoutY="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bPawn" />
            <Region id="w3" layoutX="160.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wBishop" />
            <Region id="w12" layoutX="240.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w10" layoutX="80.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w5" layoutX="80.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wKnight" />
            <Region id="w7" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wRook" />
            <Region id="w14" layoutX="400.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w1" layoutX="320.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wKing" />
            <Region id="w2" layoutX="240.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wQueen" />
            <Region id="w6" layoutX="480.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wKnight" />
            <Region id="w13" layoutX="320.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w16" layoutX="560.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w9" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w15" layoutX="480.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w11" layoutX="160.0" layoutY="480.0" prefHeight="80.0" prefWidth="80.0" styleClass="wPawn" />
            <Region id="w8" layoutX="560.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wRook" />
            <Region id="w4" layoutX="400.0" layoutY="560.0" prefHeight="80.0" prefWidth="80.0" styleClass="wBishop" />
         </children></AnchorPane>
         <AnchorPane id="board-overlay" layoutX="60.0" layoutY="60.0" prefHeight="640.0" prefWidth="640.0" />
   </children>
</AnchorPane>

更新:我已经将我的代码放入GitHub repo中。
完整的源代码位于github.com/stitch366/chess/tree/master/chess。

您已经在主布局中的所有其他组件的顶部放置了一个锚窗格(带有id
板覆盖层)。它显示为“在顶部”(按Z顺序),因为您最后将其放置在那里。当用户单击电路板时,由于该节点位于顶部,因此它接收鼠标事件;因此,表示片段的
区域
都不会接收鼠标事件并调用侦听器

现在还不清楚你为什么需要覆盖层:显然,如果你只是删除它,一切都会工作。如果出于其他原因需要它,可以通过在FXML中设置
mouseTransparent=“true”
来停止它拦截鼠标事件:


可能离题:

您的应用程序的结构是非常不推荐的
Application
子类的目的是管理应用程序生命周期:即启动应用程序(
start(…)
方法)并在需要时完全关闭它(
stop()
方法)。应用程序类不负责管理用户事件:这是控制器类的明确目的。我强烈建议重构它,以便在控制器中管理事件处理。一个原因(主要原因)是您的应用程序通过这样做变得更加灵活。(例如,如果您想要一个应用程序,其中多个游戏显示在不同的选项卡中,则很难从现在的位置进行重构。使用控制器管理每个FXML的事件处理将非常简单。)另一个原因是使用查找非常脆弱:通常它依赖于已应用于场景图的CSS,默认情况下,直到第一次将场景实际渲染到屏幕时才会发生这种情况。在这里,它似乎可以正常工作,可能是因为CSS id是显式设置的,但是不能保证在JavaFX的未来版本中可以正常工作

我将重构您的应用程序类,使其不再启动应用程序(这是其职责):

并将事件处理移动到控制器类:

package application;


import java.util.ArrayList;

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

public class Controller {

    @FXML
    private AnchorPane root ;

    private ChessUtil chess = new ChessUtil();

    @FXML
    private void click(MouseEvent event) {
        String id = ((Node) event.getSource()).getId();
        ArrayList<String> moves = chess.findPeiceMoves(id);
        System.out.println(moves.size());
        if(moves.size() > 0)
        {
            System.out.println(moves);
        }
        System.out.println("Handling event " + event.getEventType()); 
        event.consume();
    }

    public void initialize() {
        disablePeicesToggle(chess.blackID, true);
    }


    public void disablePeicesToggle(String[] idSet, boolean disable)
    {
        Node peice;
        for(int x = 0; x < 16 ;x++)
        {
            peice = root.lookup("#" + idSet[x]);
            peice.setDisable(disable);
        }

    }
}

没有。我正在查找的内容已经在FXML中。完整的源代码位于。此外,我正在加载一个FXML文件,并且在FXML文件中设置了ID。没有控制器,因为我没有使用自定义组件或显示数据;添加FXML将使道路比现在更长。另外,控制器不能用于我的应用程序。
package application;


import java.util.ArrayList;

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

public class Controller {

    @FXML
    private AnchorPane root ;

    private ChessUtil chess = new ChessUtil();

    @FXML
    private void click(MouseEvent event) {
        String id = ((Node) event.getSource()).getId();
        ArrayList<String> moves = chess.findPeiceMoves(id);
        System.out.println(moves.size());
        if(moves.size() > 0)
        {
            System.out.println(moves);
        }
        System.out.println("Handling event " + event.getEventType()); 
        event.consume();
    }

    public void initialize() {
        disablePeicesToggle(chess.blackID, true);
    }


    public void disablePeicesToggle(String[] idSet, boolean disable)
    {
        Node peice;
        for(int x = 0; x < 16 ;x++)
        {
            peice = root.lookup("#" + idSet[x]);
            peice.setDisable(disable);
        }

    }
}