JavaFx透明窗口-是的.鼠标透明-不用了 [英] JavaFx Transparent window - yes please. Mouse transparent - no thanks

查看:101
本文介绍了JavaFx透明窗口-是的.鼠标透明-不用了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个简单的JavaFx类,该类向用户显示覆盖用户屏幕的半透明矩形(例如,任意50%的透明度).它应该只允许我获得鼠标单击事件的指示.这听起来很琐碎,但是当我创建透明窗口时,它们似乎始终对鼠标事件透明,而不仅仅是我对半透明可见性的要求.鼠标事件永远不会触发.

I would like to create a simple JavaFx class that shows the user a translucent rectangle (say an arbitrary 50% transparency) covering the users screen. It should simply allow me to get the Point of a mouse click event. This sounds trivial, but when I create transparent windows they always seem to be transparent to mouse events rather than just my requirement of semi-transparent visibility. The mouse event is never triggered.

我在矩形和根窗格上使用了setMouseTransparent(false),但这没有什么区别.如果有人可以指出任何错误/误解,我将不胜感激.

I've used setMouseTransparent(false) on the rectangle and the root pane, but this makes no difference. I'd be really grateful if somebody could indicate any errors/misconceptions.

这是我创建的普通测试类:

Here's the trivial test class I have created:

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的机会单击按钮或仅单击通过"并将焦点移到基础窗口上(在我的情况下通常是日蚀).希望您对此有想法.

A simpler example of the transparency issue I am experiencing is from this Hello World! example. When I mouse over the button, it's about 50:50 chance of clicking the button or just clicking "through" and giving focus to the underlying window (which is usually eclipse in my case). Would love you thoughts on this.

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

推荐答案

检查您的导入

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

You are using some kind of weird setup where you are mixing AWT/Swing classes and JavaFX classes, which really isn't advised (and doesn't work at all in the combination and manner you have used). Just be careful in your JavaFX programs not to import any java.awt.* or javax.swing.* classes unless you really know what you are doing in mixing code for two different toolkits.

示例解决方案

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

Here is a sample solution which imports only JavaFX classes and utilizes JavaFX events, but otherwise tries to stick to the coding/callback style of the sample code in your question. (The sample could be further simplified through use of 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<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;
    }
}

这篇关于JavaFx透明窗口-是的.鼠标透明-不用了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