2010-08-30 16 views
8

que tienen una ventana principal:Java la propagación de eventos detenido

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

Y un niño 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"); 
    } 
} 

Con la llamada a addMouseListener comentado en el panel de niño, el padre recibe eventos de clic cuando Hago clic en cualquier parte de la ventana, incluso en el niño. Si elimino el comentario de esa llamada y hago clic en el panel secundario, solo, el elemento secundario recibe el evento click y no se propaga al elemento primario.

¿Cómo evito que el niño consuma el evento?

+1

Eso es raro ... Recuerdo haber tenido el problema opuesto, donde el padre estaba consumiendo los eventos de ratón ligado niño – TheLQ

Respuesta

3

No creo que puedas. Creo que es un principio de diseño de Swing que solo un componente recibe un evento.

Puede obtener el comportamiento que desee, pero pase el JFrame al ChildPanel y llame al mouseClicked(MouseEvent) o el método que desee. O simplemente obtenga el componente principal.

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

estoy cuidado con el estrecho acoplamiento implícito en este enfoque. – trashgod

+2

Parece que voy a ir con getParent() a menos que se me ocurra una forma de cambiar mi proyecto, de modo que ni el padre ni el hijo necesiten manejar el evento. Restringir el manejo de eventos a un componente me parece una decisión de diseño ridícula ... – takteek

5

En Swing, generalmente quiere que el componente cliqueado responda; pero puede reenviar el evento del mouse al padre, como se muestra a continuación. Aquí hay un relacionado 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

Véase también [* 'EventListenerList' orden de activación *] (http://stackoverflow.com/q/2159803/230513). – trashgod

+0

¿Cómo se puede propagar el evento si no puede acceder al padre? –

+0

Me gustaría ver 'SwingUtilities' y las extensiones mencionadas [aquí] (http://stackoverflow.com/a/17631267/230513). – trashgod

Cuestiones relacionadas