2014-09-23 25 views
1

我有一個類延伸BufferedImage應該顯示爲提供給它的構造函數的字符串。我希望這樣做的原因是允許graphics2D的抗鋸齒功能(有關更多詳細信息,請參閱我的previous question),如果您有任何更好的建議,那麼通過所有方法建議他們!)。我現在有BufferedImage類工作,但我無法弄清楚如何確定所需的寬度和高度,以便在實際設置字體之前顯示輸入字符串。一旦設置了初始大小,我也找不到調整BufferedImage家長的方法。這裏是我的代碼:創建未知尺寸的緩衝圖像

import java.awt.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

public class Test extends JFrame{ 
    public Test(){ 
     this.add(new JLabel(new ImageIcon(new IconImage("Test", new Font("Sans-Serif", Font.PLAIN, 16))))); 
     this.setVisible(true); 
     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     this.pack(); 
    } 

    class IconImage extends BufferedImage{ 
     public IconImage(String text, Font font){ 
      super(..., ..., BufferedImage.TYPE_INT_ARGB);//*****Unknown dimensions***** 

      Graphics2D g2d = (Graphics2D) this.getGraphics(); 
      g2d.setFont(font); 
      g2d.setColor(Color.BLACK); 

      int stringHeight = (int) g2d.getFontMetrics().getStringBounds(text, g2d).getHeight(); 
      g2d.drawString(text, 0 , stringHeight); 
      g2d.dispose(); 
     } 
    } 

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

有什麼建議嗎?謝謝。

+0

我想問你爲什麼試圖先創建圖像然後創建按鈕?你有可能以相反的方式做到這一點嗎? (如果是的話:你可以測量按鈕,然後創建該圖像)順便說一句:如何顯示比你的組件更大的圖形 - 它的工作原理,但修剪... – 2014-09-23 11:05:34

+0

由於實際的實現只是創建一個按鈕,然後調用'setIcon '和'setRolloverIcon'。我無法弄清楚如何在一個已經調用setText的按鈕上執行反鋸齒。 – Hungry 2014-09-23 11:13:28

回答

2

兩個可能的解決方案:

  1. 創建一個微小的BufferedImage(1×1),只是爲了獲得Graphics對象,做你的計算。然後創建實際圖像
  2. 創建任意維度的BufferedImage並將文本縮放到BufferedImage的大小。有關縮放比例的示例,請參閱StandardPrint.preview
+0

自從我問這個問題以來,第一點實際上就是我一直在努力的。它的工作原理雖然有些遲鈍,但我問了這個問題,看看是否有更傳統的方法。 – Hungry 2014-09-23 11:16:10

+0

我經常使用第一種策略。 – 2014-09-23 11:20:05

+0

@安德魯·湯普森噢還不錯,那麼會做到這一點。 – Hungry 2014-09-23 11:32:07

2

我只發現相對情況下的代碼。 需要FontMetrics,它依賴於圖形設備(屏幕/打印機)。

因此,我製作了一個超大的圖像,與屏幕兼容。

static BufferedImage textToImage(Font font, String text) { 
    BufferedImage testImg = GraphicsEnvironment.getLocalGraphicsEnvironment() 
      .getDefaultScreenDevice() 
      .getDefaultConfiguration() 
      .createCompatibleImage(1000, 100); 
    FontMetrics fm; 

    Graphics2D g = testImg.createGraphics(); 
    g.setFont(font); 
    fm = g.getFontMetrics(font); 
    Rectangle2D bounds = fm.getStringBounds(text, g); 
    System.out.println("Bounds: " + bounds); 
    g.setColor(Color.WHITE); 
    g.fillRect(0, 0, testImg.getWidth(), testImg.getHeight()); 
    g.setColor(Color.MAGENTA.darker()); 
    g.drawString(text, 0, fm.getHeight() - fm.getDescent()); 
    g.dispose(); 

    Rectangle viewR = new Rectangle(0, 0, 1000, 100); 
    Rectangle iconR = new Rectangle(); 
    Rectangle textR = new Rectangle(); 
    String displayedText = SwingUtilities.layoutCompoundLabel(fm, text, null, 
        SwingConstants.TOP, SwingConstants.LEFT, 0, 0, 
        viewR, iconR, textR, 0); 

    System.out.println("textR: " + textR); 
    BufferedImage img = testImg.getSubimage(0, 0, textR.width, textR.height); 
    return img; 
} 

字符串邊界是一個浮點矩形。通過比較使用SwingUtilities.layoutComponentLabel,可以看到邊界向上舍入了一個半像素:字體可能會使像素部分移動以產生銳利的邊緣。