2016-04-16 83 views
5

我的課GraphicButton.java創建一個自定義JButton與一定的文字和字體和矩形邊框。我的問題是,在字符串的最後一個字符和我想要刪除的邊框的末尾之間有一些額外的空間。如何從Java中用Graphics顯示的字符串的末尾刪除空格?

這裏是一個GraphicButton的實例,看起來像一個字符串「PLAY」和字體FFF Forward直接下載鏈接)添加到JFrame紅線是我想要刪除的空間

這裏是我使用(JFrame創建和設置省略)代碼:

GraphicButton.java

public class GraphicButton extends JButton { 

    private static final long serialVersionUID = 1L; 

    //Fields 
    private String text; 
    private Font font; 

    //Constructor 
    public GraphicButton(String text, Font font) { 
     super(text); 

     this.text = text; 
     this.font = font; 
     //Setting preferred size here. 
     this.setPreferredSize(new Dimension(this.getFontMetrics(font).stringWidth(text), this.getFontMetrics(font).getAscent())); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     g.setFont(this.font); 

     //Draw text 
     g.drawString(this.text, 0, this.getHeight()); 
     //Draw border 
     g.drawRect(0, 0, this.getWidth(), this.getHeight()); 
    } 
} 

我在Mac上運行Eclipse的Java 1.8。

+0

該空格是字母之間的空格。我猜你可以在BufferedImage上繪製「PLAY」,找到最右邊的空間,刪除空間,並將修改後的BufferedImage作爲ImageIcon傳遞給JButton。 –

+0

我喜歡你的建議@GilbertLeBlanc,只是我不知道如何去做你的建議。請在答案中添加一些內容,告訴我該怎麼做。 – MasterBlaster

+0

閱讀我的文章[Java Swing Marquee](http://java-articles.info/articles/?p=681),瞭解我如何操作BufferedImage。 –

回答

3

您可能可以使用TextLayout來獲得更好的寬度計算。

在下面的例子可以看到使用TextLayoutFontMetrics之間的不同:

import javax.swing.*; 
import java.awt.*; 
import java.awt.font.*; 
import java.awt.geom.*; 

public class DrawTest extends JPanel 
{ 
    String text; 

    public DrawTest(String text) 
    { 
     this.text = text; 
//  setFont(new Font("Arial", Font.PLAIN, 24)); 
     setFont(new Font("Monospaced", Font.PLAIN, 24)); 
    } 

    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setFont(getFont()); 
     g2d.setPaint(Color.RED); 

     // Draw text using FontMetrics 

     FontMetrics fm = g2d.getFontMetrics(); 
     Rectangle2D rect = fm.getStringBounds(text, g2d); 
     rect.setRect(rect.getX() + 100, rect.getY() + 50, rect.getWidth(), rect.getHeight()); 
     g2d.draw(rect); 

     // Draw text using TextLayout 

     g2d.setPaint(Color.BLACK); 

     Point2D loc = new Point2D.Float(100, 50); 
     FontRenderContext frc = g2d.getFontRenderContext(); 
     TextLayout layout = new TextLayout(text, getFont(), frc); 
     layout.draw(g2d, (float)loc.getX(), (float)loc.getY()); 

     Rectangle2D bounds = layout.getBounds(); 
     bounds.setRect(bounds.getX()+loc.getX(), bounds.getY()+loc.getY(), bounds.getWidth(), bounds.getHeight()); 
     g2d.draw(bounds); 
    } 

    private static void createAndShowUI() 
    { 
     DrawTest text = new DrawTest("This is some ugly test i"); 

     JFrame frame = new JFrame("SSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(text); 
     frame.setSize(400, 200); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

此外則不應:

  1. 是設定的最佳尺寸。相反,您應該覆蓋getPreferredSize()方法返回大小

  2. 在繪畫方法中設置字體。所有組件都支持setFont()方法。所以只需在構造函數中設置Font。

+0

爲了讓你的方法起作用,我不得不在'bounds.getX()'和'bounds.getY()'上調用'Math.ceil()',因爲它們是負數,'Math.floor()'在'邊界上.getWidth()'和'bounds.getHeight()'因爲它們大於實際的寬度和高度。我還將'Point2D loc'更改爲'new Point2D.float(0,getHeight())'將文本放在正確的位置。 – MasterBlaster

+0

@TurtulWarrior,很高興的建議幫助。不要忘了單擊複選標記以「接受」答案,以便人們知道問題已解決。 – camickr

+0

我會接受你的回答,但我注意到你沒有向'Math.ceil()'或'Math.floor()'添加任何調用到你的答案。只是我需要他們被叫,或者這可能會成爲未來其他用戶的問題嗎? – MasterBlaster