【问题标题】:JList's ListCellRenderer not printing the proper index of the DefaultListModelJList 的 ListCellRenderer 未打印 DefaultListModel 的正确索引
【发布时间】:2016-05-10 10:29:44
【问题描述】:

我有一个带有JList mediaListJScrollPane 面板。列表内容由DefaultListModel 维护。通过 JDBC (Sqlite 3) 进行查询后,我得到了新的列表模型

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

//代码sn-p

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

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

index: 0  
index: 1

但是,当 mediaModel 的长度为 3 时,它会打印在 index 下方

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

谁能帮忙解决这个问题?

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖 minimal reproducible exampleShort, Self Contained, Correct Example。硬编码一些数据来替换数据库。
  • 上述代码中的 getNextMenu 给出了以下形式的 DefaultlistModel: HashMap fieldList = new HashMap(); listModel.addElement(fieldList);
  • "..in 上面的代码给出了一个.." 别费心用文字解释了。我会更仔细地研究 MCVE。

标签: java swing jscrollpane jlist defaultlistmodel


【解决方案1】:

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

但是,当 mediaModel 的长度为 3 时,它会在 index 下方打印

问题是您还没有将新的 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,但是你还没有将滚动窗格添加到框架中。

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

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 更新现有的滚动窗格。

【讨论】:

    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    相关资源
    最近更新 更多