[英]Modifying element in DefaultListModel not updating model
我有一个DefaultListModel
支持的JList
,并且有一个自定义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;
}
}
AppListItem
pojo
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;
}
}
App
pojo
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;
}
}
您的selectAllApps()
不会触发任何事件。 由于您无法在默认模型上调用fire…
方法之一,因此至少应在更新后在JList
上调用repaint
。
但我建议您实施自己的模型; 这并不难。
public class MyListModel extends AbstractListModel<AppListItem> {
ArrayList<AppListItem> list=new ArrayList<>();
public void selectAllApps() {
for(AppListItem i:list) i.setSelected(true);
fireContentsChanged(this, 0, getSize()-1);
}
public int getSize() {
return list.size();
}
public AppListItem getElementAt(int index) {
return list.get(index);
}
// if you need such updates:
public void add(int index, AppListItem item) {
list.add(index, item);
fireIntervalAdded(this, index, index);
}
public boolean remove(AppListItem i) {
int index = list.indexOf(i);
if(index<0) return false;
remove(index);
return true;
}
public void remove(int index) {
list.remove(index);
fireIntervalRemoved(this, index, index);
}
}
在要将更改应用于JList的点上,使用AbstractListModel的以下方法。
fireContentsChanged (model, changeStartIndex, changeEndIndex);
更改的元素由封闭间隔changeStartIndex,changeEndIndex指定-包括端点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.