Is it possible to open a second window in processing 3.4 using G4P

Hello,
i am using G4P and i want to open a second window using the variables set in the G4P window. Is there a way ?
thanks

OK no problem so far!

Now that bit is not clear. What variables? What G4P window? Can you explain a little more?

Tanks for your answer quark,
I used G4P to built a window with textfields check-boxes buttons etc the result is what i called the G4P window. In that window, the user will set parameters like : size of the new window, thickness of the lines, the number of shapes to use or the color list for the shapes and others.
When the user clicks on the “execute” button i would like to start a program receiving these parameters and building a new windows with them.
I hope this will explain what a try to do. If not, tell me i will send you examples.

Creating a new GWindow is straightforward enough but to launch a new program (sketch) and passing values form an existing sketch is a different problem altogether.

Are you using the GUI Builder tool to create your initial GUI?

@quark
Creating a new GWindow is straightforward enough
Please show me how to create a new GWindow it could be the answer …

Are you using the GUI Builder tool to create your initial GUI?
yes i do

I created this sketch using GUI Builder. I have removed all the comments and merged the code from the two tabs for this forum. WARNING it does not perform any error checking on the values entered by the user. The code is fairly self explanatory.

The window is created in the makeWindow(...) method

// Need G4P library
import g4p_controls.*;

GWindow window;

String renderer;

public void setup() {
  size(300, 240, JAVA2D);
  // Turn off mouse over icon change due to Processing bug
  G4P.setMouseOverEnabled(false);
  createGUI();
  customGUI();
  // Place your setup code here
}

public void draw() {
  background(230);
}

// Use this method to add additional statements
// to customise the GUI controls
public void customGUI() {
  renderer = JAVA2D;
}

public void selectJava2D(GOption source, GEvent event) {
  renderer = JAVA2D;
}

public void selectP2D(GOption source, GEvent event) {
  renderer = P2D;
}

public void selectP3D(GOption source, GEvent event) {
  renderer = P3D;
}

public void makeWindow(GButton source, GEvent event) {
  String title = txfTitle.getText();
  int x = int(txfX.getText());
  int y = int(txfY.getText());
  int w = int(txfW.getText());
  int h = int(txfH.getText());
  window = GWindow.getWindow(this, title, x, y, w, h, renderer);
  source.setVisible(false);
} 

public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setCursor(ARROW);
  surface.setTitle("Sketch Window");
  lblTitle = new GLabel(this, 10, 10, 70, 20);
  lblTitle.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblTitle.setText("Title");
  lblTitle.setOpaque(false);
  lblX = new GLabel(this, 10, 40, 70, 20);
  lblX.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblX.setText("X position");
  lblX.setOpaque(false);
  lblY = new GLabel(this, 10, 70, 70, 20);
  lblY.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblY.setText("Y position");
  lblY.setOpaque(false);
  lblW = new GLabel(this, 10, 100, 70, 20);
  lblW.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblW.setText("Width");
  lblW.setOpaque(false);
  lblH = new GLabel(this, 10, 130, 70, 20);
  lblH.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblH.setText("Height");
  lblH.setOpaque(false);
  optRenderer = new GToggleGroup();
  optJava2D = new GOption(this, 90, 160, 70, 20);
  optJava2D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optJava2D.setText("JAVA2D");
  optJava2D.setOpaque(false);
  optJava2D.addEventHandler(this, "selectJava2D");
  optP2D = new GOption(this, 160, 160, 50, 20);
  optP2D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optP2D.setText("P2D");
  optP2D.setOpaque(false);
  optP2D.addEventHandler(this, "selectP2D");
  optP3D = new GOption(this, 210, 160, 50, 20);
  optP3D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optP3D.setText("P3D");
  optP3D.setOpaque(false);
  optP3D.addEventHandler(this, "selectP3D");
  optRenderer.addControl(optJava2D);
  optJava2D.setSelected(true);
  optRenderer.addControl(optP2D);
  optRenderer.addControl(optP3D);
  txfTitle = new GTextField(this, 90, 10, 170, 20, G4P.SCROLLBARS_NONE);
  txfTitle.setText("My Window");
  txfTitle.setOpaque(true);
  txfX = new GTextField(this, 90, 40, 170, 20, G4P.SCROLLBARS_NONE);
  txfX.setText("100");
  txfX.setOpaque(true);
  txfY = new GTextField(this, 90, 70, 170, 20, G4P.SCROLLBARS_NONE);
  txfY.setText("60");
  txfY.setOpaque(true);
  txfW = new GTextField(this, 90, 100, 170, 20, G4P.SCROLLBARS_NONE);
  txfW.setText("800");
  txfW.setOpaque(true);
  txfH = new GTextField(this, 90, 130, 170, 20, G4P.SCROLLBARS_NONE);
  txfH.setText("600");
  txfH.setOpaque(true);
  lblRenderer = new GLabel(this, 10, 160, 70, 20);
  lblRenderer.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblRenderer.setText("Renderer");
  lblRenderer.setOpaque(false);
  btnMakeWindow = new GButton(this, 10, 190, 250, 30);
  btnMakeWindow.setText("Make the window");
  btnMakeWindow.setTextBold();
  btnMakeWindow.addEventHandler(this, "makeWindow");
}

