# Get user input with textbox class

**URL:** <https://discourse.processing.org/t/get-user-input-with-textbox-class/16150>\
**Category:** Libraries\
**Created:** [December 5, 2019, 1:47pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150 "2019-12-05T13:47:38Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thomas/32/7236_2.png) [@Thomas](https://discourse.processing.org/u/Thomas)\
**Post date:** [December 5, 2019, 1:47pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/1 "2019-12-05T13:47:38Z")

</div>

Hi, I would like to input a text into a ‘textbox’ and save the input into a variable when for example enter is pressed. So far I have come up with the following code:  
**main.pde** :

```auto
TextBox textBox1;

void setup(){
    size(1000, 600);
    background(0);

    textBox1 = new TextBox(200, 200, 500, 50);
}

void draw(){
    textBox1.draw();
}

```

And **TextBox.pde** :

```auto
class TextBox{
    TextBox(int x, int y, int boxWidth, int boxHeight){
        this.x = x;
        this.y = y;
        this.boxWidth = boxWidth;
        this.boxHeight = boxHeight;
    }

    void draw(){
        drawBox();
        drawText();
        getUserInput();
    }

    void drawBox(){
        stroke(205);
        fill(205);
        rect(x, y, boxWidth, boxHeight);
    }

    void drawText(){
        textAlign(LEFT, CENTER);
        textSize(16);
        fill(255);
        text(textValue + getCursor(), x + 5, y + boxHeight/2);
    }

    void getUserInput(){
        if(!keyPressed){
            keyReleased = true;
            keyCounter = 0;
            previousKeyCounter = 0;
        }
        if (keyPressed && c != key){
            keyCounter = millis();

            c = key;

            if (c == BACKSPACE) textValue = "";
            else if (c >= ' ') textValue += str(c);
            if (textValue.length() > textLimit) textValue = "";

            previousKeyCounter = keyCounter;
            keyReleased = false;
        }

    }

    String getCursor() {
      return hovering() && (frameCount>>4 & 1) == 0 ? "|" : "";
    }

    boolean hovering(){
        return mouseX >= x && mouseX <= x + boxWidth && mouseY >= y && mouseY <= y + boxHeight;
    }

    private int x, y, boxWidth, boxHeight, textLimit = 40;
    private float currentValue, keyCounter, previousKeyCounter;
    private String textValue;
    private char keyInput, c;
    private boolean keyReleased;
}

```

For now let’s focus on the typing aspect first. As you can experience, typing fast does not work as expected, if you type character by character it does work. How can I include this functionality of pressing multiple keys at the same time? I would like the code to be modular, so nothing in functions like mouseClicked() or mouseReleased() etc.

If anyone can give me an example of how to use a library which has this functionality, that would be much appreciated as well. I don’t have a lot of knowledge on how to import libraries.

Thanks in advance,  
Thomas

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 5, 2019, 2:12pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/2 "2019-12-05T14:12:53Z")

</div>

