JavaFX TransparentWindow Drawing

Demonstrates using JavaFX to create a transparent window with drawing. Developed on macOS; will not draw in Windows 11, but does allow click throughs. Not tested on Linux.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.canvas.*;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.event.ActionEvent;
import javafx.scene.input.InputEvent;
import javafx.scene.input.MouseEvent;

Canvas canvas;
Stage stage;
Scene scene;
Pane pane;
ActionEvent event;
MouseEvent msEvent;

GraphicsContext gc;
ColorPicker colorPicker;

void setup() {
  size(1, 1, FX2D);
  surface.setVisible(false);
  pane = new Pane();
  stage = new Stage();
  scene = new Scene(pane, displayWidth, displayHeight);
  // Canvas
  canvas = new Canvas(displayWidth, displayHeight);
  canvas.setLayoutX(0);
  canvas.setLayoutY(0);
  gc = canvas.getGraphicsContext2D();
  gc.setLineWidth(10.0);
  canvas.setOnMousePressed(event -> {
    gc.moveTo(event.getX(), event.getY());
  }
  );
  canvas.setOnMouseDragged(event -> {
    gc.lineTo( event.getX(), event.getY());
    gc.stroke();
    gc.setStroke(colorPicker.getValue());
    gc.setLineCap(StrokeLineCap.ROUND);
    gc.setLineJoin(StrokeLineJoin.ROUND);
  }
  );
  pane.getChildren().add(canvas);
  // Color Picker
  colorPicker = new ColorPicker(Color.BLUE);
  colorPicker.setLayoutX(60);
  colorPicker.setLayoutY(24);
  pane.getChildren().add(colorPicker);
  // Quit Button
  Button btn = new Button("Q");
  btn.setStyle("-fx-background-radius:5em;"+"-fx-min-width:30px;"+"-fx-min-height:30px;"+"-fx-max-width:30px;"+"-fx-max-height:30px;");
  btn.setLayoutX(10);
  btn.setLayoutY(24);
  btn.setOnAction(event -> {
     stage.close();
  }
  );
  pane.getChildren().add(btn);
  stage.setX(0);
  stage.setY(0);
  scene.setFill(null);
  scene.getRoot().setStyle("-fx-background-color: transparent");
  stage.initStyle(javafx.stage.StageStyle.TRANSPARENT);
  stage.setScene(scene);
  stage.setAlwaysOnTop(true);
  stage.show();
}

Output:

Addendum:

Can also use this technique to display an image and text. Image is taken from sketch folder in this example.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
import javafx.scene.text.*;
import javafx.event.ActionEvent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.nio.file.Path;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

Canvas canvas;
Stage stage;
Scene scene;
Pane pane;
ActionEvent event;
Image image;

void setup() {
  size(1, 1, FX2D);
  surface.setVisible(false);
  pane = new Pane();
  stage = new Stage();
  scene = new Scene(pane, displayWidth, displayHeight);
  // Canvas
  canvas = new Canvas(displayWidth, displayHeight);
  canvas.setLayoutX(0);
  canvas.setLayoutY(0);
  pane.getChildren().add(canvas);
  // Text
  Text text = new Text(400, 70, "Welcome to JavaFX!");
  text.setFont(new Font(35));
  pane.getChildren().add(text);
  // ImageView
  double requestedWidth = 600;
  double requestedHeight = 600;
  boolean preserveRatio = true;
  boolean smooth = true;
  try {
    image = new Image(new FileInputStream( sketchPath() + "/myImage.png"), requestedWidth, requestedHeight, preserveRatio, smooth);
  }
  catch (FileNotFoundException e) {
    println(e);
  }
  ImageView imageView = new ImageView(image);
  imageView.setLayoutX(250);
  imageView.setLayoutY(124);
  pane.getChildren().add(imageView); 
  // Quit Button
  Button btn = new Button("Q");
  btn.setStyle("-fx-background-radius:5em;"+"-fx-min-width:30px;"+"-fx-min-height:30px;"+"-fx-max-width:30px;"+"-fx-max-height:30px;");
  btn.setLayoutX(10);
  btn.setLayoutY(24);
  btn.setOnAction(event -> {
     stage.close();
  }
  );
  pane.getChildren().add(btn);
  stage.setX(0);
  stage.setY(0);
  scene.setFill(null);
  scene.getRoot().setStyle("-fx-background-color: transparent");
  stage.initStyle(javafx.stage.StageStyle.TRANSPARENT);
  stage.setScene(scene);
  stage.setAlwaysOnTop(true);
  stage.show();
}

Output:

1 Like

(post deleted by author)

Thanks for looking at it and glad that you got it running in Windows 10. For reasons unclear to me I am still unable to get it to run in Windows 11 even with these additions.

(post deleted by author)