How to bind a List (one or more times)?
I follow开发者_StackOverflow社区 the Presentation Model pattern for coding some screens.
- I store some Beans in an
ArrayList
- I will display the content of this List in a
JTable
, thanks to anAbstractTableModel
- I also want to display some records from this list in a Combo Box (in a form) and some others in a JList, at the same time
- These three screens (and their model) are independent from each other
How to manage add {one or more}/remove {one or more} on my List and view changes in "real-time" everywhere?
I'm about to write my own ObservableList or implement that around an EventDispatcher... What do you think?
PS:
- I know that in C# the
BindingList
helps for that purpose, what about Java? - I'm already able to display updates of each bean, thanks to
PropertyChangeSupport
.
Let your AbstractTableModel
implement ListModel
, which is usable with both JComboBox and
JList. You can forward methods to the default model implementations as required.
Addendum: SharedModelDemo
, mentioned in How to Use Tables, is an example that may get you started. It extends DefaultListModel implements TableModel
, while you should do extends AbstractTableModel implements ListModel
Addendum: For reference, here's an outline of the minimal implementation and three test instantiations. I've used the default combo and list implementations, but you can use the corresponding abstract implementations if necessary.
public class SharedModel extends AbstractTableModel
implements ComboBoxModel, ListModel {
private ComboBoxModel comboModel = new DefaultComboBoxModel();
private ListModel listModel = new DefaultListModel();
//ComboBoxModel
@Override
public void setSelectedItem(Object anItem) {
comboModel.setSelectedItem(anItem);
}
@Override
public Object getSelectedItem() {
return comboModel.getSelectedItem();
}
// ListModel
@Override
public int getSize() {
return listModel.getSize();
}
@Override
public Object getElementAt(int index) {
return listModel.getElementAt(index);
}
@Override
public void addListDataListener(ListDataListener l) {
listModel.addListDataListener(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listModel.removeListDataListener(l);
}
// TableModel
@Override
public int getRowCount() {
return 0;
}
@Override
public int getColumnCount() {
return 0;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return null;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SharedModel sm = new SharedModel();
JTable table = new JTable(sm);
JList list = new JList(sm);
JComboBox check = new JComboBox(sm);
}
});
}
}
For the JComboBox and the JList you could simply reference sections of the ArrayList using the subList() method. This will work if you can easily identify the starting and ending locations within the ArrayList and the elements you need are sequential.
If the situation is more dynamic than that you could implement custom List classes that took the ArrayList in the constructor and then apply whatever logic you need to return the appropriate records.
精彩评论