How do I create a fullscreen window with title bar on my second monitor?

The title describes the problem.

I can use fullScreen() to cover the screen with a window on any monitor. But it doesn’t have a title bar.

The following code creates a window with a title bar that covers the screen. But only for the default monitor. (Also, the positioning is wrong, since a bug persists from years ago.)

void settings() {
    size(displayWidth, displayHeight);
}

void setup() {
    surface.setTitle("my application");
    surface.setLocation(0, 0);
}

void draw() {
    background(0);
    fill(200);
    circle(mouseX, mouseY, width/4.);
}

Three years later and I found my own post about the problem. Which still exists!

How do we properly position a window without an error of several pixels?

How can we create a window on a second monitor that is NOT full screen?

Hello @esc746,

I have used java.awt.Robot for issues like this and it works for Windows 10 and has been useful for other projects for me.
There may be other solutions.

This seems to work for Windows 10:

import java.awt.Robot;
import java.awt.event.KeyEvent;

void settings() {
    size(displayWidth, displayHeight);
    println(displayWidth, displayHeight);
}

void setup() {
    // Initialize surface size to full screen
    surface.setResizable(true);
    //surface.setLocation(0, 0);
    //surface.setSize(displayWidth, displayHeight);

    // Maximize window using Robot (Windows-specific)
    try {
        Robot robot = new Robot();
        robot.keyPress(KeyEvent.VK_ALT);
        robot.keyPress(KeyEvent.VK_SPACE);  // Open the window menu
        robot.keyRelease(KeyEvent.VK_SPACE);
        robot.keyRelease(KeyEvent.VK_ALT);

        //delay(100); // Add a small delay for the menu to open

        robot.keyPress(KeyEvent.VK_X);  // Simulate pressing "X" to maximize the window
        robot.keyRelease(KeyEvent.VK_X);
    } catch (Exception e) {
        println("Error using Robot to maximize window: " + e);
    }
}

void draw() {
    background(0);
    fill(200);
    circle(mouseX, mouseY, width / 4.0);
}

This is my monitor arrangement (they are each 1920x1200):

This moves it to my second monitor:

surface.setLocation(-displayWidth, 0);

Reference:

:)

The operating system was not given in your post. The following source code works on a Mac M4 running Tahoe 26.2:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

void setup() {
  size(600,600);
  surface.setTitle("Default Window");
  surface.setResizable(true);
  JFrame frame = new JFrame("JFrame Window");
  frame.setBounds(2500,200,800,800);
  frame.setVisible(true);
  frame.setAlwaysOnTop(true);
}

void draw(){
}

Output from your code on Windows 10 has a similar issue with the original sketch (it is off to the right a few pixels):

Only adjustment to your code:

  frame.setBounds(0, 0, 1920, 1200);  // Display 1
  //frame.setBounds(-1920, 0, 1920, 1200);  // Display 2

Update

My monitors are 1920x1200 so the above is same as:

  frame.setBounds(0, 0, displayWidth, displayHeight);  // Display 1
  //frame.setBounds(-displayWidth, 0, displayWidth, displayHeight);  // Display 2

See previous posts for my monitor arrangement which is why there is a -displayWidth

Not sure what you’re trying to say. JFrame is on second monitor and he stated that he did not want it full screen, although that can be easily done by hitting the third button on a Mac.

Hello folks!

Summary of my observations follows…

Observation #1:

  • Windows 10
  • Orange background.
  • Code from original post.
  • surface.setLocation(0, 0);

Upper left corner:

It goes off the screen on the right side.

Observation #2:

  • Same as #1 with this change to move to second monitor:
  • surface.setLocation(-displayWidth, 0);
  • The same offset as #1 is observed

Observation #3:

  • Windows 10
  • Code from @svan post
  • frame.setBounds(0, 0, 1920, 1200); // Display #1 resolution

Upper left:

Bottom left:

Upper right:

Observation #4:

  • Windows 10
  • Code from @svan post
  • frame.setBounds(-1920, 0, -1920, 1200); // Display #2 resolution

This moves it to the second display with the same results as #3

Observation #4:

  • Windows 10
  • Code from original post.
  • This is required to maximize it (keyboard, mouse or
    java.awt.Robot) with Windows:
    surface.setResizable(true);

Before (it is off screen to the right):

Maximized (title bar is smaller vertically and also fits inside Windows display):

The above may provide some insight to the behavior on Windows and a solution\workaround for your questions (subject and posts).

I did try and in the end the Windows keyboard\mouse or automating with java.awt.robot was a solution on my end to maximize it with the title bar.

As for the placement being off I do not have an answer for this at this time.

Have fun!

And finally… It only works for the default JAVA2D renderer:

Code

Chat GPT (free version) was used to help iterate down to a working minimal solution after many failed attempts.

Windows 10 PC.

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

JFrame frame;

void setup() {
  size(600, 400); // Default is JAVA2D
  surface.setTitle("Processing Window Control Demo");
  surface.setResizable(true);
  surface.setLocation(100, 100); // Display 1
  //surface.setLocation(-1920 +100, 100); // Display 2

  // Correct way to get the JFrame in Processing 4
  PSurfaceAWT awtSurface = (PSurfaceAWT) surface;
  PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) awtSurface.getNative();
  frame = (JFrame) canvas.getFrame();
  
  // Cool trick! 
  // Simulates keypress on start to maximize:
  //key= 'X';
  //keyPressed();
  
  //Or do this:
  //frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
}

int count = 0;

void draw() {
  background(200);
   
  fill(0);
  textSize(24);
  
  if (frameCount%30 == 0)
   count++; 
   
  textAlign(LEFT, TOP); 
  text(count, 10, 10); 
  
  textAlign(CENTER, CENTER);
  text("Window Controls:\n" +
       "M = Minimize\n" +
       "X = Maximize\n" +
       "R = Restore\n" +
       "H = Hide\n" +
       "S = Show", width/2, height/2);       
}

void keyPressed() {
  if (key == 'M' || key == 'm') {
    frame.setState(JFrame.ICONIFIED); // Minimize
  } else if (key == 'X' || key == 'x') {
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // Maximize
  } else if (key == 'R' || key == 'r') {
    frame.setExtendedState(JFrame.NORMAL); // Restore
  } else if (key == 'H' || key == 'h') {
    frame.setVisible(false); // Hide
  } else if (key == 'S' || key == 's') {
    frame.setVisible(true); // Show
  }
}

Reference:

I restored my orange background to a nice comfortable black.

:)

(Also, the positioning is wrong, since a bug persists from years ago.)

There is nothing wrong with the original post on my Mac system so it must be a Windows problem.

The image below is a screenshot from my Mac:

Hello @esc746,

I did some further exploration here:

It certainly helped me understand the behavior in Windows 10 and make adjusments as required.

:)