简体   繁体   English

使用自定义渲染器在jComboBox中显示值时出错

[英]Error using custom renderer to show value in jComboBox

I have researched and attempted to fill a jcombobox dynamically from an arraylist containing Publisher Objects. 我已经研究并尝试从包含Publisher对象的数组列表中动态填充jcombobox。 I have tried to implement a renderer in order to show the Publishers name using the getName() method. 我试图实现一个渲染器,以便使用getName()方法显示发布者的名称。 The combobox shows the names when the program is run, however, if a new Publisher is then added to the ArrayList, the combobox becomes blank. 组合框显示程序运行时的名称,但是,如果随后将新的Publisher添加到ArrayList,则组合框将变为空白。

Creating Model: 创建模型:

public class PublisherComboBoxModel implements ComboBoxModel{

protected List<Publisher> publishers;

public PublisherComboBoxModel(List<Publisher> list) {
    this.listeners = new ArrayList();
    this.publishers = list;
    if(list.size() > 0) {
        selected = list.get(0);
    }     
}

protected Object selected;
@Override
public void setSelectedItem(Object item) {
    this.selected = item;
}
@Override
public Object getSelectedItem() {
    return this.selected;
}

@Override
public Object getElementAt(int index) {
    return publishers.get(index);
}
@Override
public int getSize() {
    return publishers.size();
}

protected List listeners;
@Override
public void addListDataListener(ListDataListener l) {
    listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
    this.listeners.remove(l);
}

}

Creating renderer: 创建渲染器:

jComboBoxPublisher.setModel(publisherComboModel);
jComboBoxPublisher.setRenderer(new DefaultListCellRenderer() {
    @Override
    public Component getListCellRendererComponent(JList list,
                                           Object value,
                                           int index,
                                           boolean isSelected,
                                           boolean cellHasFocus) {
        Publisher publisher = (Publisher)value;
        if(value!=null)
        {
            value = publisher.getName();
        }
        return super.getListCellRendererComponent(list, value,
            index, isSelected, cellHasFocus);
    }

在添加新发布者之前

添加新的发布者之后

This is not necessarily an answer, but highlights a potential problem 这不一定是答案,而是突出了潜在的问题

While skimming over your code, I noticed that you combo box model is simply maintaining a reference to the original list. 浏览代码时,我注意到组合框模型只是在维护对原始列表的引用。 This isn't necessarily a problem, but may result in some unexpected and potentially, unwanted behaviour... 这不一定是问题,但可能会导致一些意外的和潜在的有害行为……

The main problem, is that the combo box model has no idea when the list is changed, therefore it can't tell combo box that it should updated. 主要问题在于,组合框模型不知道何时更改列表,因此无法告诉组合框应更新列表。

Generally, what I would normally do is make a new List of the original list. 一般情况下,我通常会做的是使一个新的List原来的名单。 This means that if the original is updated, it won't cause issues for the model and and combo box. 这意味着,如果原始文件被更新,则不会导致模型和组合框出现问题。

I would then add mutation functionality to the combo box model so it could be updated, for example... 然后,我将突变功能添加到组合框模型,以便可以对其进行更新,例如...

public class PublisherComboBoxModel extends AbstractListModel implements ComboBoxModel {

    private List<Publisher> publishers;
    private Publisher selectedItem;

    public PublisherComboBoxModel(List<Publisher> publishers) {
        this.publishers = new ArrayList<>(publishers);
    }

    public void addPublisher(Publisher pub) {

        publishers.add(pub);
        fireIntervalAdded(this, publishers.size() - 1, publishers.size() - 1);

    }

    @Override
    public int getSize() {            
        return publishers.size();            
    }

    @Override
    public Object getElementAt(int index) {            
        return publishers.get(index);        
    }

    @Override
    public void setSelectedItem(Object anItem) {            
        selectedItem = (Publisher) anItem;            
    }

    @Override
    public Object getSelectedItem() {
        return selectedItem;
    }
}

There are several alternatives to this idea. 这个想法有几种选择。 You could create a "general" model, which listed the publishers, but provided event notification to interested parties, so when you added or removed publishers from this model, interested parties, like the combo box model, would be notified and have an opportunity to update themselves and forward appropriate notifications to their interested parties. 您可以创建一个“通用”模型,该模型列出了发布者,但向感兴趣的参与者提供了事件通知,因此,当您从该模型中添加或删除发布者时,将通知感兴趣的参与者,如组合框模型,并有机会更新自己,并将适当的通知转发给他们感兴趣的各方。

Personally, in larger scaled applications, this is my preferred approach. 就个人而言,在较大规模的应用程序中,这是我的首选方法。

Another approach would be to provide the combo box model with direct notification... 另一种方法是为组合框模型提供直接通知。

Thats, you would maintain a reference to the existing list as you are, but the combo box model would have methods that you could call which it could then forward on. 就是说,您将按原样维护对现有列表的引用,但是组合框模型将具有您可以调用的方法,然后可以将其转发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM