java 将事件传递给父级
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3818246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing events to parent
提问by viraptor
I'd like to create an app where some events are supposed to be handled as if they were delivered to parent containers. For example I've got a JPanelwhich contains JLabel. The top JPanelimplements mousepress and dragging right now. What do I need to do, in order to make the events look like they arrived to JPanelinstead of the label itself. (changing source object is important)
我想创建一个应用程序,其中一些事件应该被处理,就好像它们被传递到父容器一样。例如,我有一个JPanel包含JLabel. 顶部JPanel现在实现了鼠标按下和拖动。我需要做什么,才能使事件看起来像他们到达JPanel而不是标签本身。(更改源对象很重要)
Is there some better solution than actually implementing the events and replicating them in the parent? (this would get tedious after some objects with >5 children).
有没有比实际实现事件并在父级中复制它们更好的解决方案?(在一些对象超过 5 个孩子之后,这会变得乏味)。
回答by Tomas Narros
At your event listener, you can dispatch the event to the parent component.
在您的事件侦听器中,您可以将事件分派给父组件。
Being myEventthe event handling function argument:
作为myEvent事件处理函数参数:
Component source=(Component)myEvent.getSource();
source.getParent().dispatchEvent(myEvent);
But this solution implies creating a new EventListener for each element to add.
但是这个解决方案意味着为每个要添加的元素创建一个新的 EventListener。
So, you could create a single event handler and reuse it, adding it to all the chosen children, like this:
因此,您可以创建一个单独的事件处理程序并重用它,将其添加到所有选定的子项中,如下所示:
final Container parent=this; //we are a the parent container creation code
MouseListener myCommonListener=new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
parent.dispatchEvent(e);
}
@Override
public void mouseEntered(MouseEvent e) {
parent.dispatchEvent(e);
}
@Override
public void mouseExited(MouseEvent e) {
parent.dispatchEvent(e);
}
@Override
public void mousePressed(MouseEvent e) {
parent.dispatchEvent(e);
}
@Override
public void mouseReleased(MouseEvent e) {
parent.dispatchEvent(e);
}
};
JLabel label=new JLabel("This is the first Label");
label.addMouseListener(myCommonListener);
JLabel label2=new JLabel("This is the second Label");
label2.addMouseListener(myCommonListener);
//... and so on
回答by Wojciech Wirzbicki
You should convert event before dispatching it to the parent. Conversion includes coordinates translation to parent-relative.
您应该在将事件分派给父级之前转换事件。转换包括坐标转换到父相关。
public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{
public void mouseClicked(MouseEvent e) {
redispatchToParent(e);
}
public void mousePressed(MouseEvent e) {
redispatchToParent(e);
}
public void mouseReleased(MouseEvent e) {
redispatchToParent(e);
}
public void mouseEntered(MouseEvent e) {
redispatchToParent(e);
}
public void mouseExited(MouseEvent e) {
redispatchToParent(e);
}
public void mouseWheelMoved(MouseWheelEvent e){
redispatchToParent(e);
}
public void mouseDragged(MouseEvent e){
redispatchToParent(e);
}
public void mouseMoved(MouseEvent e) {
redispatchToParent(e);
}
private void redispatchToParent(MouseEvent e){
Component source = (Component) e.getSource();
MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent());
source.getParent().dispatchEvent(parentEvent);
}
}
回答by qwertzguy
Mouse events are automatically targeted to the deepest component that has mouse listeners.
鼠标事件会自动针对具有鼠标侦听器的最深组件。
Because of this, to achieve your goal, you can simply remove all mouse listeners on the JLabel and it will never get picked as the target for mouse events.
因此,为了实现您的目标,您可以简单地删除 JLabel 上的所有鼠标侦听器,并且它永远不会被选为鼠标事件的目标。
The following code will disable mouse listeners on the given components and their children recursively:
以下代码将递归禁用给定组件及其子组件上的鼠标侦听器:
public static void disableMouseForComponent(Component... components) {
for (Component c : components) {
if (c instanceof Container) {
disableMouseForComponent(((Container) c).getComponents());
}
for (MouseListener l : c.getMouseListeners()) {
c.removeMouseListener(l);
}
for (MouseMotionListener l : c.getMouseMotionListeners()) {
c.removeMouseMotionListener(l);
}
}
}

