2012-06-23 2 views
0

Java에서 사용자 지정 텍스트 구성 요소를 만드는 방법은 무엇입니까? 나는 내 텍스트 구성을 측정해야한다고 그것에 대해 getPreferredSize()을 제공해야합니다. 그러나 먼저 Graphics을 얻지 않고 텍스트 측정 항목을 측정 할 수는 없습니다. 하지만 먼저 그림 구성 요소없이 Graphics을 얻을 수 없습니다. 하지만 부품을 먼저 측정하지 않고 칠할 수는 없습니다.맞춤 텍스트 구성 요소를 만드는 방법은 무엇입니까?

이 악순환을 어기는 방법?

예제 코드

public class Text_CustomTextual { 

    public static class JHelloWorld extends JComponent { 

     private final String content = "Hello world!"; 
     private final Font font = new Font(Font.SERIF, Font.PLAIN, 12); 
     private Dimension dim = null; 
     private FontMetrics fm; 

     @Override 
     public Dimension getPreferredSize() { 

      // I can't measure control until I paint it once 
      if(dim == null) { 
       return new Dimension(300,5); 
      } 

      // I can measure it only after it was painter at least once 
      else { 
       return dim; 
      } 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      g.setFont(font); 

      // this is branch for first paint where I can measure control 
      if(dim == null) { 

       // why should I have Graphics to measure font??? 
       fm = g.getFontMetrics(); 

       // why should I feed Graphics to getStringBound method??? 
       // did FontMetrics already forgot one I constructed it with??? 
       Rectangle2D rect = fm.getStringBounds(content, g); 
       dim = new Dimension((int)rect.getWidth(),(int)rect.getHeight()); 

       // how to cause control size to be reevaluated? 
       // repaint() does not help, control remains 300x5 
       repaint(); 
      } 
      else { 
       g.setColor(getForeground()); 
       g.drawString(content, 0, fm.getAscent()); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 

       final JHelloWorld h = new JHelloWorld(); 

       final JFrame f = new JFrame(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.add(h); 
       f.pack(); 
       f.setTitle(String.format("%dx%d", h.getWidth(), h.getHeight())); 

       h.addComponentListener(new ComponentListener() { 

        @Override 
        public void componentShown(ComponentEvent e) { 

        } 

        @Override 
        public void componentResized(ComponentEvent e) { 
         f.setTitle(String.format("%dx%d", h.getWidth(), h.getHeight())); 
        } 

        @Override 
        public void componentMoved(ComponentEvent e) { 
        } 

        @Override 
        public void componentHidden(ComponentEvent e) { 
        } 
       }); 

       f.setVisible(true); 

      } 
     }); 
    } 
} 
+0

혼란. 이 질문이 닫히기 전에 [sscce] (http://www.sscce.org)를 포함 시키십시오. – user1329572

+0

코드 *의 어느 부분에 문제가 있습니까? 이미 몇 가지 논리 오류를 발견 할 수 있습니다 .. – user1329572

+0

문제는 순환 종속성입니다. 코드의 특정 위치에 기인 할 수 없습니다. –

답변

0

일반적으로 선호하는 크기를 동적으로 설정되어 있지 않습니다. 그러나 사용하기에 적합한 크기는 무엇입니까? :

String text = "Hello world!"; 
    Font font = new Font(Font.SERIF, Font.PLAIN, 12);  
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    BufferedImage bufferedImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2d = ge.createGraphics(bufferedImage); 
    FontRenderContext frc = g2d.getFontRenderContext(); 
    GlyphVector glyphVector = font.createGlyphVector(frc, text); 
    Rectangle2D rectangle2D = glyphVector.getLogicalBounds(); 
    double w = rectangle2D.getWidth(); 
    double h = rectangle2D.getHeight(); 
    System.out.println("width = "+w+"\theight = "+h); 
관련 문제