Swing 将调度事件切换到多个级别的容器
下面是演示我的问题的代码: 父类:Swing 将调度事件切换到多个级别的容器,swing,events,event-handling,Swing,Events,Event Handling,下面是演示我的问题的代码: 父类: 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 exte
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);
}
});
}
}
我希望一旦JTextField中触发了mouseclick事件,就会使用dispatchEvent将其传播到父面板。但对于具有JTextField的子面板,MouseClicked事件似乎只能访问APanel。然后打印APanel的父对象是APanel!。所以在我看来,dispatchEvent只将事件发送到下一个即时容器,而不再发送
我怎样才能解决这个问题?有没有一种方法可以将事件直接发送到另一个容器?您看到这种行为是因为
MouseEvent\getSource()
返回JTextField
,其父对象是APanel
。您希望getSource()
返回APanel
看起来您可以通过调用getParent().getParent()
来达到所需的效果。请记住,这是一个非常脆弱和糟糕的解决方案,因为如果您决定在APanel
和它的JTextField
之间需要另一个组件,它将崩溃
也许您可以使用递归方法来遍历组件层次结构,调用
getParent()
,直到到达PPanel
,此时您可以调用dispatchEvent
,对于更好的解决方案,您有何建议+getParent()为1。getParent()解决了我的问题。啊,是的。我正在考虑使用一个循环,并使用instanceof检查发送事件的desire容器。事实上,我可以使用循环分派到所有其他容器,直到getParent()返回null!是的,您可以在组件层次结构上递归调用dispatchEvent
,直到getParent()
返回null
!Swing中是否有一个实用程序方法可以自动将事件分派到父容器?另外,我看到您使用的是MouseListener
,但只定义了一个方法-check out,它提供了所有侦听器方法的空实现,允许您重写和定义您感兴趣的方法。哦,没关系。这个例子只是我的问题的一个基本演示,所以我不得不减少到简单的方法(保持简短)来显示主要问题。再次阅读我自己的评论,现在我意识到我没有完全注意到你的评论。我的意思是,我使用Netbeans来编写这个示例,所以它为我导入了所有这些方法。又快又脏!正如您所注意到的,mouseEvents位于感兴趣的最上面的组件(aka:is mouseEnabled或has mouseListeners),而不是更进一步——原因很好:想象一下,所有这些事件在容器层次结构中向上移动,而大多数情况下都不感兴趣。那么,你为什么想在父面板上看到mouseEvent?@kleopatra:原因是我可以使用mouseListener MouseClicked和MouseDragged来移动和拖动主(父)面板。但是,由于添加了所有3个子面板,它们是第一个与mouseEvent交互的面板,因此我无法拖动和移动主面板。将mouseEvent移动到父面板让我再次拥有此功能。