JavaFX:点击New Game按钮弹出新Stage后按钮悬停状态异常
解决JavaFX按钮悬停状态卡住的问题
这个问题我太熟悉了!本质是模态弹窗弹出后直接抢占了所有输入焦点,导致主Stage上的"New Game"按钮根本没机会收到MOUSE_EXITED事件,所以悬停高亮就一直卡着了。不用移除悬停效果,只要手动帮按钮重置状态就行,给你两个最靠谱的方案:
方案一:手动移除按钮的悬停伪类
JavaFX的控件悬停样式是通过:hover伪类实现的,我们可以在弹窗弹出前,强制把这个伪类从按钮的状态里移除。
假设你的按钮是通过FXML注入的(比如@FXML private Button newGameBtn;),修改你的showPopUp()方法就行:
@FXML private Button newGameBtn; public void showPopUp() { // 强制移除悬停伪类,让按钮回到正常状态 newGameBtn.getPseudoClassStates().remove(PseudoClass.getPseudoClass("hover")); try { Stage stage = new Stage(); Parent root = FXMLLoader.load(getClass().getResource("popUp.fxml")); Scene scene = new Scene(root, 210,55); stage.setScene(scene); stage.initStyle(StageStyle.UNDECORATED); stage.initModality(Modality.APPLICATION_MODAL); stage.show(); scene.setOnKeyPressed(e -> { if ((e.getCode() == KeyCode.SPACE)) { stage.close(); startGame(); } }); } catch (IOException ieo) { ieo.printStackTrace(); } }
方案二:手动触发鼠标离开事件
如果伪类的方式你觉得不够直观,也可以直接给按钮发送一个MOUSE_EXITED事件,模拟鼠标离开的动作:
@FXML private Button newGameBtn; public void showPopUp() { // 手动触发鼠标离开事件,让按钮重置状态 newGameBtn.fireEvent(new MouseEvent( MouseEvent.MOUSE_EXITED, 0, 0, 0, 0, MouseButton.NONE, 0, false, false, false, false, false, false, false, false, false, false, false, null )); // 后面的弹窗代码不变 try { Stage stage = new Stage(); Parent root = FXMLLoader.load(getClass().getResource("popUp.fxml")); Scene scene = new Scene(root, 210,55); stage.setScene(scene); stage.initStyle(StageStyle.UNDECORATED); stage.initModality(Modality.APPLICATION_MODAL); stage.show(); scene.setOnKeyPressed(e -> { if ((e.getCode() == KeyCode.SPACE)) { stage.close(); startGame(); } }); } catch (IOException ieo) { ieo.printStackTrace(); } }
这两个方案都能完美解决你的问题:既保留了按钮原本的悬停效果,又能在弹窗弹出后让按钮回到正常样式。我自己做JavaFX小游戏的时候也遇到过一模一样的坑,用方案一就搞定了~
内容的提问来源于stack exchange,提问作者tcodeb
相关产品推荐
相关产品推荐

