Google Tag Manager

2008/06/25

Mouse Drag Auto Scrolling

Code

JLabel label = new JLabel();
//"CRW_3857_JFR.jpg" > http://sozai-free.com/
label.setIcon(new ImageIcon(getClass().getResource("CRW_3857_JFR.jpg")));
JScrollPane scroll = new JScrollPane(label,
    JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//*
ViewportDragScrollListener l = new ViewportDragScrollListener(label);
JViewport v = scroll.getViewport();
v.addMouseMotionListener(l);
v.addMouseListener(l);
v.addHierarchyListener(l);
/*/
//If label has its own MouseListeners, recommended to use ComponentDragScrollListener instead of ViewportDragScrollListener:
ComponentDragScrollListener l = new ComponentDragScrollListener(label);
label.addMouseMotionListener(l);
label.addMouseListener(l);
label.addHierarchyListener(l);
//*/
add(scroll);
scroll.setPreferredSize(new Dimension(320, 320));
class ViewportDragScrollListener extends MouseAdapter
                                 implements HierarchyListener {
  private static final int SPEED = 4;
  private static final int DELAY = 10;
  private final Cursor dc;
  private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final javax.swing.Timer scroller;
  private final JComponent label;
  private Point startPt = new Point();
  private Point move    = new Point();

  public ViewportDragScrollListener(JComponent comp) {
    this.label = comp;
    this.dc = comp.getCursor();
    this.scroller = new javax.swing.Timer(DELAY, new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        JViewport vport = (JViewport)label.getParent();
        Point vp = vport.getViewPosition();
        vp.translate(move.x, move.y);
        label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
      }
    });
  }
  @Override public void hierarchyChanged(HierarchyEvent e) {
    JComponent c = (JComponent)e.getSource();
    if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED)!=0
       && !c.isDisplayable()) {
      scroller.stop();
    }
  }
  @Override public void mouseDragged(MouseEvent e) {
    JViewport vport = (JViewport)e.getSource();
    Point pt = e.getPoint();
    int dx = startPt.x - pt.x;
    int dy = startPt.y - pt.y;
    Point vp = vport.getViewPosition();
    vp.translate(dx, dy);
    label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
    move.setLocation(SPEED*dx, SPEED*dy);
    startPt.setLocation(pt);
  }
  @Override public void mousePressed(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(hc); //label.setCursor(hc);
    startPt.setLocation(e.getPoint());
    move.setLocation(0, 0);
    scroller.stop();
  }
  @Override public void mouseReleased(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc); //label.setCursor(dc);
    scroller.start();
  }
  @Override public void mouseExited(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc); //label.setCursor(dc);
    move.setLocation(0, 0);
    scroller.stop();
  }
}
class ComponentDragScrollListener extends MouseAdapter
                                  implements HierarchyListener {
  private static final int SPEED = 4;
  private static final int DELAY = 10;
  private final Cursor dc;
  private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final javax.swing.Timer scroller;
  private final JComponent label;
  private Point startPt = new Point();
  private Point move    = new Point();

  public ComponentDragScrollListener(JComponent comp) {
    this.label = comp;
    this.dc = comp.getCursor();
    this.scroller = new javax.swing.Timer(DELAY, new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Container c = label.getParent();
        if(c instanceof JViewport) {
          JViewport vport = (JViewport)c;
          Point vp = vport.getViewPosition();
          vp.translate(move.x, move.y);
          label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
        }
      }
    });
  }
  @Override public void hierarchyChanged(HierarchyEvent e) {
    JComponent jc = (JComponent)e.getSource();
    if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED)!=0
       && !jc.isDisplayable()) {
      scroller.stop();
    }
  }
  @Override public void mouseDragged(MouseEvent e) {
    scroller.stop();
    JComponent jc = (JComponent)e.getSource();
    Container c = jc.getParent();
    if(c instanceof JViewport) {
      JViewport vport = (JViewport)jc.getParent();
      Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport);
      int dx = startPt.x - cp.x;
      int dy = startPt.y - cp.y;
      Point vp = vport.getViewPosition();
      vp.translate(dx, dy);
      jc.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
      move.setLocation(SPEED*dx, SPEED*dy);
      startPt.setLocation(cp);
    }
  }
  @Override public void mousePressed(MouseEvent e) {
    scroller.stop();
    move.setLocation(0, 0);
    JComponent jc = (JComponent)e.getSource();
    jc.setCursor(hc);
    Container c = jc.getParent();
    if(c instanceof JViewport) {
      JViewport vport = (JViewport)c;
      Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport);
      startPt.setLocation(cp);
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc);
    scroller.start();
  }
  @Override public void mouseExited(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc);
    move.setLocation(0, 0);
    scroller.stop();
  }
}

References