How to Highlight Text in a ControlP5 Textfield?

I’m feeling rather dense ATM, but I’m using the standard example that comes with Control5P for text fields, and I cannot seem to highlight text that I enter. I want to the user to be able to type something, then highlight it if they wish, perhaps delete what they typed and retype, as I do when I’m entering text/making changes…

But it seems that highlighting is not possible? There’s a million methods/properties listed, but nothing for highlighting?

In the documentation there’s one mention of a HIGHLIGHT for the textfield, but much googling/trolling around has not yielded any answers as of yet.

Here’s the standard example that comes with the library. If anyone can help me figure out how to implement or unlock basic highlighting of entered text, I would be grateful.

Thank you,

Mike

/**
* ControlP5 Textfield
*
*
* find a list of public methods available for the Textfield Controller
* at the bottom of this sketch.
*
* by Andreas Schlegel, 2012
* www.sojamo.de/libraries/controlp5
*
*/


import controlP5.*;

ControlP5 cp5;

String textValue = "";

void setup() {
  size(700,400);
  
  PFont font = createFont("arial",20);
  
  cp5 = new ControlP5(this);
  
  cp5.addTextfield("input")
     .setPosition(20,100)
     .setSize(200,40)
     .setFont(font)
     .setFocus(true)
     .setColor(color(255,0,0))
     ;
                 
  cp5.addTextfield("textValue")
     .setPosition(20,170)
     .setSize(200,40)
     .setFont(createFont("arial",20))
     .setAutoClear(false)
     ;
       
  cp5.addBang("clear")
     .setPosition(240,170)
     .setSize(80,40)
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;    
  
  cp5.addTextfield("default")
     .setPosition(20,350)
     .setAutoClear(false)
     ;
     
  textFont(font);
}

void draw() {
  background(0);
  fill(255);
  text(cp5.get(Textfield.class,"input").getText(), 360,130);
  text(textValue, 360,180);
}

public void clear() {
  cp5.get(Textfield.class,"textValue").clear();
}

void controlEvent(ControlEvent theEvent) {
  if(theEvent.isAssignableFrom(Textfield.class)) {
    println("controlEvent: accessing a string from controller '"
            +theEvent.getName()+"': "
            +theEvent.getStringValue()
            );
  }
}


public void input(String theText) {
  // automatically receives results from controller input
  println("a textfield event for controller 'input' : "+theText);
}




