2010-08-30 2 views
8

У меня есть главное окно:распространения события Java перестало

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

и ребенок 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"); 
    } 
} 

С вызовом addMouseListener закомментированным в детской панели, родитель получает нажмите событие, когда Я щелкаю в любом месте окна, в том числе и на дочернем. Если я раскомментирую этот вызов и нажимаю на дочернюю панель, только ребенок получает событие click и не распространяется на родителя.

Как остановить событие от потребления ребенком?

+1

Вот странно ... Я помню, что Противоположная проблема, когда родитель был потребляющего ребенка связаны события мыши – TheLQ

ответ

3

Я не думаю, что вы можете. Я считаю, что принцип дизайна Swing состоит в том, что только один компонент получает событие.

Вы можете получить поведение, которое хотите, однако, но передайте JFrame на номер ChildPanel и называя его mouseClicked(MouseEvent) или любым другим способом, который вы хотите. Или просто получить родительский компонент.

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

Я настороженно относится к тесной связи, подразумеваемой этим подходом. – trashgod

+2

Похоже, что я собираюсь пойти с getParent(), если не могу придумать способ изменить мой проект, поэтому родителям и дочерним элементам не нужно обрабатывать событие. Ограничение обработки событий одним компонентом кажется смешным дизайнерским решением для меня ... – takteek

5

В Swing вы, как правило, хотите, чтобы щелкнувший компонент ответил; но вы можете переслать событие мыши родительскому, как показано ниже. Вот связанный 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

См. Также [* 'Порядок запуска * EventListenerList *] (http://stackoverflow.com/q/2159803/230513). – trashgod

+0

Как вы можете распространять событие, если вы не можете получить доступ к родительскому? –

+0

Я бы посмотрел на 'SwingUtilities' и упомянутые расширения [здесь] (http://stackoverflow.com/a/17631267/230513). – trashgod

Смежные вопросы