How to make a program windowless/frameless?

So lets say I have this;

void setup(){
  size(200, 200);
  surface.setAlwaysOnTop(true);
}

void draw(){
  fill(255);
  textSize(35);
  text("Hello",50,75);
}

How can I get rid of the window frame and the background behind hello? Just hello showing up on screen?

I tried surface.setVisible(false); but it didn’t work.

And another question if anyone knows: How can I make the program see keyboard strokes outside the program ( like when the program isn’t clicked) ?

Another edit: found how to remove title bar but still don’t know about others

Another another edit: turns out the frame background doesn’t support transparency… f

1 Like
void setup() {
  fullScreen();
  surface.setSize(200, 200); //Change size here
}

void draw() {
  background(0);
  ellipse(mouseX, mouseY, 20, 20);
}
2 Likes

Yep, I found that after posting. Thanks anyway!

The frame background can have transparency, at least for the JAVA2D / “default” renderer in Processing. Here’s a post the question of which shows code for doing so:

I had myself used this technique many months ago, and it works nicely! I don’t know if the code in the aforementioned post still works as expected, but feel free to ask me for my old code if it doesn’t.

1 Like

Right on,

I was going to suggest fullScreen(SPAN); for apps that use the entire screen.

I’d love to get a sample of your code that has transparent window/background.

I literally just posted that question in the Code subforum

Thank you in advance!

Hello there…
…Iiiiiiiii know it has been 6 months, but it’s important that I write the answer here even though I’m this terribly late. At least for future readers.

Steps on how I did that back then:

  • Use the JAVA2D renderer in your call to size(),
  • Now we write some Java AWT code!
  • Get the AWT JFrame from your Processing sketch by using PApplet::getSurface(), then calling PSurface::getNative() on it, and casting it to a JFrame.
  • Give it a transparent background using JFrame::setBackground(). Pass a new Color(0, 0, 0, 1) into it. I think this has to be repeated in PApplet::draw().
  • Call JFrame::setOpacity() with 0.5f or a similar value. Setting the alpha in the background-color to 1 in the [1, 255] range that AWT accepts is enough only on Windows; opacity control is required everywhere else. It’s just neater to use it anyway…!
  • Use as desired!

The code is here: [ AndroidGameControllerLegacy/src/com/brahvim/androidgamecontroller/server/Sketch.java at 88b1cd89d853cf5d2304f013be57523a9fec0c3b · Brahvim/AndroidGameControllerLegacy · GitHub ], …though I realize now that it skipped over the entire concept of JFrame::setOpacity()!

I also realized that I essentially re-created Processing’s event-handling using AWT listeners, but in a poorer manner - one that does not consider using PApplet::handle*Event() methods. That part is apparently entirely useless!

Anyway. Here’s a minimal example:

import processing.awt.PSurfaceAWT;
import javax.swing.JFrame;

JFrame g_frame;

void setup() {
  g_frame = (JFrame) ((PSurfaceAWT.SmoothCanvas) super.getSurface().getNative()).getFrame();

  g_frame.removeNotify();

  g_frame.setUndecorated(true);

  g_frame.setBackground(new java.awt.Color(0, 0, 0, 1));
  g_frame.setOpacity(0.5f);

  g_frame.addNotify();

  rectMode(CENTER);
}

void draw() {
  background(0, 127);
  square(width * 0.5f, height * 0.5f, sin(millis() * 0.001f) * 40);
}

While digging through my archives, I also discovered a way to make “undecorated” windows in P3D mode.

import com.jogamp.newt.opengl.GLWindow;

GLWindow g_window;

void settings() {
  size(400, 400, P3D);
}

void setup() {
  g_window = (GLWindow)surface.getNative();
  super.surface.initOffscreen(this);
  registerMethod("post", this);
  textMode(MODEL);
}

void draw() {
  background(0, 102, 153, 1);

  noStroke();
  rect(0, 0, width, 30);

  stroke(0);
  fill(0);
  text("Press escape to close, :D", 10, 20);

  fill(255);
  circle(200, 200, abs(sin(millis() * 0.001f) * 50));
}

void post() {
  if (frameCount == 1 && !g_window.isUndecorated()) {

    try {
      
      g_window.setVisible(false);
      g_window.setUndecorated(true);
      while (!g_window.isUndecorated());
      g_window.setVisible(true);
      
    }
    catch(Exception e) {
      
    }

  }
}

Bonus: If you’d like to turn a P3D sketch into a “fullscreen”-ed one dynamically - that is, while it’s running - check out this trick you can perform in PApplet::post() that I used in my years-old project: [ TheNerdProject/src/com/brahvim/nerd/window_management/window_module_impls/NerdGlWindowModule.java at 003b1654ffdac4aee77af0d0c9fe23030ce4cfb6 · Brahvim/TheNerdProject · GitHub ].

