JOGL Tutorial 2 - Creating a Window

Windowing Toolkits

The first step in graphics programming is creating a window, which will contain OpenGL drawings. A window should be a familiar concept, as you see them all the time in operating systems with graphical user interfaces (GUIs). Windows are managed by a windowing system, and programmers can make use of toolkits to produce GUIs.

Three AWT frames (left to right): an undecorated window, a window with Java "look and feel", and a window with default operating system "look and feel"

If you’ve done GUI programming with Java before, you’re already familiar with AWT (and probably Swing), which is the Abstract Window Toolkit. Java makes creating a window very simple by using the Frame (AWT) or JFrame (Swing) classes. It takes only a few lines of code to display a window using AWT classes:

Frame frame = new Frame("A window");
frame.setSize(200, 75);

Java programmers can use the existing Java 2D API to program the rendering, or painting, of AWT and Swing interfaces. However, Java 2D is more for simple 2D effects, not advanced real-time rendering in 3D. This is why it is desirable to use JOGL, which provides access to the OpenGL API using Java. 

There are two main approaches I will describe for creating a window for OpenGL rendering within JOGL programs. The first method allows JOGL to hook into AWT components; the second is to use the NEWT API. Both of these approaches provide access to the windowing system used by the operating system (X11, GDI, etc.), but there are important performance and functionality considerations. JOGL provides the NativeWindow interface such that APIs other than AWT and NEWT may be used, as well.

The layers involved in creating windows with JOGL

The advantages to using AWT (or Swing) with JOGL:
  • Access to GUI widgets such as buttons, sliders, text fields, menu bars, etc.
  • Can mix OpenGL rendering with GUI components mentioned above, or even use OpenGL rendering inside of interface components
  • Familiar to most Java programmers
The advantages of using NEWT:
In my experience, using AWT or Swing is fine for most programs including those which may be considered demanding. I have only recently started exploring NEWT, so you may wish to try it yourself.

Basics of a JOGL Application 

Before explaining how to create window using either AWT or NEWT, there are a few classes that need to be described first. These classes are used regardless of the windowing toolkit, and they will be present in any JOGL application. I won’t go into too much detail here, but rather I will describe what these objects are used for at a high level. 

The field of computer graphics changes rapidly. Unlike many programming APIs, graphics APIs must often break backwards compatibility with each revision. New versions of OpenGL typically incorporate new functionality while deprecating or entirely removing older functionality. Programming OpenGL applications is not as simple as using the most recent version of OpenGL, because many users will not be able to run these applications. Even if users update their graphics drivers, their hardware itself must support the core features of the OpenGL version a program was written against.

It is important that programmers have control over which version of OpenGL is used by the application, and the GLProfile class allows just that. If a user has hardware drivers that support OpenGL 4.0, for example, they can still run OpenGL 2.1 programs. By using a GLProfile, the programmer can write their program in a manner that supports all users while still providing newer, more advanced functionality if is available. An instance of the GLProfile object can specify which versions are supported by the client and allow the program to conditionally use different pieces of code.

To select OpenGL 2.1, for example, a GLProfile would be created as follows: 

GLProfile glp = GLProfile.get(GLProfile.GL2);

The system's default OpenGL profile can be selected as well, which represents the profile which is "best for the running platform":

GLProfile glp = GLProfile.getDefault();

The developers of JOGL highly recommend calling the static method initSingleton before doing anything else in a JOGL program. This appears to be particularly relevant if you are using Linux, intend to perform any GUI work, or you're writing a multi-threaded application. The method allows JOGL to prepare some "Linux specific locking optimization" and what may otherwise be some unrecoverable crashes. It is suggested you add the following code to your main method before doing anything else:


Otherwise, put it in a static block inside your main class:

static { GLProfile.initSingleton(true); }

More details about GLProfile are explained here.

GLContext (OpenGL Rendering Context)
OpenGL is essentially a state machine, which might cause some confusion if you've only experienced pure object-oriented programming. States in OpenGL are things like current color, active drawing mode, if lighting is enabled, transformation details, and so on. An OpenGL rendering context is what keeps track of all these states. In JOGL, this context is abstracted into the GLContext class:

