Swing/DragScrollLayer のバックアップの現在との差分(No.4)
- category: swing folder: DragScrollLayer title: JScrollPane内にある複数Componentを配置したJPanelをJLayerを使ってドラッグスクロール tags: [JScrollPane, JPanel, JLayer] author: aterai pubdate: 2013-08-05T11:49:22+09:00 description: 複数のネストしたComponentを配置したJPanelのドラッグイベントを、JScrollPaneをラップしたJLayerで受け取ってスクロール可能にします。 image:
概要
概要
複数のネストしたComponent
を配置したJPanel
のドラッグイベントを、JScrollPane
をラップしたJLayer
で受け取ってスクロール可能にします。
Screenshot
Advertisement
サンプルコード
サンプルコード
class DragScrollLayerUI extends LayerUI<JScrollPane> {
private final Point pp = new Point();
#spanadd
#spanend
@Override public void installUI(JComponent c) {
super.installUI(c);
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
}
#spanadd
#spanend
@Override public void uninstallUI(JComponent c) {
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(0);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
#spanadd
#spanend
@Override protected void processMouseEvent(
MouseEvent e, JLayer<? extends JScrollPane> l) {
Component c = e.getComponent();
if(c instanceof JScrollBar || c instanceof JSlider) {
if (c instanceof JScrollBar || c instanceof JSlider) {
return;
}
if(e.getID()==MouseEvent.MOUSE_PRESSED) {
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
JViewport vport = l.getView().getViewport();
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport);
pp.setLocation(cp);
}
}
#spanadd
#spanend
@Override protected void processMouseMotionEvent(
MouseEvent e, JLayer<? extends JScrollPane> l) {
Component c = e.getComponent();
if(c instanceof JScrollBar || c instanceof JSlider) {
if (c instanceof JScrollBar || c instanceof JSlider) {
return;
}
if(e.getID()==MouseEvent.MOUSE_DRAGGED) {
if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
JViewport vport = l.getView().getViewport();
JComponent cmp = (JComponent)vport.getView();
JComponent cmp = (JComponent) vport.getView();
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport);
Point vp = vport.getViewPosition();
vp.translate(pp.x-cp.x, pp.y-cp.y);
vp.translate(pp.x - cp.x, pp.y - cp.y);
cmp.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
pp.setLocation(cp);
}
}
}
View in GitHub: Java, Kotlin解説
- 左:
DragScrollListener
解説
-
DragScrollListener
- JTreeの余白をドラッグしてスクロール
- このリスナーを追加した一つの
Component
をドラッグしてスクロールが可能 -
JPanel
を掴んでスクロールすることができるが、その子コンポーネントのJTabbedPane
などをドラッグしてもスクロールはできない
- 右:
DragScrollLayer
-
JPanel
を掴んでのスクロールが実行可能だが、その子コンポーネントのJTabbedPane
などをドラッグしてもスクロールは不可
-
-
DragScrollLayer
- すべての下位コンポーネントの
MouseEvent
をキャッチするようJLayer#setLayerEventMask(...)
と設定したJLayer
を作成 - この
JLayer
でJScrollPane
をラップし、子にマウスイベントを消費するコンポーネントがあっても、ビューであるJPanel
をドラッグに応じてスクロール -
JScrollBar
やJSlider
のように、ノブのドラッグを使用するコンポーネントは二重にスクロールしてしまうので除外 - この
JLayer
でJScrollPane
をラップし、子にマウスイベントを消費するコンポーネントが存在する場合でも、ビューのJPanel
をドラッグに応じてスクロール -
JScrollBar
やJSlider
のようにノブのドラッグを使用するコンポーネントは二重にスクロールしてしまうので除外
- すべての下位コンポーネントの
参考リンク
参考リンク
- Java Swing Tips: Mouse Dragging ViewPort Scroll
- JTreeの余白をドラッグしてスクロール
- JScrollPaneのViewportをマウスで掴んでスクロール