/*
a list of all methods available for the Textfield Controller
use ControlP5.printPublicMethodsFor(Textfield.class);
to print the following list into the console.

You can find further details about class Textfield in the javadoc.

Format:
ClassName : returnType methodName(parameter type)


controlP5.Controller : CColor getColor() 
controlP5.Controller : ControlBehavior getBehavior() 
controlP5.Controller : ControlWindow getControlWindow() 
controlP5.Controller : ControlWindow getWindow() 
controlP5.Controller : ControllerProperty getProperty(String) 
controlP5.Controller : ControllerProperty getProperty(String, String) 
controlP5.Controller : ControllerView getView() 
controlP5.Controller : Label getCaptionLabel() 
controlP5.Controller : Label getValueLabel() 
controlP5.Controller : List getControllerPlugList() 
controlP5.Controller : Pointer getPointer() 
controlP5.Controller : String getAddress() 
controlP5.Controller : String getInfo() 
controlP5.Controller : String getName() 
controlP5.Controller : String getStringValue() 
controlP5.Controller : String toString() 
controlP5.Controller : Tab getTab() 
controlP5.Controller : Textfield addCallback(CallbackListener) 
controlP5.Controller : Textfield addListener(ControlListener) 
controlP5.Controller : Textfield addListenerFor(int, CallbackListener) 
controlP5.Controller : Textfield align(int, int, int, int) 
controlP5.Controller : Textfield bringToFront() 
controlP5.Controller : Textfield bringToFront(ControllerInterface) 
controlP5.Controller : Textfield hide() 
controlP5.Controller : Textfield linebreak() 
controlP5.Controller : Textfield listen(boolean) 
controlP5.Controller : Textfield lock() 
controlP5.Controller : Textfield onChange(CallbackListener) 
controlP5.Controller : Textfield onClick(CallbackListener) 
controlP5.Controller : Textfield onDoublePress(CallbackListener) 
controlP5.Controller : Textfield onDrag(CallbackListener) 
controlP5.Controller : Textfield onDraw(ControllerView) 
controlP5.Controller : Textfield onEndDrag(CallbackListener) 
controlP5.Controller : Textfield onEnter(CallbackListener) 
controlP5.Controller : Textfield onLeave(CallbackListener) 
controlP5.Controller : Textfield onMove(CallbackListener) 
controlP5.Controller : Textfield onPress(CallbackListener) 
controlP5.Controller : Textfield onRelease(CallbackListener) 
controlP5.Controller : Textfield onReleaseOutside(CallbackListener) 
controlP5.Controller : Textfield onStartDrag(CallbackListener) 
controlP5.Controller : Textfield onWheel(CallbackListener) 
controlP5.Controller : Textfield plugTo(Object) 
controlP5.Controller : Textfield plugTo(Object, String) 
controlP5.Controller : Textfield plugTo(Object[]) 
controlP5.Controller : Textfield plugTo(Object[], String) 
controlP5.Controller : Textfield registerProperty(String) 
controlP5.Controller : Textfield registerProperty(String, String) 
controlP5.Controller : Textfield registerTooltip(String) 
controlP5.Controller : Textfield removeBehavior() 
controlP5.Controller : Textfield removeCallback() 
controlP5.Controller : Textfield removeCallback(CallbackListener) 
controlP5.Controller : Textfield removeListener(ControlListener) 
controlP5.Controller : Textfield removeListenerFor(int, CallbackListener) 
controlP5.Controller : Textfield removeListenersFor(int) 
controlP5.Controller : Textfield removeProperty(String) 
controlP5.Controller : Textfield removeProperty(String, String) 
controlP5.Controller : Textfield setArrayValue(float[]) 
controlP5.Controller : Textfield setArrayValue(int, float) 
controlP5.Controller : Textfield setBehavior(ControlBehavior) 
controlP5.Controller : Textfield setBroadcast(boolean) 
controlP5.Controller : Textfield setCaptionLabel(String) 
controlP5.Controller : Textfield setColor(CColor) 
controlP5.Controller : Textfield setColorActive(int) 
controlP5.Controller : Textfield setColorBackground(int) 
controlP5.Controller : Textfield setColorCaptionLabel(int) 
controlP5.Controller : Textfield setColorForeground(int) 
controlP5.Controller : Textfield setColorLabel(int) 
controlP5.Controller : Textfield setColorValue(int) 
controlP5.Controller : Textfield setColorValueLabel(int) 
controlP5.Controller : Textfield setDecimalPrecision(int) 
controlP5.Controller : Textfield setDefaultValue(float) 
controlP5.Controller : Textfield setHeight(int) 
controlP5.Controller : Textfield setId(int) 
controlP5.Controller : Textfield setImage(PImage) 
controlP5.Controller : Textfield setImage(PImage, int) 
controlP5.Controller : Textfield setImages(PImage, PImage, PImage) 
controlP5.Controller : Textfield setImages(PImage, PImage, PImage, PImage) 
controlP5.Controller : Textfield setLabel(String) 
controlP5.Controller : Textfield setLabelVisible(boolean) 
controlP5.Controller : Textfield setLock(boolean) 
controlP5.Controller : Textfield setMax(float) 
controlP5.Controller : Textfield setMin(float) 
controlP5.Controller : Textfield setMouseOver(boolean) 
controlP5.Controller : Textfield setMoveable(boolean) 
controlP5.Controller : Textfield setPosition(float, float) 
controlP5.Controller : Textfield setPosition(float[]) 
controlP5.Controller : Textfield setSize(PImage) 
controlP5.Controller : Textfield setSize(int, int) 
controlP5.Controller : Textfield setStringValue(String) 
controlP5.Controller : Textfield setUpdate(boolean) 
controlP5.Controller : Textfield setValue(float) 
controlP5.Controller : Textfield setValueLabel(String) 
controlP5.Controller : Textfield setValueSelf(float) 
controlP5.Controller : Textfield setView(ControllerView) 
controlP5.Controller : Textfield setVisible(boolean) 
controlP5.Controller : Textfield setWidth(int) 
controlP5.Controller : Textfield show() 
controlP5.Controller : Textfield unlock() 
controlP5.Controller : Textfield unplugFrom(Object) 
controlP5.Controller : Textfield unplugFrom(Object[]) 
controlP5.Controller : Textfield unregisterTooltip() 
controlP5.Controller : Textfield update() 
controlP5.Controller : Textfield updateSize() 
controlP5.Controller : boolean isActive() 
controlP5.Controller : boolean isBroadcast() 
controlP5.Controller : boolean isInside() 
controlP5.Controller : boolean isLabelVisible() 
controlP5.Controller : boolean isListening() 
controlP5.Controller : boolean isLock() 
controlP5.Controller : boolean isMouseOver() 
controlP5.Controller : boolean isMousePressed() 
controlP5.Controller : boolean isMoveable() 
controlP5.Controller : boolean isUpdate() 
controlP5.Controller : boolean isVisible() 
controlP5.Controller : float getArrayValue(int) 
controlP5.Controller : float getDefaultValue() 
controlP5.Controller : float getMax() 
controlP5.Controller : float getMin() 
controlP5.Controller : float getValue() 
controlP5.Controller : float[] getAbsolutePosition() 
controlP5.Controller : float[] getArrayValue() 
controlP5.Controller : float[] getPosition() 
controlP5.Controller : int getDecimalPrecision() 
controlP5.Controller : int getHeight() 
controlP5.Controller : int getId() 
controlP5.Controller : int getWidth() 
controlP5.Controller : int listenerSize() 
controlP5.Controller : void remove() 
controlP5.Controller : void setView(ControllerView, int) 
controlP5.Textfield : String getText() 
controlP5.Textfield : String[] getTextList() 
controlP5.Textfield : Textfield clear() 
controlP5.Textfield : Textfield keepFocus(boolean) 
controlP5.Textfield : Textfield setAutoClear(boolean) 
controlP5.Textfield : Textfield setColor(int) 
controlP5.Textfield : Textfield setColorCursor(int) 
controlP5.Textfield : Textfield setFocus(boolean) 
controlP5.Textfield : Textfield setFont(ControlFont) 
controlP5.Textfield : Textfield setFont(PFont) 
controlP5.Textfield : Textfield setFont(int) 
controlP5.Textfield : Textfield setHeight(int) 
controlP5.Textfield : Textfield setInputFilter(int) 
controlP5.Textfield : Textfield setPasswordMode(boolean) 
controlP5.Textfield : Textfield setSize(int, int) 
controlP5.Textfield : Textfield setText(String) 
controlP5.Textfield : Textfield setValue(String) 
controlP5.Textfield : Textfield setValue(float) 
controlP5.Textfield : Textfield setWidth(int) 
controlP5.Textfield : Textfield submit() 
controlP5.Textfield : boolean isAutoClear() 
controlP5.Textfield : boolean isFocus() 
controlP5.Textfield : int getIndex() 
controlP5.Textfield : void draw(PGraphics) 
controlP5.Textfield : void keyEvent(KeyEvent) 
java.lang.Object : String toString() 
java.lang.Object : boolean equals(Object) 

created: 2015/03/24 12:21:31

*/


