Swing/ContinuousMonthlyCalendar のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ContinuousMonthlyCalendar へ行く。
- 1 (2023-02-27 (月) 01:06:51)
- 2 (2023-02-27 (月) 04:18:48)
- 3 (2024-09-13 (金) 17:41:43)
- category: swing folder: ContinuousMonthlyCalendar title: JScrollPaneにJTableを配置して連続月間カレンダーを作成する tags: [JScrollPane, JTable, LocalDate, Calendar] author: aterai pubdate: 2023-02-27T01:05:27+09:00 description: JScrollPaneにJTableを配置してマウスホイールなどでスクロール可能な連続月間カレンダーを作成します。 image: https://drive.google.com/uc?id=1t_loMpWjMtdCAC6iCBzebKnkdJoiV7pj
概要
JScrollPane
にJTable
を配置してマウスホイールなどでスクロール可能な連続月間カレンダーを作成します。
Screenshot
Advertisement
サンプルコード
JScrollBar verticalScrollBar = new JScrollBar(Adjustable.VERTICAL) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = 0;
return d;
}
};
verticalScrollBar.setUnitIncrement(monthTable.getRowHeight());
scroll.setVerticalScrollBar(verticalScrollBar);
verticalScrollBar.getModel().addChangeListener(e -> {
EventQueue.invokeLater(() -> {
JViewport viewport = scroll.getViewport();
Point pt = SwingUtilities.convertPoint(viewport, 0, 0, monthTable);
int row = monthTable.rowAtPoint(pt);
int col = 6; // monthTable.columnAtPoint(pt);
LocalDate localDate = (LocalDate) monthTable.getValueAt(row, col);
currentLocalDate = localDate;
updateMonthLabel(localDate, locale1);
viewport.repaint();
});
});
View in GitHub: Java, Kotlin解説
- 表示用の
JTable
やJTableHeader
、TableCellRenderer
はJTableにLocaleを考慮したLocalDateを適用してカレンダーを表示するとほぼ同じものを使用- 行の高さを
32px
固定に変更している
- 行の高さを
TableModel
は1
月7
週分の7
行ではなく、現在の日付から前後500
週分の1000
行分保持するよう変更し、スクロールで表示する週を変更可能にしている- このため月変更用
JButton
はTableModel
の入れ替えではなく、以下のようにmonthTable.scrollRectToVisible(...)
メソッドを実行して対象となる月の1
週目が先頭に表示される位置までスクロールするよう変更public void updateMonthView(LocalDate localDate, Locale locale) { currentLocalDate = localDate; updateMonthLabel(localDate, locale); TableModel model = monthTable.getModel(); int v = model.getRowCount() / 2; LocalDate startDate1 = getTopLeftCellDayOfMonth(realLocalDate, locale); LocalDate startDate2 = getTopLeftCellDayOfMonth(localDate, locale); int between = (int) ChronoUnit.WEEKS.between(startDate1, startDate2); Rectangle r = monthTable.getCellRect(v + between, 0, false); r.height = scroll.getViewport().getViewRect().height; monthTable.scrollRectToVisible(r); scroll.repaint(); }
- このため月変更用
- 縦
JScrollBar
はその幅を0
に設定して不可視化しているがMouseWheel
でスクロール可能になるよう設定 - 縦
JScrollBar
ChangeListener
を設定しMouseWheel
などでスクロールしたとき右上隅に表示されるセルの日付の月を取得して月表示JLabel
に設定
参考リンク
- JTableにLocaleを考慮したLocalDateを適用してカレンダーを表示する
- JScrollBarが非表示でもMouseWheelでScrollする
- JEditorPaneのスクロールに連動してJTreeのノードを選択する