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++:

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).
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:
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);
}
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).

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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With