Yes I was the one that posted that, with little hope of a response because the lib is so old.

So, does anyone have any ideas?

controlP5 is an excellent library but I think that G4P will be better for what you want to do

G4P has both text field (single-line input ) and text area (mult-iline input) controls. In both cases the user can

  • move the text insertion point (TIP) using the arrow keys
  • select text using SHIFT + ARROW keys
  • select all text with CTRL+A
  • select text using the mouse
  • copy selected text with CTRL+C
  • paste selected text with CTRL+V
  • the DELETE and BACKSPACE keys delete characters to the right and left of the TIP respectively
  • selected text is replaced if a visible character key is typed, text is pasted, or the DELETE / BACKSPACE key is pressed.

NOTE: the text area control does not support blank lines.

I think that about covers your needs :grin:

1 Like

R U Kiddin? I adore your library!

I’m running into one huge stumbling block though with the text fields. I use some special fonts that I create in processing, for special characters like stars and music notes. It’s for a music fader box, and the added characters give the unit a little charm.

But as far as I understand it, it is not possible to use a font I generate in processing with the *.vlw extension, correct?

Also, I love your textfields; they are great!

My one small niggle - no disrespect - is I find quite hard to skin the controls. Using the palette.gif is so unintuitive and confusing…I managed to hack a gray scheme but it’s not quite what I’m wanting…and…the drop down menu arrows look like dots, not arrows.