> [@Thomas](#):
>
> example of how to use a library

When you look at the library controlP5 or g4p they come with a lot of examples

See section libraries on the website

You can install them via the library installer

They have good websites

Eg

> **[Quarks Place](http://www.lagers.org.uk/g4p/)**
>
> G4P and Processing

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [December 9, 2019, 12:41am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/3 "2019-12-09T00:41:37Z")

</div>

> [@Thomas](#):
>
> As you can experience, typing fast does not work as expected, if you type character by character it does work.

A fast typist will be hitting approximately 375 chars per minute, and Processing defaults to 60fps. However, no matter what its frameRate, Processing doesn’t drop these events. Even at 1fps, it will catch dozens of keys correctly in each frame, in the correct order. Try it!

```auto
void draw(){
  frameRate(1);
}
void keyReleased(){
  print(key);
}

```

Don’t invoke `key` from inside draw() → textBox1.draw() → getUserInput() – that is a convenience keyword and will only give you a single event per frame. Call it from `keyReleased()`, which is invoked by every single queued event. Pass the unique key value each time.

```auto
void keyReleased() {
  textBox1.getUserInput(key);
}

```

---

<div class="post-metadata">

**Author:** ![Thomas](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thomas/32/7236_2.png) [@Thomas](https://discourse.processing.org/u/Thomas)\
**Post date:** [December 9, 2019, 8:59am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/4 "2019-12-09T08:59:54Z")

</div>

Thank you for the reply. Would it be possible to put the keyReleased() function inside a class?

---

<div class="post-metadata">

**Author:** ![Thomas](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thomas/32/7236_2.png) [@Thomas](https://discourse.processing.org/u/Thomas)\
**Post date:** [December 9, 2019, 9:56am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/5 "2019-12-09T09:56:15Z")

</div>

Thank you for your answer. I installed the G4P library via the Processing IDE and made the following script using the examples provided in the IDE, to get a textfield:

```auto
import g4p_controls.*;

GTextField txf1;

public void setup() {
  size(500, 300);

  txf1 = new GTextField(this, 10, 10, 200, 20);
  txf1.setPromptText("Text field 1");
  txf1.setText("test1"); // works
}

public void draw() {
  background(200, 128, 200);

  if (keyPressed && key == ENTER){
    println(txf1.getText());
    txf1.setText("test2"); // gives nullpointerexception
    }
}

```

However, when I try to set a new text in the textfield, I get a nullpointer exception. The setText() function does work as expected in the setup, but not in the draw. Does anyone know how I can solve this problem?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 9, 2019, 10:52am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/6 "2019-12-09T10:52:38Z")

</div>

> [@Thomas](#):
>
> println(txf1.getText());

Maybe that’s the guilty line though?

---

<div class="post-metadata">

**Author:** ![Thomas](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thomas/32/7236_2.png) [@Thomas](https://discourse.processing.org/u/Thomas)\
**Post date:** [December 9, 2019, 11:17am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/7 "2019-12-09T11:17:36Z")

</div>

Unfortunately, running the above script without

> [@Chrisir](#):
>
> println(txf1.getText());

gives the same error:

> java.lang.NullPointerException  
> at g4p\_controls.GTextField.keyEvent(Unknown Source)  
> at g4p\_controls.GWindowImpl.sendKeyEvent(Unknown Source)  
> at g4p\_controls.GWindowImpl.keyEvent(Unknown Source)  
> at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)  
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
> at java.lang.reflect.Method.invoke(Method.java:498)  
> at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1432)  
> at processing.core.PApplet.handleMethods(PApplet.java:1634)  
> NullPointerException  
> at processing.core.PApplet.handleKeyEvent(PApplet.java:3014)  
> at processing.core.PApplet.dequeueEvents(PApplet.java:2648)  
> at processing.core.PApplet.handleDraw(PApplet.java:2486)  
> at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)  
> at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [December 9, 2019, 12:07pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/8 "2019-12-09T12:07:31Z")

</div>

yes, i see that too,  
even i try not to use your keyPressed …  
but the G4P internal event handler…  
still.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [December 10, 2019, 12:14pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/9 "2019-12-10T12:14:12Z")

</div>

Looking at your sample code that uses GTextField there are a number of things worth mentioning but first of all the error is caused because you attempted to use `setText("test2");` while the textfield still had focus (the text insertion cursor is flashing). If you enter some text in the textfield and then click outside the textfield before pressing ENTER then it works.

NEVER use `setText(...)` while the textfield has focus, same thing applies to GPassword and GTextArea.

All G4P control use event handlers to process events. Here is an example of how to use a textfield

```auto
import g4p_controls.*;

GTextField txf1;
String t0;

public void setup() {
  size(500, 300);

  txf1 = new GTextField(this, 10, 10, 200, 20);
  txf1.setPromptText("Text field 1");
  txf1.setText("test1"); // works
}

public void draw() {
  background(200, 128, 200);

  if (keyPressed && key == ENTER) {
    println(t0);
  }
}

public void handleTextEvents(GEditableTextControl textcontrol, GEvent event) {
  if(txf1 == textcontrol && event == GEvent.ENTERED){
    t0 = txf1.getText();
  }
}

```

You will find more information about [G4P](http://www.lagers.org.uk/g4p/index.html) on my website also look at the [G4P Programmer Guides](http://www.lagers.org.uk/g4p/guides/g01-introduction.html)

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [December 10, 2019, 12:51pm UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/10 "2019-12-10T12:51:00Z")

</div>

now thanks to that info you could overwrite the typed value?  
or ( as i not fully understand your use case )  
i try to empty it and give the user a new prompt text

```auto
public void handleTextEvents(GEditableTextControl textcontrol, GEvent event) {
  if ( textcontrol == txf1 && event == GEvent.ENTERED) {
    t0 = txf1.getText();
    println("ENTER: "+t0);
    txf1.setFocus(false); // @quark is the best
    //txf1.setText("over write new?");
    txf1.setText("");
    txf1.setPromptText("next value");
  }
}

```

even something like

```auto
public void handleTextEvents(GEditableTextControl textcontrol, GEvent event) {
  if ( textcontrol == txf1 && event == GEvent.ENTERED) {
    t[count] = txf1.getText();
    count++;
    txf1.setFocus(false); 
    txf1.setText("");
    txf1.setPromptText("next value t["+count+"]");
  }
}

```

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [December 17, 2019, 6:36am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/11 "2019-12-17T06:36:25Z")

</div>

> [@Thomas](#):
>
> Would it be possible to put the keyReleased() function inside a class?

No in the sense that setup, draw, and event handlers are part of the Processing loop. Draw is called and then events are processed, then draw is called again. You can’t put draw in a class, although you could choose to invoke redraw(). Your code puts event handlers in a class, but you then still need to pass the events from keyPressed() to the Objects of that class – for example, looping over an array in keyPressed and passing each event to each object.

OR you could use `registerMethod("keyEvent")` – for a previous discussion, see:

- 

[Capturing keyEvent in own class: registerMethod() - Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/25477/capturing-keyevent-in-own-class-registermethod)

---

<div class="post-metadata">

**Author:** ![Thomas](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thomas/32/7236_2.png) [@Thomas](https://discourse.processing.org/u/Thomas)\
**Post date:** [January 7, 2020, 8:58am UTC](https://discourse.processing.org/t/get-user-input-with-textbox-class/16150/12 "2020-01-07T08:58:22Z")

</div>

That was indeed what I was trying to achieve. Thank you
