概要

JScrollPane上にマウスカーソルが存在する場合だけ、縦JScrollBarが表示されるように設定します。

サンプルコード

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);
  }
}
View in GitHub: Java, Kotlin

解説

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

参考リンク

コメント