All we’re doing here is literally “[busy-]waiting” until the GLWindow is fullscreen. Tracking time.
…Like every other time, here’s a simpler Processing sketch that should get you started [and done!]:

import com.jogamp.newt.opengl.GLWindow;

boolean fullscreen, pfullscreen;
GLWindow g_window;

void settings() {
  size(640, 480, P3D);
  super.registerMethod("post", this);
}

void setup() {
  g_window = (GLWindow) super.getSurface().getNative();
}

void draw() {
  background(0);
}

void keyPressed() {
  if (keyCode == 70) { // The `F` key. Think "Fullscreen"!

    fullscreen = !fullscreen;
    println("Changing screens...");

  }
}

void post() {
  if (pfullscreen != fullscreen) {

    g_window.setFullscreen(fullscreen);

    final long fsStartMillis = System.currentTimeMillis();

    while (fullscreen != g_window.isFullscreen()) {
      
      if (System.currentTimeMillis() - fsStartMillis > 5000) {
       
        break; // Throw an exception instead?
    
      }
  
    }

  }

  pfullscreen = fullscreen;
}

Hello @Brahvim ,

What version of Processing and which OS?

I am using W10 and Processing 4.4.10.

First example I need to comment this out to see the window:

  // g_frame.setBackground(new java.awt.Color(0, 0, 0, 1));
  // g_frame.setOpacity(0.5f);

Second example (error not highlighted):

NullPointerException
java.lang.NullPointerException: Cannot invoke "java.util.Set.iterator()" because "this.removals" is null
	at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1333)
	at processing.core.PApplet.handleMethods(PApplet.java:1460)
	at processing.core.PApplet.handleDraw(PApplet.java:2127)
	at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:840)
	at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
	at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
	at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
	at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
	at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
	at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:797)
	at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
	at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:471)
	at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:245)
	at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
	at java.base/java.util.TimerThread.run(Timer.java:516)
NullPointerException

1 Like

Ayeeh! I’m sorry. Glad you questioned!

TL;DR: Debian 12 or 13 (with KDE Plasma, atop X11), Windows 11 or 10. Processing 3.5.4!

I initially wanted to mention I myself was on Debian [13, with KDE Plasma and sddm, atop X11 (also 12…!)], but I recalled that JFrame::setOpacity() and even the GLWindow methods work on Windows [10 and 11], too!

(I have tested on all OSs mentioned here.)

…So while I don’t immediately changing between Windows or Linux matters, the version of Processing absolutely does! And I’m sorry to all those I disappoint: All of my code works with Processing 3.5.4. I’m sorry I did not consider Processing 4…!

I’m somewhat confident most of these “hacks” can be “translated” over. Though… I’m not aware of Processing 4’s internal changes. Will have to look into those.

Regardless, I hope we can do that!
Unfortunately, much of my work isn’t with Processing these days, so I can’t say how long it’ll take me to figure this out, but I’ll try :)!

PS I apologize in advance that my responses are going to be a few hours late.

1 Like

Hello @qewer3322,

This works with Processing 4.4.10 and Windows 10.

ChatGPT generated:

/*
 * This Processing sketch was generated with the help of ChatGPT.
 * Date: 2026-01-23
 */


import java.awt.Frame;               // Java's standard window class (AWT = Abstract Window Toolkit)
import processing.awt.PSurfaceAWT;   // Processing class that bridges its sketch to a Java AWT window

Frame frame; // This will hold the actual window (AWT Frame) that contains the Processing canvas

void settings() {
  // Create a 400x200 JAVA2D sketch
  // JAVA2D is Processing's default 2D renderer that draws using Java2D graphics
  size(400, 200, JAVA2D);
}

void setup() {
  // ---------------------------
  // Understanding the "surface"
  // ---------------------------
  // In Processing, the 'surface' is the object that represents where your sketch draws.
  // It manages the connection between Processing's drawing commands and the actual window.
  // For JAVA2D sketches, the surface wraps an AWT Frame and a Canvas inside it.
  PSurfaceAWT awtSurface = (PSurfaceAWT) surface; // Cast Processing's surface to an AWT-specific version

  // Get the canvas inside the surface
  // The canvas is the actual drawing area inside the window (where background(), text(), etc. appear)
  PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) awtSurface.getNative();

  // ---------------------------
  // Understanding the AWT Frame
  // ---------------------------
  // An AWT Frame is Java's object for a window with borders, title bar, and close/minimize buttons.
  // The "native peer" refers to the actual OS-level window that the Frame represents.
  // Processing creates this automatically when you call size().
  frame = (Frame) canvas.getFrame();

  // ---------------------------
  // Make the window borderless
  // ---------------------------
  // To remove the OS window decorations safely, we must first dispose the native peer
  frame.dispose();             // Temporarily destroys the OS window
  frame.setUndecorated(true);  // Remove title bar and borders
  frame.setResizable(false);   // Optional: disable resizing
  frame.setVisible(true);      // Show the frame again (now borderless)

  // Ensure Processing knows the canvas size, syncing it with the frame
  surface.setSize(width, height);

  // ---------------------------
  // Text setup
  // ---------------------------
  textAlign(CENTER, CENTER); // Center text horizontally and vertically
  textSize(24);              // Text size
  fill(255);                 // White text
}

