JavaFx透明窗口 – 是的请。 鼠标透明 – 不,谢谢

我想创建一个简单的JavaFx类,向用户显示覆盖用户屏幕的半透明矩形(比如任意50%的透明度)。 它应该只是让我得到鼠标点击事件的点。 这听起来微不足道,但是当我创建透明窗口时,它们似乎总是对鼠标事件透明,而不仅仅是我对半透明可见性的要求。 永远不会触发鼠标事件。

我在矩形和根窗格上使用了setMouseTransparent(false),但这没什么区别。 如果有人能指出任何错误/误解,我真的很感激。

这是我创建的琐碎测试类:

public class ClickScreen implements MouseListener { private ClickScreenListener listener; private Stage window; private Point point; public ClickScreen(ClickScreenListener listener) { // Get screen size Rectangle2D r = Screen.getPrimary().getBounds(); // Something to put stuff in StackPane root = new StackPane(); // Translucent rectangle on the pane Rectangle rectangle = new Rectangle(r.getWidth(), r.getHeight()); rectangle.setFill(Color.rgb(183, 183, 183, 0.5)); root.getChildren().add(rectangle); Scene scene = new Scene(root, r.getWidth(), r.getHeight()); scene.setFill(null); window = new Stage(); window.initStyle(StageStyle.TRANSPARENT); window.setTitle("Click drop location"); window.setScene(scene); this.listener = listener; } public Point getLocation(){ return point; } @Override public void mouseClicked(MouseEvent e) { point = e.getLocationOnScreen(); listener.screenClicked(point); } } 

编辑:我遇到的透明度问题的一个更简单的例子来自这个Hello World! 例。 当我将鼠标hover在按钮上时,点击按钮或只是单击“直通”并将焦点放在底层窗口(在我的情况下通常是eclipse)的概率大约为50:50。 会爱你这个想法。

  public class HelloWorld extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Button btn = new Button(); btn.setText("Say 'Hello World'"); btn.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { System.out.println("Hello World!"); } }); StackPane root = new StackPane(); root.getChildren().add(btn); Scene scene = new Scene(root, 300, 250); scene.setFill(null); primaryStage.setScene(scene); primaryStage.initStyle(StageStyle.TRANSPARENT); primaryStage.show(); } } 

检查您的import

您正在使用某种奇怪的设置来混合AWT / Swing类和JavaFX类,这些类实际上并不建议(并且在您使用的组合和方式中根本不起作用)。 在JavaFX程序中要小心,不要导入任何java.awt.*javax.swing.*类,除非你真的知道在混合两个不同工具包的代码时你在做什么。

样品溶液

下面是一个示例解决方案,它只导入JavaFX类并使用JavaFX事件,但在其他方面试图坚持您问题中示例代码的编码/回调样式。 (可以通过使用Java 8 lambdas进一步简化示例)。

在此处输入图像描述

 import javafx.application.Application; import javafx.event.*; import javafx.geometry.*; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.MouseEvent; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.stage.*; public class ClickListenerSample extends Application implements ClickScreenListener { private Label clickFeedbackLabel = new Label(""); @Override public void start(Stage stage) { Button listen = new Button("listen"); listen.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { new ClickScreen(ClickListenerSample.this); } }); VBox layout = new VBox(10); layout.getChildren().setAll( listen, clickFeedbackLabel ); layout.setPadding(new Insets(10)); stage.setScene(new Scene(layout, 100, 80)); stage.show(); } public static void main(String[] args) { launch(args); } @Override public void screenClicked(Point2D point) { clickFeedbackLabel.setText(point.getX() + ", " + point.getY()); } } interface ClickScreenListener { void screenClicked(Point2D point); } class ClickScreen { private ClickScreenListener listener; private Stage window; private Point2D point; public ClickScreen(ClickScreenListener listener) { // Get screen size Rectangle2D r = Screen.getPrimary().getBounds(); // Something to put stuff in StackPane root = new StackPane(); root.setStyle("-fx-background-color: null;"); // Translucent rectangle on the pane Rectangle rectangle = new Rectangle(r.getWidth(), r.getHeight()); rectangle.setFill(Color.rgb(183, 183, 183, 0.5)); root.getChildren().add(rectangle); Scene scene = new Scene(root, r.getWidth(), r.getHeight()); scene.setFill(null); window = new Stage(); window.initStyle(StageStyle.TRANSPARENT); window.setTitle("Click drop location"); window.setScene(scene); scene.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent event) { point = new Point2D(event.getScreenX(), event.getScreenY()); listener.screenClicked(point); window.hide(); } }); window.show(); this.listener = listener; } public Point2D getLocation(){ return point; } }