2012-04-07 88 views
3

傍晚的女士們,先生們,聆聽/處理JPanel事件

我有一個Java Swing的問題,我無法解決,也許你可以幫助我。這是它:

  • 我有一個JFrame使用BorderLayout和許多JPanel。
  • 每當我需要建立一個新的屏幕(即從主菜單,當點擊搜索按鈕,進入搜索菜單),我只是刪除位於中心的組件(JPanel),並把新的屏幕(新的JPanel)在中心。
  • 這樣,每次我想放置一個新的屏幕時,我都不會調用所有的頁眉和頁腳對象。

除了這個小問題,一切都正常工作:我想每次觸發一些方法,我建立一個新的JPanel或改回現有的JPanel(一般來說,每當JPanel出現時)。爲了做到這一點,我試圖實現ComponentListener的componentShown(ComponentEvent e)方法,並將一個ComponentListener添加到我放在JFrame中心的JPanel中,但它不起作用。在此之後,我做了一些研究,發現這個componentShown(@ComponentListener)方法只在JPanel的可見性被改變時(從不可見到可見或相反)才起作用。不幸的是,我沒有改變JPanel的可見性,只是用另一個替換它:刪除當前的一個,並添加新的。下面的代碼說明了我如何替換JPanel。

// Get the JPanel located in the center of our JFrame 
JPanel currentView = (JPanel) myFrame.getContentPane().getComponent(2); 

if (currentView != null) 
{ 
    // Remove it from the JPanel   
    myFrame.getContentPane().remove(currentView); 
} 

// Add the new JPanel  
myFrame.getContentPane().add(otherView, BorderLayout.CENTER); 

// Pack the JFrame and show it 
myFrame.pack(); 

所以這裏是我的。如果你能幫助我,我將不勝感激。

+4

你能做什麼,而不是添加/刪除'JPanel's自己是在你的'CENTER'使用一個''JPanel' contentPane'與['CardLayout'](http://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html)。 [如何使用'CardLayout'](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)。 – Jeffrey 2012-04-07 02:18:45

+1

@傑弗裏,謝謝你的快速回復。你所說的是好的和合理的,但我正在處理的是一個小組工作。我們現在有一種模式,在建議改變我們的模式(BorderLayout - > CardLayout)之前,我想 - 至少 - 嘗試用當前模式提出解決方案。 – 629 2012-04-07 02:26:35

+1

僅僅因爲您使用BorderLayout並不意味着您不能使用CardLayout,因爲它們不是互斥的。 BorderLayout.CENTER面板可以是持卡人,即使用CardLayout的JPanel。 – 2012-04-07 02:53:09

回答

2

我認爲,隨着HierarchyListener相應的這個問題,比較

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class ContainerListener extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public ContainerListener() { 
     super("Test"); 
     setContentPane(new TestPanel()); 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     pack(); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    public static void main(String[] parameters) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ContainerListener containerListener = new ContainerListener(); 
      } 
     }); 
    } 

    private class TestPanel extends JPanel { 

     private static final long serialVersionUID = 1L; 

     TestPanel() { 
      setLayout(new FlowLayout(FlowLayout.LEFT)); 
      add(new JButton(new AbstractAction("Add label") { 

       private static final long serialVersionUID = 1L; 
       private int n = 0; 

       @Override 
       public void actionPerformed(ActionEvent event) { 
        TestPanel.this.add(new JLabel("Label " + ++n)); 
        validate(); 
       } 
      })); 
      addHierarchyListener(new HierarchyListener() { 

       @Override 
       public void hierarchyChanged(HierarchyEvent e) { 
        System.out.println("Components Change: " + e.getChanged()); 
        if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { 
         if (e.getComponent().isDisplayable()) { 
          System.out.println("Components: " + e.getChanged()); 
         } else { 
          System.out.println("Components: " + e.getChanged()); 
         } 
        } 
       } 
      }); 
      addContainerListener(new ContainerAdapter() { 

       @Override 
       public void componentAdded(ContainerEvent event) { 
        System.out.println("componentAdded : " + event.getChild() + "containerName" + " was added"); 
       } 
      }); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 400); 
     } 
    } 
} 
+0

非常感謝您的回答。當我使用HierarchyListener而不是ContainerListener時,它工作正常! – 629 2012-04-07 18:07:33

+0

很高興爲您效勞 – mKorbel 2012-04-07 19:49:29

2

我強烈建議傾聽@Jeffrey給出的建議,但如果您繼續進行此設計,那麼可能實施ContainerListener接口可能會有用。

如有疑問,請查閱API。

+0

我剛剛嘗試過您的解決方案並實施了ContainerListener 。它完全適用於新創建的JPanel。不幸的是,它返回到現有的JPanel時不起作用。無論是返回到現有的JPanel還是創建新的JPanel並放置其視圖,我總是使用上面的相同方法刪除視圖並將其添加到框架中。我不明白爲什麼當把一個現有的面板放到一個框架時它不工作::S – 629 2012-04-07 02:51:05

+3

你需要一個'WindowListener','WindowFocusListener'或'WindowStateListener'。 – trashgod 2012-04-07 03:57:38