Swing/SpinnerLocalDateTimeModel のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/SpinnerLocalDateTimeModel へ行く。
- 1 (2015-02-02 (月) 00:14:27)
- 2 (2015-04-06 (月) 18:40:08)
- 3 (2015-04-09 (木) 19:07:38)
- 4 (2015-06-02 (火) 18:49:21)
- 5 (2016-05-26 (木) 17:24:42)
- 6 (2016-06-16 (木) 00:59:24)
- 7 (2016-06-24 (金) 16:33:09)
- 8 (2017-01-09 (月) 03:51:00)
- 9 (2017-01-10 (火) 15:38:56)
- 10 (2017-04-04 (火) 14:13:45)
- 11 (2017-04-07 (金) 13:51:51)
- 12 (2017-12-13 (水) 16:02:37)
- 13 (2019-08-29 (木) 15:59:11)
- 14 (2021-04-23 (金) 20:06:05)
- 15 (2022-08-20 (土) 22:15:25)
- 16 (2023-03-16 (木) 15:43:08)
- 17 (2023-03-18 (土) 15:45:43)
- title: JSpinnerでLocalDateTimeを使用する tags: [JSpinner, SpinnerModel, LocalDateTime] author: aterai pubdate: 2015-02-02T00:12:04+09:00 description: DateやCalendarなどを使用するSpinnerDateModelの代わりに、JDK 8で導入されたLocalDateTimeなどを使用するSpinnerModelを作成して、JSpinnerで日付を選択します。
概要
Date
やCalendar
などを使用するSpinnerDateModel
の代わりに、JDK 8
で導入されたLocalDateTime
などを使用するSpinnerModel
を作成して、JSpinner
で日付を選択します。
Screenshot
Advertisement
サンプルコード
class SpinnerLocalDateTimeModel extends AbstractSpinnerModel {
private Comparable<ChronoLocalDateTime<?>> start, end;
private LocalDateTime value;
private TemporalUnit temporalUnit;
public SpinnerLocalDateTimeModel(
LocalDateTime value, Comparable<ChronoLocalDateTime<?>> start,
Comparable<ChronoLocalDateTime<?>> end, TemporalUnit temporalUnit) {
super();
if (value == null) {
throw new IllegalArgumentException("value is null");
}
if (!(start == null || start.compareTo(value) <= 0)
&& (end == null || end.compareTo(value) >= 0)) {
throw new IllegalArgumentException("(start <= value <= end) is false");
}
this.value = value;
this.start = start;
this.end = end;
this.temporalUnit = temporalUnit;
}
public void setStart(Comparable<ChronoLocalDateTime<?>> start) {
if (start == null ? this.start != null : !start.equals(this.start)) {
this.start = start;
fireStateChanged();
}
}
public Comparable<ChronoLocalDateTime<?>> getStart() {
return start;
}
public void setEnd(Comparable<ChronoLocalDateTime<?>> end) {
if (end == null ? this.end != null : !end.equals(this.end)) {
this.end = end;
fireStateChanged();
}
}
public Comparable<ChronoLocalDateTime<?>> getEnd() {
return end;
}
public void setTemporalUnit(TemporalUnit temporalUnit) {
if (temporalUnit != this.temporalUnit) {
this.temporalUnit = temporalUnit;
fireStateChanged();
}
}
public TemporalUnit getTemporalUnit() {
return temporalUnit;
}
@Override public Object getNextValue() {
//Calendar cal = Calendar.getInstance();
//cal.setTime(value.getTime());
//cal.add(calendarField, 1);
//Date next = cal.getTime();
LocalDateTime next = value.plus(1, temporalUnit);
return end == null || end.compareTo(next) >= 0 ? next : null;
}
@Override public Object getPreviousValue() {
//Calendar cal = Calendar.getInstance();
//cal.setTime(value.getTime());
//cal.add(calendarField, -1);
//Date prev = cal.getTime();
LocalDateTime prev = value.minus(1, temporalUnit);
return start == null || start.compareTo(prev) <= 0 ? prev : null;
}
public LocalDateTime getLocalDateTime() {
return value;
}
@Override public Object getValue() {
return value;
}
@Override public void setValue(Object value) {
if (!(value instanceof LocalDateTime)) {
throw new IllegalArgumentException("illegal value");
}
if (!value.equals(this.value)) {
this.value = (LocalDateTime) value;
fireStateChanged();
}
}
}
View in GitHub: Java, Kotlin解説
- 上:
SpinnerDateModel
Calendar
などを使用して開始日、終了日を生成し、SpinnerDateModel
を作成して、JSpinner
に設定Calendar cal = Calendar.getInstance(); cal.clear(Calendar.MILLISECOND); cal.clear(Calendar.SECOND); cal.clear(Calendar.MINUTE); cal.set(Calendar.HOUR_OF_DAY, 0); Date date = cal.getTime(); cal.add(Calendar.DATE, -2); Date start = cal.getTime(); cal.add(Calendar.DATE, 9); Date end = cal.getTime(); JSpinner spinner1 = new JSpinner(new SpinnerDateModel( date, start, end, Calendar.DAY_OF_MONTH));
- 参考: JSpinnerで日付を設定
- 下:
SpinnerLocalDateTimeModel
- 内部で、
Date
ではなく、LocalDateTime
を使用するSpinnerLocalDateTimeModel
(AbstractSpinnerModel
を継承)を作成LocalDateTime d = LocalDateTime.now(); LocalDateTime s = d.minus(2, ChronoUnit.DAYS); LocalDateTime e = d.plus(7, ChronoUnit.DAYS); JSpinner spinner2 = new JSpinner(new SpinnerLocalDateTimeModel( d, s, e, ChronoUnit.DAYS));
- スピナーエディタも、以下のような
LocalDateTime
を扱うものに変更class LocalDateTimeEditor extends JSpinner.DefaultEditor { private final DateTimeFormatter dateTimeFormatter; public LocalDateTimeEditor(final JSpinner spinner, String dateFormatPattern) { super(spinner); if (!(spinner.getModel() instanceof SpinnerLocalDateTimeModel)) { throw new IllegalArgumentException("model not a SpinnerLocalDateTimeModel"); } dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormatPattern); final SpinnerLocalDateTimeModel model = (SpinnerLocalDateTimeModel) spinner.getModel(); EventQueue.invokeLater(new Runnable() { @Override public void run() { DefaultFormatter formatter = new InternationalFormatter(dateTimeFormatter.toFormat()) { @Override public String valueToString(Object value) throws ParseException { //System.out.println(value.getClass().getName()); if (value instanceof LocalDateTime) { return ((LocalDateTime) value).format(dateTimeFormatter); } else { return ""; } } @Override public Object stringToValue(String text) throws ParseException { //System.out.println("stringToValue:" + text); try { return LocalDate.parse(text, dateTimeFormatter).atStartOfDay(); } catch (Exception e) { // PENDING: e.printStackTrace(); } return text; } }; formatter.setValueClass(LocalDateTime.class); DefaultFormatterFactory factory = new DefaultFormatterFactory(formatter); JFormattedTextField ftf = (JFormattedTextField) getTextField(); try { String maxString = formatter.valueToString(model.getStart()); String minString = formatter.valueToString(model.getEnd()); ftf.setColumns(Math.max(maxString.length(), minString.length())); } catch (ParseException e) { // PENDING: hmuller } ftf.setHorizontalAlignment(JTextField.LEFT); ftf.setEditable(true); ftf.setFormatterFactory(factory); } }); } public SpinnerLocalDateTimeModel getModel() { return (SpinnerLocalDateTimeModel) getSpinner().getModel(); } }
- 内部で、