修改DefaultListModel中的元素而不更新模型

时间:2013-10-31 17:40:50

标签: java swing jlist jcheckbox defaultlistmodel

JList支持DefaultListModel,并且自定义为CellRenderer

CellRenderer用于在JCheckBox中添加对JList的支持。

当我尝试修改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;
    }
}

2 个答案:

答案 0 :(得分:2)

您的selectAllApps()不会触发任何事件。由于您无法在默认模型上调用其中一个fire…方法,因此您应该在更新后至少在repaint上调用JList

但我建议您实施自己的模型;这并不难。

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

答案 1 :(得分:1)

使用AbstractListModel的以下方法,在您希望将更改应用于JList的位置。

fireContentsChanged (model, changeStartIndex, changeEndIndex);

更改的元素由闭合间隔changeStartIndex指定,changeEndIndex--包含端点。

实施例: http://www.javafaq.nu/java-example-code-674.html

相关问题