Challenges in using G4P to create textAreas that are more "text-editor capable"

Hello there,

first of all, thanks to @quark for making a really easy to use library for GUI elements. It’s also one of the few with any kind of text-areas.

I’m in a process of making a simple text-editing tool for writing stories and managing different perspectives, and was wondering if there is a way to go around the following few issues with GTextArea.

  • empty lines require trickery, and cannot be created by simply pressing enter. One must go to the end of the previous line, and then press enter to create an empty line.
  • copy-pasting does not work properly (macOS cmd vs ctrl)
  • double-clicking a word does not select it (and the same with triple clicking for a sentence)
  • is there a neat way to get focus on a textarea when dragging a piece of text from another window? (I’m using Drop -library, and while I can get it to work with G4P, focus is a bit of a challenge at the moment.)
  • is there any way to highlight part of the text in a text-area with a specific colour? I cannot even do it manually as an overlay, since G4P writes over any other graphical elements I use. This would be neat for tags in the text.

Has anyone encountered anything similar, and if so, would you have any suggestions on how to deal with them?

I think I might be able to find the right word/sentence for the double-clicking and the triple-clicking with just mouse-events, getCaretPos and getText, but how to make that text “selected”?

Also, if there are any other suggestions for making a good text-field, all suggestions are more than welcome!


Sorry I haven’t replied earlier but I have been away from my computer.

The main class used for all text rendering in G4P is the StyledString class since it has methods to change many text attributes including font face, size, colour, ilatic, bold … and also supports single and multiple lines.

To achieve this it uses many low level Java library classes, unfortunately these classes were designed to be used by the Java language and not by third party programmers like me. This has introduced a number of limitations which I have to work around, if possible.

This is one of the limitations I mentioned - empty lines cause exceptions in StyledString. So although blank lines look empty that aren’t. When you create a new text field or area it creates one with a single space which is replaced by the first key typed. Over the years I have made several attempts to find a work around to no avail.

The Control key is used for all operating systems when copying and pasting. Would be a lot of work to enable the use of the Cmd key in macOS

Not that I can think of at the moment

Yes it is possible to modify most text attributes for part or the whole text. The methods you need are

addStyle(…) which can be used to style part or full line of text.

setSelectedTextStyle(…) which sets the style of any text selected with the mouse.

The first two parameters in these methods define the text attribute to set and the value to use for the attribute. The value parameter is of type java.lang.Object so can be any valid Java class, the actual type you pass will depend on the attribute being set.

Greater flexibility can be achieved by modifying the StyledText directly. Use getStyledText() to get the text and use the in StyledString methods to modify the text before using setStyledText(...) to change the text displayed.

G4P has a number of predefined constants for both TextAttributes and Values. The library example G4P_TextAreaControl shows some of these in action.

Thanks for the reply!

Sorry it took so long for me to reply, but end of semester stuff and project reports etc. ate the time from this project. And please don’t get me wrong, your library has saved so much time, made my life and code simpler, and is really really useful!

The only thing I would change is that CLICKED would also work if the release was accepted anywhere within the button’s surface area. Now I have to write a bit of code to check for PRESSED and then separately for RELEASED, to see if the cursor is on top of the button. Seems a bit silly, especially when the button already detects if the cursor is on top or not. Currently the cursor absolutely cannot move, in order for the CLICKED to be detected. For those with touchpads, and especially with higher resolutions, clicking a button without moving the cursor is a bit of a challenge. Maybe this could be included as an option for the next release?

Copy-pasting, that I figured out and is ok. (By default CMD-c is used in place of ctrl-c, in mac.)

I figured out a kind of work-around for the drag-and-drop, it involves a drag-drop event (Sdrop) and then selecting the textarea via means beyond what processing could offer for the mouse: I had to follow the mouse position even when the window was not active. Then, after dropping the text, I could store the text temporarily, select the textarea under the mouse position, and then insert the text to that textarea.
If no previous position was selected, the text would go to the end, and the textarea was active, the text would get placed to where the cursor was. It would be really great to figure out the location of the text as well based on the mouse location, but having solved the immediate issue, I moved forward.

But for the “empty lines”. What I cannot seem to be able to have is multiple \n in a row. There always needs to be a . or empty space before \n is accepted. Is this what you mean? Because otherwise I cannot get multiple lines that appear empty. If it is due to StyledString, ok, it’s something I have to live with. Back in the day I did write a code that simply used a string, and with fixed width font, identifying the location etc. was a breeze. Didn’t have any copy-paste or select-functionality, though, hence G4P.

Now, I have a new question:

My program creates some buttons dynamically. The amount of buttons created depends on the amount of topics I have to select from, and varies. This has proven to be a bit tricky, but I figured out a way to do it.
If the program creates the buttons at an unspecified time, the program will most likely crash. However, when the buttons are created by the user clicking another button, i.e. in the event handler, the dynamic generation usually works without issues.
Is there another way to create buttons dynamically, safely? It would be extremely useful via a function call useable anywhere, since there’s one situation where I’d like to have the dynamic buttons, but there are no G4P buttons.

StyledString deliberately replaces multiple newlines with a single one so \n\n\n will be replaced with \n if it didn’t do thie Java classes I use would cause the sketch to crash. It is a limitation of StyledString so afraid you will have to live with it.
I created StyledString to enable mixed styles in a single string but it introduced some limitations.

G4P queues new controls and adds them to the GUI after the draw function has finished so I am not sure why it should crash.

Can you create a simple short sketch that demonstrates a crash or copy and paste the stacktrace here. I can then investigate the problem otherwise I can do much about it.

One thing I suggest is to avoid creating G4P controls inside the draw function or any function called from draw.

1 Like

I’ll try to make a short example that reproduces the results, in the meantime, here’s what I get when I try to use it in my larger code. I’ll post this because I am a bit swamped at the moment, and might have time make a similar but small example during the weekend.

I have no idea why that is happening, but have a hunch that it tries to display something that has not yet had time to initialise. Alternatively, it might be the erasure that causes it to go belly-up.

Before creating a new batch of buttons, I dispose() each, set them to null, and then recreate a NEW GButton array, where the size is based on a variable. Then, I’ll initialise and add (to group) each new button individually.

java.lang.NullPointerException: Cannot invoke “processing.awt.PGraphicsJava2D.beginDraw()” because “this.buffer” is null
at g4p_controls.GButton.updateBuffer(Unknown Source)
at g4p_controls.GButton.draw(Unknown Source)
at g4p_controls.GWindowImpl.draw(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(
at java.base/java.lang.reflect.Method.invoke(
at processing.core.PApplet$RegisteredMethods.handle(
at processing.core.PApplet.handleMethods(
at processing.core.PApplet.handleDraw(
at processing.awt.PSurfaceAWT$9.callDraw(
at processing.core.PSurfaceNone$

Anyway, I’ll get back to this hopefully in few days time.

Are you using a GGroup to group objects together? If you are then this might be the problem.

A ‘control group’ has an object reference to each of the controls in the group, but the actual controls are unaware that they are part of a group. So when you dispose of the button it can remove itself from the window but not from the group. Before calling the dispose method you should remove it from any group it is in e.g.

button = null;
1 Like