Search code examples
javaswtjface

Java SWT remove element from ListViewer


I'm writing a GUI with SWT. You can choose file/s by click on button(like Browse) and they added to a ListViewer by their name. I've created new button to remove files from the list but its dont work for me. This is the needed piece of codes I guess:

    ListViewer listViewer = new ListViewer(shlPmcompare, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
    List list = listViewer.getList();
    list.setBounds(331, 11, 305, 100);

    btnBrowse.addSelectionListener(new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e) {
            FileDialog fileBrowse = new FileDialog(shlPmcompare, SWT.MULTI);
            fileBrowse.setFilterExtensions(new String[] {"*.txt"});
            String filePath = fileBrowse.open();
            if (filePath != null) {
                StringBuffer buf = new StringBuffer();
                String[] files = fileBrowse.getFileNames();
                for (int i = 0, n = files.length; i < n; i++) {
                  buf.append(fileBrowse.getFilterPath());
                  if (buf.charAt(buf.length() - 1) != File.separatorChar) {
                    buf.append(File.separatorChar);
                  }
                  buf.append(files[i]);
                  buf.append("\n");
                }
                for (int i = 0, n = files.length; i < n; i++) {
                    list.add(files[i], 0);
                }
            }
        }
    });

    btnRemoveFile.addSelectionListener(new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e) {
            IStructuredSelection selectionFile = (IStructuredSelection)listViewer.getSelection();
            List RemoveFile = (List)selectionFile.getFirstElement();
            if(RemoveFile == null) {
                MessageDialog.openError(shlPmcompare, "Removing Error", "You need to select file first.");
                return;
            }
            list.remove(RemoveFile);
            listViewer.refresh(false);
        }
    });

Solution

  • When you are using a JFace viewer like ListViewer with a few exceptions you should not call any methods on the underlying control (List in this case). The viewer manages the control and you should only uses the viewer's methods to change it.

    To remove a selection from the list you call the ListViewer remove method, not List.remove.

    So this is a viewer which just displays some strings:

    ListViewer listViewer = new ListViewer(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
    listViewer.getList().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    
    listViewer.setContentProvider(ArrayContentProvider.getInstance());
    
    ArrayList<String> contents = new ArrayList<>();
    contents.add("a");
    contents.add("b");
    contents.add("c");
    
    listViewer.setInput(contents);
    
    Button btnRemoveFile = new Button(shell, SWT.PUSH);
    btnRemoveFile.setText("Remove");
    btnRemoveFile.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(final SelectionEvent e) {
          IStructuredSelection selectionFile = listViewer.getStructuredSelection();
          final Object removeFile = selectionFile.getFirstElement();
          // TODO check for no selection
    
          listViewer.remove(removeFile);
    
          contents.remove(removeFile);
      }
    });