【发布时间】:2013-10-31 17:40:49
【问题描述】:
我有一个JList 受DefaultListModel 支持,并有一个自定义CellRenderer。
CellRenderer 用于在我的JList 中添加对JCheckBox 的支持。
当我尝试修改 DefaultListModel 中某个元素的选中状态时,它似乎不会更新我的 JList。当我尝试使用以下三种方法中的任何一种来获取某个索引处的元素时,就会发生这种情况:DefaultListModel.elementAt(...)、DefaultListModel.get(...) 或 DefaultListModel.getElementAt(...)。
为什么我的JList 没有收到更新?
JList 部分中被注释掉的代码部分将起作用。但是,我不喜欢仅仅为了更改布尔值而将新对象复制到该位置。
这是我的代码,为了便于阅读和理解而进行了简化。
JList 部分
public AppsPanel() {
super(new BorderLayout());
this.appsListModel = new DefaultListModel<AppListItem>();
this.appsList = new JList<AppListItem>(this.appsListModel);
this.appsList.setCellRenderer(new AppsListRenderer());
this.appsList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JList list = (JList) e.getSource();
int index = list.locationToIndex(e.getPoint());
AppListItem appListItem = (AppListItem)list.getModel().getElementAt(index);
appListItem.setSelected(!appListItem.isSelected());
list.repaint(list.getCellBounds(index, index));
}
});
this.appsScrollPane = new JScrollPane(this.appsList);
this.add(this.appsScrollPane);
}
...
public void selectAllApps() {
// for (int i = 0; i < this.appsListModel.size(); i++) {
// this.appsListModel.set(i, new AppListItem(this.appsListModel.get(i).getApp(), true));
// }
for (int i = 0; i < this.appsListModel.size(); i++) {
this.appsListModel.getElementAt(i).setSelected(true);
}
}
CellRenderer 部分。
public class AppsListRenderer extends JCheckBox implements ListCellRenderer<AppListItem> {
@Override
public Component getListCellRendererComponent(JList<? extends AppListItem> list, AppListItem value, int index, boolean isSelected, boolean cellHasFocus) {
this.setSelected(value.isSelected());
if (value.getApp() != null) {
this.setText(value.getApp().getAppName());
}
return this;
}
}
AppListItempojo
public class AppListItem {
private App app;
private boolean selected;
public AppListItem(App app, boolean selected) {
this.app = app;
this.selected = selected;
}
public App getApp() {
return app;
}
public void setApp(App app) {
this.app = app;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
Apppojo
public class App {
private String appName;
private String appPath;
public App(String appName, String appPath) {
this.appName = appName;
this.appPath = appPath;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppPath() {
return this.appPath;
}
public void setAppPath(String appPath) {
this.appPath = appPath;
}
}
【问题讨论】:
-
请解释为什么 JCheckBox 在 non_editable JList 中呈现 JComponents
-
默认布尔值存储在 XxxXxxModel 中,表示 JCheckBox 作为渲染 JComponents
-
很难理解您的 cmets。 =/
-
您的
selectAllApps()不会触发任何事件。由于您无法在默认模型上调用fire…方法之一,因此您至少应该在更新后在JList上调用repaint。但我建议实现你自己的模型;没那么难。 -
扩展
AbstractListModel。您只需要实现两种方法,这在委托给List时很容易,例如ArrayList或LinkedList。当然,然后添加您自己的方法。
标签: java swing jlist jcheckbox defaultlistmodel