【问题标题】:JavaFx Transparent window - yes please. Mouse transparent - no thanksJavaFx 透明窗口 - 是的,请。鼠标透明 - 不,谢谢
【发布时间】:2014-07-01 18:37:02
【问题描述】:

我想创建一个简单的 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!例子。当我将鼠标悬停在按钮上时,大约有 50:50 的机会单击按钮或单击“通过”并将焦点放在底层窗口(在我的情况下通常是 eclipse)。希望您对此有想法。

    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<ActionEvent>() {

            @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();
    }
}

【问题讨论】:

  • 你没有将你的听众附加到任何东西上,比如scene.setOnMouseClicked(listener)。更多详情请关注Handling JavaFX Events

标签: java javafx-2 mouseevent transparency


【解决方案1】:

检查您的导入

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

示例解决方案

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

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<ActionEvent>() {
            @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<MouseEvent>() {
            @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;
    }
}

【讨论】:

  • 感谢该代码,通过混合 AWT 将我的颜色显示为 JavaFx 菜鸟。但是,仍然无法正常工作。我想我有一个与透明度有关的问题,我将在我的原始帖子中添加一个编辑以包含一个更简单的透明度问题案例。
  • 好的。作为一个仅供参考,我发布的示例适用于 Java 8u5、Win 7、ATI 卡硬件加速管道。
  • 看起来我必须在我的系统上等待大约 10 秒才能让点击在透明项目上按预期工作。您的示例效果很好,谢谢。
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 2019-04-24
相关资源
最近更新 更多