• category: swing folder: DiagonalHeaderCellBorder title: JTableHeaderのTableColumnを斜め線で分割する tags: [JTableHeader, Border] author: aterai pubdate: 2023-03-27T00:15:21+09:00 description: JTableHeaderの第0番目のTableColumnを斜め線で分割して行と列で異なる見出しを表示します。 image: https://drive.google.com/uc?id=1ZYw3qU1gbO_gq4-6YrfXTlkH35QLEAyf

概要

JTableHeaderの第0番目のTableColumnを斜め線で分割して行と列で異なる見出しを表示します。

サンプルコード

int size = 32;
JTable table = new JTable(model) {
  @Override public void updateUI() {
    super.updateUI();
    setRowHeight(size);
    TableCellRenderer hr = new VerticalTableHeaderRenderer();
    TableColumnModel cm = getColumnModel();
    cm.getColumn(0).setHeaderRenderer(
        new DiagonallySplitHeaderRenderer());
    cm.getColumn(0).setPreferredWidth(size * 5);
    for (int i = 1; i < cm.getColumnCount(); i++) {
      TableColumn tc = cm.getColumn(i);
      tc.setHeaderRenderer(hr);
      tc.setPreferredWidth(size);
    }
  }
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

JScrollPane scroll = new JScrollPane(table);
scroll.setColumnHeader(new JViewport() {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = size * 2;
    return d;
  }
});
// ...

class DiagonallySplitBorder extends MatteBorder {
  protected DiagonallySplitBorder(
      int top, int left, int bottom, int right, Color matteColor) {
    super(top, left, bottom, right, matteColor);
  }

  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    super.paintBorder(c, g, x, y, width, height);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setPaint(getMatteColor());
    g2.drawLine(0, 0, c.getWidth() - 1, c.getHeight() - 1);
    g2.dispose();
  }
}
View in GitHub: Java, Kotlin

解説

  • JScrollPaneColumnHeaderの高さを変更してその内部に配置されるJTableHeaderの高さも変更して列タイトル文字列を回転して垂直表示
  • 0番目のTableColumnを取得しTableColumn#setHeaderRenderer(...)DiagonallySplitHeaderRendererを設定
    • DiagonallySplitHeaderRendererMatteBorderを継承して上下左右の罫線と斜め線を描画可能なBorderを設定
    • 斜め線はMatteBorder#paintBorder(...)をオーバーライドしてBorderとして描画
    • JTextAreaの背景に画像を表示
  • 行と列の見出しは別々にJLabelで作成してBorderLayoutを設定したJPanelの上下に配置
    • 列見出し用のJLabelSwingConstants.RIGHTで右寄せで表示するよう設定し、BorderLayout.NORTHJPanelの上辺に配置
    • 行見出し用のJLabelSwingConstants.LEFTで左寄せで表示するよう設定し、BorderLayout.SOUTHJPanelの下辺に配置

参考リンク

コメント