Swing/AutoScroll のバックアップの現在との差分(No.8)
JScrollPaneのオートスクロール
編集者:Terai Atsuhiro~
作成日:2004-11-22
更新日:2023-07-15 (土) 22:14:03
- category: swing folder: AutoScroll title: JScrollPaneのオートスクロール tags: [JScrollPane, JViewport, JScrollPane, DragAndDrop, Timer, MouseListener, MouseMotionListener] author: aterai pubdate: 2004-11-22T00:57:31+09:00 description: JScrollPane上でのマウスドラッグに応じてラベルをオートスクロールします。 image: hreflang:
href: https://java-swing-tips.blogspot.com/2008/06/mouse-drag-auto-scrolling.html lang: en
概要
JScrollPane
上でのマウスドラッグに応じてラベルをオートスクロールします。
概要
JScrollPane上のマウスポインタに応じてラベルをオートスクロールします。Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
class ViewportDragScrollListener extends MouseAdapter
#spanend
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 Timer scroller;
private final JComponent label;
private Point startPt = new Point();
private Point move = new Point();
#spandel
**サンプルコード [#nf7c2bf6]
#spanend
private void autoScroll(Point ptLabel) {
Point ptScroll = SwingUtilities.convertPoint(label, ptLabel, scroll);
int iv = (int) scroll.getPreferredSize().getHeight();
if(ptScroll.y < iv/2) {
rect.setRect(0, ptLabel.y-ptScroll.y-SCROLL, 0, SCROLL);
flg = true;
}else{
rect.setRect(0, ptLabel.y-ptScroll.y+iv+SCROLL, 0, SCROLL);
flg = false;
}
scroller.start();
}
public ViewportDragScrollListener(JComponent comp) {
this.label = comp;
this.dc = comp.getCursor();
this.scroller = new Timer(DELAY, new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
Container c = SwingUtilities.getAncestorOfClass(
JViewport.class, label);
if (c instanceof JViewport.class) {
JViewport vport = (JViewport) c;
Point vp = vport.getViewPosition();
vp.translate(move.x, move.y);
label.scrollRectToVisible(
new Rectangle(vp, vport.getSize()));
}
}
});
}
-[[サンプルを起動>http://terai.xrea.jp/swing/autoscroll/sample.jnlp]]
-[[jarファイル>http://terai.xrea.jp/swing/autoscroll/sample.jar]]
-[[ソース>http://terai.xrea.jp/swing/autoscroll/src.zip]]
@Override public void hierarchyChanged(HierarchyEvent e) {
JComponent c = (JComponent) e.getSource();
if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
&& !c.isDisplayable()) {
scroller.stop();
}
}
#spandel
**解説 [#i40d83e6]
#spanend
#spandel
上記のサンプルでは、マウスポインタの位置に応じて、上下方向にのみ一定速度で自動スクロールします。SwingUtilities.convertPoint()メソッドを使って座標の変換を行っています。
#spanend
@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);
}
#spandel
JTextPaneで文字列を挿入したときに、最後まで自動スクロールしたい場合は、[[JTextPaneで最終行に移動>Swing/CaretPosition]]を参考にしてください。
#spanend
#spandel
**参考リンク [#j6c969ff]
#spanend
-[[JTextPaneで最終行に移動>Swing/CaretPosition]]
@Override public void mousePressed(MouseEvent e) {
e.getComponent().setCursor(hc); // label.setCursor(hc);
startPt.setLocation(e.getPoint());
move.setLocation(0, 0);
scroller.stop();
}
#spandel
**コメント [#paa26bcc]
#spanend
@Override public void mouseReleased(MouseEvent e) {
e.getComponent().setCursor(dc); // label.setCursor(dc);
scroller.start();
}
#spanadd
#spanend
@Override public void mouseExited(MouseEvent e) {
e.getComponent().setCursor(dc); // label.setCursor(dc);
move.setLocation(0, 0);
scroller.stop();
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JViewport
内の画像ラベルをマウスでドラッグするとその移動方向に応じて自動的にスクロールします。
-
javax.swing.Timer
を使うことでスクロールの開始、継続、停止を実行 - 自動スクロール中に画像をマウスでクリックすると移動を停止
参考リンク
- JScrollPaneのViewportをマウスで掴んでスクロール
- JTextPaneで最終行に移動
-
JTextPane
で文字列を挿入したときに最後まで自動スクロールするサンプル
-
- 2000ピクセル以上のフリー写真素材集