イベントを伝播するJScrollPane
JScrollPaneを入れ子構造にした場合、マウス位置の最も上にあるJScrollPaneがイベントを消費してしまい、結果スクロール途中のマウスの下に入れ子のJScrollPaneが来てしまうとスクロールを止められてしまいとても不便です。
そんなわで、上もしくは下までスクロールしきったJScrollPaneのイベントを下のコンポーネントにスルーしてくれるMouseWheelListenerを作ったのでメモ。
JScrollPaneをわざわざメンバー変数に保持してるけど、MouseWheelEventから取り出したほうがよかったかも。
import java.awt.Component; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import javax.swing.JScrollBar; import javax.swing.JScrollPane; /** * JScrollPaneがスクロール方向の限界値までスクロールしている場合に * 親コンポーネントへイベントを伝播させるMouseWheelListenerの実装です。 * */ public class JScrollPaneHandler implements MouseWheelListener{ private JScrollPane mTarget; /** * MouseWheelListenerExを生成します。 * @param target このリスナを登録するJScrollPane */ public JScrollPaneHandler( JScrollPane target ){ mTarget = target; } /** * 登録されているJScrollPaneがスクロール方向の限界値までスクロールしている場合に * イベントを親コンポーネントに伝播させます。 * @param e MouseWheelEvent */ @Override public void mouseWheelMoved( MouseWheelEvent e ){ JScrollBar vBar = mTarget.getVerticalScrollBar(); int rotation = e.getWheelRotation(); int current = vBar.getValue(); int height = mTarget.getHeight(); if( rotation > 0 ){ //下にスクロール int max = vBar.getMaximum() - height; if( current >= max ){ //限界値までスクロールしている dispatchParent( e ); } }else if( rotation < 0 ){ //上にスクロール int min = vBar.getMinimum(); if( current <= min ){ //限界値までスクロールしている dispatchParent( e ); } } } /** * 登録されているJComponentの親コンポーネントにMouseWheelイベントを発行します。 * 親コンポーネントが存在しない場合は何もしません。 * @param e 発行するMouseWheelEvent */ private void dispatchParent( MouseWheelEvent e ){ Component parent = mTarget.getParent(); if( parent != null ){ parent.dispatchEvent( e ); } } }