Fullscreen in Processing.org with Eclipse

Processing.org is very useful for making audio-visual applications quickly and easily.  The included Processing Development Environment (PDE) makes it easy for nonprogrammers to get started with Processing and Java programming in general but experienced programmers will probably prefer using their IDE of choice, such as Eclipse.

Processing.org has some instructions on using the Processing library with Eclipse which is a good overview for transitioning to pure Java code since the PDE performs some pre-processing that allows for their simplified syntax.

The PDE has a ‘present’ mode that makes it real easy to view the program in fullscreen but it only works on the primary display and is not directly accessible in Eclipse.

In my work on my live animation program I have figured out the code to use the default present mode with Eclipse and to do arbitrary fullscreen that automatically scales to fit the device. This way I do not need to modify any width & height variables when i set up using a projector or another monitor.

After the jump are some code snippets to help get fullscreen working automatically regardless of screen size and layout.

Present Mode in Eclipse

The Processing in Eclipse tutorial from the official Processing website specifies how to run the sketch as a Java Application (instead of Java Applet) and access present mode.

This is done by putting in a standard java main() method and explicitly calling the processing applet’s main() method with certain parameters:

  public static void main(String args[]) {
    PApplet.main(new String[] { "--present", "MyProcessingSketch" });
  }

“MyProcessingSketch” must equal the class name (case sensitive) of the main sketch. This is whichever file has the setup() and draw() methods. The PApplet.main() function provides a wrapper around your applet so that you can modify properties about the window (such as its size and location).

Arbitrary Fullscreen

For my project I wanted to automatically detect the presence of a secondary display (most likely a projector) and position the animation window to perfectly fit the projector window. This required adding code to a few places in my application.

Note that I have tested this only in Windows. There may be slight syntax changes depending on platform. Consult the source code for Processing to see how they do presentation mode for each platform if needed.

Positioning the Frame

The PApplet.main() method provides a command line option to position the window which is the first step to putting the window in fullscreen on a projector. See the docs for PApplet.main() for more information.

To do this we detect the presence of a secondary display and the size of the primary display so we know where to put it. This assumes that the second display is to the right of the main one and that they are at the same height (so y=0).

      public static void main2(String args[]) {

          int primary_display = 0; //index into Graphic Devices array...  

          int primary_width;

          GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
          GraphicsDevice devices[] = environment.getScreenDevices();
           String location;
           if(devices.length>1 ){ //we have a 2nd display/projector

               primary_width = devices[0].getDisplayMode().getWidth();
               location = "--location="+primary_width+",0";

           }else{//leave on primary display
               location = "--location=0,0";

           }

          String display = "--display="+primary_display+1;  //processing considers the first display to be # 1
            PApplet.main(new String[] { location , "--hide-stop", display,"RazzleX" });

          }

Modifying the Frame

We need to extend the init() method in PApplet that is called before setup() so we can access the Frame before it is drawn to the screen. We use this time to remove the window decoration, namely the titlebar with the ‘X’ on it to close. I think this might not work similarly on Mac OSX. The source code for PApplet (and Processing in general) may be of use to see how they do it.

This function goes somewhere in the same file that has setup(). Note that this only works if running as a Java Application (using the main() methods described above). Otherwise frame is null and we can’t modify it.

public void init(){
          if(frame!=null){
            frame.removeNotify();//make the frame not displayable
            frame.setResizable(false);
            frame.setUndecorated(true);
            println("frame is at "+frame.getLocation());
            frame.addNotify();
          }
        super.init();
    }

Note also that the docs for Java says that removeNotify() and addNotify() should not be called
by the user application so this may cause unintended side effects somewhere else.

We call super.init() at the end to ensure the rest of the PApplet is properly initialized.

Resizing the Window

My code needs to know the size of the window so that things can be properly centered or otherwise distributed. The built-in Processing variable ‘screen’ only provides the width & height of the main screen which in this case is not the one we want. Thus in setup() we access the GraphicsEnvironment again and set some variables. Below is an excerpt of my setup() method.

int WIDTH, HEIGHT;

 public void setup(){

     //***** figure out the display environment ****/
      GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
      GraphicsDevice devices[] = environment.getScreenDevices();
     //  System.out.println(Arrays.toString(devices));

       if(devices.length>1 ){ //we have a 2nd display/projector
           //learn the true dimensions of the secondary display
           WIDTH =devices[1].getDisplayMode().getWidth();
           HEIGHT= devices[1].getDisplayMode().getHeight();
           println("Adjusting animation size to "+WIDTH+"x"+HEIGHT+" b/c of 2ndary display");
       }else{ //no 2nd screen but make it fullscreen anyway
           WIDTH =devices[0].getDisplayMode().getWidth();
           HEIGHT= devices[0].getDisplayMode().getHeight();
           println("Adjusting animation size to "+WIDTH+"x"+HEIGHT+" to fit primary display");
       }
}

Note that this assumes that the primary display is indexed as 0 and the secondary display to be used is indexed as 1.

This may be different depending on the system configuration.

With the above code modifications it should be possible (at least in Windows) to make an application that automatically sizes to the screen, and automatically uses a secondary display if available.

posted on Tuesday, February 10th, 2009 by Pehr in Code