编辑:问题似乎来自使用SplitPane。我删除了它,但现在我遇到了MouseTransparent问题,cf评论
我在StackPane上遇到问题,其中Controller类应该通过鼠标拖动来管理节点转换:
出于某种原因,只要鼠标进入StackPane,就会正确触发.setOnMouseEntered事件。但是,setOnMousePressed(在单击StackPane中的节点时)根本不会触发,除非在StackPane中心的标签上。当我删除标签时,没有任何东西发射。 StackPane本身由SplitPane组成,它由几个其他节点组成。
其中一些节点(那些应该被拖动的节点)也有一些setOnMousePressed等事件管理,它们被正确触发了!
更多地了解背景:我正在进行海军对战游戏实施。我目前正在尝试通过控制器类来管理船只放置(这样我就可以确认船不会被放置在界外或在另一条船上)。控制器类(BoatMoveManager)在实例化时,在最高的StackPane上创建所有这些mouseEvent处理程序(GameBoard扩展StackPane)。
public class BoatMoveManager {
GameBoard gB;
public BoatMoveManager(GameBoard g){
gB = g;
//the following mouseEventHandler fires correctly whenever the mouse enters the GameBoard (StackPane)
gB.setOnMouseEntered(event -> {
System.out.println("GameBoard OnMouseEntered");
//the following mouseEventHandler doesn't fire, except on a label in the middle of the GameBoard
gB.setOnMousePressed(event -> {
System.out.println("GameBoard OnMousePressed");
});
我不明白为什么事件会与标签一起触发,而不是GameBoard中的其他节点......(可能是标签是直接"内部&#34 ; GameBoard,而其他节点位于水平分割器的顶部?)
例如,这是GameBoard的构造函数:
public class GameBoard extends StackPane {
private SplitPane splitter;
private TilePane gameZone;
private TabZone tabs;
private Grid playerGrid, opponentGrid, playerHarbor, opponentHarbor;
private FlowPane playerGrids, opponentGrids, playerZone, opponentZone;
private Score playerScore, opponentScore;
private Label popup;
private static HBox playerHBox, opponentHBox;
private static VBox playerVBox, opponentVBox;
private static BoatMoveManager bMM;
private List<Boat> playerBoatsList = new ArrayList<Boat>(), opponentBoatsList = new ArrayList<Boat>() ;
public GameBoard(){
super();
playerGrid = new Grid('G','H');
opponentGrid = new Grid('G','H');
playerHarbor = new Grid('H','H');
opponentHarbor = new Grid('H','H');
bMM = new BoatMoveManager(this);
for(int i = 1 ; i < 5 ; ++i){
playerBoatsList.add(new Boat(i, playerGrid, playerHarbor));
opponentBoatsList.add(new Boat(i, opponentHarbor, opponentGrid));
}
playerGrid.drawBoat(playerBoatsList.get(0), 3, 4);
playerGrid.drawBoat(playerBoatsList.get(1), 3, 5);
playerGrid.drawBoat(playerBoatsList.get(2), 3, 6);
playerGrid.drawBoat(playerBoatsList.get(3), 3, 7);
playerScore = new Score();
opponentScore = new Score();
gameZone = new TilePane(Orientation.HORIZONTAL);
gameZone.setStyle("-fx-background-color: lightgray");
playerHBox = new HBox();
playerHBox.getChildren().addAll(playerHarbor, playerGrid);
playerHBox.setSpacing(Grid.getUnit());
playerVBox = new VBox();
playerVBox.getChildren().addAll(playerScore,playerHBox);
playerVBox.maxWidthProperty().bind(gameZone.widthProperty().divide(2));
playerScore.setAlignment(Pos.CENTER);
opponentHBox = new HBox();
opponentHBox.getChildren().addAll(opponentGrid, opponentHarbor);
opponentHBox.setSpacing(Grid.getUnit());
opponentVBox = new VBox();
opponentVBox.getChildren().addAll(opponentScore,opponentHBox);
opponentScore.setAlignment(Pos.CENTER);
gameZone.getChildren().addAll(playerVBox, opponentVBox);
gameZone.setHgap(Grid.getUnit()*3);
gameZone.setAlignment(Pos.CENTER);
gameZone.setSnapToPixel(false);
tabs = new TabZone();
splitter = new SplitPane();
splitter.setOrientation(Orientation.VERTICAL);
splitter.setDividerPositions(0.75f,0.25f);
splitter.getItems().addAll(gameZone,tabs);
splitter.setOnDragEntered(event ->{
BoatMoveManager.setTarget(splitter);
});
popup = new Label("uninitialized");
this.getChildren().addAll(splitter,popup);
this.setOnDragEntered(event -> {
BoatMoveManager.setTarget(this);
});
}
我正在谈论的标签是&#34; popup&#34;,它在构造函数的最后添加了&#34; splitter&#34;在
this.getChildren().addAll(splitter,popup);
但考虑到这样一个事实,即使我没有添加它,像MousePressed这样的事件也不会通过GameBoard激发......
这里是GameBoard的布局,以清理事物(网格和船只布局是不言自明的): (在新标签页中打开此图片,以全尺寸查看) 我希望这并不是太混乱,无法理解我想要做的事情。为什么它不起作用。
答案 0 :(得分:0)
我现在还不确定。我几乎必须在我的计算机上测试代码才能确定,但请尝试
this.setMouseTransparency(true);
这将使其无法单击堆栈窗口。同样为了将来参考,您可以在GameBoard的调用开始时删除“this”。如果你的类扩展了StackPane,那么调用getChildren()。add(node)是完全合法的。
答案 1 :(得分:0)
遇到同样的问题(再次)..
我相信StackPane是你的问题。他们不喜欢明显地传递事件.. 在我的情况下,设置: stackPane .setPickOnBounds(假);
是我的修复。
我希望这能为您解决问题......也许是一个错误?