Mutiple windows with G4P

This applet is a simple example to demonstrate the most advanced feature of G4P, multiple windows. When you click on the start button 3 windows will open and you can click and drag with the mouse to draw a rectangle in any of them. This example is included with the library and what follows is a description of the classes responsible for handling windows in G4P and how they are used.

To handle multiple windows the G4P has 3 main classes the first 2 are

  • GWindow this class inherits from (extends) the java.awt.Frame class and creates an application type actual window with the normal controls, minmise, close etc.
  • GWinApplet this class inherits from PApplet so provides all the features that we would expect from a Processing sketch.

When a GWindow is created a GWinApplet object is also created and embedded into the GWindow object. (Note the user would normally only access the GWinApplet object in the draw and event handling methods). Okay so now we have a sketch that has created a separate window which is basically a second Processing sketch except how can we use the second window because all the draw and event handling is in the GWinApplet object and we can't simply add our own draw method etc?

The solution is to create methods in the main sketch that will be called from the GWinApplet object and this is show in the following code (taken from the example)

window[i].addDrawHandler(this, "windowDraw");
window[i].addMouseHandler(this, "windowMouse");

This code tells the GWindow object the name of the method to be used. So in this case it will look for a method called windowDraw that has 2 parameters of type GWinApplet and GWindata e.g.

public void windowDraw(GWinApplet appc, GWinData data){

}

The appc parameter is a reference to the embedded GWinApplet object so can be used to access all the methods available in PApplet e.g. stroke, fill, color etc.

So now we come to the GWinData class but just before that I want to mention a couple of things.

  1. Since our 'windowDraw' method is in the main sketch it can access all the attributes (variables) in the main sketch.
  2. in the example code the same draw method has been used for all 3 windows, you might want a different method for each window this can be done with -
window[0].addDrawHandler(this, "windowDraw0");
window[1].addDrawHandler(this, "windowDraw1");
window[2].addDrawHandler(this, "windowDraw2");

So back to GWinData, in this example we have three windows using the same method to do essentially the same thing i.e. draw a rectangle BUT it is drawing a different rectangle for each window. I could create 3 sets of variables in the main applet for storing the rectangles position and size - not too bad for three windows but what if you had 10! In fact you might look at the Mandelbrot example where we can have dozens of windows, so our main applet is not a good place to store the windows data.

GWinData provides a mechanism for creating objects that can hold data required by a particular GWindow object. To use it you must create your own class that inherits from it i.e.

class MyWinData extends GWinData {

In this class (MyWinDate or whatever you want to call it) you can put any attributes and methods that you like. Then you create objects of this class and add them to the window e.g.

window[i].addData(new MyWinData());{

The only restriction is that in the handler methods, since it is provides a reference to a GWinData object we need to cast it to our class type so we can access the attributes and methods e.g.

public void windowDraw(GWinApplet appc, GWinData data){
	MyWinData data2 = (MyWinData)data;

Putting the cast at the beginning of the draw loop simplifies it use rather casting it every time we want to use data.