Swing/HandScroll のバックアップの現在との差分(No.15)
TITLE:JScrollPaneのViewPortをマウスで掴んでスクロール
Posted by aterai at 2006-01-02
JScrollPaneのViewPortをマウスで掴んでスクロール
JScrollPaneの窓の中をマウスで掴んで画像をスクロールします。-
category: swing
folder: HandScroll
title: JScrollPaneのViewportをマウスで掴んでスクロール
tags: [JScrollPane, JViewport, MouseListener, MouseMotionListener, JLabel]
author: aterai
pubdate: 2006-01-02T06:45:45+09:00
description: JScrollPaneの窓の中をマウスで掴んで画像をスクロールします。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2009/03/mouse-dragging-viewport-scroll.html lang: en
概要
JScrollPane
の窓の中をマウスで掴んで画像をスクロールします。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spandel
class HandScrollListener extends MouseInputAdapter {
#spanend
private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
class HandScrollListener extends MouseAdapter {
#spanend
private final Cursor defCursor = Cursor.getDefaultCursor();
private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
private final Point pp = new Point();
@Override
public void mouseDragged(final MouseEvent e) {
#spanadd
#spanend
@Override public void mouseDragged(MouseEvent e) {
JViewport vport = (JViewport) e.getComponent();
Point cp = e.getPoint();
Point vp = vport.getViewPosition(); //= SwingUtilities.convertPoint(vport,0,0,label);
vp.translate(pp.x-cp.x, pp.y-cp.y);
//vport.setViewPosition(vp);
label.scrollRectToVisible(
new Rectangle(vp, vport.getSize()));
Point vp = vport.getViewPosition();
// = SwingUtilities.convertPoint(vport, 0, 0, label);
vp.translate(pp.x - cp.x, pp.y - cp.y);
// if (r1.isSelected()) {
label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
// } else {
// vport.setViewPosition(vp);
// }
pp.setLocation(cp);
}
@Override
public void mousePressed(MouseEvent e) {
label.setCursor(hndCursor);
#spanadd
#spanend
@Override public void mousePressed(MouseEvent e) {
e.getComponent().setCursor(hndCursor);
pp.setLocation(e.getPoint());
}
@Override
public void mouseReleased(MouseEvent e) {
label.setCursor(defCursor);
label.repaint();
#spanadd
#spanend
@Override public void mouseReleased(MouseEvent e) {
e.getComponent().setCursor(defCursor);
}
}
解説
JViewportの原点(左上)を解説
JViewport
の原点(左上)をマウスの移動に応じて変更し、JComponent#scrollRectToVisible
メソッドの引数として使用して覗き窓のスクロールを行っています。
-
JComponent#scrollRectToVisible(...)
ではなくJViewport#setViewPosition(Point)
を使用すると内部コンポーネントの外側に移動可能
JComponent#scrollRectToVisible(...)ではなく、JViewport#setViewPosition(Point)を使用すると、内部コンポーネントの外側に移動することができます。
- JDK-6333318 JViewPort.scrollRectToVisible( Rectangle cr ) doesn't scroll if cr left or above - Java Bug System
-
JDK 1.7.0
から、JViewport#setViewPosition(Point)
などで左上外部などの枠外に移動不可になっている - 左上外部は
Java 11
で修正された?、右下外部は移動不可のまま - 以下のように
JViewport#revalidate()
をオーバーライドして枠外スクロールは可能に戻せるが、親JFrame
をリサイズすると表示位置はリセットされる
-
参考リンク
- JScrollPaneのオートスクロール
- 2000ピクセル以上のフリー写真素材集
- 大きな猫写真があったので拝借しています。
- Bug ID: 6333318 JViewPort.scrollRectToVisible( Rectangle cr ) doesn't scroll if cr left or above
- JScrollPaneでキネティックスクロール
#spanend #spanadd // // JDK 1.6.0 #spanend #spanadd // JScrollPane scroll = new JScrollPane(label); #spanend #spanadd // JViewport vport = scroll.getViewport(); #spanend #spandel **コメント [#ubd1d4e0] #spanend - つかんで移動ということですが、移動方向が逆の気がします。 -- [[名無し]] &new{2006-02-25 (土) 01:24:46}; -- ご指摘ありがとうございます。確かに逆ですね。画像を掴んでというより、スクロールバーを掴んでみたいな動きになってました。修正しておきます。 -- [[aterai]] &new{2006-02-25 (土) 03:33:50}; - SwingUtilities.convertPointの代わりに、vport.getViewPosition()を使用するように変更。スクリーンショットの更新。 -- [[aterai]] &new{2009-01-19 (Mon) 16:58:27}; - JDK 1.7.0 では、JViewport#setViewPosition(Point)を使って右下外部に移動できなくなっている。HeavyweightとLightweightコンポーネントが混在しても問題ないようにするために、内部でrevalidate()しているのが原因? このサンプルではLightweightコンポーネントしか使用しないので、revalidate()しないように対応。 -- [[aterai]] &new{2011-10-03 (月) 18:03:55}; #spanadd // JDK 1.7.0 or later #spanend #spanadd JViewport vport = new JViewport() { #spanend private static final boolean WEIGHT_MIXING = false; private boolean isAdjusting; @Override public void revalidate() { if (!WEIGHT_MIXING && isAdjusting) { return; } super.revalidate(); } @Override public void setViewPosition(Point p) { if (WEIGHT_MIXING) { super.setViewPosition(p); } else { isAdjusting = true; super.setViewPosition(p); isAdjusting = false; } } #spanadd }; #spanend #spanadd vport.add(label); #spanend #spanadd JScrollPane scroll = new JScrollPane(); #spanend #spanadd scroll.setViewport(vport); #spanend #spanadd
参考リンク
- JScrollPaneのオートスクロール
- 2000ピクセル以上のフリー写真素材集
- 猫の写真を引用
- JDK-6333318 JViewPort.scrollRectToVisible( Rectangle cr ) doesn't scroll if cr left or above - Java Bug System
- JScrollPaneでキネティックスクロール
- JTreeの余白をドラッグしてスクロール