GLabel lblTitle; 
GLabel lblX; 
GLabel lblY; 
GLabel lblW; 
GLabel lblH; 
GToggleGroup optRenderer; 
GOption optJava2D; 
GOption optP2D; 
GOption optP3D; 
GTextField txfTitle; 
GTextField txfX; 
GTextField txfY; 
GTextField txfW; 
GTextField txfH; 
GLabel lblRenderer; 
GButton btnMakeWindow; 
1 Like

Although I don’t know if this works with G4P or not, I think that this is relevant enough to post here.
One thing I figured out(i.e. shamelessly stolen from the forums) is that you can define another sketch inside your sketch. Here’s some random bit of code I figured out:


int mousePosition;
void settings() {
  size(640, 480, P2D);
}
void draw() {
  background(0);
  mousePosition=mouseX;
  text("Current time is "+millis()/1000, 0, 15);
}

void mousePressed() {
  runSecondWindow();
}


void runSecondWindow() {
  String[] args = {
    "test" //First argument seems to be eaten...?
    , 
    "Argument #1: launched at "+(millis()/1000)
    , 
    "Argument #2: mouse position was "+mouseX+" and "+mouseY
  };
  PApplet.runSketch(args, new NewWindowThing());
}


public class NewWindowThing extends PApplet {
  void settings() {
    size(320, 120); //Don't set this to P2D - if you do, closing main window will make a ThreadDeath.
  }
  void setup() {
    surface.setTitle("Hi. "+random(1));
  }
  void draw() {
    background(128, 64, 128);
    fill(255);
    text("mousePosition: "+mousePosition, 0, 15);
    text("Arguments:", 0, 30);
    if (args!=null) { //Go through arguments
      for (int i=0; i<args.length; i++) {
        text(args[i], 0, 45+15*i);
      }
    }
  }
}

Click on the main window to spawn a new window with custom arguments.
There are 2 little inconveniences to this that I found: first one is that you have to define size() only inside settings() and not in setup() for it to work properly, and that setting the second window’s renderer to P2D in size() results in a ThreadDeath appearing when you close the main window.
Other than that, it’s quite awesome. You can access your main variables from that second window and do things with them, and so far I didn’t really had problems with that. At one point I had a big array of objects that was being read and written from both windows, and never really had any problems with it.

If you feel like it, you could make a counter that goes up with every launched window to give them a unique ID, and then have an array of objects that you append() a new one to every time you make a new window - and then have every single window operate on an object of its ID in the array. (although, if you want multithreading, I think it’s better to look into thread() function instead.

1 Like

thanks quark, i will try this.

@Architector_4
thanks for that reply i will try this way too.

@quark
I have a problem with the code below. All the objects described in createNewGUI()
come into the initial window instead of the new window and i cannot fix it. Can you help ?

public void makeWindow(GButton source, GEvent event) {
  //String title = txfTitle.getText();
  //int x = int(txfX.getText());
  //int y = int(txfY.getText());
  //int w = int(txfW.getText());
  //int h = int(txfH.getText());
  String title = "New window";
  int x = 1;
  int y = 1;
  int w = 600;
  int h = 400;
  window = GWindow.getWindow(this, title, x, y, w, h, renderer);
  window.setup();
  createnewGUI();
}


public void createnewGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setCursor(ARROW);
  surface.setTitle("Sketch Window");
  lblTitle = new GLabel(this, 10, 10, 70, 20);
  lblTitle.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblTitle.setText("Title");
  lblTitle.setOpaque(false);
  lblX = new GLabel(this, 10, 40, 70, 20);
  lblX.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblX.setText("X position");
  lblX.setOpaque(false);
  lblY = new GLabel(this, 10, 70, 70, 20);
  lblY.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblY.setText("Y position");
  lblY.setOpaque(false);
  lblW = new GLabel(this, 10, 100, 70, 20);
  lblW.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblW.setText("Width");
  lblW.setOpaque(false);
  lblH = new GLabel(this, 10, 130, 70, 20);
  lblH.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblH.setText("Height");
  lblH.setOpaque(false);
  optRenderer = new GToggleGroup();
  optJava2D = new GOption(this, 90, 160, 70, 20);
  optJava2D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optJava2D.setText("JAVA2D");
  optJava2D.setOpaque(false);
  optJava2D.addEventHandler(this, "selectJava2D");
  optP2D = new GOption(this, 160, 160, 50, 20);
  optP2D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optP2D.setText("P2D");
  optP2D.setOpaque(false);
  optP2D.addEventHandler(this, "selectP2D");
  optP3D = new GOption(this, 210, 160, 50, 20);
  optP3D.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  optP3D.setText("P3D");
  optP3D.setOpaque(false);
  optP3D.addEventHandler(this, "selectP3D");
  optRenderer.addControl(optJava2D);
  optJava2D.setSelected(true);
  optRenderer.addControl(optP2D);
  optRenderer.addControl(optP3D);
  txfTitle = new GTextField(this, 90, 10, 170, 20, G4P.SCROLLBARS_NONE);
  txfTitle.setText("My Window");
  txfTitle.setOpaque(true);
  txfX = new GTextField(this, 90, 40, 170, 20, G4P.SCROLLBARS_NONE);
  txfX.setText("100");
  txfX.setOpaque(true);
  txfY = new GTextField(this, 90, 70, 170, 20, G4P.SCROLLBARS_NONE);
  txfY.setText("60");
  txfY.setOpaque(true);
  txfW = new GTextField(this, 90, 100, 170, 20, G4P.SCROLLBARS_NONE);
  txfW.setText("800");
  txfW.setOpaque(true);
  txfH = new GTextField(this, 90, 130, 170, 20, G4P.SCROLLBARS_NONE);
  txfH.setText("600");
  txfH.setOpaque(true);
  lblRenderer = new GLabel(this, 10, 160, 70, 20);
  lblRenderer.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
  lblRenderer.setText("Renderer");
  lblRenderer.setOpaque(false);
  btnMakeWindow = new GButton(this, 10, 190, 250, 30);
  btnMakeWindow.setText("Make the window");
  btnMakeWindow.setTextBold();
  btnMakeWindow.addEventHandler(this, "makeWindow");
}

