JList 的 ListCellRenderer 不打印 DefaultListModel 的正确索引
JList's ListCellRenderer not printing the proper index of the DefaultListModel
我有一个带有 JList mediaList
的 JScrollPane
面板。列表的内容由 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
在 mediaModel
的长度为 2
时打印在索引下方
index: 0
index: 1
但是,当 mediaModel 的长度为 3 时,它会在索引下方打印
index: 0
index: 1
index: 0 // it prints 0 instead of 2
谁能帮忙解决这个问题?
首先你的渲染代码不正确。您不应该创建新的 JLabel。使用渲染器的想法是为 JList 中的所有项共享相同的渲染器。这使它更有效率。阅读 Using a Custom Renderer 上的 Swing 教程部分以获取更多信息。请注意,您需要按照 link 的组合框教程来获取实际的渲染器示例代码。
But, it prints below index when length of mediaModel is 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,但您还没有将滚动窗格添加到框架中。
更好的解决方案是只用新的 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 更新现有的滚动窗格。
我有一个带有 JList mediaList
的 JScrollPane
面板。列表的内容由 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
在 mediaModel
的长度为 2
index: 0
index: 1
但是,当 mediaModel 的长度为 3 时,它会在索引下方打印
index: 0
index: 1
index: 0 // it prints 0 instead of 2
谁能帮忙解决这个问题?
首先你的渲染代码不正确。您不应该创建新的 JLabel。使用渲染器的想法是为 JList 中的所有项共享相同的渲染器。这使它更有效率。阅读 Using a Custom Renderer 上的 Swing 教程部分以获取更多信息。请注意,您需要按照 link 的组合框教程来获取实际的渲染器示例代码。
But, it prints below index when length of mediaModel is 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,但您还没有将滚动窗格添加到框架中。
更好的解决方案是只用新的 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 更新现有的滚动窗格。