【发布时间】:2014-06-03 15:06:34
【问题描述】:
我为 JCombobox 创建了一个自定义模型,以使其与 LinkedHashMap 同步。我想创建一个可以与任何 LinkedHashMap 重用的模型(因此使用泛型)。当我使用我的应用程序运行它时,字符串无法出现。当我单击字符串应该在的位置时,动作侦听器会正确触发并且所选项目会更改。然而,下拉菜单不显示字符串?我知道它是基于 JList 的,所以我需要对 JLabels 等做任何花哨的事情吗?那也是模型的一部分吗?我还需要实现什么吗?
这是我的自定义模型
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import javax.swing.AbstractListModel;
import javax.swing.MutableComboBoxModel;
/**
* A model design to automatically update based of a the key values of a Hashmap
* @author Skylion
*
* @param <K> The generic representing key of the Hashmap
* @param <V> The generic representing the value of the Hashmap
*/
public class HashMapComboBoxModel<K, V> extends AbstractListModel<K> implements MutableComboBoxModel<K>,
Serializable {
/**
* Auto-generated
*/
private static final long serialVersionUID = -1293826656458176439L;
/**
* The Selected Item
*/
private K selectedItem;
LinkedHashMap<K,V> data;
public HashMapComboBoxModel(LinkedHashMap<K,V> data){
this.data = data;
}
@Override
public K getElementAt(int index) {
List<Entry<K,V>> randAccess = new ArrayList<Entry<K,V>>((Collection<? extends Entry<K, V>>) data.entrySet());
return randAccess.get(index).getKey();
}
@Override
public int getSize() {
return data.size();
}
@Override
public K getSelectedItem() {
return selectedItem;
}
@SuppressWarnings("unchecked")//Equals() implements the check
@Override
public void setSelectedItem(Object anItem) {
for(K keys: data.keySet()){
if(keys.equals(anItem)){
this.selectedItem = (K) anItem;
return;
}
}
}
@Override
public void addElement(Object obj) {
addElement(downcastToEntry(obj));
}
@SuppressWarnings("unchecked")
private Entry<K,V> downcastToEntry(Object obj){
if(obj instanceof Entry && obj.getClass().isAssignableFrom(
data.entrySet().iterator().next().getClass())){
return (Entry<K,V>)obj;
}
return null;
}
/**
* Adds an Entry value to the hashmap
* @param obj The Entry value you want to add
* @return return true if added false otherwise
*/
public boolean addElement(Entry<K,V> obj){
if(obj == null){return false;}
return this.data.entrySet().add(obj);
}
@Override
public void insertElementAt(Object obj, int index) {
Entry<K,V> entry = downcastToEntry(obj);
addToMapAtIndex(index, entry.getKey(), entry.getValue());
}
private void addToMapAtIndex(int index, K key, V value) {
assert (data != null);
assert !data.containsKey(key);
assert (index >= 0) && (index < data.size());
int i = 0;
List<Entry<K, V>> rest = new ArrayList<Entry<K, V>>();
for (Entry<K, V> entry : data.entrySet()) {
if (i++ >= index) {
rest.add(entry);
}
}
data.put(key, value);
for (int j = 0; j < rest.size(); j++) {
Entry<K, V> entry = rest.get(j);
data.remove(entry.getKey());
data.put(entry.getKey(), entry.getValue());
}
}
@Override
public void removeElement(Object obj) {
data.remove(obj);
}
@Override
public void removeElementAt(int index) {
data.remove(getElementAt(index));
}
}
这是我构建 JCombobox 的方式。
LinkedHashMap<String, myCustomClass> map = new LinkedHashMap<String, myCustomClass();
// 代码...代码...更多代码...
JCombobox box = new JCombobox<String>(new HashMapComboBoxModel<String,myCustomClass>(map));
//在代码后面
map.put("myString", myObject);
//JCombobox 更新,但是下拉框变白了。
【问题讨论】:
-
一个数据模型负责在其内容发生变化时发送事件。你完全错过了那部分。
-
为了尽快获得更好的帮助,请发布MCVE(最小完整且可验证的示例)。
标签: java swing generics jcombobox linkedhashmap