2014-02-19 153 views
3

我试图创建一个自定义反锯齿JLabel,但我的文字仍然是僵硬的。为什么这不起作用?反锯齿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

+0

是否超集的呈现提示本身? – Others

+0

那么,渲染提示是Graphics2D对象的一个​​属性,我将该对象传递给要使用的父类。 –

+0

那么超级可以通过设置它们自己来覆盖提示......你还可以检查你的系统是否支持抗锯齿? – Others

回答

6

截图

文字的截图被渲染:

  1. Graphics2DRenderingHints.VALUE_TEXT_ANTIALIAS_ON(绿色边框)
  2. 标准JLabel(蓝色边框)
  3. 一个SmoothLabel强制执行RenderingHints.VALUE_TEXT_ANTIALIAS_ON(红色边框)

金属

雨云

在所有测试的PLAFs

CDE /基序

结论

SmoothLabel支撑/强制消除锯齿的文本。这里唯一的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); 
    } 
} 
+0

感谢您的回复!看看我的编辑。 –

+0

古怪的是,在Linux上使用Swing LAF不适合我。 (Windows很好。)例如:http://tinybrain.de/1007789 –