在我的代码中,我创建了一个最初工作的事件处理程序;但是在添加更多代码之后它停止了工作,所以我恢复到我的更改之前它仍然无法工作。有什么我做错了吗?另外,如果这有助于确定原因,我正在使用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);
}
}
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仓库中。 完整源代码在github.com/stitch366/chess/tree/master/chess。
答案 0 :(得分:0)
您已将锚定窗格(ID为board-overlay
)放置在主布局中的所有其他组件之上。它出现在“顶部”(按Z顺序),因为你把它放在最后。当用户点击电路板时,由于该节点位于顶部,它接收鼠标事件;因此,代表作品的Region
没有一个接收鼠标事件并调用监听器。
目前尚不清楚为什么需要覆盖:很明显,如果你只是删除它,一切都会起作用。如果由于其他原因需要它,可以通过在FXML中设置mouseTransparent="true"
来阻止它拦截鼠标事件:
<AnchorPane id="board-overlay" layoutX="60.0" layoutY="60.0"
prefHeight="640.0" prefWidth="640.0" mouseTransparent="true"/>
可能偏离主题:
您的应用程序结构 非常强烈不推荐 。 Application
子类的目的是管理应用程序生命周期:即启动应用程序(start(...)
方法)并在需要时干净地关闭它(stop()
方法) 。应用程序类不负责管理用户事件:这是控制器类的明确目的。我 强烈 建议重构此操作,以便在控制器中管理您的事件处理。一个原因(主要原因)是,通过这样做,您的应用程序变得更加灵活。 (例如,如果你想要一个应用程序,其中多个游戏显示在不同的选项卡中,那么从现在的位置进行重构将非常困难。使用控制器来管理每个FXML的事件处理将非常容易。)另一个原因是使用查找是非常脆弱的:通常它依赖于已经应用于场景图的CSS,默认情况下,直到第一次将场景实际渲染到屏幕时才会发生。这似乎可以正常工作,可能是因为CSS ID是明确设置的,但实际上并不能保证这将在JavaFX的未来版本中有效。
我会重构您的应用程序类,以便它不会启动应用程序(这是它的责任):
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("/Chess.fxml"));
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();
}
}
public static void main(String[] args) {
launch(args);
}
}
并将事件处理移至控制器类:
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以引用根节点,并将表示一个片段的每个Region
映射到控制器中的事件处理程序方法:
<AnchorPane prefHeight="740.0" prefWidth="740.0" stylesheets="@application/application.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.Controller" fx:id="root">
<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" onMouseClicked="#click" />
<Region id="b3" layoutX="160.0" prefHeight="80.0" prefWidth="80.0" styleClass="bBishop" onMouseClicked="#click" />
<Region id="b5" layoutX="80.0" prefHeight="80.0" prefWidth="80.0" styleClass="bKnight" onMouseClicked="#click" />
<!-- etc... -->
</children></AnchorPane>
<AnchorPane id="board-overlay" layoutX="60.0" layoutY="60.0"
prefHeight="640.0" prefWidth="640.0" mouseTransparent="true"/>
</children>
</AnchorPane>