JList - Part 3

The third part of this topic will look at letting your user add and remove items from the list.

To allow the addition and removal of items from a list, you need to create a ListModel. The ListModel controls the movement of items within the list.

We will change the example before to a two-list GUI, with buttons in the middle letting you swap items between each List. In this case it's the items you want to have on a shopping list.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Color;
import java.awt.event.*;

public class ListExample_UltraExtended implements  ActionListener{

    JList itemList, shoppingList;
    JButton buttonin, buttonout;
    
    // The ListModels we will be using in the example.
    DefaultListModel shopping, items;

    public JPanel createContentPane (){

        // Create the final Panel.
        JPanel totalGUI = new JPanel();
        
        // Instantiate the List Models.
        shopping = new DefaultListModel();
        items = new DefaultListModel();

        // Things to be in the list.
        String shoppingItems[] = {"Milk", "Cheese", "Bread", "Butter", "Beans",
        "Soup", "Bacon", "Chicken", "Curry Sauce", "Chocolate"};

        // Using a for loop, we add every item in the String array
        // into the ListModel.

        for(int i = 0; i < shoppingItems.length; i++)
        {
            shopping.addElement(shoppingItems[i]);
        }

        // Creation of the list.
        // We set the cells in the list to be 20px x 140px.
        
        itemList = new JList(shopping);
        itemList.setVisibleRowCount(10);
        itemList.setFixedCellHeight(20);
        itemList.setFixedCellWidth(140);
        itemList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        
        // We then add them to a JScrollPane.
        // This means when we remove items from the JList
        // it will not shrink in size.
        JScrollPane list1 = new JScrollPane(itemList);
        
        shoppingList = new JList(items);
        shoppingList.setVisibleRowCount(10);
        shoppingList.setFixedCellHeight(20);
        shoppingList.setFixedCellWidth(140);
        shoppingList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        
        // We add this list to a JScrollPane too.
        // This is so the list is displayed even though there are 
        // currently no items in the list.
        // Without the scrollpane, the list would not show.
        JScrollPane list2 = new JScrollPane(shoppingList);

        // We create the buttons to be placed between the lists.
        JPanel buttonPanel = new JPanel();

        buttonin = new JButton(">>");
        buttonin.addActionListener(this);
        buttonPanel.add(buttonin);

        buttonout = new JButton("<<");
        buttonout.addActionListener(this);
        buttonPanel.add(buttonout);

        // This final bit of code uses a BoxLayout to space out the widgets
        // in the GUI.

        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));

        bottomPanel.add(Box.createRigidArea(new Dimension(10,0)));
        bottomPanel.add(list1);
        bottomPanel.add(Box.createRigidArea(new Dimension(5,0)));
        bottomPanel.add(buttonPanel);
        bottomPanel.add(Box.createRigidArea(new Dimension(5,0)));
        bottomPanel.add(list2);
        bottomPanel.add(Box.createRigidArea(new Dimension(10,0)));

        totalGUI.add(bottomPanel);
        totalGUI.setOpaque(true);
        return totalGUI;
    }

    // In this method, we create a square JPanel of a colour and set size
    // specified by the arguments.

    private JPanel createSquareJPanel(Color color, int size) {
        JPanel tempPanel = new JPanel();
        tempPanel.setBackground(color);
        tempPanel.setMinimumSize(new Dimension(size, size));
        tempPanel.setMaximumSize(new Dimension(size, size));
        tempPanel.setPreferredSize(new Dimension(size, size));
        return tempPanel;
    }

    // valueChanged is the method that deals with a ListSelectionEvent.
    // This simply changes the boxes that are selected to true.

    public void actionPerformed(ActionEvent e) 
    {
        int i = 0;
        
        // When the 'in' button is pressed,
        // we take the indices and values of the selected items
        // and output them to an array.

        if(e.getSource() == buttonin)
        {
            int[] fromindex = itemList.getSelectedIndices();
            Object[] from = itemList.getSelectedValues();

            // Then, for each item in the array, we add them to
            // the other list.
            for(i = 0; i < from.length; i++)
            {
                items.addElement(from[i]);
            }
            
            // Finally, we remove the items from the first list.
            // We must remove from the bottom, otherwise we try to 
            // remove the wrong objects.
            for(i = (fromindex.length-1); i >=0; i--)
            {
                shopping.remove(fromindex[i]);
            }
        }
        
        // If the out button is pressed, we take the indices and values of
        // the selected items and output them to an array.
        else if(e.getSource() == buttonout)
        {
            Object[] to = shoppingList.getSelectedValues();
            int[] toindex = shoppingList.getSelectedIndices();
            
            // Then, for each item in the array, we add them to
            // the other list.
            for(i = 0; i < to.length; i++)
            {
                shopping.addElement(to[i]);
            }
            
            // Finally, we remove the items from the first list.
            // We must remove from the bottom, otherwise we try to
            // remove the wrong objects.
            for(i = (toindex.length-1); i >=0; i--)
            {
                items.remove(toindex[i]);
            }
        }
    }

    private static void createAndShowGUI() {

        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("[=] JListExample - Adding and Removing [=]");

        ListExample_UltraExtended demo = new ListExample_UltraExtended();
        frame.setContentPane(demo.createContentPane());
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Picture of the GUI

As was mentioned at the start, we need to use ListModels to control the addition and removal of items from the list. The ListModel in this case is a DefaultListModel. We begin by listing them at the start, then instantiating them at the start of the createContentPane method.
13
    DefaultListModel shopping, items;
21
22
        shopping = new DefaultListModel();
        items = new DefaultListModel();
To add items to the ListModel, I have listed them in a String array then added them using a for loop. You can add each one individually if you so wish.
24
25
26
27
28
29
30
31
32
33
34
        // Things to be in the list.
        String shoppingItems[] = {"Milk", "Cheese", "Bread", "Butter", "Beans",
        "Soup", "Bacon", "Chicken", "Curry Sauce", "Chocolate"};

        // Using a for loop, we add every item in the String array
        // into the ListModel.

        for(int i = 0; i < shoppingItems.length; i++)
        {
            shopping.addElement(shoppingItems[i]);
        }
With the items added to the ListModel, we instantiate the JList with the ListModel as an argument.
39
        itemList = new JList(shopping);
Another new thing to this example is that we add the JList to a JScrollPane. By adding the JList to a ScrollPane, the JList does not change size on the GUI when we add or remove items from it. The JScrollPane is automatically sized by the sizes set in the JList (setVisibleRowCount(), setFixedCellWidth(), setFixedCellHeight()).
48
        JScrollPane list1 = new JScrollPane(itemList);
The rest of the GUI is simple, and we've covered it all before.

The Event Listener is an ActionListener since we are waiting for a button press before we do anything.
On the 'buttonin' press, we take a snapshot of the indices selected and their corresponding values.
117
118
            int[] fromindex = itemList.getSelectedIndices();
            Object[] from = itemList.getSelectedValues();
For each selected item in the list, we add it to the other lists ListModel, using the addElement() syntax that we have used before.
122
123
124
125
            for(i = 0; i < from.length; i++)
            {
                items.addElement(from[i]);
            }
Then, we must remove each item from the first list. Removal must occur from the last item in the list to the first.
This is because after every item removal, the ListModel resets the index of each item in it's list. Thus, if there are 4 items in the list (0,1,2,3) and we remove No.2 (0,1,3) the ListModel resets the indices (0,1,2).

Thus, if there are four items in the list, and we want to remove the last two, we will want to remove index 2 and 3 from the list. But if we remove index 2, index 3 gets set to index 2 and there is no longer an index 3 in which we can remove! An ArrayOutOfBounds error occurs, and everything gets nasty!

To actually remove the item, we use the syntax .remove(int); where the integer is the index of the item you wish to remove.
130
131
132
133
            for(i = (fromindex.length-1); i >=0; i--)
            {
                shopping.remove(fromindex[i]);
            }
That is how we add and remove things from a JList, and this concludes our tutorial on the JList.

There are lots more you can do with the DefaultListModel we use here though and you can find out more about it in the Java API.

Questions

JList questions from all three sections!

Question 1. How do we control the adding and removing of items from a JList?

  • a) By always adding and removing from the bottom of the list.
  • b) By keeping track using integers.
  • c) By using a ListModel.

Question 2. What Event Listener does a JList use?

  • a) ListListener
  • b) ListSelectionListener
  • c) ListSubmissionListener

Question 3. How do you add items to a ListModel?

  • a) addElement(Object);
  • b) addItem(Object);
  • c) addObject(Object);

Question 4. How do you remove items from a ListModel?

  • a) remove()
  • b) delete()
  • c) getRid()




Back Top Next
Email Me
Code Style


Required Lessons

External Links

Created and Edited by Stuart Davidson
All Rights Reserved ©

Valid XHTML 1.0 Strict