I appreciate your constant dedication, and I definitely am already going to use your library for a lot of the GUI.

Thank you Peter; you’re a gem.

Mike

G4P does not use vlw files for text, rather you can use any ttf font installed on your computer e.g.

  // We this import to use system fonts
  import java.awt.Font; 

  // txf1 = textfield control
  txf1.setFont(new Font("Digiface", G4P.PLAIN, 30));

Screenshot 2024-04-09 at 16.27.14

When I created G4P I wanted it to be easy for users to choose a consistent colour scheme for their GUI controls, hence the colour schemes available. TBH I never considered users wanting to spend the time creating their own skins so sorry about that. No library satisfies all the users all the time LOL.

2 Likes

I totally hear you. As a dev myself, I get the “but why doesn’t it have WINGS???” questions LOL!

In this case, if my customer doesn’t have the *.ttf installed, then the app won’t look (or work) right.

Is there a way to bundle the *.ttf with the app when exported standalone, to ensure it will work right? Sounds like a Pandora’s box. But I am using only open source fonts.

And I get your stance on skinning. Wasn’t designed for everyone’s needs.

Might you consider upgrading this area of the library? At least, make it easy to create new skins?

In any case, again thank you Peter. :slight_smile:

Hi again Peter, I’m trying to use your textfield control as you suggested.

I’m using an open source font called Noto Sans, and it has “light, regular, bold, italic” etc.

When I try setting the font using this line, it doesn’t seem to use the right font:

txf1.setFont(new Font("Noto Sans", G4P.BOLD, 24));

How would I handle this? I also tried:

txf1.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 24));

But this did not work.

How to get the exact font variation for the textfield?

Thanks again,

Mike

Have you tried a JavaFX TextField? https://discourse.processing.org/t/javafx-controls-preview/41353

TextArea

Correction:

The image is a TextField not a TextArea.

1 Like

Thank you so much. I will follow up with your suggestion and let you know if I am successful.

I have download this font from Google Fonts and I experienced the same problem, although G4P.ITALIC did work.

I don’t know why this is happening but it isn’t G4P because it does the same in Java Swing.

1 Like

I appreciate it. Sorry to give you work.

Also I tried using a textarea control, and if it isn’t very tall, the text jumps up and down rapidly like crazy…not sure if this is known behavior?..would like to be able to use it more like a one line textbox but it seems it has to be very tall or this crazy jumping behavior ensues.

And before you ask, the textfield control does not allow insertion of text, only append, so I can’t insert special characters at the cursor…

I also made a cool right-click menu to insert the special chars, but unfortunately it always is rendered underneath the textarea control. Based on other posts of yours, it’s probably not possible to have processing drawn elements like rectangles appear over the textarea control (and you’d rightly say “why would you want to do that!”…well…for a custom right click menu with a drawn rect…).

Thanks Peter

I’m getting “The package “javafx” does not exist. You might be missing a library.”

I did install the lib. The preview in that link looks fantastic though.

