2017-02-04 3 views
-1

Ich versuche, einen benutzerdefinierten JLabel mit dem Umriss-Effekt zu erzeugen dies ist mein Code:Text von JLabel außerhalb der Grenzen

package test; 

import java.awt.BasicStroke; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.Stroke; 
import java.awt.font.GlyphVector; 
import java.awt.geom.Rectangle2D; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class OutlineLabel extends JLabel { 

    private Color outlineColor = Color.BLACK; 
    private Color fillColor = Color.WHITE; 


    public OutlineLabel() { 
     super(); 

    } 
    public void setThin(int thin){ 
     //this.thin=thin; 
    } 
    public OutlineLabel(String text,Color inline,Color outline) { 
     super(text); 
     outlineColor=outline; 
     fillColor=inline; 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     String text = getText(); 

     BasicStroke outlineStroke = new BasicStroke(1.5f); 

     if (g instanceof Graphics2D) { 
      Graphics2D g2 = (Graphics2D) g; 

      // remember original settings 
      Color originalColor = g2.getColor(); 
      Stroke originalStroke = g2.getStroke(); 
      RenderingHints originalHints = g2.getRenderingHints(); 


      // create a glyph vector from your text 
      GlyphVector glyphVector=g.getFont().layoutGlyphVector(g2.getFontRenderContext(),text.toCharArray(),0,text.length(),Font.LAYOUT_LEFT_TO_RIGHT); 

      // get the shape object 
      Shape textShape = glyphVector.getOutline(); 

      // activate effects 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
      g2.setRenderingHint(RenderingHints.KEY_RENDERING, 
        RenderingHints.VALUE_RENDER_QUALITY); 

      //g.translate(getX(), getY()+160); 
      g2.setColor(outlineColor); 
      g2.setStroke(outlineStroke); 
      g2.draw(textShape); // draw outline 

      g2.setColor(fillColor); 
      g2.fill(textShape); // fill the shape 

      // reset to original settings after painting 
      g2.setColor(originalColor); 
      g2.setStroke(originalStroke); 
      g2.setRenderingHints(originalHints); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame w = new JFrame(); 
     w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     Font myFont = new Font("Arial", Font.BOLD,146); 
     OutlineLabel label = new OutlineLabel("TEST",Color.red,Color.yellow); 
     label.setFont(myFont); 
     JPanel p=new JPanel(); 
     p.add(label); 
     w.setContentPane(p); 
     w.pack(); 
     w.setVisible(true); 
    } 
} 

Das Problem ist, dass der Text außerhalb der Grenzen der Komponenten gezogen wird .. . würde Ich mag zu verstehen, warum und wie diese zu beheben, können Sie das entfernen überprüfen den Kommentar aus:

g.translate(getX(), getY()+160); 

der Text gut gezeichnet ist, aber dies ist nicht akzeptabel, weil das Etikett in einem mehr verwendet werden muss komplexes Layout und mehrere Male, kann ich nicht jedes Mal die Koordinate basierend auf dem Label übersetzen Ich Position, brauche ich eine allgemeinere Lösung.

Kann mir jemand helfen?

+1

Override 'getPreferredSize().' – trashgod

+0

Overriding getPreferredSize macht keinen Unterschied ... – navy1978

+0

Ich sehe Ihre Implementierung nicht. Warum fügen Sie dem umgebenden Container keinen 'Border' hinzu? – trashgod

Antwort

0

Ok Ich habe eine Lösung dafür gefunden. Wenn jemand anderes das gleiche Problem haben: Ich weiß nicht, warum, aber Aufruf:

Shape textShape = glyphVector.getOutline(); 

die textShape erfolgt automatisch aus der Höhe der Form selbst übersetzt. So geht es außerhalb der Grenzen. Wenn Sie es in die Mitte der Komponente (Vertikale Ausrichtung) zurückstellen möchten, benötigen Sie eine AffineTransform. Im Beispiel, das ich vor geschrieben habe, ist genug, um diese Linie zu ersetzen:

g.translate(getX(), getY()+160); 

mit diesen:

int heightComponent=getHeight(); 
int heightShape=(int)textShape.getBounds().getHeight(); 
final AffineTransform transform = AffineTransform.getTranslateInstance(
        0,heightShape+((int)heightComponent/2-heightShape/2)); 
textShape=transform.createTransformedShape(textShape); 

N. B. Die Kommentare zu meinem ersten Beitrag sind völlig falsch. Sie können Label erweitern, überhaupt kein Problem ... und Sie müssen nicht die getPreferredSize überschreiben, die Einstellung der bevorzugten Größe von außerhalb der Klasse ist genug.

Verwandte Themen