2011-03-11 11 views
1

안녕하세요. 내가 (즉, 다른 프레임의 내용 창에 속하는) 외국의 구성 요소를 페인트 할 프레임 A의 구성 요소 내부 프레임 B를 호출 할 수 있습니다다른 구성 요소의 외부 구성 요소 (즉, 다른 프레임의 내용 창에 속하는 구성 요소)를 페인트합니다.

문제 내가 구성 요소를 그릴 때 그려진 것입니다 또한 프레임 A의 내용 창에서 프레임 크기가 조정되면 (즉, 구성 요소 내부에 몇 번 칠한 파란색 사각형이 나타남) 깜박 거리거나 모두 불규칙 해집니다. 예를 들어 그림을 그리기 전에 외부 구성 요소의 크기를 조정하거나 변환하려고하면 문제가 더 잘 보입니다.

잠시 후 나는 그것을 분류했다. 하지만이 솔루션으로는 기분이 좋지 않습니다. 어떤 이유로 더 좋은 것이 더 적합 할 수도 있습니다. 여기 네가 필요해. :)

이 질문은 구성 요소 내부의 페인트 앞뒤에 이중 버퍼링 기능을 조작하지 않고 외부 구성 요소가 잘못 그려진 이유에 대한 설명이 더 필요합니다. 또는 disableDoubleBuffering (JP) (거짓) 및 setDoubleBuffered (참) setDoubleBuffered 및 enableDoubleBuffering (JP)

각각 이전 중 하나 쌍 사용과 및 외국 구성 요소의 paint 메소드를 호출 한 후 예를 들어.

미리 감사드립니다. 문제를 보여주는 SSCCE가 아래에 나와 있습니다.


import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.io.IOException; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.RepaintManager; 

public class PaintForeignComponentSSCCE extends JFrame 
{ 
    public static void main(String[] args) throws IOException 
    { 
     //foreign panel 
     JPanel fp = new JPanel(); 
     fp.setBackground(Color.PINK); 
     fp.setPreferredSize(new Dimension(200, 300)); 
     //component in which the foreign panel is painted 
     ForeignComponentPainter fcp = new ForeignComponentPainter(fp); 
     fcp.setPreferredSize(new Dimension(600, 600)); 
     //main frame's content 
     JPanel contentPane = new JPanel(); 
     contentPane.setBackground(Color.BLUE); 
     contentPane.add(fcp); 
     //main frame 
     JFrame f = new PaintForeignComponentSSCCE(); 
     f.setContentPane(contentPane); 
     f.setSize(700, 500); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true);    
     //foreign panel frame 
     JFrame fpf = new JFrame(); 
     JPanel panelFrameContent = new JPanel(); 
     panelFrameContent.add(fp); 
     fpf.setContentPane(panelFrameContent); 
     fpf.setSize(400, 400); 
     fpf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     fpf.setVisible(true); 
    } 
} 

class ForeignComponentPainter extends JButton 
{ 
    private static final long serialVersionUID = 1L; 
    private JPanel jP; 

    public ForeignComponentPainter(JPanel jP) 
    { 
     super(); 
     this.jP = jP; 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.drawString("OIOI", 50, 50); 
     //g2.translate(100, 50); 
     //g2.scale(.5, .5); 
//  jP.setDoubleBuffered(false); 
//  disableDoubleBuffering(jP); 
     jP.paint(g2); 
//  jP.setDoubleBuffered(true); 
//  enableDoubleBuffering(jP); 
     //g2.scale(1/.5, 1/.5); 
    } 
    public static void disableDoubleBuffering(Component c) 
    { 
     RepaintManager currentManager = RepaintManager.currentManager(c); 
     currentManager.setDoubleBufferingEnabled(false); 
    } 
    public static void enableDoubleBuffering(Component c) 
    { 
     RepaintManager currentManager = RepaintManager.currentManager(c); 
     currentManager.setDoubleBufferingEnabled(true); 
    } 
} 

SSCCE 예제와 관련이 없습니다.아래는 문제 자체와 관련이 없습니다. 이 코드는 인쇄 미리보기 방식으로 렌더링하려는 구성 요소에서 Printable을 구현하는 방법을 보여주기위한 목적으로 사용됩니다. 인쇄는 구성 요소의 페인트를 호출합니다 (아래 그림 참조).


