Pure Java 8 without IDE. I have a Problem creating a JComboBox with Custom Model without Warnings because of Generics. My goal is to have a dynamic Object List, where the Name of the Objects is displayed in the JComboBox and can be selected there. The Data Objects are in a DataLink Class with several Properties and one Method toString() that returns the Name of the Object as String. Then I have a Custom ComboBoxModel called ComboModel. It extends AbstractListModel and implements ComboBoxModel. It operates with items of the Object Class that it holds in a ArrayList. It holds the selectedIndex value and overrides the 4 Methods getElementAt(), getSize(), getSelectedItem(), setSelectedItem(). Additinally it implemtes clear(), size(), get(), add() and remove() to operate on the arrayList. Then I have a DataLinkModel class (this additionally implements Methods to act as a JTableModel as well, but not important here and now). It uses the beforementioned ComboModel to store its Elements, that are of type DataLink. It has a Method public ComboModel getComboList(), to return the ComboModel, to pass it to a JComboBox Constructor or setModel() Method. The DataLinkModel is created in a DataClass as dataLink that has a Method public ComboModel getDataLinkComboList() that returns dataLink.getComboList(). In a JFrame I have now this declaration and instancing (the DataClass is instanced before):
JComboBox<String> comboDataObject;
comboDataObject = new JComboBox<>((ComboBoxModel<String>)dataClass.getDataLinkComboList()); // Line 3649
this syntax gives (with Xlint:unchecked):
AppFrame.java:3649: warning: [unchecked] unchecked cast required: ComboBoxModel<String> found: ComboModel 1 warning
I tried that with givin the type as DataLink, or ComboModel, or DataLinkModel in different combinations. Sometimes I get two Warnings, sometimes one, but always warnings. I dont have a clue how to tell the Type. Skipping the cast warns for unchecked conversion. At least its a String that is coming from the toString() Method in the DataLink Object that should be shown in the JComboBox. In looked here and googled, I only found string[] solutions, never complex object lists.
Beside the warnings the app works as expected.
How do I instanciate correctly?
Code Structure (not compilable, but could make the description clear):
public class DataLink {
... several properties, getter, setter
public String toString() {
return name;
}
}
class ComboModel extends AbstractListModel implements ComboBoxModel {
List<Object> data;
int selectedIndex;
public ComboModel() {
data = new ArrayList<Object>();
selectedIndex = -1;
}
public Object getElementAt(int index) // Overides operate on data list
public int getSize()
public Object getSelectedItem()
public void setSelectedItem(Object anItem)
// Custom methods:
public void clear()
public int size()
public Object get(int index)
public void add(Object object)
public void remove(int index) // remove, add and clear after data change have: fireContentsChanged(this, -1, -1);
}
public class DataLinkModel extends AbstractTableModel {
ComboModel comboList;
public DataLinkModel() {
comboList = new ComboModel();
}
public ComboModel getComboList() {
return comboList;
}
... some methods to extend abstractTableModel
... methods as proxie methods that operate on the comboList(add, remove etc).
}
public class DataClass {
DataLinkModel dataLink;
...
public DataClass() {
dataLink = new DataLinkModel();
createDataInDataLink();
}
public ComboModel getDataLinkComboList() {
return dataLink.getComboList();
}
...
}
Thanks, Frankie
You are getting warnings because of raw types in your ComboModel
(List<Object>
), but trying to cast it to ComboBoxModel<String>
. This unchecked cast causes the compiler warning.
To fix warnings in your code, try to parameterise your ComboModel
with a generic type, as shown below
class ComboModel<T> extends AbstractListModel<T> implements ComboBoxModel<T> {
List<T> data = new ArrayList<>();
int selectedIndex = -1;
public T getElementAt(int index) { return data.get(index); }
public int getSize() { return data.size(); }
public T getSelectedItem() { return selectedIndex >= 0 ? data.get(selectedIndex) : null; }
public void setSelectedItem(Object anItem) { selectedIndex = data.indexOf(anItem); }
// Custom methods
public void clear() { data.clear(); fireContentsChanged(this, -1, -1); }
public int size() { return data.size(); }
public T get(int index) { return data.get(index); }
public void add(T object) { data.add(object); fireContentsChanged(this, -1, -1); }
public void remove(int index) { data.remove(index); fireContentsChanged(this, -1, -1); }
}
Then, use it as shown below.
The JComboBox
will display the names via toString()
and no cast or warning is needed.
ComboModel<DataLink> model = dataClass.getDataLinkComboList();
// assuming return type is ComboModel<DataLink>
JComboBox<DataLink> combo = new JComboBox<>(model);