2013-05-06 61 views
2

考慮我有以下代碼:爪哇 - 註冊父的JPanel到的MouseEvent

public LSUIEditingPanel(LSView view) { 
    super(); 
    parent  = view; 
    controller = view.getController(); 

    LayoutManager overlay = new OverlayLayout(this); 

    setLayout(overlay); 
    scribbleArea = new LSScribblePanel(); 
    scribbleArea.setOpaque(false); 
    add(scribbleArea); 
    viewArea = new LSCanvasViewport(view); 
    add(viewArea); 
    setAutoscrolls(true); 
    drawListener = new SVGEditorDrawMouseAdaptor(); 

} 

其中scribbleArea和viewArea都是定製的JPanel。它們都是添加到主面板的子面板。

現在我想讓它能夠將MouseEvent註冊到父面板本身,這是我可以對面板進行平移,因爲父面板將在實例化後嵌入到JScrollPane中。

這是代碼段執行拖動:

public class LSPanMouseAdapter extends MouseAdapter { 

/** 
* Panning pivot point 
*/ 
private final Point panPoint = new Point(); 

/** 
* {@inheritDoc}<p> 
* Set pan starting point to be the point where the mouse currently located, and change the 
* current cursor to <code>HAND_CURSOR</code>. 
*/ 
@Override 
public void mousePressed(MouseEvent event) { 
    JViewport viewport = (JViewport) event.getSource(); 
    JComponent component = (JComponent) viewport.getView(); 

    panPoint.setLocation(event.getPoint()); 
    component.setCursor(new Cursor(Cursor.HAND_CURSOR)); 
} 

/** 
* {@inheritDoc}<p> 
* Reset cursor to <code>DEFAULT_CURSOR</code>. 
*/ 
@Override 
public void mouseReleased(MouseEvent event) { 
    JViewport viewport = (JViewport) event.getSource(); 
    JComponent component = (JComponent) viewport.getView(); 

    component.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 
} 

/** 
* {@inheritDoc}<p> 
* Get the current viewport of the canvas and move the viewable area respective to the 
* event cursor location. 
*/ 
@Override 
public void mouseDragged(MouseEvent event) { 
    JViewport viewport  = (JViewport) event.getSource(); 
    JComponent component = (JComponent) viewport.getView(); 
    Point  currentPoint = event.getPoint(); 
    Point  viewPoint = viewport.getViewPosition(); 

    viewPoint.translate(panPoint.x - currentPoint.x, panPoint.y - currentPoint.y); 
    component.scrollRectToVisible(new Rectangle(viewPoint, viewport.getSize())); 
    panPoint.setLocation(currentPoint); 
} 
} 

我試圖註冊該事件,但父面板不火的情況下,我應該怎麼做什麼建議嗎?

+0

我沒有看到任何將MouseListener添加到父面板的位置,因此將調用事件回調函數。也不會因爲孩子面板在父母面前而接收鼠標事件嗎? (我不記得他們是否傳播到底層組件。) – 2013-05-06 12:30:31

+0

爲了更快地發佈[SSCCE](http://sscce.org/),更好的幫助,短的,可運行的,可編譯的,仍然不知道爲什麼有JViewport和scrollRectToVisible和DragAndDrop ???,在我的mind_readers單元格中沒有電池,之前什麼都可能檢查SwingUtilities#convert ... – mKorbel 2013-05-06 12:32:14

+0

@mKorbel對不起,冗長的代碼,但感謝您的提醒convertMouseEvent =) – 2013-05-06 13:52:18

回答

2

請參閱下面的示例,其中顯示瞭如何可以進行某種類型的視口拖動。鼠標偵聽器附加到視口視圖,並在鼠標被拖動時修改視口位置。爲了計算鼠標的正確「偏移」,鼠標位置將在拖動鼠標時轉換爲視口座標。

import java.awt.Component; 
import java.awt.Cursor; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JScrollPane; 
import javax.swing.JViewport; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestDragViewPortView { 
    public static class MouseDragger extends MouseAdapter { 
     private Point startPoint; 
     private Component draggedObject; 
     private JViewport viewport; 

     @Override 
     public void mousePressed(MouseEvent e) { 
      draggedObject = (Component) e.getSource(); 
      viewport = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, draggedObject); 
      if (viewport != null) { 
       startPoint = SwingUtilities.convertPoint(draggedObject, e.getPoint(), viewport); 
       draggedObject.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 
      } 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (viewport == null) { 
       return; 
      } 
      Point location = SwingUtilities.convertPoint(draggedObject, e.getPoint(), viewport); 
      Point newPosition = viewport.getViewPosition(); 
      newPosition.translate(startPoint.x - location.x, startPoint.y - location.y); 
      newPosition.x = Math.min(newPosition.x, draggedObject.getWidth() - viewport.getExtentSize().width); 
      newPosition.y = Math.min(newPosition.y, draggedObject.getHeight() - viewport.getExtentSize().height); 
      newPosition.x = Math.max(newPosition.x, 0); 
      newPosition.y = Math.max(newPosition.y, 0); 
      viewport.setViewPosition(newPosition); 
      startPoint = location; 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      draggedObject.setCursor(Cursor.getDefaultCursor()); 
      startPoint = null; 
      draggedObject = null; 
      viewport = null; 
     } 

     public void makeDraggable(Component component) { 
      component.addMouseListener(this); 
      component.addMouseMotionListener(this); 
     } 

    } 

    private JFrame frame; 

    protected void initUI() throws MalformedURLException { 
     frame = new JFrame(TestDragViewPortView.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JLabel background = new JLabel(new ImageIcon(new URL("http://blogs.dirteam.com/photos/sanderberkouwer/images/2157/original.aspx"))); 
     JScrollPane scrollPane = new JScrollPane(background); 
     new MouseDragger().makeDraggable(background); 
     frame.add(scrollPane); 
     frame.pack(); 
     frame.setSize(frame.getWidth()/2, frame.getHeight()/2); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
      UnsupportedLookAndFeelException { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        new TestDragViewPortView().initUI(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+0

我掙扎了3天它表現爲無辜的視覺障礙。我嘗試了玻璃窗格,JLayer,繼承了JViewport和事件重定向。不過我不知道我的問題是什麼 - 我懷疑拖動事件是在視口在鼠標下移動組件時創建的 - 在這裏,您的代碼直接從盒子中運行。我猜想座標變換部分是至關重要的。 – Rekin 2014-12-18 15:29:14