• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.gui;
22 
23 import java.awt.*;
24 import java.awt.event.*;
25 import java.util.List;
26 import java.util.*;
27 
28 import javax.swing.*;
29 import javax.swing.event.*;
30 
31 /**
32  * This <code>Jpanel</code> allows the user to move and remove entries in a
33  * list and between lists. Extensions of this class should add buttons to add
34  * and possibly edit entries, and to set and get the resulting list.
35  *
36  * @author Eric Lafortune
37  */
38 abstract class ListPanel extends JPanel
39 {
40     protected final DefaultListModel listModel = new DefaultListModel();
41     protected final JList            list      = new JList(listModel);
42 
43     protected int firstSelectionButton = 2;
44 
45 
ListPanel()46     protected ListPanel()
47     {
48         GridBagLayout layout = new GridBagLayout();
49         setLayout(layout);
50 
51         GridBagConstraints listConstraints = new GridBagConstraints();
52         listConstraints.gridheight = GridBagConstraints.REMAINDER;
53         listConstraints.fill       = GridBagConstraints.BOTH;
54         listConstraints.weightx    = 1.0;
55         listConstraints.weighty    = 1.0;
56         listConstraints.anchor     = GridBagConstraints.NORTHWEST;
57         listConstraints.insets     = new Insets(0, 2, 0, 2);
58 
59         // Make sure some buttons are disabled or enabled depending on whether
60         // the selection is empty or not.
61         list.addListSelectionListener(new ListSelectionListener()
62         {
63             public void valueChanged(ListSelectionEvent e)
64             {
65                 enableSelectionButtons();
66             }
67         });
68 
69         add(new JScrollPane(list), listConstraints);
70 
71         // something like the following calls are up to the extending class:
72         //addAddButton();
73         //addEditButton();
74         //addRemoveButton();
75         //addUpButton();
76         //addDownButton();
77         //
78         //enableSelectionButtons();
79     }
80 
81 
addRemoveButton()82     protected void addRemoveButton()
83     {
84         JButton removeButton = new JButton(msg("remove"));
85         removeButton.addActionListener(new ActionListener()
86         {
87             public void actionPerformed(ActionEvent e)
88             {
89                 // Remove the selected elements.
90                 removeElementsAt(list.getSelectedIndices());
91             }
92         });
93 
94         addButton(tip(removeButton, "removeTip"));
95     }
96 
97 
addUpButton()98     protected void addUpButton()
99     {
100         JButton upButton = new JButton(msg("moveUp"));
101         upButton.addActionListener(new ActionListener()
102         {
103             public void actionPerformed(ActionEvent e)
104             {
105                 int[] selectedIndices = list.getSelectedIndices();
106                 if (selectedIndices.length > 0 &&
107                     selectedIndices[0] > 0)
108                 {
109                     // Move the selected elements up.
110                     moveElementsAt(selectedIndices, -1);
111                 }
112             }
113         });
114 
115         addButton(tip(upButton, "moveUpTip"));
116     }
117 
118 
addDownButton()119     protected void addDownButton()
120     {
121         JButton downButton = new JButton(msg("moveDown"));
122         downButton.addActionListener(new ActionListener()
123         {
124             public void actionPerformed(ActionEvent e)
125             {
126                 int[] selectedIndices = list.getSelectedIndices();
127                 if (selectedIndices.length > 0 &&
128                     selectedIndices[selectedIndices.length-1] < listModel.getSize()-1)
129                 {
130                     // Move the selected elements down.
131                     moveElementsAt(selectedIndices, 1);
132                 }
133             }
134         });
135 
136         addButton(tip(downButton, "moveDownTip"));
137     }
138 
139 
140     /**
141      * Adds a button that allows to copy or move entries to another ListPanel.
142      *
143      * @param buttonTextKey the button text key.
144      * @param tipKey        the tool tip key.
145      * @param panel         the other ListPanel.
146      */
addCopyToPanelButton(String buttonTextKey, String tipKey, final ListPanel panel)147     public void addCopyToPanelButton(String          buttonTextKey,
148                                      String          tipKey,
149                                      final ListPanel panel)
150     {
151         JButton moveButton = new JButton(msg(buttonTextKey));
152         moveButton.addActionListener(new ActionListener()
153         {
154             public void actionPerformed(ActionEvent e)
155             {
156                 int[]    selectedIndices  = list.getSelectedIndices();
157                 Object[] selectedElements = list.getSelectedValues();
158 
159                 // Remove the selected elements from this panel.
160                 removeElementsAt(selectedIndices);
161 
162                 // Add the elements to the other panel.
163                 panel.addElements(selectedElements);
164             }
165         });
166 
167         addButton(tip(moveButton, tipKey));
168     }
169 
170 
addButton(JComponent button)171     protected void addButton(JComponent button)
172     {
173         GridBagConstraints buttonConstraints = new GridBagConstraints();
174         buttonConstraints.gridwidth = GridBagConstraints.REMAINDER;
175         buttonConstraints.fill      = GridBagConstraints.HORIZONTAL;
176         buttonConstraints.anchor    = GridBagConstraints.NORTHWEST;
177         buttonConstraints.insets    = new Insets(0, 2, 0, 2);
178 
179         add(button, buttonConstraints);
180     }
181 
182 
183     /**
184      * Returns a list of all right-hand side buttons.
185      */
getButtons()186     public List getButtons()
187     {
188         List list = new ArrayList(getComponentCount()-1);
189 
190         // Add all buttons.
191         for (int index = 1; index < getComponentCount(); index++)
192         {
193             list.add(getComponent(index));
194         }
195 
196         return list;
197     }
198 
199 
addElement(Object element)200     protected void addElement(Object element)
201     {
202         listModel.addElement(element);
203 
204         // Make sure it is selected.
205         list.setSelectedIndex(listModel.size() - 1);
206     }
207 
208 
addElements(Object[] elements)209     protected void addElements(Object[] elements)
210     {
211         // Add the elements one by one.
212         for (int index = 0; index < elements.length; index++)
213         {
214             listModel.addElement(elements[index]);
215         }
216 
217         // Make sure they are selected.
218         int[] selectedIndices = new int[elements.length];
219         for (int index = 0; index < selectedIndices.length; index++)
220         {
221             selectedIndices[index] =
222                 listModel.size() - selectedIndices.length + index;
223         }
224         list.setSelectedIndices(selectedIndices);
225     }
226 
227 
moveElementsAt(int[] indices, int offset)228     protected void moveElementsAt(int[] indices, int offset)
229     {
230         // Remember the selected elements.
231         Object[] selectedElements = list.getSelectedValues();
232 
233         // Remove the selected elements.
234         removeElementsAt(indices);
235 
236         // Update the element indices.
237         for (int index = 0; index < indices.length; index++)
238         {
239             indices[index] += offset;
240         }
241 
242         // Reinsert the selected elements.
243         insertElementsAt(selectedElements, indices);
244     }
245 
246 
insertElementsAt(Object[] elements, int[] indices)247     protected void insertElementsAt(Object[] elements, int[] indices)
248     {
249         for (int index = 0; index < elements.length; index++)
250         {
251             listModel.insertElementAt(elements[index], indices[index]);
252         }
253 
254         // Make sure they are selected.
255         list.setSelectedIndices(indices);
256     }
257 
258 
setElementAt(Object element, int index)259     protected void setElementAt(Object element, int index)
260     {
261         listModel.setElementAt(element, index);
262 
263         // Make sure it is selected.
264         list.setSelectedIndex(index);
265     }
266 
267 
setElementsAt(Object[] elements, int[] indices)268     protected void setElementsAt(Object[] elements, int[] indices)
269     {
270         for (int index = 0; index < elements.length; index++)
271         {
272             listModel.setElementAt(elements[index], indices[index]);
273         }
274 
275         // Make sure they are selected.
276         list.setSelectedIndices(indices);
277     }
278 
279 
removeElementsAt(int[] indices)280     protected void removeElementsAt(int[] indices)
281     {
282         for (int index = indices.length - 1; index >= 0; index--)
283         {
284             listModel.removeElementAt(indices[index]);
285         }
286 
287         // Make sure nothing is selected.
288         list.clearSelection();
289 
290         // Make sure the selection buttons are properly enabled,
291         // since the above method doesn't seem to notify the listener.
292         enableSelectionButtons();
293     }
294 
295 
removeAllElements()296     protected void removeAllElements()
297     {
298         listModel.removeAllElements();
299 
300         // Make sure the selection buttons are properly enabled,
301         // since the above method doesn't seem to notify the listener.
302         enableSelectionButtons();
303     }
304 
305 
306     /**
307      * Enables or disables the buttons that depend on a selection.
308      */
enableSelectionButtons()309     protected void enableSelectionButtons()
310     {
311         boolean selected = !list.isSelectionEmpty();
312 
313         // Loop over all components, except the list itself and the Add button.
314         for (int index = firstSelectionButton; index < getComponentCount(); index++)
315         {
316             getComponent(index).setEnabled(selected);
317         }
318     }
319 
320 
321     /**
322      * Attaches the tool tip from the GUI resources that corresponds to the
323      * given key, to the given component.
324      */
tip(JComponent component, String messageKey)325     private static JComponent tip(JComponent component, String messageKey)
326     {
327         component.setToolTipText(msg(messageKey));
328 
329         return component;
330     }
331 
332 
333     /**
334      * Returns the message from the GUI resources that corresponds to the given
335      * key.
336      */
msg(String messageKey)337     private static String msg(String messageKey)
338     {
339          return GUIResources.getMessage(messageKey);
340     }
341 }
342