2013-12-20 31 views
0

我研究並試圖從包含發佈者對象的數組列表動態地填充jcombobox。我試圖實現渲染器,以便使用getName()方法顯示發佈者名稱。組合框顯示程序運行時的名稱,但是,如果新的發佈服務器隨後被添加到ArrayList中,則組合框將變爲空白。使用自定義渲染器在jComboBox中顯示值的錯誤

創建型號:

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

} 

創建渲染:

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

Before Addding new Publisher

After adding new Publisher

+0

當您將一個新的'Publisher'添加到列表中時,您是否可以演示此問題... – MadProgrammer

+0

@MadProgrammer嗨,我已編輯帖子以顯示該問題。 – Zak

+0

您是否有可重現此問題的可運行示例? (我們可以玩) – MadProgrammer

回答

1

這未必是一個答案,但突出了潛在的問題

在瀏覽您的代碼時,我注意到您的組合框模型只是維護對原始列表的引用。這不一定是一個問題,但可能會導致一些意想不到的和潛在的,不想要的行爲...

主要問題是,組合框模型不知道列表更改時,因此它不能告訴組合框它應該更新。

一般情況下,我通常會做的是做一個新的List原始列表。這意味着如果原件更新,它不會導致模型和組合框出現問題。

我會再加入突變的功能組合框模型,它可以被更新,例如...

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; 
    } 
} 

有幾種替代這種想法。您可以創建一個「常規」模型,列出發佈商,但向感興趣的各方提供了事件通知,因此當您從此模型中添加或刪除發佈商時,相關方(例如組合框模型)將被通知並有機會更新自己並將適當的通知轉發給其相關方。

就個人而言,在更大規模的應用程序中,這是我的首選方法。

另一種方法是提供直接通知組合框模型...

那,你將維持現有列表的引用,你是,但組合框模型將有方法,你可以打電話給它然後可以轉發。

相關問題