Search code examples
javaswingjlistdefaultlistmodel

How to dynamicly add elemnts to a JList / DefaultListModel


I'm want to dynamic add elements to my DefaultListModel / JList but the list needs to emptied first. I do this opening an dialog-window . My problem is that when I use model.removeAllElements() my dialog-window reappears multiple times. What am i doing wrong?

I also tried model.addElementAt(index) to bypass model.removeAllElements() but the result is the same.

private javax.swing.JList serviceList;
serviceList.setModel(model);
serviceList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
serviceList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
serviceList.setSelectionBackground(java.awt.Color.white);
serviceList.setVisibleRowCount(3);
serviceList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
        public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
            serviceListValueChanged(evt);
        }
    });

 private void serviceListValueChanged(javax.swing.event.ListSelectionEvent evt) {                                         
    showTasksDialog();
}

showTasksDialog(): open a dialog-window with 3 buttons when the user clicks the first one it connects to a URL then the List is updated by filllst().

public void showTasksDialog() {
    int selection = serviceList.getSelectedIndex();
    Object[] options = {"Analyse", "Build", "Stop"};
    int n = taskDialog.showOptionDialog(this,
            "What should this Service do?",
            "",
            JOptionPane.YES_NO_CANCEL_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null,
            options,
            null);
    if (n == 0) {
        try {
            connection.setSlaveToAnalyse(serviceURLJSONArray.getString(selection));
            filllist();
        } catch (JSONException | IOException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

filllist(): should remove all elements from my default list and the refill it, but if I use model.removeAllElements() the Dialog-windows reappears multiple times. When I don't use removeAllElements then everything is fine but the list is not emptied

public void filllist() throws JSONException, IOException {        
    model.removeAllElements();
    serviceURLJSONArray = connection.getSlaves();
    for (int i = 0; i < serviceURLJSONArray.length(); i++) {
        String slaveStatus = new Connection().getSlaveStatus(serviceURLJSONArray.getString(i));
        model.addElement("Service " +(i+1)+" "+slaveStatus);
    }
}

Solution

  • Remove listeners (or deactivate them) from the list before removing and adding elements, and then re-add the listeners when done.

    e.g.,

    public void filllist() throws JSONException, IOException {        
    
        // remove all listeners
        ListSelectionListener[] listeners = serviceList.getListSelectionListeners();
        for (ListSelectionListener l : listeners) {
            serviceList.removeListSelectionListener(l);
        }
    
        // do your work
        model.removeAllElements();
        serviceURLJSONArray = connection.getSlaves();
        for (int i = 0; i < serviceURLJSONArray.length(); i++) {
            String slaveStatus = new Connection().getSlaveStatus(serviceURLJSONArray.getString(i));
            model.addElement("Service " +(i+1)+" "+slaveStatus);
        }
    
        // add them back
        for (ListSelectionListener l : listeners) {
            serviceList.addListSelectionListener(l);
        }
    
    }