概要

JSplitPaneDividerJTableHeaderTableColumnでコンボーネントをリサイズ中に表示されるマウスカーソルを変更します。

スクリーンショット

Swing/ResizeColumnCursor.png

サンプルコード

JSplitPane sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
BasicSplitPaneDivider divider = ((BasicSplitPaneUI) sp2.getUI()).getDivider();
divider.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));

JSplitPane sp3 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT) {
  @Override public void updateUI() {
    super.updateUI();
    EventQueue.invokeLater(() -> {
      BasicSplitPaneDivider d = ((BasicSplitPaneUI) getUI()).getDivider();
      d.setCursor(ResizeCursorUtils.createCursor("⇹", 32, 32, d));
    });
  }
};
View in GitHub: Java, Kotlin

解説

  • 上: JSplitPane
    • デフォルトは左右分割の場合Cursor.E_RESIZE_CURSOR、上下分割の場合Cursor.S_RESIZE_CURSORを使用するようBasicSplitPaneDividerでハードコーディングされている
    • Ubuntu環境のCursor.E_RESIZE_CURSORはホットスポットがカーソルの中央ではなく左端に存在するため、左右分割のDivider上にカーソルを置くと左コンポーネント上にカーソルがジャンプ?してしまう
  • 中: JSplitPane
    • 左右分割DividerのカーソルをUbuntu環境ではホットスポットが右端に存在するCursor.W_RESIZE_CURSORに変更
    • Windows環境ではCursor.E_RESIZE_CURSORCursor.W_RESIZE_CURSORともにホットスポットはカーソル中央なので変化なし
    • このサンプルでは上下分割に切り替えた場合などには未対応
  • 下: JSplitPane
    • ホットスポットを文字の中央に設定したカスタムカーソルを作成してリサイズカーソルとしてDividerに設定
    • Cursorオブジェクトの生成
    • このサンプルでは上下分割に切り替えた場合などには未対応
  • 上中: TableColumn
    • JSplitPaneと同様にデフォルトは左右分割の場合Cursor.E_RESIZE_CURSOR、上下分割の場合Cursor.S_RESIZE_CURSORを使用するようBasicTableHeaderUIでハードコーディングされている
    • リサイズカーソル(Cursor.E_RESIZE_CURSOR)表示中にキー入力でLookAndFeelを切り替えるとJTableHeader上では常にCursor.E_RESIZE_CURSORが表示されてCursor.DEFAULT_CURSORに戻せなくなる
  • 下: TableColumn
    • ホットスポットをExcel風に文字の中央に設定したカスタムカーソルを作成
    • BasicTableHeaderUI.MouseInputHandler#mouseMoved(...)メソッドをオーバーライドしてJTableHeaderで使用
class MyBasicTableHeaderUI extends BasicTableHeaderUI {
  @Override protected MouseInputListener createMouseInputListener() {
    return new MouseInputHandler() {
      private final Cursor resizeCursor = ResizeCursorUtils.createCursor("⇼", 32, 32, header);
      private final Cursor defaultCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);

      @Override public void mouseMoved(MouseEvent e) {
        super.mouseMoved(e);
        if (!header.isEnabled()) {
          return;
        }
        if (ResizeCursorUtils.canResize(ResizeCursorUtils.getResizeColumn(header, e.getPoint()), header)) {
          header.setCursor(resizeCursor);
        } else {
          header.setCursor(defaultCursor);
        }
      }
    };
  }
}

参考リンク

コメント