"In order to perform OpenGL rendering, a context must be 'made current' on the current thread. OpenGL rendering semantics specify that only one context may be current on the current thread at any given time, and also that a given context may be current on only one thread at any given time. Because components can be added to and removed from the component hierarchy at any time, it is possible that the underlying OpenGL context may need to be destroyed and recreated multiple times over the lifetime of a given component. This process is handled by the implementation, and the GLContext abstraction provides a stable object which clients can use to refer to a given context."

This object describes some specific capabilities a rendering context should support. The default settings are usually fine, but you can play with some of the capabilities for achieving certain effects such as full-scene anti-aliasing, stereo rendering, and so forth. This object takes an instance of GLProfile as a parameter.

GLCapabilities caps = new GLCapabilities(glp); 

GLDrawable GLAutoDrawable 
These are interfaces that describes a target for OpenGL rendering, and it has the purpose of creating and maintaining the rendering context. Implementations of GLAutoDrawable automatically create that rendering context, while GLDrawable requires the programmer to do so. I will focus on GLAutoDrawable, as the details of creating a context aren't necessary for basic graphics programming. 

The rendering mechanism of GLAutoDrawable is event-based, so the programmer provides an event listener (GLEventListener) to any implementation of GLAutoDrawable to perform the actual rendering. This class and the rendering process will be described in more detail later.

Creating a Window with AWT 

To work with AWT, JOGL provides a class GLCanvas which extends the AWT Component class, so it can be added to an AWT/Swing GUI. There are a few steps involved in creating a window that is prepared for OpenGL rendering:
  1. Choose GLProfile
  2. Configure GLCapabilities
  3. Create GLCanvas (implementation of GLAutoDrawable), which automatically creates our GLContext
  4. Add GLCanvas to Frame (the AWT Frame is our window)
Here's an example that will create a window using AWT. This is kept as simple as possible to show the minimum code to get a window up and running with AWT. The actual OpenGL rendering,  animation loop, and GLEventListener details will be covered later.

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class SimpleScene {
    public static void main(String[] args) {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        GLCanvas canvas = new GLCanvas(caps);

        Frame frame = new Frame("AWT Window Test");
        frame.setSize(300, 300);
        // by default, an AWT Frame doesn't do anything when you click
        // the close button; this bit of code will terminate the program when
        // the window is asked to close
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {

The result of running this program will actually vary depending on your windowing system and graphics drivers. The interior of the window may be completely different from what you see below: it may be filled with black or white, contain garbled graphics, etc. The window decoration depends upon your windowing system and appearance settings.

Creating a Window with NEWT

Using NEWT to create a window shares some of the steps from the AWT example:
  1. Choose GLProfile
  2. Configure GLCapabilities
  3. Create GLWindow (implementation of GLAutoDrawable), which automatically creates our GLContext
The following example is, once again, the minimum to get a native window up using NEWT.

import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;

public class SimpleScene {
    public static void main(String[] args) {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);

        GLWindow window = GLWindow.create(caps);
        window.setSize(300, 300);
        window.setTitle("NEWT Window Test");

        window.addWindowListener(new WindowAdapter() {
            public void windowDestroyNotify(WindowEvent arg0) {

Running Examples in Eclipse

Make sure you've configured your Eclipse workspace as described here. To run the above examples using Eclipse, create a new package in the Tutorials project folder:
  • Right click the Tutorials project
  • Select New > Package
  • Enter "windows" as the name
Now create a Java class inside the windows package:
  • Right click on the windows package inside the Tutorials project
  • Select New > Class
  • Enter "SimpleScene" as the name
  • Copy and paste one of the examples above into the source editor, overwriting anything that is there
  • At the top of the source code, type "package windows;" since the source file is inside the windows package
  • Save (ctrl-s or File > Save)
Eclipse should look like this:

Click the button that is a green circle with a white arrow inside to run your program. This button is at the top of Eclipse, just above the package explorer. Alternatively, right click and select "Run As > Java Application".