Come promesso, ecco qui un semplice esempio per un combo box model "sorted" (ordinato) per date Calendar.
Questa è la implementazione del ComboBoxModel:
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
public class SortedDateComboBoxModel extends AbstractListModel implements ComboBoxModel {
private List<DateItem> dateItems;
private DateFormat dateFormat;
private Object selectedItem;
public SortedDateComboBoxModel(DateFormat dateFormat) {
dateItems = new ArrayList<DateItem>();
this.dateFormat = dateFormat;
}
@Override
public int getSize() {
return dateItems.size();
}
@Override
public Object getElementAt(int index) {
return dateItems.get(index);
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
@Override
public void setSelectedItem(Object item) {
if ((selectedItem != null && !selectedItem.equals(item)) ||
selectedItem == null && item != null) {
selectedItem = item;
fireContentsChanged(this, -1, -1);
}
}
// Metodi extra
public void addDate(Calendar calendar) {
DateItem dateItem = new DateItem(calendar);
int index = Collections.binarySearch(dateItems, dateItem);
if (index < 0) {
index = -index - 1;
}
dateItems.add(index, dateItem);
fireIntervalAdded(this, index, index);
}
// altri metodi extra possibili: getDateAt, clear, removeDateAt, setDateFormat, ecc....
private class DateItem implements Comparable<DateItem> {
private Calendar calendar;
private String formattedDate;
public DateItem(Calendar calendar) {
setCalendar(calendar);
}
public Calendar getCalendar() {
return calendar;
}
public void setCalendar(Calendar calendar) {
this.calendar = calendar;
updateFormattedDate();
}
public void updateFormattedDate() {
formattedDate = dateFormat.format(calendar.getTime());
}
public String toString() {
return formattedDate;
}
@Override
public int compareTo(DateItem otherItem) {
return getCalendar().compareTo(otherItem.getCalendar());
}
}
}
E questo è un semplice frame di test:
import java.awt.BorderLayout;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class SortedDateComboDemoFrame extends JFrame {
private SortedDateComboBoxModel model;
private JComboBox dateComboBox;
public SortedDateComboDemoFrame() {
super("Sorted Date Combo Demo Frame");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
model = new SortedDateComboBoxModel(df);
dateComboBox = new JComboBox(model);
model.addDate(new GregorianCalendar(2015, Calendar.MARCH, 10));
model.addDate(new GregorianCalendar(2015, Calendar.MARCH, 25));
model.addDate(new GregorianCalendar(2015, Calendar.FEBRUARY, 9));
model.addDate(new GregorianCalendar(2015, Calendar.JULY, 18));
model.addDate(new GregorianCalendar(2015, Calendar.JANUARY, 5));
model.addDate(new GregorianCalendar(2015, Calendar.MARCH, 22));
getContentPane().add(dateComboBox, BorderLayout.NORTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SortedDateComboDemoFrame().setVisible(true);
}
});
}
}
Le date di test sono inserite "a casaccio" ma nella combo risultano ordinate. Anche se in seguito, a fronte di un evento, si aggiunge una data con il addDate, essa verrà inserita nel punto "giusto" per mantenere l'ordine.
Ovviamente il model che ho fatto è abbastanza basilare e sarebbe altamente espandibile con altri metodi aggiuntivi (vedi quelli che ho citato nel codice).