package com.revolsys.swing.field; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Closeable; import java.util.List; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import com.revolsys.identifier.Identifier; import com.revolsys.record.code.CodeTable; import com.revolsys.swing.parallel.Invoke; import com.revolsys.util.Property; import com.revolsys.util.Strings; public class CodeTableComboBoxModel extends AbstractListModel<Identifier> implements ComboBoxModel<Identifier>, PropertyChangeListener, Closeable { private static final long serialVersionUID = 1L; public static ComboBox<Identifier> newComboBox(final String fieldName, final CodeTable codeTable, final boolean allowNull, final boolean idSuffix) { final CodeTableComboBoxModel model = new CodeTableComboBoxModel(codeTable, allowNull); final ComboBox<Identifier> comboBox = ComboBox.newComboBox(fieldName, model, (id) -> { if (id == null || id == Identifier.NULL) { return null; } else { final List<Object> values = codeTable.getValues(id); if (values == null || values.isEmpty()) { return null; } else { final String string = Strings.toString(":", values); if (idSuffix) { return string + " (" + id + ")"; } else { return string; } } } }); return comboBox; } private final boolean allowNull; private CodeTable codeTable; private Object selectedItem; public CodeTableComboBoxModel(final CodeTable codeTable) { this(codeTable, true); } public CodeTableComboBoxModel(final CodeTable codeTable, final boolean allowNull) { this.codeTable = codeTable; this.allowNull = allowNull; Property.addListener(codeTable, "valuesChanged", this); } @Override public void close() { Property.removeListener(this.codeTable, "valuesChanged", this); this.codeTable = null; this.selectedItem = null; } @Override public void fireContentsChanged(final Object source, final int index0, final int index1) { Invoke.later(() -> super.fireContentsChanged(source, index0, index1)); } @Override public Identifier getElementAt(int index) { if (this.allowNull) { if (index == 0) { return Identifier.NULL; } index--; } if (index >= 0 && index < getSize()) { final List<Identifier> identifiers = this.codeTable.getIdentifiers(); return identifiers.get(index); } else { return null; } } @Override public Object getSelectedItem() { if (this.selectedItem == Identifier.NULL) { return null; } else { return this.selectedItem; } } @Override public int getSize() { if (this.codeTable == null) { return 0; } else { int size = this.codeTable.getIdentifiers().size(); if (this.allowNull) { size++; } return size; } } @Override public void propertyChange(final PropertyChangeEvent event) { if (event.getPropertyName().equals("valuesChanged")) { final int size = getSize(); fireContentsChanged(this, 0, size); } } @Override public void setSelectedItem(final Object item) { if (this.selectedItem != null && !this.selectedItem.equals(item) || this.selectedItem == null && item != null) { this.selectedItem = item; fireContentsChanged(this, -1, -1); } } }