2016-04-16 14 views
5

Lớp học của tôi GraphicButton.java tạo một tùy chỉnh JButton với văn bản và phông chữ nhất định và đường viền hình chữ nhật. Vấn đề của tôi là có thêm khoảng trống giữa ký tự cuối cùng trong chuỗi và phần cuối của đường viền mà tôi muốn loại bỏ.Làm thế nào để loại bỏ không gian từ cuối của một chuỗi hiển thị với đồ họa trong Java?

Đây là những gì một thể hiện của một GraphicButton trông giống như với chuỗi "PLAY" và font FFF Forward (Direct Download Link) thêm vào một JFrame. Đường màu đỏ là khoảng trắng tôi muốn xóa.

Đây là mã Tôi đang sử dụng (JFrame sáng tạo và thiết lập bỏ qua):

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()); 
    } 
} 

Tôi đang chạy Eclipse trên máy Mac với Java 1.8.

+0

Không gian đó là khoảng cách giữa các chữ cái. Tôi đoán bạn có thể vẽ "PLAY" trên BufferedImage, tìm không gian ngoài cùng bên phải, xóa không gian và chuyển BufferedImage đã sửa đổi thành ImageIcon thành JButton. –

+0

Tôi thích đề xuất của bạn @GilbertLeBlanc, nó chỉ là tôi không biết làm thế nào để làm những gì bạn đang đề xuất. Vui lòng thêm điều gì đó vào câu trả lời của bạn để cho tôi biết phải làm gì. – MasterBlaster

+0

Đọc bài viết của tôi, [Java Swing Marquee] (http://java-articles.info/articles/?p=681), để xem cách tôi thao tác một BufferedImage. –

Trả lời

3

Bạn có thể sử dụng TextLayout để có được phép tính chiều rộng tốt hơn.

Trong ví dụ dưới đây bạn có thể thấy sự khác nhau giữa việc sử dụng 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(); 
      } 
     }); 
    } 
} 

Ngoài ra bạn không nên:

  1. thể thiết lập kích thước ưa thích. Thay vào đó, bạn nên ghi đè phương thức getPreferredSize() để trả lại kích thước

  2. đặt phông chữ trong phương pháp vẽ. Tất cả các thành phần đều hỗ trợ một phương thức setFont(). Vì vậy, chỉ cần đặt Font trong hàm tạo.

+0

Để phương thức của bạn hoạt động, tôi phải gọi 'Math.ceil()' trên 'bounds.getX()' và 'bounds.getY()' bởi vì chúng là âm và 'Math.floor()' trên 'giới hạn .getWidth() 'và' bounds.getHeight() 'vì chúng lớn hơn chiều rộng và chiều cao thực tế. Tôi cũng đã thay đổi 'Point2D loc' thành' new Point2D.float (0, getHeight()) 'để đặt văn bản vào đúng vị trí. – MasterBlaster

+0

@TurtulWarrior, vui mừng đề nghị đã giúp. Đừng quên "chấp nhận" câu trả lời bằng cách nhấp vào dấu kiểm để mọi người biết vấn đề đã được giải quyết. – camickr

+0

Tôi sẽ chấp nhận câu trả lời của bạn, nhưng tôi nhận thấy rằng bạn không thêm bất kỳ cuộc gọi nào vào 'Math.ceil()' hoặc 'Math.floor()' vào câu trả lời của bạn. Có phải chỉ là tôi cần họ được gọi hay đây có thể là vấn đề cho những người dùng khác trong tương lai không? – MasterBlaster

Các vấn đề liên quan