Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java image for control characters in JTextArea

I'm writing an application which consists of 2 panels. One JTextArea for entering text and another one for showing text.

In these texts I have two special characters namely STX/ETX (0x02, 0x03 in ASCII). When I enter these characters they are shown as invisible or some other symbol. I would like to make them visible and copyable like in Notepad++: notepad++ special characters example

Could anyone point me to a solution how to achieve that with a (probably custom) JTextArea? Is it possible to overwrite Font images or something like that?

For my other view, where I don't need to manipulate the text I will have html showing these characters as images (if you know of a better solution, please tell me).

like image 902
Marco Avatar asked May 19 '26 11:05

Marco


2 Answers

Replacing control characters with images works, nevertheless it seems to take CPU resources and make the GUI lag.

A better solution is to use font glyph in a modified TrueType font file. You can draw a glyph for STX, ETX, etc and add them to the font file but it's a lot of work to reproduce the Scintilla glyph that you see in Notepadd++.

You can use another simple method:

  1. Download a TTF file like UbuntuMono-R.ttf, open the file in FontForge, you can see a list of all the native glyph and the empty control characters at the start of the list.
  2. Open another TTF file like Digits.ttf in FontForge and copy characters you are interested in and paste them at the start of the list. Here I pasted the circled numbers representing Hexadecimal codes of control characters.
  3. Generate the new TTF file which contains your control characters representation.
  4. Embbed the font file in your jar and register it in your application:

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    try (InputStream fontStream = new BufferedInputStream(SwingAppender.class.getResourceAsStream("/com/jsql/view/swing/resources/font/UbuntuMono-Regular-new.ttf"))) {
        Font ubuntuFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
        ge.registerFont(ubuntuFont);
    } catch (FontFormatException | IOException e) {
        LOGGER.warn("Loading Font Ubuntu failed", e);
    }
    
  5. Instanciate the font and apply it to a JTextComponent:

    public static final Font FONT_UBUNTU = new Font("Ubuntu Mono", Font.PLAIN, 12);
    

The process will be identical if someone find the original Scintilla glyph or draw it themself, add them to the list in FontForge and you will see them in your text component (I have tested and drawn the control character EOT pixel by pixel on http://fontstruct.com, it was OK in Swing but I'm too lazy to draw the rest).

enter image description here

like image 179
ron190 Avatar answered May 21 '26 00:05

ron190


I'm not sure it's possible with a JTextArea, at least not without messing with a lot of Swing internals. But a JTextPane can do it:

JTextPane textPane = new JTextPane();
Icon stx = new ImageIcon("stx.png");
Icon etx = new ImageIcon("etx.png");

textPane.setText("\u0002Example\u0003");
StyledDocument doc = textPane.getStyledDocument();

MutableAttributeSet attr;

attr = new SimpleAttributeSet();
StyleConstants.setIcon(attr, stx);
doc.setCharacterAttributes(0, 1, attr, false);

attr = new SimpleAttributeSet();
StyleConstants.setIcon(attr, etx);
doc.setCharacterAttributes(8, 1, attr, false);
like image 25
VGR Avatar answered May 21 '26 00:05

VGR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!