动态编辑JCombobox中的项目

时间:2014-07-19 00:27:23

标签: java swing jcombobox

我这里有一个小问题。 我有一个带有许多不可编辑的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)但是我不能保持列表中项目的相同位置。 有什么建议??

2 个答案:

答案 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);
    }
}