Swing/DiagonallySplitCellCalendar の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DiagonallySplitCellCalendar へ行く。
- Swing/DiagonallySplitCellCalendar の差分を削除
--- category: swing folder: DiagonallySplitCellCalendar title: JTableのセルを斜めに分割する tags: [JTable, JLayer, JLabel, Calendar] author: aterai pubdate: 2020-06-01T03:09:34+09:00 description: JTableのセルレンダラーにJLayerで直線を描画して斜め分断セルを表示します。 image: https://drive.google.com/uc?id=19GKh0Ts86Zd4J0mjJTp1pmNkOnrcURBy hreflang: href: https://java-swing-tips.blogspot.com/2020/06/create-month-calendar-with-diagonally.html lang: en --- * 概要 [#summary] `JTable`のセルレンダラーに`JLayer`で直線を描画して斜め分断セルを表示します。 #download(https://drive.google.com/uc?id=19GKh0Ts86Zd4J0mjJTp1pmNkOnrcURBy) * サンプルコード [#sourcecode] #code(link){{ private class CalendarTableRenderer extends DefaultTableCellRenderer { private final JPanel p = new JPanel(); @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean selected, boolean focused, int row, int column) { JLabel c = (JLabel) super.getTableCellRendererComponent( table, value, selected, focused, row, column); if (value instanceof LocalDate) { LocalDate d = (LocalDate) value; c.setText(Objects.toString(d.getDayOfMonth())); c.setVerticalAlignment(SwingConstants.TOP); c.setHorizontalAlignment(SwingConstants.LEFT); updateCellWeekColor(d, c, c); LocalDate nextWeekDay = d.plusDays(7); boolean isLastRow = row == table.getModel().getRowCount() - 1; if (isLastRow && YearMonth.from(nextWeekDay).equals(YearMonth.from(getCurrentLocalDate()))) { JLabel sub = new JLabel(Objects.toString(nextWeekDay.getDayOfMonth())); sub.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); sub.setOpaque(false); sub.setVerticalAlignment(SwingConstants.BOTTOM); sub.setHorizontalAlignment(SwingConstants.RIGHT); p.removeAll(); p.setLayout(new BorderLayout()); p.add(sub, BorderLayout.SOUTH); p.add(c, BorderLayout.NORTH); p.setBorder(c.getBorder()); c.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); updateCellWeekColor(d, sub, p); return new JLayer<>(p, new DiagonallySplitCellLayerUI()); } } return c; } // ... }} * 解説 [#explanation] 上記のサンプルでは、月カレンダーで`6`週目になる日を前の`5`週目の同じ曜日のセルを斜め分割してまとめて表示しています。 - `DefaultTableModel#getRowCount()`が常に`5`を返すようオーバーライドして月カレンダーが`5`週分のみ表示するよう設定 - `5`週目(`row==4`)を表示するセルレンダラーで対象日の`7`日後が今月の場合、`BorderLayout`を設定した`JPanel`に対象日用の`JLabel`を`BorderLayout.NORTH`、`7`日後の日付を表示するための別`JLabel`を`BorderLayout.SOUTH`で追加 - この`JPanel`に斜め線を表示する`JLayer`を作成してセルレンダラーとして使用 #code{{ class DiagonallySplitCellLayerUI extends LayerUI<JPanel> { @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); if (c instanceof JLayer) { Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(UIManager.getColor("Table.gridColor")); g2.drawLine(c.getWidth(), 0, 0, c.getHeight()); g2.dispose(); } } } }} * 参考リンク [#reference] - [[JTableにLocaleを考慮したLocalDateを適用してカレンダーを表示する>Swing/CalendarViewTable]] - [[JTableの行高がJViewportの高さに合うまで調整する>Swing/AdjustRowHeightFillsViewport]] - [[JTableHeaderのTableColumnを斜め線で分割する>Swing/DiagonalHeaderCellBorder]] -- `JLayer`ではなく`Border`を使用して斜め線を描画する方法もある * コメント [#comment] #comment #comment