JScrollPaneにJTableを配置して連続月間カレンダーを作成する
Total: 904
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
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
月6
週分の6
行ではなく、現在の日付から前後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のノードを選択する