2011-11-20 26 views
2

BorderLayoutをレイアウトマネージャとして使用するJFrameがあります。 このJFrameには、中央と南の2つのパネルもあります。 CENTERの位置にあるパネルは、一部のユーザー操作で動的に変更されます(実際には、ユーザーが下のパネルで「次へ」を押すと表示されます)。JFrameでJPanelを動的に変更する際の問題

コードがfollwingさ:

private void switchToPanelByState(State state) 
{ 
    this.getContentPane().removeAll(); 

    JPanel panel = _panels.get(state); 
    this.getContentPane().add(panel, BorderLayout.CENTER); 

    this.getContentPane().add(_controlPanel, BorderLayout.SOUTH); 
    this.pack(); 
} 

問題は、GUI要素が(前回のパネルから)「古い」の部分であるパネルのいくつかの変更後に現在のパネルに表示されていることです。随時

そしてまた、私は次の例外を参照してください。それが問題に関連していた場合、私は知りませんが

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
     at javax.swing.JComponent._paintImmediately(Unknown Source) 
     at javax.swing.JComponent.paintImmediately(Unknown Source) 
     at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
     at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
     at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source) 
     at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source) 
     at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
     at java.awt.EventQueue.dispatchEvent(Unknown Source) 
     at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.run(Unknown Source) 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
     at javax.swing.JComponent._paintImmediately(Unknown Source) 
     at javax.swing.JComponent.paintImmediately(Unknown Source) 
     at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
     at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) 
     at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source) 
     at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source) 
     at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
     at java.awt.EventQueue.dispatchEvent(Unknown Source) 
     at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.run(Unknown Source) 

を。

これらの問題の原因としてはどのようなものがありますか? アドバイスをいただければ幸いです。

+3

removeAll()メソッドが表示されるときはいつでも、あなたは[カードレイアウト](http://download.oracle.com/javase/tutorial/uiswing/layout/card.html)を使用する必要があるということに気づくでしょう。 – camickr

答えて

4

BorderLayoutは、Areaの中に1つだけJComponentを受け入れると、remove()/ removeAll()に理由はありません。以下に示すように、あなたのコードは次のようになります。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class MyFrame extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public MyFrame() { 
     final JPanel parentPanel = new JPanel(); 
     parentPanel.setLayout(new BorderLayout(10, 10)); 
     JButton myButton = new JButton("Add Component "); 
     myButton.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       JPanel childPanel1 = new JPanel(); 
       childPanel1.setBackground(Color.red); 
       childPanel1.setPreferredSize(new Dimension(300, 40)); 
       JPanel childPanel2 = new JPanel(); 
       childPanel2.setBackground(Color.blue); 
       childPanel2.setPreferredSize(new Dimension(800, 600)); 

       parentPanel.add(childPanel1, BorderLayout.NORTH); 
       parentPanel.add(childPanel2, BorderLayout.CENTER); 

       parentPanel.revalidate(); 
       parentPanel.repaint(); 

       pack(); 
      } 
     }); 
     setTitle("My Empty Frame"); 
     setLocation(10, 200); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     parentPanel.add(myButton, BorderLayout.SOUTH); 
     add(parentPanel); 
     pack(); 
     setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       MyFrame myFrame = new MyFrame(); 
      } 
     }); 
    } 
} 

または直接

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class MyFrame extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JPanel childPanel1 = new JPanel(); 
    private JPanel childPanel2 = new JPanel(); 
    private JPanel childPanel3 = new JPanel(); 

    public MyFrame() { 
     childPanel1.setBackground(Color.red); 
     childPanel1.setPreferredSize(new Dimension(300, 40)); 
     childPanel2.setBackground(Color.blue); 
     childPanel2.setPreferredSize(new Dimension(300, 40)); 
     childPanel3.setBackground(Color.yellow); 
     childPanel3.setPreferredSize(new Dimension(300, 40)); 

     JButton myButton = new JButton("Add Component "); 
     myButton.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       add(childPanel2, BorderLayout.CENTER); 
       pack(); 
      } 
     }); 

     setTitle("My Empty Frame"); 
     setLocation(10, 200); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     add(childPanel3, BorderLayout.CENTER); 
     add(myButton, BorderLayout.SOUTH); 
     pack(); 
     setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       MyFrame myFrame = new MyFrame(); 
      } 
     }); 
    } 
} 

2)誰もがパラメータstate何を知っていない、そしてSSCCEせずに、この質問

3に答えることはできませんされて)I CustomPaintingがネイティブOSからのレイテンシより速いときにRepaintManagerの例外をシミュレートできます

+0

mKorbel、答えに感謝します。残念ながら、JFrame(これ)もコンテナ(コンテンツペイン)もメソッドの再検証をしていません。 「状態」については、HashMapで正しいパネルを見つけるためのキーに過ぎません。 – Oleg

+0

@Oleg私の編集 – mKorbel

+2

を参照してください。この回答は間違っています - BorderLayoutは最後に追加されたコンポーネント(各コントレインエリア内)のみを示しますが、以前はすべて同じコンストレインを持つコンポーネントがコンテナの子です。 BTW:ちょっと変わったバリエーションを使って答えを捨ててはいけません - 1つを選んでください(2つのchildPanelフィールドだけを持つ2番目の最小値です)。 – kleopatra

関連する問題