[英]Modifying element in DefaultListModel not updating model
I have a JList
that is supported by a DefaultListModel
and has a custom CellRenderer
. 我有一个
DefaultListModel
支持的JList
,并且有一个自定义CellRenderer
。
The CellRenderer
is for adding support for JCheckBox
in my JList
. CellRenderer
用于在我的JList
添加对JCheckBox
支持。
When i try to modify the checked state for an element in the DefaultListModel
it does not appear to update my JList
. 当我尝试修改
DefaultListModel
某个元素的选中状态时,它似乎没有更新我的JList
。 This happens when i try to use any of the three methods to get the element at a certain index: DefaultListModel.elementAt(...)
, DefaultListModel.get(...)
or DefaultListModel.getElementAt(...)
. 当我尝试使用三种方法中的任何一种以某个索引获取元素时,就会发生这种情况:
DefaultListModel.elementAt(...)
, DefaultListModel.get(...)
或DefaultListModel.getElementAt(...)
。
Why is my JList
not getting the update? 为什么我的
JList
没有得到更新?
The section of code below in my JList
section that is commented out, will work. 在我的
JList
部分中被注释掉的下面的代码部分将起作用。 But, i do not like having to copy a new object into that position just to change the boolean. 但是,我不喜欢将新对象复制到该位置以更改布尔值。
Here is my code, simplified for easy reading and understanding. 这是我的代码,经过简化以方便阅读和理解。
JList
section 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
section. 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 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 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;
}
}
Your selectAllApps()
does not trigger any event. 您的
selectAllApps()
不会触发任何事件。 Since you can't invoke one of the fire…
methods on the default model you should at least invoke repaint
on the JList
after the update. 由于您无法在默认模型上调用
fire…
方法之一,因此至少应在更新后在JList
上调用repaint
。
But I recommend implementing your own model; 但我建议您实施自己的模型; it's not that hard.
这并不难。
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);
}
}
Use the following method of AbstractListModel, at the point where you want the change to be applied to JList. 在要将更改应用于JList的点上,使用AbstractListModel的以下方法。
fireContentsChanged (model, changeStartIndex, changeEndIndex);
The changed elements are specified by the closed interval changeStartIndex, changeEndIndex-- the endpoints are included. 更改的元素由封闭间隔changeStartIndex,changeEndIndex指定-包括端点。
Example: http://www.javafaq.nu/java-example-code-674.html 范例: http : //www.javafaq.nu/java-example-code-674.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.