2016-04-16 10 views
5

La mia classe GraphicButton.java crea un numero personalizzato JButton con un determinato testo e carattere e un bordo rettangolare. Il mio problema è che c'è qualche spazio in più tra l'ultimo carattere nella stringa e la fine del bordo che vorrei rimuovere.Come rimuovere lo spazio dalla fine di una stringa visualizzata con Grafica in Java?

Ecco cosa un'istanza di una GraphicButton assomiglia con la stringa "PLAY" e il tipo di carattere FFF Forward (Diretto Download Link) aggiunto ad una JFrame. La riga rossa è lo spazio che desidero rimuovere.

Ecco il codice che sto utilizzando (JFrame creazione e la configurazione omesso):

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

Sono in esecuzione Eclipse su un Mac con Java 1.8.

+0

Quello spazio è lo spazio tra le lettere. Immagino che tu possa disegnare "PLAY" su una BufferedImage, trovare lo spazio più a destra, rimuovere lo spazio e passare la BufferedImage modificata come ImageIcon al JButton. –

+0

Mi piace il tuo suggerimento @GilbertLeBlanc, è solo che non so come fare ciò che stai suggerendo. Per favore aggiungi qualcosa alla tua risposta per mostrarmi cosa fare. – MasterBlaster

+0

Leggi il mio articolo [Java Swing Marquee] (http://java-articles.info/articles/?p=681), per vedere come manipolo una BufferedImage. –

risposta

3

Potrebbe essere possibile utilizzare TextLayout per ottenere un calcolo della larghezza migliore.

Nell'esempio qui sotto potete vedere la differenza tra utilizzando il TextLayout e 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(); 
      } 
     }); 
    } 
} 

Inoltre non si deve:

  1. essere impostare la dimensione preferita. Invece è necessario ignorare il metodo getPreferredSize() per restituire la dimensione

  2. impostare il carattere nel metodo di pittura. Tutti i componenti supportano un metodo setFont(). Quindi basta impostare il carattere nel costruttore.

+0

Per far funzionare il metodo, ho dovuto chiamare 'Math.ceil()' su 'bounds.getX()' e 'bounds.getY()' perché erano negativi e 'Math.floor()' sui 'limiti .getWidth() 'e' bounds.getHeight() 'perché erano più grandi della larghezza e altezza effettive. Ho anche cambiato 'Point2D loc' con' new Point2D.float (0, getHeight()) 'per inserire il testo nel punto corretto. – MasterBlaster

+0

@TurtulWarrior, felice che il suggerimento sia stato d'aiuto. Non dimenticare di "accettare" la risposta facendo clic sul segno di spunta in modo che la gente sappia che il problema è stato risolto. – camickr

+0

Accetterò la tua risposta, ma ho notato che non hai aggiunto alcuna chiamata a 'Math.ceil()' o 'Math.floor()' alla tua risposta. Sono stato solo io a doverli chiamare o questo potrebbe essere un problema per altri utenti in futuro? – MasterBlaster

Problemi correlati