G4P GtextArea scrolling to bottom as you type

edited May 2016 in Library Questions

I am trying to figure out a way to scroll down to the last line of the GTextArea after each time text is set.

If you try my code you can see when the text reaches the bottom of the view nothing happens. I tried using getTextAsArray in combination with moveCaretTo in order to place caret at the end of the text, hoping it would scroll down. But getTextAsArray always returns an array with only one element, even after text goes to a new line.

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

   GTextArea textArea;
   String txtMain ="";
   int screenWidth;
   int screenHeight;

   void setup() {
     screenWidth = 400;
     screenHeight = 300;
     size(screenWidth, screenHeight, JAVA2D);
     smooth();
     background(255);

     textArea = new GTextArea(this, 5, 0, screenWidth - 10, screenHeight);
     textArea.setFont(new Font("", Font.PLAIN, 80));
     textArea.setText("", screenWidth - 20);
     textArea.setTextEditEnabled(false);
   }

   void draw() {
     background(255);
    }

   void keyPressed() {
     txtMain = txtMain + key;
     textArea.setText(txtMain);
   }

Answers

  • There are several things about your code

    1) The font size is massive compared with the textarea size so you may get some unusual results.

    2) Line 21 means that the textarea will NOT respond to the keyboard. Remove this line, click on the text area and start typing - scrolling will now work.

    3) Without scrollbars the text will only scroll when moving the caret with the arrow keys. It is possible to add scrollbars when you create the textarea control.

    4) The getTextAsArray method return an array of paragraphs (text separated with new-line-characters i.e. when you press Enter key) NOT an array of display lines. Text is wrapped horizontally so the end of a display line is not necessarily the end of a paragraph.

    Anyway try this code. :)

    import g4p_controls.*;
    import g4p_controls.GCScheme;
    import java.awt.Font;
    import java.awt.*;
    
    GTextArea textArea;
    String txtMain ="";
    int screenWidth;
    int screenHeight;
    
    void setup() {
      screenWidth = 400;
      screenHeight = 300;
      size(screenWidth, screenHeight, JAVA2D);
      smooth();
      background(255);
    
      textArea = new GTextArea(this, 5, 0, screenWidth - 10, screenHeight, G4P.SCROLLBARS_BOTH | G4P.SCROLLBARS_AUTOHIDE);
      textArea.setFont(new Font("", Font.PLAIN, 40));
      textArea.setText("", screenWidth - 20);
    }
    
    void draw() {
      background(255);
     }
    
  • Thanks for your response quark. I had tried what you're advising me to do, but here are the reasons I looking for ways around:

    1) The font size is massive compared with the textarea size so you may get some unusual results.

    I am sketching a little artistic project, so I need to use big font size, probably even bigger than this.

    2) Line 21 means that the textarea will NOT respond to the keyboard. Remove this line, click on the text area and start typing - scrolling will now work.

    For my project the text input will not be coming from the keyboard input, but via OSC from another device.

    3) Without scrollbars the text will only scroll when moving the caret with the arrow keys. It is possible to add scrollbars when you create the textarea control.

    For me it is necessary to hide the scrollbars, as eventually the text area will be in full screen with nothing visible but the letters (no caret either).

    4) The getTextAsArray method return an array of paragraphs (text separated with new-line-characters i.e. when you press Enter key) NOT an array of display lines. Text is wrapped horizontally so the end of a display line is not necessarily the end of a paragraph.

    I expected that the new lines would be created based on how the text appears within its frame.

    As a workaround I've tried your suggested approach, I made a colour scheme with mostly white color, including the caret, that looks ok, but not ideal as the caret sometimes overlaps certain letters which take more space and makes itself visible. Even then I can't do something that I need, which is to clear the text with one button press and start typing from the beginning. See the code below.

    import g4p_controls.*;
    import g4p_controls.GCScheme;
    import java.awt.Font;
    import java.awt.*;
    
    GTextArea textArea;
    int screenWidth;
    int screenHeight;
    
    void setup() {
      screenWidth = 400;
      screenHeight = 300;
      size(screenWidth, screenHeight, JAVA2D);
      smooth();
      background(255);
    
      textArea = new GTextArea(this, 5, 0, screenWidth - 10, screenHeight, G4P.SCROLLBARS_BOTH | G4P.SCROLLBARS_AUTOHIDE);
      textArea.setFont(new Font("", Font.PLAIN, 40));
      textArea.setText("", screenWidth - 20);
    }
    
    void draw() {
      background(255);
    }
    
    void keyPressed() {
      // I am able to get the text, thats nice
      println(textArea.getTextAsArray());
    
      if (key == CODED) {
        // I'd like to delete all text by one key press
        // and change the font
        if (keyCode == CONTROL) {
          // I clear the text
          textArea.setText(""); // caret pos seems to not update after this
          println("caret position: " + textArea.getCaretPos()); // weird
          textArea.moveCaretTo(0, 0); // also doesn't work
    //      textArea.setFont(new Font("someOtherFont", Font.PLAIN, 40));
        // if caret is not placed to the beginning manually, app will crash
        }
      }
    }
    
  • I made a colour scheme with mostly white color, including the caret, that looks ok, but not ideal as the caret sometimes overlaps certain letters

    Make the caret colour transparent.

    You can also use the appendText method which adds text and then scrolls. Scrollbars are not essential.

    I expected that the new lines would be created based on how the text appears within its frame.

    the getText(int lineNo) method will return the text as it appears on a particular line

    For me it is necessary to hide the scrollbars, as eventually the text area will be in full screen with nothing visible but the letters (no caret either).

    The GTextArea class is primarily for accepting and displaying text entered at the keyboard. Are you sure this control is appropriate for an artistic project it seems to me that this could be done without resorting to using a textarea control.

  • Thanks for your answer. But you're right it seems it's not the right tool for what I'm trying to achieve.

    Still I suggest you to update caret position after setting text (setText(String string)). Developers may want to have a "clearAll" option and set the caret to the 0th position.

    Also, having an option of using data source instead of only keyboard input would be a nice improvement.

  • Hi! I'm running in exactly the same problem with GTextArea. I need to clear the textarea but caret position is not getting updated and crashes the app.

    So I agree with auris suggestion — caret position should get updated after setText and/or there could be "clearAll" function that would empty the area and put the caret to the 0th position.

  • edited May 2016

    @izumitelj can you post a simple example that demonstrates the problem? Also what version of Processing and G4P you are using.

  • edited May 2016

    Here it is @quark. When you press F1 GTextArea will be cleared, BUT the caret will remain in old position. Than if you try to enter any key StringIndexOutOfBoundsException will be thrown. I'm using Processing 3.1.1 and G4P 4.0.3.

    import g4p_controls.*;
    import java.awt.event.KeyEvent;
    
    GTextArea a;
    
    public void setup() {
      size(640, 400);
      a = new GTextArea(this, 20, 20, 280, 200);
    }
    
    public void draw() {
      background(255, 128, 128);
      fill(255);
      text(a.getText(), 340, 20, 280, 200);
    }
    
    void keyPressed() {
      if (keyCode == KeyEvent.VK_F1) {
        a.setText("");
      }
    }
    
  • Thanks for that. It only occurs if the TextArea has focus but it still wants fixing.

    I have raised a ticket for it.

  • That's great. Thank you :)

  • Answer ✓

    @izumitelj fixed see this discussion

Sign In or Register to comment.