2010-09-29 8 views
8

Bazı olayların üst kapsayıcılara teslim edilmiş gibi ele alınması gereken bir uygulama oluşturmak istiyorum. Örneğin JLabel içeren bir JPanel var. En iyi JPanel şu anda mousepress ve sürükleme uygular. Olayları, etiketin yerine JPanel'e geldiklerine benzetmek için ne yapmam gerekiyor. (kaynak nesnesini değiştirmek önemlidir)Etkinlikleri ana sayfaya geçirme

Olayları gerçekte uygulamaktan ve bunları ebeveynte çoğaltmaktan daha iyi bir çözüm var mı? (Bu,> 5 çocuklu bazı nesnelerden sonra sıkıcı olur).

+0

Neden bu (örnek) yapmama gerek var mı? – Pete

+0

Birçok etiketli nesnelerim var, bunlar gerçekten ilk kez tıkladıkları her yerde sürüklenebilmelidir. Şu anda, sadece öğenin arka planını tıklattığımda, içerideki herhangi bir etiketi değilken sürüklenebilirler. – viraptor

cevap

10

Etkinlik dinleyicinizle, etkinliği ana bileşene gönderebilirsiniz.

fonksiyonu bağımsız değişken taşıma etkinliği myEvent olmak:

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

Ancak bu çözelti, her bir eleman eklemek için yeni bir EventListener oluşturmak anlamına gelir.

Yani, böyle seçilen tüm çocuklara eklemeden, tek olay işleyicisi oluşturmak ve yeniden kullanımı:

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 
+0

Bu, awt iş parçacığında bir yığın taşması oluşturdu (ebeveyn, olayı alt denetime geri döndürdüğü için). Bu problemin nasıl aşıldığına dair bir fikrin var mı? Ebeveyn sınıfını düzenleyemem, ancak olayı almak için buna ihtiyacım var, ancak ebeveynin kontrolüme geri döneceği etkinlikte hareket etmesini engelliyorum. – ed22

+0

Kaynak açısından bu kötü bir fikir. Hiçbir şey için fazla yük katıyorsun. Çocuk elemanları üzerindeki fare dinleyicilerini kaldırmak çok daha verimlidir. Cevabımı, yinelemeli olarak nasıl yapılacağını görebilirsiniz. – qwertzguy

2

Sen ebeveyne bunu sevk edilmeden önce olayı dönüştürmek gerekir. Dönüşüm, ana akrabaya çeviri koordinatlarını içerir.

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

Cevabınız aslında Tomas Narros'un yanıtına bir yorum. – SeniorJD

+0

@SeniorJD Bu mükemmel bir cevaptır. Sadece diğer cevap üzerinde inşa edilir ve kendi başına durabilir. Wojtek bu düzeltmenin neden gerekli olduğunu biraz daha açıklayacak olsaydı daha iyi olurdu. –

+0

Kaynak açısından bu kötü bir fikir. Hiçbir şey için fazla yük katıyorsun. Çocuk elemanları üzerindeki fare dinleyicilerini kaldırmak çok daha verimlidir. Cevabımı, yinelemeli olarak nasıl yapılacağını görebilirsiniz. – qwertzguy

-1

Fare olayları otomatik fare dinleyicileri sahiptir derin bileşene hedeflenir. Bu nedenle, hedefinize ulaşmak için, JLabel'deki tüm fare dinleyicilerini kaldırabilirsiniz ve asla fare olayları için hedef olarak seçilmez.

Aşağıdaki kod yinelemeli verilen bileşenler ve çocuklarının üzerinde fare dinleyici devre dışı bırakacaktır:

private 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); 
     } 
    } 
} 
+0

Kim -1'ed? Neden açıklıyorsunuz? Bu şekilde yapmak, ebeveynlere gönderen bir dinleyici eklemekten çok daha iyi kaynaklıdır. – qwertzguy