2014-01-30 49 views
0

我有一個外面板,外面板上有另一個jPanel。將一個jPanel上的點擊事件傳遞給另一個JPanel

如果我在內部面板上點擊右鍵,外部面板的右擊動作應該會發生。如果我在內部面板上單擊左鍵,則會發生其自己的內部面板的單擊操作。

是否可以將點擊事件從一個面板傳遞到另一個面板?

+0

設計是否'延伸JPanel'?如果是這樣,爲什麼?此外,'MouseListener'是一個非常低級的偵聽器,可以添加到'JPanel'中。 *假設*在右鍵點擊時發生了什麼? –

+0

是的,它擴展jPanel。兩個不同的動態菜單。這些菜單將根據運行時間決定。 – CrazyProgrammer

回答

4

爲解決此問題需要解決多個問題。

第一個是理解鼠標事件對創建它的組件是上下文的,特別是位置信息。點擊點是源組件x/y位置的偏移量(鼠標事件將爲0x0)。這意味着如果您想重新分派事件,則至少需要將位置上下文轉換爲父組件空間。

源組件也應該改變。如果未能做到這一點,可能會導致API的其他部分出現問題,這些問題可能依賴於它進行確定(例如彈出窗口,該窗口將要將位置信息從組件空間轉換爲屏幕空間)。

其次,你不應該假定父母。也就是說,您不應該假定父級可能會或可能不會實現鼠標偵聽器接口。

一種可能的解決辦法是使用SwingUtilities.convertMouseEvent到在所述內板中提出的MouseEvent轉換爲與外板兼容,然後使用Component#dispatchEvent到模擬天生的標準的事件處理過程中,例如...

import java.awt.BorderLayout; 
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; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 

public class TestTree { 

    public static void main(String[] args) { 
     new TestTree(); 
    } 

    public TestTree() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new OutterPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class InnerPane extends JPanel { 

     public InnerPane() { 
      setBackground(Color.RED); 
      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseClicked(MouseEvent e) { 
        System.out.println("Inner was clicked at : " + e.getPoint()); 
        MouseEvent convertMouseEvent = SwingUtilities.convertMouseEvent(e.getComponent(), e, getParent()); 
        getParent().dispatchEvent(convertMouseEvent); 
       } 

      }); 
     } 

    } 

    public class OutterPane extends JPanel { 

     public OutterPane() { 
      setLayout(new BorderLayout()); 
      setBorder(new EmptyBorder(10, 10, 10, 10)); 
      add(new InnerPane()); 

      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseClicked(MouseEvent e) { 
        System.out.println("Outter was clicked at : " + e.getPoint()); 
       } 

      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 
0

你有沒有試過類似於你的內部面板?

void mouseClicked(MouseEvent e) { 
     if (e.getButton() == MouseEvent.BUTTON2) { 
     outter.mouseClicked(e); 
     } 
    else { 
    // do job for your inner panel 
    } 

     } 
+1

與此相關的問題是'MouseEvent'是內部面板的上下文需要的信息,即'source'和'position'是與內部面板相關的。如果OP想要獨立使用這些值(這就是說,外部面板不需要對鼠標事件的狀態做出決定),這可能會嚴重地影響事物 – MadProgrammer

0

下面的代碼爲我工作

JPanel parent = (JPanel) me.getComponent().getParent(); 
MouseMotionListener[] ml = parent.getMouseMotionListeners(); 
ml[0].mouseClicked(me); 

感謝所有

+0

這不會將'MouseEvent'轉換爲父組件上下文和'MouseMotionListener'沒有'mouseClicked'事件... – MadProgrammer

+0

是的。你的答案是更好的解決方案。 :) 謝謝 – CrazyProgrammer

相關問題