void draw() {
  background(255, 0, 0); // Solid red background
  text("Borderless JAVA2D Window", width / 2, height / 2);
}

// ---------------------------
// Optional: ESC key handling
// ---------------------------
// Pressing ESC will close the sketch cleanly.
// Processing automatically calls exit() on ESC, so this is optional.
void keyPressed() {
  if (key == ESC) {
    key = 0; // Prevent default Processing ESC behavior
    println("So long folks!");
    delay(1000);
    exit();  // Close the sketch cleanly
  }
}

ChatGPT was used because this is an advanced topic and was able to generate a working and commented example. It took several passes and was a useful tool for an experienced user. The response should be subjected to scrutiny.

:)

I thought the goal was to get rid of the window frame and the background. Original poster asked:

The following source code achieves this:

import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

void setup() {
  size(1, 1, FX2D);
  Stage stage = new Stage();
  stage.initStyle(StageStyle.TRANSPARENT);
  Text text = new Text("Hello!");
  text.setFont(new Font(40));
  text.setLayoutX(60);
  text.setLayoutY(100);
  Pane pane = new Pane();
  pane.getChildren().add(text);
  Scene scene = new Scene(pane, 200, 200);
  scene.setFill(null);
  stage.setScene(scene);
  stage.setX(10);
  stage.setY(10);
  stage.show();
}

Hello folks!

This will work on W10 and Processing 4.4.10 in a Swing window:

/*
  Processing + Swing Overlay Demo
  -------------------------------
  Goal:
    Render content offscreen in Processing (PGraphics), convert it to a Java BufferedImage,
    then display it in a transparent, undecorated, always-on-top Swing JFrame.

  Pipeline:
    PGraphics (JAVA2D) -> PImage snapshot -> BufferedImage (ARGB) -> ImageIcon/JLabel -> JFrame

  Key points:
    - Processing launches the app and renders offscreen only.
    - Swing owns the visible window (JFrame) and presents the BufferedImage.
    - Alpha transparency is preserved end-to-end (clear() + TYPE_INT_ARGB + transparent JFrame).
*/

import java.awt.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
//import java.net.*;
//import java.io.*;

// ==============================
// Global Variables
// ==============================

JFrame frame;        // Floating Swing window
BufferedImage img;   // Final Java image buffer for Swing

// Offscreen drawing surface (Processing)
PGraphics pg;

// ==============================
// Processing Setup
// ==============================

void settings() {
  size(1, 1);  // Minimal Processing window
}

void setup() {
  surface.setVisible(false); // Hide the Processing window
  createImageWindow();       // Build and show the Swing overlay
}

void draw() {
  // No Processing drawing on the main surface; Swing handles the visible window.
}

// ==============================
// Build the Swing overlay window
// ==============================

void createImageWindow() {

  // 1) Render offscreen to a PGraphics buffer.
  // JAVA2D keeps pixels CPU-accessible for transfer into BufferedImage.
  pg = createGraphics(200, 100, JAVA2D);
  pg.beginDraw();
  pg.clear(); // Transparent background
  pg.fill(0, 255, 0);
  pg.textSize(48);
  pg.textAlign(CENTER, CENTER);
  pg.text("TEXT", pg.width/2, pg.height/2);
  //pg.save("/data/image.png"); // Optional: save the generated buffer
  pg.endDraw();

  // 2) Snapshot the PGraphics into a PImage (CPU-side pixel array).
  PImage pi = pg.get();

  // Optional: use a file image instead of generated content.
  //pi = loadImage("image.png");

  pi.loadPixels();

  // 3) Copy Processing pixels (ARGB ints) into a Java BufferedImage (ARGB).
  BufferedImage img = new BufferedImage(pi.width, pi.height, BufferedImage.TYPE_INT_ARGB);
  img.setRGB(0, 0, pi.width, pi.height, pi.pixels, 0, pi.width);

  // 4) Display in Swing: ImageIcon -> JLabel -> transparent, undecorated JFrame.
  ImageIcon icon = new ImageIcon(img);
  JLabel label = new JLabel(icon);

  frame = new JFrame();
  frame.setUndecorated(true);
  frame.setBackground(new Color(0, 0, 0, 0)); // Transparent window background
  frame.setAlwaysOnTop(true);
  frame.add(label);
  frame.pack();
  frame.setVisible(true);
}

Reference:

:)