消除锯齿的JLabel

时间:2014-02-19 02:19:27

标签: java swing jlabel paintcomponent antialiasing

我试图创建一个自定义的抗锯齿JLabel,但我的文字仍然很僵硬。为什么这不起作用?

类似问题的答案包括更详细的解决方案,但我想知道为什么这不起作用。

编辑:

这是一个SSCCE:

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Tester {

    public static void main(String[] args) {
        SmoothLabel label = new SmoothLabel("Hello");
        label.setFont(new Font("Times New Roman", Font.PLAIN, 100));
        JFrame frame = new JFrame("SmoothLabel test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);

        frame.add(label);
        frame.setVisible(true);
    }
}

class SmoothLabel extends JLabel {

    String text;

    public SmoothLabel (String text) {
        super(text);

        this.text = text;
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        super.paintComponent(g2d);
    }
}

当我的字体大小为100时,我得到以下输出,它似乎没有消除锯齿:

100pt font

将字体设置为150,它突然显示为消除锯齿:

250pt font

1 个答案:

答案 0 :(得分:7)

截图

呈现的文字截图:

  1. Graphics2D RenderingHints.VALUE_TEXT_ANTIALIAS_ON(绿色边框)
  2. 标准JLabel(蓝色边框)
  3. 强制SmoothLabel(红色边框)
  4. RenderingHints.VALUE_TEXT_ANTIALIAS_ON

    金属

    雨云

    CDE /基序

    结论

    SmoothLabel支持/强制执行所有测试的PLAF中的抗锯齿文本。 尚未使用消除锯齿文本的唯一PLAF是CDE / Motif。

    代码

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.font.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    import javax.swing.border.LineBorder;
    
    import java.io.*;
    import javax.imageio.ImageIO;
    
    class FontAntialiasingInSwingPLAFs {
    
        private JPanel gui = new JPanel(new BorderLayout(2, 2));
        String[] types = {"Graphics2D", "JLabel", "SmoothLabel"};
        private JLabel[] labels = {
            new JLabel(""), new JLabel(""), new SmoothLabel("")
        };
        private JLabel[] scaleLabels = {
            new JLabel(""), new JLabel(""), new JLabel("")
        };
        private Color[] colors = {Color.GREEN, Color.BLUE, Color.RED};
        private JComboBox<String> plaf = null;
        private UIManager.LookAndFeelInfo[] plafs;
    
        FontAntialiasingInSwingPLAFs() {
            initComponents();
        }
    
        private final void initComponents() {
            // here we design the layout and controls..
            JToolBar tb = new JToolBar("Controls");
            tb.setFloatable(false);
            gui.add(tb, BorderLayout.PAGE_START);
    
            Action save = new AbstractAction("Save") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    saveImages();
                }
            };
            tb.add(save);
            tb.addSeparator();
    
            plafs = UIManager.getInstalledLookAndFeels();
            plaf = new JComboBox<String>() {
    
                @Override
                public Dimension getMaximumSize() {
                    return super.getPreferredSize();
                }
            };
            for (UIManager.LookAndFeelInfo info : plafs) {
                plaf.addItem(info.getName());
            }
            tb.add(plaf);
            ActionListener plafListener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    changePLAF();
                }
            };
            plaf.addActionListener(plafListener);
    
    
            JPanel normalSize = new JPanel(new GridLayout(0, 3, 2, 2));
            gui.add(normalSize);
            for (int ii = 0; ii < labels.length; ii++) {
                labels[ii].setBorder(new LineBorder(colors[ii]));
                normalSize.add(labels[ii]);
            }
    
            JPanel scaledSize = new JPanel(new GridLayout(0, 3, 2, 2));
            gui.add(scaledSize, BorderLayout.PAGE_END);
            for (int ii = 0; ii < scaleLabels.length; ii++) {
                scaledSize.add(scaleLabels[ii]);
            }
    
            setText();
        }
    
        private void setText() {
            String plafName = (String) plaf.getSelectedItem();
            for (int ii = 1; ii < labels.length; ii++) {
                labels[ii].setText(plafName + " " + types[ii]);
            }
            labels[0].setIcon(new ImageIcon(getImage(plafName + " " + types[0])));
        }
    
        private void setScaledImages() {
            Dimension d = labels[0].getSize();
            for (int ii = 0; ii < labels.length; ii++) {
                BufferedImage scaledImage = getScaledImage(ii, 4, 200);
                scaleLabels[ii].setIcon(new ImageIcon(scaledImage));
            }
        }
    
        private BufferedImage getScaledImage(
                int index, int scale, int max) {
            BufferedImage input = getImage(index);
            int w = input.getWidth() * scale;
            int h = input.getHeight() * scale;
            w = w > max ? max : w;
            h = h > max ? max : h;
            BufferedImage temp = new BufferedImage(
                    w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = temp.createGraphics();
    
            // do the drawing..
            g.scale(scale, scale);
            g.drawImage(input, 0, 0, gui);
    
            g.dispose();
            return temp;
        }
    
        private BufferedImage getImage(int index) {
            JLabel input = labels[index];
            int w = input.getWidth();
            int h = input.getHeight();
            BufferedImage temp = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = temp.createGraphics();
    
            // do the drawing..
            input.paintAll(g);
    
            g.dispose();
            return temp;
        }
    
        private BufferedImage getImage(String text) {
            int w = 5;
            int h = 5;
            BufferedImage temp = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = temp.createGraphics();
    
            FontRenderContext frc = g.getFontRenderContext();
            Font f = labels[1].getFont();
            GlyphVector gv = f.createGlyphVector(frc, text);
            Shape s1 = gv.getOutline();
            Shape s = gv.getOutline(-s1.getBounds().x, -s1.getBounds().y);
            Rectangle textBounds = s.getBounds();
            // recreate the image at the required size
            temp = new BufferedImage(
                    textBounds.width,
                    textBounds.height,
                    BufferedImage.TYPE_INT_ARGB);
            // get the graphics object of the new image
            g = temp.createGraphics();
            g.setFont(f);
            // set a RenderingHints.KEY_TEXT_ANTIALIASING
            g.setRenderingHint(
                    RenderingHints.KEY_TEXT_ANTIALIASING,
                    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g.setColor(Color.BLACK);
    
            // do the drawing..
            g.drawString(text, 0, textBounds.height);
    
            g.dispose();
            return temp;
        }
    
        private final void changePLAF() {
            int selected = plaf.getSelectedIndex();
            try {
                UIManager.setLookAndFeel(plafs[selected].getClassName());
                Container c = gui.getTopLevelAncestor();
                SwingUtilities.updateComponentTreeUI(c);
                setText();
                setScaledImages();
                if (c instanceof Window) {
                    Window w = (Window) c;
                    w.pack();
                } else {
                    System.err.println(c.getClass().getSimpleName());
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
        private final String getImageName(int index, boolean scaled) {
            String name = "";
            String sText = scaled ?  " Scaled" : "";
            if (index == 0) {
                name = (String)plaf.getSelectedItem() + " " + types[0];
            } else {
                String text = labels[index].getText();
                name = text;
            }
            String sPattern = "\\/";
            name = name.replaceAll(sPattern, "-");
            return name + sText + ".png";
        }
    
        private final void saveImages() {
            File f = new File(System.getProperty("user.home"));
            f = new File(f, "zundry");
            f = new File(f, "font-antialias");
            boolean success = true;
            if (!f.exists()) {
                success = f.mkdirs();
            }
            if (success) {
                // save the images!
                for (int ii = 0; ii < labels.length; ii++) {
                    try {
                        File tempSmall = new File(f, getImageName(ii, false));
                        ImageIO.write(getImage(ii), "png", tempSmall);
                        File tempScaled = new File(f, getImageName(ii, true));
                        ImageIO.write(getScaledImage(ii, 4, 200), "png", tempScaled);
                        Desktop.getDesktop().open(f);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            } else {
                System.err.println(
                        "The directory could not be created!  "
                        + f.getAbsolutePath());
            }
        }
    
        public JComponent getGui() {
            return gui;
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    FontAntialiasingInSwingPLAFs fawp =
                            new FontAntialiasingInSwingPLAFs();
    
                    JOptionPane.showMessageDialog(null, fawp.getGui());
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
            SwingUtilities.invokeLater(r);
        }
    }
    
    class SmoothLabel extends JLabel {
    
        public SmoothLabel(String text) {
            super(text);
        }
    
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    
            super.paintComponent(g2d);
        }
    }