2012-11-02 4 views
0

필자는 Graphics2D 영역을 가지고 있는데, 여기에는 기하학적 도형이 그려져 있습니다. g2.scale (x, y)를 사용하면 쉽게 확장 할 수 있습니다. 이제 확장 가능한 영역에 텍스트를 페인트하고 텍스트를 바로 편집하고 싶습니다. 그것은 역시 효과가 있지만 불행히도 설명 할 수있는 한 가지 문제가 있습니다. enter image description hereJEditorPane 및 폰트 스케일

을 그리고 그것은 300 %에 일어나는 내용은 다음과 같습니다 : 이것은 100 %로 모니터를 보는 방법이다

enter image description here

lette의 위치 "A"는 거의 OK,하지만의 위치 B자가 좌우로 움직입니다. JEditorPane은 크기가 조정 된 글꼴을 렌더링하기 위해 가장 가까운 글꼴을 사용한다고 가정합니다. 그리고 다른 글꼴의 공간은 픽셀 단위로 약간 다른 크기 일 수 있습니다. 문자열의 처음에는 문제가 발생하지 않지만 결국에는 오류가 누적됩니다.

g2scale()에서 JEditorPane이 정확히 같은 위치에 글꼴을 렌더링한다는 것을 어떻게 알 수 있습니까? (예를 들어 오픈 오피스는 똑같은 문제를 해결합니다).

UPD : sscce는

class Canvas extends JPanel { 
    @Override 
    public void paint(Graphics g) { 
     Graphics2D g2 = (Graphics2D) g; 
     g.translate(p.x, p.y); 
     g2.scale(scale, scale); 
     g2.setColor(Color.GRAY); 
     g2.fill(g2.getClip()); 

     JEditorPane pane = new JEditorPane(); 
     pane.setFont(pane.getFont().deriveFont(22f)); 
     pane.setText("A                        B"); 
     pane.setBounds(new Rectangle(100, 100, 700, 30)); 
     g2.translate(100, 100); 
     pane.paint(g2); 
     g2.translate(-100, -100); 

     g2.setColor(Color.BLACK); 
     g2.draw(new Rectangle(100, 100, 700, 30)); 


     g2.scale(1/scale, 1/scale); 
     g.translate(-p.x, -p.y); 
     g2.setColor(Color.GREEN); 
     g2.setFont(g2.getFont().deriveFont(33f)); 
     g2.drawString("Scale (mouse wheel): " + new DecimalFormat("#.##").format(scale * 100) + "%", 2, 768-66); 
     g2.drawString("(Drag mouse to move)", 2, 768-33); 
    } 


// +++++++++++++++++++++++++++ GUI +++++++++++++++++++++++++++++++++++++ 

    public Canvas() { 
     addMouseWheelListener(new MouseWheelListener() { 
      @Override 
      public void mouseWheelMoved(MouseWheelEvent e) { 
       scale += e.getWheelRotation() * 1.0/10; 
       repaint(); 
      } 
     }); 

     addMouseMotionListener(new MouseMotionAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent e) { 
       p.x = e.getPoint().x - startDrag.x; 
       p.y = e.getPoint().y - startDrag.y; 
       repaint(); 
      } 
     }); 

     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       startDrag = e.getPoint(); 
       startDrag.x -= p.x; 
       startDrag.y -= p.y; 
      } 
     }); 
    } 

    public static double scale = 1.0; 
    public static Point p = new Point(); 
    public static Point startDrag = new Point(); 
} 

public class Main { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.add(new Canvas()); 

     frame.setSize(1024, 768); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

문제를 설명하는 [sscce] (http://sscce.org/)를 포함하여 질문을 편집하십시오. – trashgod

+0

이 'TextLayout' [예제] (http://stackoverflow.com/a/4287269/230513)도 참조하십시오. – trashgod

+0

upd : sscce가 – AvrDragon

답변

2

는 JEditorPane의 스케일링 접촉이 http://java-sl.com/articles.html 기사를 참조하십시오. "사용자 지정 GlyphPainter 및 소수점 지원을 사용하여 크기 조정"문서에서는 글꼴 크기 조정 및 측정 문제에 대해 설명합니다. TextLayout 기반 또는 GlyphVector 기반의 그림을 사용하여 분수 fnt 측정을 수정할 수 있습니다.

+0

을 추가했습니다.> GlyphPainter1 (불행히도 공개되지 않습니다) 은 여전히 ​​공개가 아니며 GlyphPainter1입니까? – AvrDragon

+0

자신의 GlyphPainter를 작성하거나 두 번째 기사에서 설명한 것을 사용할 수 있습니다. – StanislavL

1

나는 한동안 같은 시간에 맞서 싸웠다. 문제는 텍스트를 오른쪽 정렬하고 작은 글꼴 크기를 사용하려고 할 때 커집니다 (따라서 줄의 문자가 많음). 스케일링은 에로스를 곱하여 쉽게 볼 수있게합니다.

위에서 언급 한 "사용자 지정 GlyphPainter 및 분수 측정 지원을 사용하여 크기 조정"문서 및 코드를 사용하면 int에서 float로 전환하면 반올림 오류가 제거되므로 도움이됩니다. 거의 정상적으로 작동하지만 정확하지는 않습니다. 즉, 거기에 다른 일이 발생하고 있습니다. ScaledGlyphPainter.getTabbedTextWidth에서

나는 분명히, 모두 측정이 동일한 텍스트에 다른 결과를 반환합니다

FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true); 
TextLayout layout = new TextLayout (text, metrics.getFont(), frc); 
nextX += layout.getBounds().getWidth(); 

으로 실제 mensurment에게

nextX += metrics.getStringBounds(txtStr, n - charCount, n, painterGr).getWidth(); 

을 대체 !!!! 측정이 한 방향으로 진행되고 다른 방향으로 그리는 경우 그리기 오류가 발생합니다. TextLayout 측정을 사용하기 위해 위의 코드를 변경하고 나면 모든 문제가 사라지고 필요에 따라 양쪽 정렬이 작동합니다.