2011-08-26 57 views
2

這裏的多電平來代碼演示我的問題: 父類:擺動調度事件容器

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class PPanel extends JPanel{ 
    private APanel panel1; 
    private APanel panel2; 
    private APanel panel3; 
    public PPanel() { 
     this.setLayout(new GridLayout(0,1)); 
     panel1 = new APanel(); 
     panel1.setLayout(new GridLayout(0,1)); 

     panel2 = new APanel(); 
     panel2.setBackground(Color.yellow); 
     panel2.setLayout(new GridLayout(0,1)); 
     panel3 = new APanel(); 
     panel3.setBackground(Color.green); 
     //panel3.setLayout(new GridLayout(0,1)); 
     this.add(panel1); 
     this.add(panel2); 
     this.add(panel3); 
     this.setBackground(Color.blue); 
     this.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Parent panel clicked!"); 
      }    
     }); 
    } 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     PPanel panel = new PPanel(); 
     frame.add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(new Dimension(350, 300)); 
     frame.setTitle("Demo"); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

子面板類:

import java.awt.Color; 
import java.awt.Component; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

public class APanel extends JPanel{ 
    private JTextField tf; 
    public APanel() { 
     tf = new JTextField("Double click"); 
     tf.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Textfiled"); 
       Component source = (Component) e.getSource(); 
       System.out.println(source.getParent()); 
       source.getParent().dispatchEvent(e); 
      } 
     }); 
     this.add(tf); 
     this.setVisible(true); 
     this.setBackground(Color.red); 

     this.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Child panel clicked!"); 
       Component source = (Component) e.getSource(); 
       System.out.println("Parent container of APanel is " + source.getParent()); 
       if(source.getParent() instanceof PPanel) 
        source.getParent().dispatchEvent(e); 
      } 
     }); 
    } 
} 

我希望一次的mouseClicked事件在JTextField中觸發,它將通過使用dispatchEvent傳播到父面板。但對於具有JTextField的子面板,似乎MouseClicked事件只能到達APanel。然後它打印APanel的父母是APanel !.所以在我看來,dispatchEvent只會將事件發送到下一個直接容器,而不會再發送。

我該如何解決這個問題?有沒有辦法將事件直接派發給另一個容器?

+0

另外,我看你在使用'MouseListener'但只能定義一個方法 - 檢查出[MouseAdapter(http://download.oracle.com/javase/6/docs/api/java/awt/event/ MouseAdapter.html),它提供了所有監聽器方法的空白實現,允許你重寫和定義你感興趣的方法。 –

+0

哦,別擔心。這個例子只是我的問題的基本演示,所以我必須減少到裸方法(保持簡短)以顯示主要問題。 – bili

+0

再次閱讀我自己的評論,現在我意識到我沒有充分注意您的評論。我的意思是我用Netbeans編寫這個例子,所以它爲我導入所有這些方法。快速和骯髒! – bili

回答

2

您看到此行爲,因爲MouseEvent#getSource()返回JTextField,其父項爲APanel。您期待getSource()返回APanel

它看起來像你可以通過調用getParent().getParent()上去另一個層次達到預期的效果。請記住,這是一個非常脆弱和糟糕的解決方案,因爲如果您決定在APanelJTextField之間需要另一個組件,它將會中斷。

也許你可以使用遞歸方法遍歷組件層次結構,調用getParent(),直到達到PPanel,此時可以調用dispatchEvent

+0

你有什麼建議更好的解決方案? getParent()。getParent(),因爲它解決了我的問題。 – bili

+0

啊,是的。我只是在考慮使用一個循環,並使用instanceof來檢查想要分發事件的容器。實際上,我可以使用一個循環來調度所有其他容器,直到getParent()返回null! – bili

+0

是的,你可以只調用組件層次結構調用'dispatchEvent',直到'getParent()'返回'null'! –