Do G4P GUI controls have to be global variables?

I’m trying to use a GWinData to save data used by a child window. I thought I would be able to declare the controls used by the child window (buttons, droplists, etc.) inside the GWinData object, but it doesn’t seem to work, at least for a droplist. The program runs, but the current state of the droplist (the current selection, in other words) isn’t being saved. If I declare the droplist as a global variable outside of the GWinData object, it works, though.

If you open the child window and select something from the droplist (other than the first item), close the child window (click on the upper right corner), then re-open it, you’ll see that the first item in the droplist is still selected.

The reason I want to declare it in the GWinData object is just to avoid a proliferation of global variables, which is considered a bad programming practice in general. And in my case, I’m going to have several child windows, so I want to encapsulate the controls within the child window that uses them, if I can. If that isn’t possible, I can live with it. I just wanted to know if it is possible or not.

import g4p_controls.*;

class MyWinData extends GWinData {
  GDropList dropList;
  String[] dest = {"Selection 1","Selection 2","Selection 3"};
  int selected = 0;
}
GButton button = null;
GWindow window;
public void setup() {
  size(600,400,JAVA2D);
  G4P.setCtrlMode(GControlMode.CORNER);
  G4P.setGlobalColorScheme(GCScheme.GREEN_SCHEME);
  G4P.setMouseOverEnabled(true);
  button = new GButton(this, 15, 40, 60, 20);
  button.setText("SETUP");
  button.addEventHandler(this,"buttonHandler");
}
public void draw() {
  background(179,237,179);
}
public void buttonHandler (GButton source, GEvent event) {
  makeChildWindow();
  button.setEnabled(false);
}
public void makeChildWindow () {
  window = GWindow.getWindow(this,"Child Window",20,40,400,200,JAVA2D);
  window.setActionOnClose(G4P.CLOSE_WINDOW);
  window.addDrawHandler(this,"windowDraw");
  window.addOnCloseHandler(this,"windowClose");
  window.addData(new MyWinData());
  ((MyWinData)window.data).dropList = new GDropList(window, 20, 20, 120, 100, 5);
  ((MyWinData)window.data).dropList.addEventHandler(this, "dropListHandler");
  ((MyWinData)window.data).dropList.setItems(
      ((MyWinData)window.data).dest,
      ((MyWinData)window.data).selected);
  ((MyWinData)window.data).dropList.setEnabled(true);
}
public void windowDraw(PApplet app, GWinData data) {
  app.background(179,237,179);
}
public void windowClose(GWindow window) {
  button.setEnabled(true);
}
public void dropListHandler (GDropList source, GEvent event) {
  ((MyWinData)window.data).selected = source.getSelectedIndex();
}
1 Like

Never mind, I see what the problem is now. Just a silly mistake.

This is true, in fact you should extend this to - the scope of all variable should be as small as possible.
With particular reference to G4P, if you are using GUIBuilder to design the GUI then all the GUI control variables are global because it doesn’t know the scope needed by the user.

If you are creating a control manually you have greater control over scope so consider using local declarations or even anonymous objects like this.

import g4p_controls.*;

int nbrClicks = 0;

public void setup() {
  size(480, 320, JAVA2D);
  createGUI();
}

public void createGUI() {
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  G4P.setDisplayFont("Arial", G4P.PLAIN, 30);
  surface.setTitle("Sketch Window");
  // Local variable
  GWindow window = GWindow.getWindow(this, "GWindow control", 0, 0, 300, 120, JAVA2D);
  window.setActionOnClose(G4P.KEEP_OPEN);
  window.addDrawHandler(this, "windowDraw");
  window.addMouseHandler(this, "windowMouse");
  // Local variable
  GButton btnClicker = new GButton(window, 20, 20, 260, 40);
  btnClicker.setText("Please click me! ");
  btnClicker.addEventHandler(this, "btn_click_handler");
  fill(0, 60, 64);
  // Anonymous variable for GLabel on main window
  new GLabel(this, 20, 20, 400, 40, "I have no name LOL");
}

public void draw() {
  background(240, 240, 255);
}

public void windowDraw(PApplet appc, GWinData data) {
  appc.background(255, 240, 240);
}

public void btn_click_handler(GButton source, GEvent event) {
  nbrClicks++;
  source.setText("Clicks " + nbrClicks);
} 
3 Likes