2011-03-11 27 views
1

喂所有(即屬於不同的幀的內容面板)。 我要畫一個外來元件(即屬於不同框架的內容窗格),允許在框架A.把它架B,一個組件內油漆外國組分在另一種組分

問題是,當我繪製組件它是畫也在框架A的內容窗格中,當框架重新調整大小(例如,在組件內部繪幾次,出現一些藍色方塊等)時,它也會閃爍或者變得很難看。如果我嘗試在繪畫之前縮放或翻譯外來組件,問題就會變得更加明顯。

一段時間我整理之後,我想。但我對這種解決方案感覺不太好,出於某種原因,我認爲可能會有更好的,更合適的解決方案。在這裏,我需要你。 :)

這個問題是更多的解釋呼叫爲什麼外界部件被錯誤地畫不操縱它的雙緩衝功能,前後組件內部漆後。例如在使用任一對 setDoubleBuffered(假)和setDoubleBuffered(真) 或 disableDoubleBuffering(JP)和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例子無關。以下與問題本身無關。 這段代碼用來演示的,我怎麼在這我也想在打印預覽的方式來呈現組件實現打印的目的。打印件調用組件的油漆(如下所示)。


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 2011-03-11 16:26:50

+0

這種選擇的原因是向用戶顯示一個框架中的面板如何在一個框架中顯示,而另一個框架中則顯示其顯示效果如何,如打印預覽。 – Boro 2011-03-11 16:53:11

+1

重新標記「擺動」以查看是否可以提供更好的答案。 – trashgod 2011-03-14 17:05:24

回答

2

對不起,我不能直接解決您的問題,但它可能通過具有公共模型的兩個不同的意見,以避免它。如How to Write a Document Listener所示,可以更新Document的多個view。你的模型和視圖可能不同,但這個概念仍然適用。

附錄:

我認爲這就是我此刻做的,不是嗎?我有一個模型,即'外國'組件,以及兩個視圖,一個是默認繪畫和第二個自定義繪畫。

沒有,你有一個視圖更新他人;你需要兩個視圖響應一個模型。這個相關的example可能會提供一些見解。

我仍然對這個錯誤的繪畫的原因的建議感興趣。

嘗試交叉兩個組件的更新是IMO從根本上有缺陷;它顛覆了Painting in Swing的正常過程。在我的平臺上,我看到的只是一個非常短暫的閃爍,並沒有任何繪畫。儘管可能在一個系統上獲得滿意的結果,但這種安排在實施過程中不可靠。

是一個簡單的調用重繪的標籤,放置在ModelObserverupdate()方法合適的解決方案?

是,repaint(),但應在ButtonHandler做了View

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

感謝您的嘗試,垃圾。雖然這對我沒有多大幫助。我認爲那是我目前正在做的,不是嗎?我有一個模型,即'外國'組件,以及兩個視圖,一個是默認繪畫和第二個自定義繪畫。 我仍然對這幅錯誤的繪畫的理由感興趣。 – Boro 2011-03-14 09:44:16

+0

感謝垃圾。我明白你現在要去哪裏。你會說哪些對象會起到模型的作用,以及如果我要重新編碼我的示例中的哪個視圖? 該模型將是面板繪畫,即外國組件,對嗎?那些意見呢? – Boro 2011-03-15 13:27:37

+0

PS:我一直在玩你指出的例子。我注意到一個有趣的行爲。一切工作正常,直到你有一種情況,你連續選擇2個錯誤的答案,然後標籤不重新塗成錯誤答案的第二種顏色。我認爲在輸入相同文本的情況下,它必須與JLabel重繪優化有關。你會如何推薦解決這個問題?是一個簡單的調用重新繪製標籤,放置在ModelObserver的更新方法,適當的解決方案? – Boro 2011-03-15 13:56:33