Anti-aliasing of JButton text

2019-06-27 05:34发布

问题:

I'm using Font Awesome within a JButton to create a click-able icon, however the resulting icon appears aliased when at a small size. Just as a bit of background, Font Awesome is a downloadable ttf file (the font file) in which each character is a 'scalable vector icon'. Having looked at previous answers on Google and stack overflow, I have tried to force anti-aliasing by overriding the paintComponent method of JButton; this however has seemingly no effect:

import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Test extends JFrame{

    public Test(){
        Font fontAwesome = null;
        try {
            fontAwesome = Font.createFont(Font.TRUETYPE_FONT, new File("font-awesome-4.2.0\\fonts\\fontawesome-webfont.ttf"));
            fontAwesome = fontAwesome.deriveFont(Font.PLAIN, 100);
        } catch (FontFormatException | IOException e) {
            e.printStackTrace();
        }

        JButton iconButton = new JButton("\uf0a8"){
            @Override
            public void paintComponent(Graphics g) {
                Graphics2D graphics2d = (Graphics2D) g;
                graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                //graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                //graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                //graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                super.paintComponent(graphics2d);
            }
        };

        iconButton.setFont(fontAwesome);
        iconButton.setFocusPainted(false);

        this.add(iconButton);
        this.setVisible(true);
        this.pack();
    }

    public static void main(String[] args){
        new Test(); 
    }
}

The following images show the resulting font icons at font sizes 30, 100 and 200:

How can I force anti-aliasing for small font sizes?

UPDATE: I have tested the same code using a built in java font rather than Font Awesome, and exactly the same issue applies.

回答1:

JLabel does proper text hinting, so you can put the Font Awesome text in a JLabel, and then put the JLabel in a JButton:

    JLabel iconLabel = new JLabel( "\uf0a8" );
    iconLabel.setFont( fontAwesome );

    JButton iconButton = new JButton( );
    iconButton.add( iconLabel );

This solves successfully works around the issue on Linux with the NimROD L&F. Seems reasonable to expect it to work on other configurations as well, but YMMV.