How to remove space from end of line displayed in Graphics in Java?

My GraphicButton.java class creates a custom JButton with specific text and font and a rectangular border. My problem is that there is extra space between the last character in the line and the end of the border I would like to remove.

Here's what an instance of GraphicButton looks like with the string "PLAY" and the font FFF Forward (Direct Download Link) added to the JFrame . The red line is the space that I would like to remove .

Here is the code I'm using ( JFrame creation and installation omitted):

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

I am running Eclipse on a Mac with Java 1.8.

+5
source share
1 answer

You might be able to use TextLayout to get a better width calculation.

In the example below, you can see the difference between using TextLayout and FontMetrics :

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

Also you must NOT:

  • set your preferred size. Instead, you must override the getPreferredSize() method to return the size

  • set the font in the drawing method. All components support the setFont () method. So just set the font in the constructor.

+3
source

Source: https://habr.com/ru/post/1247276/


All Articles