如何在JavaFX中实现鼠标透明的十字准星舞台
问题描述
我想开发一个在屏幕中间显示十字准星的JavaFX应用,但鼠标悬停在ImageView上时,会阻挡鼠标事件导致后台程序无法操作。试过Node#setMouseTransparent()和Scene.setFill(null)都没效果,以下是当前代码:
当前代码
setStageProperties() 方法
private void setStageProperties() { Screen screen = Screen.getPrimary(); Rectangle2D bounds = screen.getBounds(); stage.setWidth(bounds.getWidth()); stage.setHeight(bounds.getHeight()); Scene scene = new Scene(this); scene.setFill(null); stage.setScene(scene); stage.setAlwaysOnTop(true); this.primary = new Stage(); primary.initStyle(StageStyle.UTILITY); primary.setOpacity(0); primary.setHeight(0); primary.setWidth(0); primary.show(); stage.initOwner(primary); stage.initStyle(StageStyle.TRANSPARENT); double centerX = bounds.getMinX() + bounds.getWidth() / 2; double centerY = bounds.getMinY() + bounds.getHeight() / 2; stage.setX(centerX - stage.getWidth() / 2); stage.setY(centerY - stage.getHeight() / 2); }
CrosshairScene() 构造方法
public CrosshairScene() { this.stage = new Stage(); this.crosshairImage = new ImageView("crosshair.png"); this.crosshairImage.setPickOnBounds(false); this.setMouseTransparent(true); this.setCenter(crosshairImage); this.setStageProperties(); this.setStyle("-fx-background-color: null;"); }
运行配置
启动参数:
--add-opens javafx.graphics/javafx.stage=com.example.demo --add-opens javafx.graphics/com.sun.javafx.tk.quantum=com.example.demo
解决方案
要让十字准星不阻挡鼠标事件,核心是让整个Stage对鼠标事件完全穿透,具体修改如下:
给Stage设置鼠标透明
在setStageProperties()方法中添加一行代码,让整个窗口忽略所有鼠标事件:stage.setMouseTransparent(true);给ImageView补充鼠标透明设置
虽然已经给容器设置了鼠标透明,但直接给十字准星图片也加上,避免节点层面拦截事件:this.crosshairImage.setMouseTransparent(true);
修改后的完整代码如下:
修改后的setStageProperties()方法
private void setStageProperties() { Screen screen = Screen.getPrimary(); Rectangle2D bounds = screen.getBounds(); stage.setWidth(bounds.getWidth()); stage.setHeight(bounds.getHeight()); Scene scene = new Scene(this); scene.setFill(null); stage.setScene(scene); stage.setAlwaysOnTop(true); stage.setMouseTransparent(true); // 新增:让整个Stage穿透鼠标事件 this.primary = new Stage(); primary.initStyle(StageStyle.UTILITY); primary.setOpacity(0); primary.setHeight(0); primary.setWidth(0); primary.show(); stage.initOwner(primary); stage.initStyle(StageStyle.TRANSPARENT); double centerX = bounds.getMinX() + bounds.getWidth() / 2; double centerY = bounds.getMinY() + bounds.getHeight() / 2; stage.setX(centerX - stage.getWidth() / 2); stage.setY(centerY - stage.getHeight() / 2); }
修改后的CrosshairScene()构造方法
public CrosshairScene() { this.stage = new Stage(); this.crosshairImage = new ImageView("crosshair.png"); this.crosshairImage.setPickOnBounds(false); this.crosshairImage.setMouseTransparent(true); // 新增:让图片穿透鼠标事件 this.setMouseTransparent(true); this.setCenter(crosshairImage); this.setStageProperties(); this.setStyle("-fx-background-color: null;"); }
修改完成后,十字准星会正常显示在屏幕中央,鼠标操作会直接穿透到后台窗口,不会影响其他程序的正常使用。
内容的提问来源于stack exchange,提问作者Polterg
相关产品推荐
相关产品推荐

