Swing/CalendarViewTable の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/CalendarViewTable へ行く。
- Swing/CalendarViewTable の差分を削除
--- category: swing folder: CalendarViewTable title: JTableにLocaleを考慮したLocalDateを適用してカレンダーを表示する tags: [JTable, LocalDate, Locale, Calendar] author: aterai pubdate: 2018-01-29T14:57:32+09:00 description: JTableに週の最初の曜日がLocaleに応じて変化するカレンダーを表示します。 image: https://drive.google.com/uc?id=1jXZtiYFaA5ABWsdaRBnPUKqS2_VBDkFqQA hreflang: href: https://java-swing-tips.blogspot.com/2018/01/apply-localdate-considering-locale-to.html lang: en --- * 概要 [#summary] `JTable`に週の最初の曜日が`Locale`に応じて変化するカレンダーを表示します。 #download(https://drive.google.com/uc?id=1jXZtiYFaA5ABWsdaRBnPUKqS2_VBDkFqQA) * サンプルコード [#sourcecode] #code(link){{ class CalendarViewTableModel extends DefaultTableModel { private final LocalDate startDate; private final WeekFields weekFields = WeekFields.of(Locale.getDefault()); public CalendarViewTableModel(LocalDate date) { super(); LocalDate firstDayOfMonth = YearMonth.from(date).atDay(1); int dowv = firstDayOfMonth.get(weekFields.dayOfWeek()) - 1; startDate = firstDayOfMonth.minusDays(dowv); } @Override public Class<?> getColumnClass(int column) { return LocalDate.class; } @Override public String getColumnName(int column) { return weekFields.getFirstDayOfWeek().plus(column) .getDisplayName(TextStyle.SHORT_STANDALONE, Locale.getDefault()); } @Override public int getRowCount() { return 6; } @Override public int getColumnCount() { return 7; } @Override public Object getValueAt(int row, int column) { return startDate.plusDays(row * getColumnCount() + column); } @Override public boolean isCellEditable(int row, int column) { return false; } } }} * 解説 [#explanation] 上記のサンプルでは、`Java 8`から`java.time`パッケージに追加された`LocalDate`を`JTable`のモデルとして使用し、月のカレンダーを表示しています。 - [https://docs.oracle.com/javase/jp/8/docs/api/java/time/temporal/WeekFields.html#getFirstDayOfWeek-- WeekFields#getFirstDayOfWeek()]メソッドで`Locale`に応じた週の最初の曜日を取得して`JTable`の`0`列目を設定 -- 例: 週の最初の曜日はロケールがフランスや`ISO-8601`標準の場合は月曜日、アラビアなら土曜日になる -- 週の最初の曜日はロケールがフランスや`ISO-8601`標準の場合は月曜日、アラビアなら土曜日になる #twocolumn `java -Duser.language=fr -jar example.jar` // #img4(https://drive.google.com/uc?id=1SmGpl6oxRwwb8tZM2Vc0C7oFS_UCT_Ck6Q) #img2(https://2.bp.blogspot.com/-70trH_7BlH4/Wm68XxCFSdI/AAAAAAAAQHc/j8cfHasYBIMmiN9IBFiVyulLWmP_lihFQCLcBGAs/s1600/CalendarViewTable1.png) #twocolumn `java -Duser.language=ar -jar example.jar` #img2(https://4.bp.blogspot.com/-gR-ZIzebjI8/WpZl3xJH3wI/AAAAAAAAQMY/428-GXuyU-4pZu3CDVghkY19YPcRXfLAwCLcBGAs/s1600/CalendarViewTable2.png) #twocolumn - 土曜と日曜の位置も`6`列目と`0`列目固定ではないので、以下のように`LocalDate.getDayOfWeek()`メソッドで曜日を確認してその背景色を変更する必要がある #code{{ private class CalendarTableRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean selected, boolean focused, int row, int column) { super.getTableCellRendererComponent(table, value, selected, focused, row, column); setHorizontalAlignment(SwingConstants.CENTER); if (value instanceof LocalDate) { LocalDate d = (LocalDate) value; setText(String.valueOf(d.getDayOfMonth())); if (YearMonth.from(d).equals(YearMonth.from(currentLocalDate))) { setForeground(Color.BLACK); } else { setForeground(Color.GRAY); } DayOfWeek dow = d.getDayOfWeek(); if (d.isEqual(realLocalDate)) { setBackground(new Color(220, 255, 220)); } else if (dow == DayOfWeek.SUNDAY) { setBackground(new Color(255, 220, 220)); } else if (dow == DayOfWeek.SATURDAY) { setBackground(new Color(220, 220, 255)); } else { setBackground(Color.WHITE); } } return this; } } }} * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/java/time/temporal/WeekFields.html#getFirstDayOfWeek-- WeekFields#getFirstDayOfWeek() (Java Platform SE 8)] - [https://tips4java.wordpress.com/2015/04/22/local-date-combo/ Local Date Combo « Java Tips Weblog] - [[JListで月のカーソルキー移動や、週を跨いた日付を範囲選択が可能なカレンダーを作成する>Swing/CalendarViewList]] -- `JTable`ではなく、`JList`を使用すると上下カーソルキーで週を跨いだ日付の範囲選択が可能 * コメント [#comment] #comment #comment