2010-08-30 7 views
8

Ich habe ein Hauptfenster:Java Ereignispropagierung gestoppt

public class MainPanel extends JFrame implements MouseListener { 

    public MainPanel() { 
     setLayout(new FlowLayout()); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     addMouseListener(this); 

     ChildPanel child = new ChildPanel(); 
     add(child); 

     JPanel spacer = new JPanel(); 
     spacer.setPreferredSize(new Dimension(50, 50)); 
     add(spacer); 

     pack(); 
     setLocationRelativeTo(null); 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on MainPanel"); 
    } 
} 

Und ein Kind JPanel:

public class ChildPanel extends JPanel implements MouseListener { 

    public ChildPanel() { 
     setBackground(Color.RED); 
     setPreferredSize(new Dimension(200, 200)); 
     //addMouseListener(this); 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on ChildPanel"); 
    } 
} 

Mit dem Aufruf von addMouseListener in der Kindertafel kommentiert, erhält die übergeordneten Ereignisse klicken, wenn Ich klicke irgendwo in das Fenster, auch auf das Kind. Wenn ich diesen Aufruf auschecke und auf das untergeordnete Bedienfeld klicke, nur, erhält das untergeordnete Element das Klickereignis und es wird nicht an das übergeordnete Element weitergegeben.

Wie kann ich verhindern, dass das Ereignis vom Kind konsumiert wird?

+1

Das ist seltsam ... Ich erinnere mich, das umgekehrte Problem, wo die Eltern das Kind gebunden Mausereignisse raubend – TheLQ

Antwort

3

Ich glaube nicht, dass Sie können. Ich glaube, es ist ein Swing-Design-Prinzip, dass nur eine Komponente ein Ereignis erhält.

Sie können das gewünschte Verhalten erhalten, aber übergeben Sie die JFrame an die ChildPanel und rufen Sie mouseClicked(MouseEvent) oder was auch immer Sie wollen. Oder hol dir einfach die Elternkomponente.

@Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on ChildPanel"); 
     this.frame.mouseClicked(e); 
     getParent().mouseClicked(e); 
    } 
+3

Ich bin vorsichtig die enge Kopplung durch diesen Ansatz impliziert. – trashgod

+2

Sieht aus, als würde ich mit getParent() gehen, es sei denn, ich kann mir einen Weg vorstellen, wie ich mein Projekt ändern kann, so dass Eltern und Kind das Ereignis nicht behandeln müssen. Die Beschränkung der Ereignisbehandlung auf eine Komponente scheint mir eine lächerliche Designentscheidung zu sein ... – takteek

5

In Swing möchten Sie im Allgemeinen die angeklickte Komponente antworten; aber Sie können vorwärts das das Mausereignis zu dem Eltern, wie unten gezeigt. Hier ist eine verwandte example.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** @see https://stackoverflow.com/questions/3605086 */ 
public class ParentPanel extends JPanel { 

    public ParentPanel() { 
     this.setPreferredSize(new Dimension(640, 480)); 
     this.setBackground(Color.cyan); 
     this.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Mouse clicked in parent panel."); 
      } 
     }); 
     JPanel child = new JPanel(); 
     child.setPreferredSize(new Dimension(320, 240)); 
     child.setBackground(Color.blue); 
     child.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Mouse clicked in child panel."); 
       ParentPanel.this.processMouseEvent(e); 
      } 
     }); 
     this.add(child); 
    } 

    private void display() { 
     JFrame f = new JFrame("MouseEventTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ParentPanel().display(); 
      } 
     }); 
    } 
} 
+0

Siehe auch [* 'EventListenerList'Feuerreihenfolge *] (http://Stackoverflow.com/q/2159803/230513). – trashgod

+0

Wie können Sie das Ereignis weitergeben, wenn Sie nicht auf das übergeordnete Element zugreifen können? –

+0

Ich würde 'SwingUtilities' und die hier erwähnten Erweiterungen [http://stackoverflow.com/a/17631267/230513] ansehen. – trashgod