public int print(Graphics g, PageFormat pageFormat, int pageIndex) 
{ 
    if(pageIndex >= pageHeights.size()) 
     return NO_SUCH_PAGE; 
    int savedPage = currentPageIndex; 
    currentPageIndex = pageIndex; 
    Graphics2D g2 = (Graphics2D) g; 
    paint(g2); 
    currentPageIndex = savedPage; 
    return PAGE_EXISTS; 
} 
+2

나는이 디자인 선택의 의심스러운입니다. 두 모델 모두 동일한 모델을 관찰하는 대신 왜 한 뷰를 다른 모델로 업데이트해야하는지 설명하는 것이 도움이 될 수 있습니다. – trashgod

+0

이 선택의 이유는 한 프레임에서 패널이 어떻게 보이는지를 한 프레임에 표시하고 다른 프레임에서는 인쇄 미리보기와 같이 렌더링이 어떻게 보이는지를 보여주기 때문입니다. – Boro

+1

좋은 답변이 제공되는지 확인하려면 "스윙"에 대한 태그를 다시 지정하십시오. – trashgod

답변

2

죄송합니다. 귀하의 질문에 직접 답변 할 수는 없지만 일반적인 모델에 대한 두 가지 다른 견해를 가지고 피할 수는 있습니다. How to Write a Document Listener에 표시된 것처럼 Document 중 하나 이상을 업데이트 할 수 있습니다. view 모델과 뷰는 다를 수 있지만 개념은 계속 적용됩니다.

은 부록 :

나는 그것, 그것이 내가 지금 뭐하는 거지하지 생각? 하나의 모델, 즉 '외국'구성 요소와 기본 페인트와 두 번째 맞춤 페인트를 수행하는 두 개의보기가 있습니다.

아니요, 다른보기를 업데이트 할 수 있습니다. 한 모델에 응답하는 두 가지보기가 필요합니다. 이 관련 example 몇 가지 통찰력을 제공 할 수 있습니다.

나는 여전히이 잘못된 그림의 이유에 대한 제안에 관심이 있습니다.

두 구성 요소의 업데이트를 인터리빙하려는 시도는 근본적으로 결함이 있습니다. 그것은 Painting in Swing의 정상적인 과정을 파괴합니다. 제 플랫폼에서는 아주 짧은 깜박임과 우연한 그림 만 보았습니다.하나의 시스템에서 만족스러운 결과를 얻는 것이 가능할 수도 있지만, 구현은 구현 전체에서 신뢰할 수 없습니다.

ModelObserverupdate() 방법 적절한 솔루션에 배치 라벨로 다시 칠하는 간단한 호출을 있습니까?

예, repaint()는 있지만 ViewButtonHandler에서 수행해야합니다

private class ButtonHandler implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     PieceButton pb = (PieceButton) e.getSource(); 
     icon.color = pb.piece.color; 
     label.repaint(); 
     model.check(pb.piece); 
    } 
} 
+0

시도해 주셔서 감사합니다, trashgod. 그것은 나를 많이 도움이되지 않습니다. 나는 그것이 내가 지금하고있는 일이라고 생각한다. 그렇지 않습니까? 하나의 모델, 즉 '외국'구성 요소와 기본 페인트와 두 번째 맞춤 페인트를 수행하는 두 개의보기가 있습니다. 저는이 잘못된 그림의 이유에 대한 제안에 여전히 관심이 있습니다. – Boro

+0

고맙습니다 trashgod. 나는 네가 지금 어디로 가는지 보았다. 위의 예제를 다시 작성하려면 어떤 오브젝트가 모델의 역할을하고 어떤 뷰가 제공 될 것이라고 말합니까? 모델은 페인트 할 패널, 즉 외부 컴포넌트입니다. 견해는 어떨까요? – Boro

+0

추신 : 나는 당신이 지적한 예를 가지고 놀았습니다. 그리고 저는 흥미로운 행동을 발견했습니다. 2 개의 잘못된 대답을 연속적으로 선택하고 레이블이 잘못된 대답의 두 번째 색으로 다시 그려지지 않을 때까지 모든 것이 잘 작동합니다. 동일한 텍스트를 입력 할 경우 JLabel 재 작성 최적화와 관련이 있어야한다고 생각합니다. 어떻게 이것을 해결할 것을 권하고 싶습니까? ModelObserver의 업데이트 메소드, 적절한 솔루션에 배치 된 레이블을 다시 그리는 간단한 호출입니까? – Boro

관련 문제