JList的ListCellRenderer不打印DefaultListModel

时间:2016-05-10 10:29:44

标签: java swing jscrollpane jlist defaultlistmodel

我有一个JScrollPane小组JList mediaList。列表的内容由DefaultListModel维护。在通过JDBC(Sqlite 3)

进行查询后,我获得了新的列表模型

我遇到一个问题,当新生成的模型的大小大于先前获取的模型的大小时,滚动窗格不会绘制模型的新索引。

//代码段

label.addMouseListener (new MouseAdapter() {
    DefaultListModel<HashMap<String,String>> mediaModel=new DefaultListModel<>();
    mediaModel=mProvider.getNextMenu(paramsCid); // new DefaultListModel

    medialist = new JList(mediaModel);
    medialist.setOpaque(false);         
    medialist.setCellRenderer(new MediaCellRenderer());

    panel = new JScrollPane(medialist);
    panel.setPreferredSize(new Dimension(300,300));
    pane1.setOpaque(true);
});

class MediaCellRenderer implements ListCellRenderer {
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        System.out.println("index: "+index);
        JLabel menuTextLabel = new JLabel(mediaModel.get(index).get("title"));
        return menuTextLabel;
    }
}

MediaCellRenderer的长度为2时,已观察到mediaModel打印在索引之下

index: 0  
index: 1

但是,当mediaModel的长度为3时,它会打印在索引之下

index: 0  
index: 1  
index: 0 // it prints 0 instead of 2

任何人都可以帮忙解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

首先,您的渲染代码不正确。你不应该创建一个新的JLabel。使用渲染器的想法是为JList中的所有项共享相同的渲染器。这使它更有效率。有关详细信息,请阅读Using a Custom Renderer上Swing教程中的部分。请注意,您需要按照指向实际渲染器示例代码的组合框教程的链接。

  

但是,当mediaModel的长度为3时,它会打印在索引之下

问题是您尚未将新的ListModel添加到GUI。

mediaModel=mProvider.getNextMenu(paramsCid);
medialist = new JList(mediaModel);
medialist.setOpaque(false);         
medialist.setCellRenderer(new MediaCellRenderer());

panel = new JScrollPane(medialist);
panel.setPreferredSize(new Dimension(300,300));
pane1.setOpaque(true);

上面创建了一个新的JScrollPane,但是你还没有将滚动窗格添加到框架中。

更好的解决方案是使用新的JList更新ListModel

mediaModel=mProvider.getNextMenu(paramsCid);
mediaList.setModel( mediaModel );
//medialist = new JList(mediaModel);
//medialist.setOpaque(false);         
//medialist.setCellRenderer(new MediaCellRenderer()); // may need this as well?

//panel = new JScrollPane(medialist);
//panel.setPreferredSize(new Dimension(300,300));
//pane1.setOpaque(true);

这将使用新的JList更新现有的滚动窗格。