Auto scroll to end not working with GTextarea

I want to send a command in serial and it prints many lines of data in serial monitor.
but here auto scroll not working, and even I remove the lines (see comment // auto scroll)
still the scroll bar moving slowly to down even all data printed still scroll bar moving slowly to down which make the UI a bit lag, when I use Queue method instead of synchronized(buffer) it stop printing after few lines of data . below Is my code, I want to make it autoscroll to end / bottom like in arduino ide serial monitor

import g4p_controls.*;
import processing.serial.*;

Serial myPort;
GTextArea receivedDataArea;
GTextField commandInput;
GButton sendButton;
StringBuilder buffer = new StringBuilder();
int currentTextLength = 0;

void setup() {
  size(800, 600);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);

  // Initialize serial port
  String portName = Serial.list()[0]; // Adjust this if necessary
  myPort = new Serial(this, portName, 115200);

  // Create text area for received data
  receivedDataArea = new GTextArea(this, 10, 10, 780, 500, G4P.SCROLLBARS_BOTH | G4P.SCROLLBARS_AUTOHIDE);
  //receivedDataArea.setFont(new Font("Arial", Font.PLAIN, 16));
  receivedDataArea.setTextEditEnabled(false);

  // Create text field for command input
  commandInput = new GTextField(this, 10, 520, 680, 30);
  commandInput.setPromptText("Enter command here");

  // Create send button
  sendButton = new GButton(this, 700, 520, 90, 30, "Send");
  sendButton.addEventHandler(this, "sendButtonEvent");
}

void draw() {
  background(240);
  updateReceivedDataArea();
}

void updateReceivedDataArea() {
  synchronized (buffer) {
    if (buffer.length() > currentTextLength) {
      String newData = buffer.substring(currentTextLength);
      receivedDataArea.appendText(newData);
      currentTextLength = buffer.length();

      // Auto-scroll to the bottom
      int length = receivedDataArea.getText().length();
      receivedDataArea.moveCaretTo(length, length);
    }
  }
}

void serialEvent(Serial myPort) {
  String inData = myPort.readStringUntil('\n');
  if (inData != null) {
    synchronized (buffer) {
      buffer.append(inData.trim()).append("\n");
    }
  }
}

void sendButtonEvent(GButton button, GEvent event) {
  if (event == GEvent.CLICKED) {
    String command = commandInput.getText();
    if (command != null && !command.isEmpty()) {
      myPort.write(command + "\n");
      commandInput.setText(""); // Clear the input field after sending
    }
  }
}

Welcome to the forum :+1:

Unfortunately I cannot run your code as I don’t have a serial device to try it out. You might try the append text method as this should add text and then scroll to the end.

A word of caution, the text area control was designed to accept keyboard input and allow the user to edit the text. It was not designed to be a “console” display and very large amounts of text will seriously affect it’s performance.

1 Like

Alternate technique using JTextArea which works as expected on macOS:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.DefaultCaret;
import processing.serial.*;

javax.swing.JFrame frame;
java.awt.Canvas canvas;

JTextArea txtArea;
Serial myPort;

int _wndW = 300;
int _wndH = 620;

void setup() {
  frame = (javax.swing.JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
  canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) ((processing.awt.PSurfaceAWT)surface).getNative();
  frame.setBounds(500, 300, _wndW, _wndH);
  frame.remove(canvas);

  txtArea = new JTextArea();
  JScrollPane scrlPane = new JScrollPane(txtArea);
  scrlPane.setBounds(10, 10, 200, _wndH - 50);
  frame.add(scrlPane);
  txtArea.setEditable(true);
  txtArea.setLineWrap(false);
  txtArea.setWrapStyleWord(true);
  txtArea.repaint();

  printArray(Serial.list());
  String portName = Serial.list()[1]; // Adjust this if necessary
  myPort = new Serial(this, portName, 115200);
  DefaultCaret caret = (DefaultCaret)txtArea.getCaret();
  caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
}

void serialEvent(Serial myPort) {
  String inData = myPort.readStringUntil('\n');
  if (inData != null) {
    txtArea.append(inData);
  }
}

void draw() {
}

3 Likes

Thank you so much.
I am working on making software and serial communication is a part of it (which has many other UI elements, saving files…) will jtextarea method work along with g4p lib? and will there be any effect in the speed of receiving data as my code have many other functions?

Not sure, you’ll have to try it.

Seems to run ok on macos. This is what I see:

OK thanks for verifying, maybe it is the problem with my device.