G4P Key Event Fires Twice

Some reason when I use a key event on a second window, the event is fired twice. Issue is there for image buttons and normal buttons. Have also tried the new update to the library but no joy.

Here’s repeatable code:

import g4p_controls.*;
import java.awt.Font; 

GWindow qBox = null;
GLabel lblQBox;
GImageButton imgBtnOKQBox;
GImageButton imgBtnCancelQBox;

int buttonWidth = 80;
int buttonHeight = 30;
int buttonXOffset = 100;
int buttonYOffset = 50;

public void setup(){
   size(300, 300, JAVA2D);
   createGUI();
};
public void draw(){
  background(200);
}

public void qBoxDraw(PApplet app, GWinData data){
  qBox.background(127);  
}
  
void showQBox(String strTitle, String strMessage) {
  int windowWidth = 300;
  int windowHeight = 160;
  if (qBox == null) {
    qBox =  GWindow.getWindow(this, strTitle, width/2 + 120, height/2 + 65, 300, 160, JAVA2D);
    qBox.setActionOnClose(G4P.HIDE_WINDOW);//HIDE_WINDOW
    qBox.addDrawHandler(this, "qBoxDraw"); 
    qBox.addKeyHandler(this, "qBoxKey");
    
    btnOK = new GButton(qBox, 50, 100, 80, 30);
    btnOK.setText("OK");
    btnOK.addEventHandler(this, "btnOK_click");
    
    btnCancel = new GButton(qBox, 175, 100, 80, 30);
    btnCancel.setText("Cancel");
    btnCancel.addEventHandler(this, "btnCancel_click");   
    
  }//if (qBox == null) {
  else {
    //imgBtnOKQBox.addEventHandler(this, "btnOK_click");
    //qBox.addKeyHandler(this, "qBoxKey");
    //qBox.setTitle(strTitle);
    //qBox.setVisible(true);  
  }    
}


public void qBoxKey(PApplet app, GWinData data, KeyEvent event) {
  if (event.getKey() == RETURN || event.getKey() == ENTER) { 
    onYes();
  }
}

public void btnOK_click(GButton source, GEvent event) {
  onYes();  
}
public void onYes(){
  qBox.setVisible(false);
  println();
  println("RUNNING KEY EVENT!");
  
}

public void btnCancel_click(GButton source, GEvent event) {  
  qBox.setVisible(false);    
}

public void btnTest_click(GButton source, GEvent event) { //_CODE_:button1:499313:
  println("button1 - GButton >> GEvent." + event + " @ " + millis());
  showQBox("Title","Message");
} //_CODE_:button1:499313:

public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  btnTest = new GButton(this, 102, 130, 80, 30);
  btnTest.setText("Test");
  btnTest.addEventHandler(this, "btnTest_click");
}

GButton btnTest; 
GButton btnOK;
GButton btnCancel;

If you click the Test button, then use the Enter key to select OK, the event fires twice. See serial monitor for output.

I’m SURE I’m missing something, so apologies if this is something stupid. This is causing backups to be run twice, so if there’s any way to get rid of this double firing I’d be grateful.

Oh, I do have an awkward workaround, but it’s really bad coding practice the way I have the workaround.

Thanks for any insights.

Mike

The problem is that this event handler can be called on three key event actions. These event actions are found in the source code in the KeyEvent class

public class KeyEvent extends Event {
  static public final int PRESS = 1;
  static public final int RELEASE = 2;
  static public final int TYPE = 3;

A simple tapping of a key will generate 2 events PRESS and RELEASE so your backup is executed twice. The trick here is to test the key action as well

public void qBoxKey(PApplet app, GWinData data, KeyEvent event) {
  if (event.getAction() == KeyEvent.TYPE && (event.getKey() == RETURN || event.getKey() == ENTER)) { 
    onYes();
  }
}
2 Likes

Shocker. I knew you’d know what was wrong! :slight_smile:

I’m not clear on this TYPE action - is this a custom action? What does it mean?

public class KeyEvent extends Event {
  static public final int PRESS = 1;
  static public final int RELEASE = 2;
  static public final int TYPE = 3; // <--does this represent a complete down/up event of a key or something?

I thank you kindly Peter.

All the best,

Mike

AFAIK this is how it works.

  • When a key is pressed a PRESS event is fired
  • When the key is released there are two options depending on the time elapsed since the PRESS event
    1. If the time interval is below some threshold the a TYPE event is fired
    2. If the time interval is above this threshold then a RELEASE event is fired

So whenever a key is pressed and released two events are fired either

  • PRESS followed by TYPE, or
  • PRESS followed by RELEASE

The idea is a TYPE action is appropriate for entering text in a word processor. The RELEASE events might be used in games where keys are held down to perform some action then later released to stop that action.

Many applications use both, for instance holding down a key to modify how mouse events are actioned.

3 Likes

I so appreciate that Peter.

Many thanks!!! :smiling_face_with_three_hearts: