G4P textarea too slow?

Hi i’m working on this project. https://github.com/bonner72/SerialTerminal

when i send data to G4P text area any faster than a line per 200-300 millis it does not update fast enough.

This is how i push data to the textarea.

  if (CMDtextAreaMessage != CMDtextAreaMessageOld) {
    CMDmessageTrig = true;
    if (showTimeStamp == true) {
      CMDtextarea.appendText(timeStamp + " " + CMDtextAreaMessage + "\n");
      CMDtextAreaMessageOld = CMDtextAreaMessage;
    } else {
      CMDtextarea.appendText(CMDtextAreaMessage + "\n");
      CMDtextAreaMessageOld = CMDtextAreaMessage;
    }

@quark would you have an idea? Thanks.

The main problem is that the GTextArea control was never designed to handle large volumes of test. It is more like a textfield that can display a few lines of text than a “console type window”.

In G4P V3 I completely rewrote how the library rendered text. This enabled part or all the text (used in any G4P control) to be styled e.g. bold, italic etc. Additionally it meant that text area controls supported different text alignments e.g. left, center, right, justified.

This does mean that text rendering is more CPU intensive but this is partly mitigated because G4P uses double buffering for its controls.

So in your program you adding at least 3-5 lines of text every second. As each line of text is appended the control has to recalculates ALL the text in the control even though most of it will not be shown.

One solution is to limit the number of messages stored in the textarea by removing the oldest messages when a user defined limit is exceeded.

The sketch below shows my way of doing this, it can easily be modified to suit most purposes. It adds a message every frame and on my computer it slowed the frame rate to ~25 fps but this should be the worst case scenario unless you increase the buffer limit. Feel free to experiment.

The code should be self explanatory but if you have questions feel free to ask. :smile:

/*
Demonstrates the use of a buffer to limit the amount of text displayed by 
a GTextArea control
created by Quark 6th Aug 2025
*/
import g4p_controls.*;

GTextArea gta;
GtaBuffer gtab;
GLabel instr, bsize;
boolean add_messages = true;
int cnt = 0;

void setup() {
  size(640, 480);
  instr = new GLabel(this, 40, 40, 560, 20);
  instr.setText("S key toggles start / stop messages.");
  bsize = new GLabel(this, 40, 80, 560, 20);
  gta = new GTextArea(this, 40, 120, 560, 200);
  gtab = new GtaBuffer(gta, 100);
}

void keyReleased() {
  if (key == 's')add_messages = !add_messages;
}

void draw() {
  background(200, 255, 192);
  bsize.setText("Buffer size  "+  gtab.size());
  if (add_messages)
    gtab.append("Quark added '" + cnt++ +"' this at " + millis() + " ms");
}

// Text buffer for a specified GTextArea control
class GtaBuffer {
  ArrayList<String> buffer = new ArrayList<String>();
  GTextArea area;
  int limit;

  GtaBuffer(GTextArea area, int limit) {
    this.area = area;
    this.limit = limit;
  }

  // Append a new message to the textarea
  void append(String msg) {
    buffer.add(msg);
    // Remove old messages if the buffer limit is exceeded
    while (buffer.size() > limit) buffer.remove(0);
    // get buffer as an array and use it to set the display text
    area.setText(buffer.toArray(new String[buffer.size()]));
  }

  // number of messages stored
  int size() {
    return buffer.size();
  }
}

Thanks for the reply.

Not really practicle in this case since the user needs to be able to see all the data.

So textarea gets noticeably slow at around 200 lines in the buffer and it starts using extensive processing power.

I may have to look into some terminal code for an alternative text window or find an alternative.:smiling_face_with_sunglasses:

There are always alternatives depending on the volume and type of data.

What is the maximum message length in characters?
How many messages are you likely to generate?
How long are you collecting the data e.g. 1 hour, 1 day?

There is no limit.

It depends on the user i would doubt more than a day, but it should be able to run indefinitely.

So I have made some assumptions based on your previous posts and my imagination , they are

  1. The average message length is 80 characters
  2. Messages are generated at 2 per second
  3. All messages must be available for the user to read no matter how old they are.

Based on this I estimate the program will store 576,000 characters per hour but I suspect this is a serious underestimate of reality.

Now google AI suggests estimates the number of characters in “The Hobbit” by J.R.R.Tolkien is similar at 524,458.


Storing this volume of data on a modern device is no problem but I can’t imagine a user scanning a book the size of “The Hobbit” for every hours worth of messages collected, but perhaps I have misunderstood the situation.

My suggestion is quite straightforward to implement -

  1. store all the messages in an arraylist, adding them to the end as they are generated.
  2. reserve a rectangular area of the screen to display the messages.
  3. create a function that accepts the number of the first and last message and returns an array of the selected messages.
  4. the messages specified in (3) are then displayed using Processing’s text function.
  5. controls e.g. sliders or buttons to change the message numbers passed to the function in (3).

This solution has several advantages

  • the number of messages is only limited by the Java language specification.
  • there is no real restriction on the rate messages are generated.
  • the controls for selecting the message range to display can be as simple or as sophisticated to suit the application needs.
  • functions can be included to search the message store and filter them based on user supplied criteria.
  • Since only small range of messages are being formatted for display there should be no noticeable slowing of the sketch.

This is all based on what I have gleaned from previous posts so I might be completely off target. :grinning_face:

1 Like

Thanks for the reply.

Testing the ControlP5 textarea.

import controlP5.*;

ControlP5 cp5;
Textarea myTextarea;
int i;
float s;
float d;
float x;
void setup() {
  size(700, 400);
  cp5 = new ControlP5(this);

  myTextarea = cp5.addTextarea("txt")
    .setPosition(100, 100)
    .setSize(500, 300)
    .setFont(createFont("arial", 12))
    .setLineHeight(14)
    .setColor(color(128))
    .setColorBackground(color(255, 100))
    .setColorForeground(color(255, 100));
  ;
  d = millis();
}



void draw() {
  s = millis();
  if (!keyPressed) {
    i ++;

    myTextarea.append("Testing Hello World"+ i + "@ " + x, 100000);
    x = s - d;
    d = millis();
    ;
  }
}


Write time starting was 16millis. At 50000 lines write time 50-55millis.

Should work for my case i don’t think most users will write that fast to it.

I will probably use this, If it doesn’t work i will try to write something custom as you suggested.

Thanks.:smiling_face_with_sunglasses: