Swing/WheelOverNestedScrollPane のバックアップ(No.11)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/WheelOverNestedScrollPane へ行く。
- 1 (2014-09-14 (日) 20:48:26)
- 2 (2014-10-18 (土) 13:08:46)
- 3 (2014-11-18 (火) 16:22:17)
- 4 (2014-11-21 (金) 18:11:05)
- 5 (2015-12-13 (日) 16:40:33)
- 6 (2017-06-08 (木) 13:24:44)
- 7 (2018-02-24 (土) 19:51:30)
- 8 (2018-05-29 (火) 14:55:35)
- 9 (2020-05-22 (金) 17:40:44)
- 10 (2021-11-09 (火) 00:42:19)
- 11 (2023-10-04 (水) 12:00:55)
- category: swing
folder: WheelOverNestedScrollPane
title: MouseWheelEventを親のJScrollPaneに転送する
tags: [JScrollPane, JLayer, MouseWheelEvent]
author: aterai
pubdate: 2014-08-18T00:11:00+09:00
description: JLayerを使って、ネストするJScrollPaneへのMouseWheelEventを転送し、スクロールが継続するように設定します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2014/09/forward-mouse-wheel-scroll-event-in.html lang: en
概要
JLayer
を使って、ネストするJScrollPane
へのMouseWheelEvent
を転送し、スクロールが継続するように設定します。
Screenshot
Advertisement
サンプルコード
class WheelScrollLayerUI extends LayerUI<JScrollPane> {
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseWheelEvent(
MouseWheelEvent e, JLayer<? extends JScrollPane> l) {
Component c = e.getComponent();
int dir = e.getWheelRotation();
JScrollPane main = l.getView();
if (c instanceof JScrollPane && !c.equals(main)) {
JScrollPane child = (JScrollPane) c;
BoundedRangeModel m = child.getVerticalScrollBar().getModel();
int extent = m.getExtent();
int minimum = m.getMinimum();
int maximum = m.getMaximum();
int value = m.getValue();
if (value + extent >= maximum && dir > 0 || value <= minimum && dir < 0) {
main.dispatchEvent(SwingUtilities.convertMouseEvent(c, e, main));
}
}
}
}
View in GitHub: Java, Kotlin解説
- ネストしている
JScrollPane
の子JScrollPane
上でマウスイベントが発生した場合、MouseWheelEvent
などのイベントは子JScrollPane
内で消費されて親JScrollPane
には伝搬しない - 上記のサンプルでは、子
JScrollPane
の縦スクロールバーが最下部にあるなら下方向(最上部なら上方向)のMouseWheelEvent
は親JScrollPane
に転送するLayerUI
を作成し、これを親JScrollPane
のJLayer<JScrollPane>
に適用している