0

I'm trying to create a cross-platform swing application, and will include at least 3 Unicode fonts (say Japanese, Tamil and Hebrew, all belonging to different families). They're supposed to be used in a component (say JTable) when there is either Japanese, Tamil or Hebrew font (none of the two will be present simultaneously in cells). Is there any way to detect glyph and set font family accordingly?

JavaUser
  • 19
  • 3
  • I would just simplify things and find a font that will do all your languages – g00se Dec 06 '22 at 17:16
  • Modern OSes automatically fallback to other fonts when the default font lacks needed glyphs. No need for you to do anything. macOS does this beautifully, and I expect Windows and Linux to perform adequately as well. On a platform where Swing makes use of the host OS’s text rendering, then all should go well. Be sure to use the latest version of Java, either current or most recent LTS version. – Basil Bourque Dec 06 '22 at 17:29
  • No such thing as a “Unicode” font. All modern font systems support Unicode, afaik. – Basil Bourque Dec 06 '22 at 17:35
  • [This](https://www.unifoundry.com/unifont/index.html) claims to have a massive number of glyphs – g00se Dec 06 '22 at 17:56
  • @g00se Unifont will render all characters in the BMP. For example, it can display [Latin, Japanese and Hindi text](https://stackoverflow.com/a/73970038/2985643). A potential issue with using it is the quality of the rendering for certain glyphs, and it is also fixed width. [Wikipedia also documents some other limitations](https://en.wikipedia.org/wiki/GNU_Unifont). But if none of that is a concern your approach seems reasonable (even though it does not directly address the OP's question). – skomisa Dec 07 '22 at 00:06
  • I tried setting default font for JTable as unifont, but that font doesn't create compound glyphs. Including Arial Unicode font will mess up licensing terms. The default font (Segoe UI in Windows and Liberation Sans in Linux) aren't falling back to the appropriate font either. – JavaUser Dec 09 '22 at 09:22

1 Answers1

0

Assuming the text appears in a JTable, you can write a custom cell renderer that will switch the font depending on the text to be displayed.

For example:

JTable table = new JTable();
table.setModel(model);
table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        
        String text = (String) value;
        
        if (text.matches(".*[\\u3040-\\u30FF]+.*")) { // Japaneese
            c.setFont(font1);
        } else if (text.matches(".*[\\u0B80-\\u0BFF]+.*")) { // Tamil
            c.setFont(font2);
        } else if (text.matches(".*[\\u0590-\\u05FF]+.*")) { // Hebrew
            c.setFont(font3);
        } else {
            c.setFont(table.getFont());
        }
        
        return c;
    }
});

Custom renderers can be used for other components as well (JList, JTree, JComboBox).

Emmanuel Bourg
  • 9,601
  • 3
  • 48
  • 76