将事件传递给父母

时间:2010-09-29 01:54:11

标签: java user-interface swing event-handling

我想创建一个应用程序,其中某些事件应该被处理,好像它们被传递到父容器一样。例如,我有JPanel,其中包含JLabel。顶部JPanel现在实现了鼠标按下和拖动。我需要做什么,以使事件看起来像是到达JPanel而不是标签本身。 (更改源对象很重要)

是否有比实际实现事件并在父代中复制它们更好的解决方案? (在使用> 5个孩子的某些对象之后,这将变得乏味。)

3 个答案:

答案 0 :(得分:12)

在您的事件监听器中,您可以将事件分派给父组件。

成为myEvent事件处理函数参数:

Component source=(Component)myEvent.getSource();
source.getParent().dispatchEvent(myEvent);

但是这个解决方案意味着为每个要添加的元素创建一个新的EventListener。

因此,您可以创建一个单独的事件处理程序并重用它,将其添加到所有选定的子项中,如下所示:

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 

答案 1 :(得分:3)

您应该在将事件分派给父母之前转换事件。转换包括到父亲亲属的坐标转换。

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);
    }
}

答案 2 :(得分:-1)

鼠标事件会自动定位到具有鼠标侦听器的最深部件。

因此,为了实现您的目标,您可以简单地删除JLabel上的所有鼠标侦听器,它永远不会被选为鼠标事件的目标。

以下代码将以递归方式禁用给定组件及其子组件上的鼠标侦听器:

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);
        }
    }
}