Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a JavaFX transparent window that ignores mouse and key events

Tags:

java

javafx

I want to make a JavaFX application that basically overlays the entire user screen with a Canvas object, so basically I can draw anything on the user's screen.

Making a window that covers the whole screen is simple. Making it essentially transparent can be achieved with this tutorial: https://assylias.wordpress.com/2013/12/08/383/

So the one and only thing stopping me is the fact that obviously, the window, albeit being transparent it will still capture user mouse and key events.

Is there a way I can achieve this? For a more concrete example, imagine I want to make a red circle surround the user's mouse cursor wherever it goes, but the user input will not be interrupted.

like image 334
Voldemort Avatar asked Apr 13 '16 01:04

Voldemort


People also ask

How do I make a scene transparent in JavaFX?

TRANSPARENT is a Color (which is a Paint ) and is not an int . So setting the fill to the transparent color is OK. This solution should work fine unless a Control is involved in the scene, in which case the additional CSS setting discussed in other answers is also required.

How do I create a new JavaFX window?

javafx Windows Creating a new Window // create sample content Rectangle rect = new Rectangle(100, 100, 200, 300); Pane root = new Pane(rect); root. setPrefSize(500, 500); Parent content = root; // create scene containing the content Scene scene = new Scene(content); Stage window = new Stage(); window.

Does JavaFX need a main method?

The main() method is not required for JavaFX applications when the JAR file for the application is created with the JavaFX Packager tool, which embeds the JavaFX Launcher in the JAR file.


2 Answers

What you want isn't possible in plain JavaFX.

You can check out my answer here, that's the closest thing. But you can't overlay a transparent canvas over the entire desktop and forward the mouse events to the underlying windows.

Having the Canvas semi-transparent would catch all events, but you could see the underlying windows. But when you have the Canvas fully transparent, your application wouldn't catch any events.

However, your "concrete example" could be solved in a different way. Here's the code:

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class CircleAroundCursor extends Application {

    double radius = 50;

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();

        Circle circle = new Circle( radius * 2,radius * 2,radius);
        circle.setStroke(Color.RED);
        circle.setFill(Color.TRANSPARENT);

        root.getChildren().add(circle);

        Scene scene = new Scene(root, Color.TRANSPARENT);

        scene.getRoot().setStyle("-fx-background-color: transparent");

        primaryStage.initStyle(StageStyle.TRANSPARENT);
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.setAlwaysOnTop(true);


        AnimationTimer loop = new AnimationTimer() {

            @Override
            public void handle(long now) {

                PointerInfo info = MouseInfo.getPointerInfo();
                Point p = info.getLocation();

                primaryStage.setX(p.getX() - radius * 2);
                primaryStage.setY(p.getY() - radius * 2);

            }
        };
        loop.start();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

This at least solves "I want to make a red circle surround the user's mouse cursor wherever it goes, but the user input will not be interrupted"

Note: Here AWT classes are mixed with FX classes. You may need to use an EDT & FX thread handling. It does work without though.

Screenshot:

enter image description here

like image 153
Roland Avatar answered Sep 30 '22 19:09

Roland


You may have a look at the Robot class. I have abused its powers many times, although I consider most solutions I used that class for as hacky.

Maybe you could do it like this:

  1. intercept MouseEvent and save its properties
  2. do your things like drawing
  3. make the Window invisible
  4. invoke the same MouseEvent with the help of Robot
  5. make the Windows visible again
like image 38
Jhonny007 Avatar answered Sep 30 '22 19:09

Jhonny007