2017-02-04 51 views
-1

我試圖創建一個自定義JLabel與輪廓效果的,這是我的代碼:文本的JLabel出界

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

的問題是,繪製文本組件的邊界之外..我想了解爲什麼,以及如何解決這個問題,你可以驗證刪除註釋:

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

該文本是很好畫,但是這是不接受的,因爲標籤上有更使用複雜的佈局和多次,我不能每次都翻譯基於labe的座標我的位置,我需要一個更通用的解決方案。

有人可以幫我嗎?

+1

覆蓋'getPreferredSize()。' – trashgod

+0

重寫getPreferredSize沒有任何區別... – navy1978

+0

我沒有看到您的實現。爲什麼不在附加的Container中添加一個'Border'? – trashgod

回答

0

好的我找到了解決方案。 如果別人有同樣的問題: 我不知道爲什麼,但呼籲:

Shape textShape = glyphVector.getOutline(); 

的textShape是自動翻譯了形狀本身的高度。 因此它走出界限。如果你想把它放回組件的中心(垂直對齊),你需要一個AffineTransform。在我以前張貼的例子就足以代替這一行:

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

這些:

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

注:我的第一篇文章的評論是完全錯誤的。您可以擴展標籤,完全沒有問題......並且您不需要重寫getPreferredSize,從類外部設置首選大小就足夠了。