我这里有一个小问题。 我有一个带有许多不可编辑的JComboBox的Swing UI。每个JComboBox都是从数据库中的特定表填充的。 用户可以编辑每个表的内容,我想要做的是根据用户在这些表中执行的操作(添加/删除/编辑)更新主JFrame中的JComboBox。
对于添加和删除项目没问题,我在相关的JComboBoxes模型中添加或删除该项目,一切顺利。
但是对于编辑,它不起作用。我在我的JCombobox模型中添加了一个方法,用一个新项替换以前的项,但无论我在这个方法中做什么(fireIntervalAdded(),fireIntervalRemoved(),或者它们两个都按任何顺序),编辑后的项目都显示在旧的状态。
以下是我的JComboBoxModels:
public class StringModel extends DefaultComboBoxModel
{
private ArrayList<String> lstStrings;
public StringModel()
{
super();
lstStrings = new ArrayList<String>();
}
public StringModel(ArrayList<String> lstStrings)
{
super();
lstStrings = new ArrayList<String>();
for (String string : lstStrings)
{
lstStrings.add(string);
}
}
protected ArrayList<String> getStrings()
{
return lstStrings;
}
public String getSelectedString()
{
return (String) getSelectedItem();
}
public void setSelectedString(String string)
{
setSelectedItem(string);
}
public Object getElementAt(int index)
{
return lstStrings.get(index);
}
public int getSize()
{
return lstStrings.size();
}
public int getIndexOf(Object element)
{
return lstStrings.indexOf(element);
}
}
和
public class ModifiableStringModel extends StringModel
{
public ModifiableStringModel()
{
super();
}
public ModifiableStringModel(ArrayList<String> lstStrings)
{
super(lstStrings);
}
public void clearStrings()
{
int oldSize = getStrings().size();
getStrings().clear();
fireIntervalRemoved(this, 0, oldSize);
}
public void addString(String string)
{
getStrings().add(string);
int size = getStrings().size();
fireIntervalAdded(this, size, size);
}
public void removeString(String string)
{
int position = getStrings().indexOf(string);
getStrings().remove(position);
fireIntervalRemoved(this, position, position);
}
public void replaceString(String oldString, String newString)
{
int position = getStrings().indexOf(oldString);
getStrings().remove(position);
fireIntervalRemoved(this, position, position);
getStrings().add(position, newString);
fireIntervalAdded(this, position, position);
}
public void removeAllStrings()
{
int positionStart=0;
int positionEnd = getStrings().size();
getStrings().clear();
fireIntervalRemoved(this, positionStart, positionEnd);
}
public ModifiableStringModel getModl()
{
return this;
}
}
有问题的方法是replaceString(String oldString,String newString)。 有人可能会争辩说我可以先删除(oldString)然后添加(newString)但是我不能保持列表中项目的相同位置。 有什么建议??
答案 0 :(得分:1)
而不是......
getStrings().remove(position);
fireIntervalRemoved(this, position, position);
getStrings().add(position, newString);
fireIntervalAdded(this, position, position);
有哪些与之相关的效率问题,你可以试试......
getStrings().set(position, newString);
fireContentsChanged(this, position, position);
,而不是...
您当前StringModel
似乎是浪费,因为DefaultComboBoxModel
已经拥有了自己的支持模型。相反,您可以从AbstractListModel
简单地扩展并实现ComboBoxModel
,这将为您提供更清晰的基类,例如......
public class StringComboBoxModel extends AbstractListModel<String> implements ComboBoxModel<String> {
private List<String> values;
private String selectedItem;
public StringComboBoxModel() {
this(new ArrayList<String>(25));
}
public StringComboBoxModel(List<String> values) {
this.values = values;
}
@Override
public int getSize() {
return values.size();
}
@Override
public String getElementAt(int index) {
return values.get(index);
}
@Override
public void setSelectedItem(Object anItem) {
if (anItem instanceof String) {
selectedItem = (String) anItem;
} else {
selectedItem = null;
}
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
protected List<String> getValues() {
return values;
}
}
public class MutableStringComboBoxModel extends StringComboBoxModel {
public MutableStringComboBoxModel() {
}
public MutableStringComboBoxModel(List<String> values) {
super(values);
}
public boolean contains(String value) {
return getValues().contains(value);
}
public void addValue(String value) {
getValues().add(value);
fireIntervalAdded(this, getSize() - 1, getSize() - 1);
}
public void replaceString(String oldString, String newString) {
if (contains(oldString)) {
int position = getValues().indexOf(oldString);
getValues().set(position, newString);
fireContentsChanged(this, position, position);
} else {
addValue(newString);
}
}
// Other management methods...
}
答案 1 :(得分:0)
正如MadProgrammer指出的那样,使用ArrayList.set()然后fireContentsChanged()完美地解决了手头的问题。顺便说一下,继承DefaultComboBoxModel 2次并不是一个好主意,所以我做了两种混合,解决了与之相关的一些问题。所以这是带有相关replaceString()方法的新JComboBox模型:
public class HybridComboModel extends DefaultComboBoxModel
{
private ArrayList<String> lstStrings;
public HybridComboModel()
{
super();
lstStrings = new ArrayList<String>();
}
public HybridComboModel(ArrayList<String> theListofStrings)
{
super();
lstStrings = new ArrayList<String>();
for (String string : theListofStrings)
{
lstStrings.add(string);
}
}
protected ArrayList<String> getStrings()
{
return lstStrings;
}
public String getSelectedString()
{
return (String) getSelectedItem();
}
public void setSelectedString(String string)
{
setSelectedItem(string);
}
public String getElementAt(int index)
{
return lstStrings.get(index);
}
public int getSize()
{
return lstStrings.size();
}
public int getIndexOf(String element)
{
return lstStrings.indexOf(element);
}
public void clearStrings()
{
int oldSize = getStrings().size();
getStrings().clear();
fireIntervalRemoved(this, 0, oldSize);
}
public void addString(String string)
{
getStrings().add(string);
int size = getStrings().size();
fireIntervalAdded(this, size, size);
}
public void removeString(String string)
{
int position = getStrings().indexOf(string);
getStrings().remove(position);
fireIntervalRemoved(this, position, position);
}
public void replaceString(String oldString, String newString)
{
int position = getStrings().indexOf(oldString);
getStrings().set(position, newString);
fireContentsChanged(this, position, position);
}
public void removeAllStrings()
{
int positionStart = 0;
int positionEnd = getStrings().size();
getStrings().clear();
fireIntervalRemoved(this, positionStart, positionEnd);
}
}