Search code examples
swingmodel-view-controllerjlistselectedvalue

MVC+ SWING and a ListSelectionListener


What I am trying to do is get the selected value from my SWING View JList to my controller class, so I can use that data in my controller. For simplicity I manually added 2 elements to my JList("Item 1", "Item 2", (so I have something to pass)I seem to have a problem accessing it. My View has a JList with a ListSelectionListener which I pass to my controller via my main:

public class AppMain {

    private AppView appView = null;

    public static void main(String[] args) {
       AppView appView = new AppView();
       Controller controller = new Controller(appView);
    }

    public AppView getView() {
        return appView;
    }
}

My view is:

import javax.swing.event.ListSelectionListener;

public class AppView extends javax.swing.JFrame {

public AppView() {
    initComponents();
    this.setVisible(true);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    ValueList = new javax.swing.JList();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    ValueList.setModel(new javax.swing.AbstractListModel() {
        String[] strings = { "Item 1", "Item 2", " " };
        public int getSize() { return strings.length; }
        public Object getElementAt(int i) { return strings[i]; }
    });
    jScrollPane1.setViewportView(ValueList);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(75, 75, 75)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(63, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(45, 45, 45)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(27, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

// Variables declaration - do not modify                     
private javax.swing.JList ValueList;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration                   
public void ListSelectionListener(ListSelectionListener selectionListener) {
        ValueList.addListSelectionListener(selectionListener);
    }
}

And a Controller:

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Controller implements ListSelectionListener{

    AppView gui;
    public Controller(AppView v)
    {
    gui = v;
    gui.ListSelectionListener(this);
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {
    this.gui.ListSelectionListener(this);
    System.out.println("FOO");      
    }
}

No I want TO get the selectedValue in the Controller. I can't seem to grasp it. Also This prints Foo 3 times and I also cannot find out why.

Thanks in advance


Solution

  • As shown in How to Write a List Selection Listener more than one ListSelectionEvent may be generated as the user selects fist one entry and then another. Try checking when the selection is stable.

    if (!e.getValueIsAdjusting()) {
        // examine result
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();
        int minIndex = lsm.getMinSelectionIndex();
        int maxIndex = lsm.getMaxSelectionIndex();
        …
    }