GLabel lblTitle; 
GLabel lblX; 
GLabel lblY; 
GLabel lblW; 
GLabel lblH; 
GToggleGroup optRenderer; 
GOption optJava2D; 
GOption optP2D; 
GOption optP3D; 
GTextField txfTitle; 
GTextField txfX; 
GTextField txfY; 
GTextField txfW; 
GTextField txfH; 
GLabel lblRenderer; 
GButton btnMakeWindow;

First learn how to format code in this forum, it is simple enough select/highlight the code using the mouse, then click on the </> button.

In you code above make the following changes

  1. In the makeWindow method change the line
    createnewGUI();
    to
    createnewGUI(window);

  2. In the createnewGUI method change the line
    public void createnewGUI(){
    to
    public void createnewGUI(GWindow gw){

  3. In the createnewGUI method locate all the control creation statments (have the word new in them and change the first parameter from this to gw. Here is what the first one should look like
    lblTitle = new GLabel(gw, 10, 10, 70, 20);
    do the same for the rest.

1 Like

@quark
It works thank you Quark !

1 Like

At one point I had a big array of objects that was being read and written from both windows, and never really had any problems with it

hello Architector_4. I am trying to use your method with a very large program in Eclipse (that is using the Processing library). I am struggling to figure out how to communicate, ie. share objects between the different Applets. I am not new to Processing but I am to full Java and Eclipse.

thank you for any help

I think you could give your second applet’s class a new constructor that accepts all the objects it could ever want, and feed them that way. Here’s my example modified so that the second sketch has a custom constructor that takes a PVector and the parent sketch’s class to know who to refer to.

int mousePosition;

NewWindowThing second;

void settings() {
  size(640, 480, P2D);
}
void draw() {
  background(0);
  mousePosition=mouseX;
  text("Current time is "+millis()/1000, 0, 15);
}

void mousePressed() {
  if (second==null) { // If it wasn't ran already
    second = new NewWindowThing(new PVector(mouseX, mouseY), this); // Create brand new instance of second window
    String[] args = {"Hi."};
    PApplet.runSketch(args, second); // Run it.
  }
}

public class NewWindowThing extends PApplet {

  PVector coolThing;
  myClass parent; // "myClass" refers to the class of the parent sketch, if testing in Processing rename to your project's name


  NewWindowThing(PVector myCoolThing, myClass myParent) { // "myClass" refers to the class of the parent sketch, if testing in Processing rename to your project's name

    coolThing = myCoolThing;
    parent = myParent;
  }

  void settings() {
    size(320, 120); //Don't set this to P2D - if you do, closing main window will make a ThreadDeath.
  }
  void setup() {
    surface.setTitle("Hi. "+random(1));
  }
  void draw() {
    background(128, 64, 128);
    fill(255);
    text("Mouse is at: "+parent.mousePosition, 0, 15);
    text("And the last key pressed in parent is "+parent.key, 0, 30);
    text("That cool vector we got is: X: "+coolThing.x+", Y: "+coolThing.y, 0, 45);
  }
}

Also I suggest not making the second applet class inside of your main applet class, but separate them into 2 different .java files. I’d give an example, but I don’t have Eclipse installed on the machine I’m using right now, sorry.

2 Likes

Ah this is just great Architector_4. I have applied what you have suggested to my project and it 100% works. Many many thanks :slight_smile:

Hello all and Architecture_4. I “shamelessly” stole your code to open a new window/sketch. I managed to make my hacks to it -more or less- work. I have one problem. If I close the new sketch/window, it also closes the parent window. I’d prefer it if this didn’t happen and is in all likelihood something I’ve done wrong/left out. Can you make any suggestions for me to try please ? Finally, thanks for making your code available.

1 Like