Please bear with me. I added one line of code to the editor to hook up all the jar files necessary to use JavaFX but was unable to convince the editor author to do the same. But… there is a work around which will hopefully work for everyone else. You stated that you installed JavaFx. Go to your libraries folder and find that folder; you may follow this path:

Processing/javafx/library/yourOSFolder/modules/

inside that modules folder should be seven jar files. Copy/paste those jar files and place them in a folder entitled ‘code’ in your sketch folder. That should allow the demo to run. If it doesn’t please post back.

Requisite jar files for JavaFx:

Thank you svan.

Sadly, no luck.

Error: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.scene.control.ControlHelper (in unnamed module @0x51c5f76e) cannot access class com.sun.javafx.scene.layout.RegionHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.layout to unnamed module @0x51c5f76e

What I told you used to work, ie the editor version before the last. They’ve apparently changed something and I have no idea how to fix it. Sorry.

No worries. Thank you svan.

I don’t know if you know how to use the command-line, but if you do, you can create a javafx demo for TextField with the following instructions.

  1. Download a current javafx-sdk from https://openjfx.io
  2. Place the sdk and the following source code in the same folder in your home directory (or wherever you want to put it, I used a folder named ‘java’).
  3. Copy/paste the following source code into a generic editor of your choice and save it as ‘TextFieldDemo.java’ in your designated directory:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class TextFieldDemo extends Application {
  public static void main(String[] args) {
    launch(args);
  }

  @Override public void start(Stage stage) {
    stage.setTitle("JavaFx TextField demo");
    Pane pane = new Pane();

    // **** TextField **** //
    TextField txtFld = new TextField();
    txtFld.setLayoutX(100);
    txtFld.setLayoutY(100);
    pane.getChildren().add(txtFld);

    Scene scene = new Scene(pane, 400, 300);
    stage.setScene(scene);
    stage.show();
  }
}
  1. Open ‘Terminal’ if you’re using MacOS and migrate to your designated folder which contains the demo file and javafx-sdk.
  2. You will need to run two commands; one to compile (javac…) and one to run (java…) the demo:
    The first is ‘javac’ to compile:
    At the prompt type the following using your path and sdk number:
javac --module-path /Users/yourName/java/javafx-sdk-20/lib/ --add-modules javafx.controls TextFieldDemo.java

Then at the prompt enter the ‘java …’ command to run the demo:

java --module-path /Users/yourName/java/javafx-sdk-20/lib/ --add-modules javafx.controls TextFieldDemo

Hopefully this will give you something to experiment with. If you don’t want to mess with it I understand.

Thank you so much svan.

I start to see why they didn’t include javafx in Processing, if it’s this tricky to get going.

Because of you I’ve now downloaded Visual Studio Code as well as JavaFX and Scene Builder.

Took all day and night just to get a hello world working (nightmare really). But that’s development for you.

I will try to run your code for the demo.

In any case I can see why ppl love Processing so much, and just how good Peter’s library really is.

Thanks again, and I’ll try to chime in now and again with progress.

I start to see why they didn’t include javafx in Processing

It really is not that difficult; the authors just failed to include the javafx.controls module, even though they did include three other modules: JavaFX Unable to add modules to Processing IDE - #3 by svan (read the entire thread)

However, the last error that you described is due to something else. I have no idea why they don’t want to support JavaFX controls. They really are good controls and were initially intended to supplant Swing.

Addendum:

Speaking of Swing, have you looked at JTextField?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

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

final int _wndW = 400;
final int _wndH = 300;

void buildWnd() {
  JTextField txtFld = new JTextField("");
  txtFld.setBounds(50, 40, 280, 30);
  txtFld.setBackground(Color.WHITE);
  frame.add(txtFld);
  // **** Action **** //
  txtFld.addActionListener( new ActionListener() {
    void actionPerformed(ActionEvent actionEvent) {
      // Do something;
    }
  }
  );
  txtFld.repaint(); // To make it visible after export application.
}

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);

  javax.swing.SwingUtilities.invokeLater(()-> {
    buildWnd(); // Builds components on EventDispatchThread
  }
  );
}

1 Like