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