概要

JSplitPaneに追加した子コンポーネントの余白などをドラッグしてDividerの位置を変更可能にするJLayerを設定します。

サンプルコード

class DividerLocationDragLayerUI extends LayerUI<JSplitPane> {
  private int dividerLocation;
  private final Point startPt = new Point();
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer) c).setLayerEventMask(
          AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_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 JSplitPane> l) {
    JSplitPane splitPane = l.getView();
    Component c = e.getComponent();
    if (splitPane.equals(SwingUtilities.getUnwrappedParent(c))
        && e.getID() == MouseEvent.MOUSE_PRESSED) {
      startPt.setLocation(SwingUtilities.convertPoint(c, e.getPoint(), splitPane));
      dividerLocation = splitPane.getDividerLocation();
    }
  }
  @Override protected void processMouseMotionEvent(
      MouseEvent e, JLayer<? extends JSplitPane> l) {
    JSplitPane splitPane = l.getView();
    Component c = e.getComponent();
    if (splitPane.equals(SwingUtilities.getUnwrappedParent(c))
        && e.getID() == MouseEvent.MOUSE_DRAGGED) {
      Point pt = SwingUtilities.convertPoint(c, e.getPoint(), splitPane);
      int delta = splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT
                  ? pt.x - startPt.x
                  : pt.y - startPt.y;
      splitPane.setDividerLocation(Math.max(0, dividerLocation + delta));
    }
  }
}
view all

解説

上記のサンプルでは、JSplitPaneDividerをマウスでドラッグするだけでなく、JSplitPane#setRightComponent(...)などで追加した子コンポーネントをマウスでドラッグすることで、分割位置を変更できるように、JSplitPaneにマウスイベントを取得するLayerUIを設定しています。

  • ドラッグ可能になるのは、JSplitPaneの子コンポーネントの余白(そのコンポーネントが別途マウスイベントを処理しない領域)
    • 例: マウスリスナーを追加していないJLabelはドラッグ可能、JButtonなどはドラッグ不可となる

参考リンク

コメント