Java image for control characters in JTextArea

梦想的初衷 提交于 2019-12-23 16:48:12

问题


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


回答1:


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




回答2:


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


来源:https://stackoverflow.com/questions/24590985/java-image-for-control-characters-in-jtextarea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!