---
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: https://lh4.googleusercontent.com/-Ax3sBgN85bo/U_DD4w3kEjI/AAAAAAAACLg/H0QTGo7hLH4/s800/WheelOverNestedScrollPane.png
hreflang:
href: https://java-swing-tips.blogspot.com/2014/09/forward-mouse-wheel-scroll-event-in.html
lang: en
---
* Summary [#summary]
`JLayer`を使って、ネストする`JScrollPane`への`MouseWheelEvent`を転送し、スクロールが継続するように設定します。
#download(https://lh4.googleusercontent.com/-Ax3sBgN85bo/U_DD4w3kEjI/AAAAAAAACLg/H0QTGo7hLH4/s800/WheelOverNestedScrollPane.png)
* Source Code Examples [#sourcecode]
#code(link){{
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 ext = m.getExtent();
int min = m.getMinimum();
int max = m.getMaximum();
int value = m.getValue();
if (value + ext >= max && dir > 0 || value <= min && dir < 0) {
main.dispatchEvent(SwingUtilities.convertMouseEvent(c, e, main));
}
}
}
}
}}
* Description [#explanation]
* Description [#description]
- ネストしている`JScrollPane`の子`JScrollPane`上でマウスイベントが発生した場合、`MouseWheelEvent`などのイベントは子`JScrollPane`内で消費されて親`JScrollPane`には伝搬しない
- 上記のサンプルでは、子`JScrollPane`の縦スクロールバーが最下部にあるなら下方向(最上部なら上方向)の`MouseWheelEvent`は親`JScrollPane`に転送する`LayerUI`を作成し、これを親`JScrollPane`の`JLayer<JScrollPane>`に適用している
* Reference [#reference]
- [[JScrollBarが最後までスクロールしたことを確認する>Swing/DetectScrollToBottom]]
* Comment [#comment]
#comment
#comment