2016-12-15 25 views
0

我見過很多海報,認爲Swing組件不應該擴展,而是應該通過組合來添加功能。所以說我希望再使用創建具有絕對定位(無佈局管理器)中,我可以用鼠標重新定位組件JPanel如何不擴展Swing組件?

public class MoveableComponentPanel 
{ 
    private final JPanel m_panel; 

    public MoveableComponentPanel() 
    { 
     m_panel = new JPanel(null); 
    } 

    public void add(Component c) 
    { 
     m_panel.add(c); 
     c.addMouseListener(m_mover); 
     c.setSize(c.getPreferredSize()); 
    } 

    private final MouseListener m_mover = new MouseListener() 
    { 
     private int m_startX, m_startY; 

     @Override 
     public void mousePressed(MouseEvent e) 
     { 
      if (e.getButton() == MouseEvent.BUTTON1) 
      { 
       m_startX = e.getX(); 
       m_startY = e.getY(); 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) 
     { 
      if (e.getButton() == MouseEvent.BUTTON1) 
      { 
       Component c = e.getComponent(); 
       Point p = c.getLocation(); 
       p.x += e.getX() - m_startX; 
       p.y += e.getY() - m_startY;   
       c.setLocation(p); 
       c.repaint(); 
      } 
     } 

     @Override 
     public void mouseClicked(MouseEvent e) {} 

     @Override 
     public void mouseEntered(MouseEvent e) {} 

     @Override 
     public void mouseExited(MouseEvent e) {} 
    }; 
} 

看起來不錯,但有沒有辦法面板添加到容器中。如果我想允許一個調用類與面板交互,則會更頭痛,例如更改大小,背景顏色,註冊事件監聽器等。我可以添加一個getPanel()訪問器,該訪問器可以打破封裝,或者爲我想要公開的方法/屬性(可能有很多)編寫傳遞方法。我在這裏錯過了一些其他策略嗎?什麼是公認的最佳做法?

+1

我看到在這裏擴展'JPanel'沒什麼問題...... –

+1

*「我看過一些海報,認爲Swing組件不應該擴展..」作爲一個經常提供這種建議的人,我會指出這是一條'一般規則',而不是一條被鑿成石頭的道路。 ***是有效的情況下擴展組件是有意義的(例如自定義繪畫)。 *「..絕對定位(沒有佈局管理器),我可以用鼠標重新定位組件」* ..爲什麼?我希望這不是試圖創建'GUI設計器'的嘗試,因爲由此產生的圖形用戶界面將會遇到所有通常在沒有佈局的情況下造成的GUI問題。 .. –

+1

..但是,如果它真的成爲了一個D'nD面板的好例子,我強烈建議實現一個'DragAndDropLayout',因爲這至少會讓你考慮一些可能的事情出錯了。 –

回答

1

中,我可以重新定位的部件用鼠標:

然後你只需要添加的MouseListener/MouseMotionListener到要拖動的組件。不需要擴展任何組件來添加該功能。

查看Component Mover類的示例,瞭解組件的基本拖動方法以及更復雜的拖動解決方案。

+0

哇,你是對的。我沒有這樣想過。實際上不需要將此功能綁定到任何特定的容器類型,如果不是,它會更靈活。 ComponentMover很好地演示了這一點。謝謝! –