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: