概要

半透明のJScrollBarJTable上に重ねてレイアウトするJScrollPaneを作成します。

サンプルコード

class OverlapScrollPaneLayout extends ScrollPaneLayout {
  private static final int BAR_SIZE = 12;
  @Override public void layoutContainer(Container parent) {
    if (parent instanceof JScrollPane) {
      JScrollPane scrollPane = (JScrollPane) parent;

      Rectangle availR = scrollPane.getBounds();
      availR.setLocation(0, 0); // availR.x = availR.y = 0;

      Insets insets = parent.getInsets();
      availR.x = insets.left;
      availR.y = insets.top;
      availR.width -= insets.left + insets.right;
      availR.height -= insets.top  + insets.bottom;

      Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0);
      if (colHead != null && colHead.isVisible()) {
        int colHeadHeight = Math.min(
            availR.height, colHead.getPreferredSize().height);
        colHeadR.height = colHeadHeight;
        availR.y += colHeadHeight;
        availR.height -= colHeadHeight;
      }

      colHeadR.width = availR.width;
      colHeadR.x = availR.x;
      if (colHead != null) {
        colHead.setBounds(colHeadR);
      }

      Rectangle hsbR = new Rectangle();
      hsbR.height = BAR_SIZE;
      hsbR.width = availR.width - hsbR.height;
      hsbR.x = availR.x;
      hsbR.y = availR.y + availR.height - hsbR.height;

      Rectangle vsbR = new Rectangle();
      vsbR.width = BAR_SIZE;
      vsbR.height = availR.height - vsbR.width;
      vsbR.x = availR.x + availR.width - vsbR.width;
      vsbR.y = availR.y;

      if (viewport != null) {
        viewport.setBounds(availR);
      }
      if (vsb != null) {
        vsb.setVisible(true);
        vsb.setBounds(vsbR);
      }
      if (hsb != null) {
        hsb.setVisible(true);
        hsb.setBounds(hsbR);
      }
    }
  }
}
View in GitHub: Java, Kotlin

解説

  • JScrollBarを半透明にするとほぼ同様のScrollPaneLayoutを使用
    • ただしJTableのヘッダを表示するためにJScrollPaneのカラムヘッダのレイアウトに対応するよう追加修正
  • 水平スクロールバーにも対応しているが右下のコーナーコンポーネントは常に空き状態になる
    • 片方のスクロールバーが非表示でもその領域まで拡張しない
  • スクロールバーの幅は推奨サイズなどを無視して固定

参考リンク

コメント