• 追加された行はこの色です。
  • 削除された行はこの色です。
---
category: swing
folder: ScrollBarOnHover
title: JScrollPane上にマウスカーソルが存在する場合のみJScrollBarを表示する
tags: [JScrollPane, JScrollBar, JLayer, MouseListener]
author: aterai
pubdate: 2017-07-31T16:08:05+09:00
description: JScrollPane上にマウスカーソルが存在する場合だけ、縦JScrollBarが表示されるように設定します。
image: https://drive.google.com/uc?id=19tpZyfx24XIIJHmLNjzpSlSQg_GAPDwkUA
---
* 概要 [#summary]
`JScrollPane`上にマウスカーソルが存在する場合だけ、縦`JScrollBar`が表示されるように設定します。

#download(https://drive.google.com/uc?id=19tpZyfx24XIIJHmLNjzpSlSQg_GAPDwkUA)

* サンプルコード [#sourcecode]
#code(link){{
class ScrollBarOnHoverLayerUI extends LayerUI<JScrollPane> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
    }
  }
  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }
  @Override protected void processMouseEvent(
      MouseEvent e, JLayer<? extends JScrollPane> l) {
    JScrollPane sp = l.getView();
    switch (e.getID()) {
    case MouseEvent.MOUSE_ENTERED:
      sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
      break;
    case MouseEvent.MOUSE_EXITED:
      sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
      break;
    default:
      break;
    }
    // super.processMouseEvent(e, l);
  }
}
}}

* 解説 [#explanation]
- 上: `MouseListener`
-- `JScrollPane`内部に配置した`JTextArea`に`MouseListener`を設定
--- `JTextArea`上にマウスカーソルが入ったら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);`で`JScrollBar`を表示
--- `JTextArea`上からマウスカーソルが出たら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);`で`JScrollBar`を非表示
--- `JTextArea`外にマウスカーソルが出たら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);`で`JScrollBar`を非表示
-- `JScrollBar`上にマウスカーソルが入ると、`JTextArea`からマウスカーソルが出たことになるので、カーソル表示などが点滅してしまう
- 下: `JLayer`
-- `JScrollPane`に`JLayer`を設定
-- `JLayer#setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);`を指定し、`JLayer`と''そのすべての下位オブジェクト''からのマウスイベントを`processMouseEvent(...)`メソッドで受け取るよう設定
--- `JLayer`上にマウスカーソルが入ったら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);`で`JScrollBar`を表示
--- `JLayer`上からマウスカーソルが出たら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);`で`JScrollBar`を非表示
--- `JLayer`外にマウスカーソルが出たら`JScrollPane#setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);`で`JScrollBar`を非表示

* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JLayer.html#setLayerEventMask-long- JLayer#setLayerEventMask(long) (Java Platform SE 8)]
- [[JScrollBarを半透明にする>Swing/TranslucentScrollBar]]

* コメント [#comment]
#comment
#comment