How to Highlight Text in a ControlP5 Textfield?

Thanks for this svan. I ran the test code and it works perfectly.

I’m a little nervous because Processing specifically states not to use swing as it can cause problems.

Any thoughts about that?

Thanks again,

Mike

I thought with all this discussion it might be worth showing what I’m trying to do.

Here’s a short video:

DIY Dropdown

Yes I could just use one of the drop-down menus from Peter’s library, but now we are really getting away from the initial brief. Originally I just wanted to be able to right-click the field and insert a special character, but the right-click menu gets hidden by the field. So then I thought put it to the side as a button. But then we are still getting the coverup issue shown in the video.

So unless there’s a way to control the z-order of a drawn control vs a lib control, I will have to strategically place the menu to avoid lib menus in its path…or go to swing or JavaFX.

Thanks for watching.

Mike

The problem is that Java Swing and their Processing sketch will have their own event threads which can either compete with each other or cause concurrent access exceptions. You can use Swing with Processing you just have to be careful.

I think the problem is in the creation of the awt font. The font file for “Noto Sans” has a ttc extension which stands for ‘true type collection’ in other words the file contains contain several font faces and I think Java does not reconise all of them when using new File(...)

Having said that G4P allows you to specify the attributes for some or all the text (see GTextBase. This image shows 4 labels using the “Noto Sans” font

Screenshot 2024-04-11 at 11.46.43

Here is the sketch code

import g4p_controls.*;
import java.awt.*;

Font font;
GLabel lbl0, lbl1, lbl2, lbl3;

void setup() {
  size(400, 260);
  font = new Font("Noto Sans", G4P.PLAIN, 24);


  lbl0 = new GLabel(this, 20, 10, 300, 40, "Plain quark");
  lbl0.setFont(font);
  lbl0.setOpaque(true);

  lbl1 = new GLabel(this, 20, 70, 300, 40, "Italic quark");
  lbl1.setFont(font);
  lbl1.setTextItalic();
  lbl1.setOpaque(true);

  lbl2 = new GLabel(this, 20, 130, 300, 40, "Bold quark");
  lbl2.setFont(font);
  lbl2.setTextBold();
  lbl2.setOpaque(true);

  lbl3 = new GLabel(this, 20, 190, 300, 40, "Italic-Bold quark");
  lbl3.setFont(font);
  lbl3.setTextBold();
  lbl3.setTextItalic();
  lbl3.setOpaque(true);
}

void draw() {
  background(200, 200, 255);
}

This will not work with the textfield and textarea classes when editing text because it changes the font metrics.

3 Likes

Just watched your video which was very helpful; thanks for posting. My initial thought would be to consider a moveable palette window for the special characters. In the video it’s tied to one of the fields so that it can be covered up by other fields. If it was moveable you could drag it around and keep it out of the way or alternatively park it permanently on the edge of your window like a drawing app. You can make multiple windows using another PApplet or JFrames.

Another possibility would be a JPopupMenu:

//https://www.javatpoint.com/java-jpopupmenu

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

void  PopupMenuExample() {
  final JFrame f= new JFrame("JPopupMenu Example");
  final JPopupMenu popupmenu = new JPopupMenu("Edit");
  JMenuItem cut = new JMenuItem("Cut");
  JMenuItem copy = new JMenuItem("Copy");
  JMenuItem paste = new JMenuItem("Paste");
  popupmenu.add(cut);
  popupmenu.add(copy);
  popupmenu.add(paste);
  f.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
      popupmenu.show(f, e.getX(), e.getY());
    }
  }
  );
  f.add(popupmenu);
  f.setBounds(300, 100, 300, 300);
  f.setLayout(null);
  f.setVisible(true);
}

void setup() {
  surface.setVisible(false);
  PopupMenuExample();
}

2 Likes

Peter, thank you so much for your time and effort. I really appreciate it!

Mike

I will check it out svan! Thank you so much!

Now I start to think swing is pretty cool…

JToolbar might work also. All the special characters would be in a toolbar across the top of your window for selection at any time.

Addendum:
It does work if you want to go that route:

Source code:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.JTextField;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Clipboard;

JFrame frame;
JButton btn1, btn2, btn3, btn4, btn5;

class ButtonEventListener implements ActionListener {
  void actionPerformed(ActionEvent event) {
    String btnStr = ((JButton)event.getSource()).getText();
    println("btn hit = ", btnStr);
    StringSelection stringSelection = new StringSelection (btnStr);
    Clipboard clpbrd = Toolkit.getDefaultToolkit ().getSystemClipboard ();
    clpbrd.setContents (stringSelection, null);
  }
}

void setup() {
  surface.setVisible(false);
  frame = new JFrame("JToolBar Example");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JToolBar toolbar = new JToolBar();
  toolbar.setRollover(true);
  btn1 = new JButton("\u2665");
  toolbar.add(btn1);
  btn1.addActionListener(new ButtonEventListener());
  btn2 = new JButton("\u2605");
  toolbar.add(btn2);
  btn2.addActionListener(new ButtonEventListener());
  btn3 = new JButton("\u2663");
  toolbar.add(btn3);
  btn3.addActionListener(new ButtonEventListener());
  btn4 = new JButton("\u2660");
  toolbar.add(btn4);
  btn4.addActionListener(new ButtonEventListener());
  btn5 = new JButton("\u2666");
  toolbar.add(btn5);
  btn5.addActionListener(new ButtonEventListener());
  Container contentPane = frame.getContentPane();
  contentPane.add(toolbar, BorderLayout.NORTH);
  frame.setBounds(300, 100, 450, 250);
  frame.setVisible(true);
  // **** JTextField  **** //
  JTextField txtFld = new JTextField("");
  txtFld.setBounds(50, 40, 280, 30);
  txtFld.setBackground(Color.WHITE);
  frame.add(txtFld);
  txtFld.setText("Jeremiah was a bullfrog.");
  txtFld.repaint(); // To make it visible after export application.
}

How it works:
Code places a series of buttons on a JToolbar, each with a unicode character title. Each button also has its own handler to retrieve the title string when the button is hit and places the string on the clipboard. The clipboard string can then be inserted into a JTextField at the caret with a cmd-v key combination on a Mac.

2 Likes