2011-08-26 55 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'! –