• 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 proguard.MemberSpecification;
24 import proguard.classfile.ClassConstants;
25 import proguard.classfile.util.ClassUtil;
26 
27 import javax.swing.*;
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.util.*;
31 import java.util.List;
32 
33 
34 /**
35  * This <code>ListPanel</code> allows the user to add, edit, move, and remove
36  * MemberSpecification entries in a list.
37  *
38  * @author Eric Lafortune
39  */
40 final class MemberSpecificationsPanel extends ListPanel
41 {
42     private final MemberSpecificationDialog fieldSpecificationDialog;
43     private final MemberSpecificationDialog methodSpecificationDialog;
44 
45 
MemberSpecificationsPanel(JDialog owner, boolean fullKeepOptions)46     public MemberSpecificationsPanel(JDialog owner, boolean fullKeepOptions)
47     {
48         super();
49 
50         super.firstSelectionButton = fullKeepOptions ? 3 : 2;
51 
52         list.setCellRenderer(new MyListCellRenderer());
53 
54         fieldSpecificationDialog  = new MemberSpecificationDialog(owner, true);
55         methodSpecificationDialog = new MemberSpecificationDialog(owner, false);
56 
57         if (fullKeepOptions)
58         {
59             addAddFieldButton();
60         }
61         addAddMethodButton();
62         addEditButton();
63         addRemoveButton();
64         addUpButton();
65         addDownButton();
66 
67         enableSelectionButtons();
68     }
69 
70 
addAddFieldButton()71     protected void addAddFieldButton()
72     {
73         JButton addFieldButton = new JButton(msg("addField"));
74         addFieldButton.addActionListener(new ActionListener()
75         {
76             public void actionPerformed(ActionEvent e)
77             {
78                 fieldSpecificationDialog.setMemberSpecification(new MemberSpecification());
79                 int returnValue = fieldSpecificationDialog.showDialog();
80                 if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
81                 {
82                     // Add the new element.
83                     addElement(new MyMemberSpecificationWrapper(fieldSpecificationDialog.getMemberSpecification(),
84                                                                   true));
85                 }
86             }
87         });
88 
89         addButton(tip(addFieldButton, "addFieldTip"));
90     }
91 
92 
addAddMethodButton()93     protected void addAddMethodButton()
94     {
95         JButton addMethodButton = new JButton(msg("addMethod"));
96         addMethodButton.addActionListener(new ActionListener()
97         {
98             public void actionPerformed(ActionEvent e)
99             {
100                 methodSpecificationDialog.setMemberSpecification(new MemberSpecification());
101                 int returnValue = methodSpecificationDialog.showDialog();
102                 if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
103                 {
104                     // Add the new element.
105                     addElement(new MyMemberSpecificationWrapper(methodSpecificationDialog.getMemberSpecification(),
106                                                                   false));
107                 }
108             }
109         });
110 
111         addButton(tip(addMethodButton, "addMethodTip"));
112     }
113 
114 
addEditButton()115     protected void addEditButton()
116     {
117         JButton editButton = new JButton(msg("edit"));
118         editButton.addActionListener(new ActionListener()
119         {
120             public void actionPerformed(ActionEvent e)
121             {
122                 MyMemberSpecificationWrapper wrapper =
123                     (MyMemberSpecificationWrapper)list.getSelectedValue();
124 
125                 MemberSpecificationDialog memberSpecificationDialog =
126                     wrapper.isField ?
127                         fieldSpecificationDialog :
128                         methodSpecificationDialog;
129 
130                 memberSpecificationDialog.setMemberSpecification(wrapper.memberSpecification);
131                 int returnValue = memberSpecificationDialog.showDialog();
132                 if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
133                 {
134                     // Replace the old element.
135                     wrapper.memberSpecification = memberSpecificationDialog.getMemberSpecification();
136                     setElementAt(wrapper,
137                                  list.getSelectedIndex());
138                 }
139             }
140         });
141 
142         addButton(tip(editButton, "editTip"));
143     }
144 
145 
146     /**
147      * Sets the MemberSpecification instances to be represented in this panel.
148      */
setMemberSpecifications(List fieldSpecifications, List methodSpecifications)149     public void setMemberSpecifications(List fieldSpecifications,
150                                         List methodSpecifications)
151     {
152         listModel.clear();
153 
154         if (fieldSpecifications != null)
155         {
156             for (int index = 0; index < fieldSpecifications.size(); index++)
157             {
158                 listModel.addElement(
159                     new MyMemberSpecificationWrapper((MemberSpecification)fieldSpecifications.get(index),
160                                                      true));
161             }
162         }
163 
164         if (methodSpecifications != null)
165         {
166             for (int index = 0; index < methodSpecifications.size(); index++)
167             {
168                 listModel.addElement(
169                     new MyMemberSpecificationWrapper((MemberSpecification)methodSpecifications.get(index),
170                                                      false));
171             }
172         }
173 
174         // Make sure the selection buttons are properly enabled,
175         // since the clear method doesn't seem to notify the listener.
176         enableSelectionButtons();
177     }
178 
179 
180     /**
181      * Returns the MemberSpecification instances currently represented in
182      * this panel, referring to fields or to methods.
183      *
184      * @param isField specifies whether specifications referring to fields or
185      *                specifications referring to methods should be returned.
186      */
getMemberSpecifications(boolean isField)187     public List getMemberSpecifications(boolean isField)
188     {
189         int size = listModel.size();
190         if (size == 0)
191         {
192             return null;
193         }
194 
195         List memberSpecifications = new ArrayList(size);
196         for (int index = 0; index < size; index++)
197         {
198             MyMemberSpecificationWrapper wrapper =
199                 (MyMemberSpecificationWrapper)listModel.get(index);
200 
201             if (wrapper.isField == isField)
202             {
203                 memberSpecifications.add(wrapper.memberSpecification);
204             }
205         }
206 
207         return memberSpecifications;
208     }
209 
210 
211     /**
212      * This ListCellRenderer renders MemberSpecification objects.
213      */
214     private static class MyListCellRenderer implements ListCellRenderer
215     {
216         private final JLabel label = new JLabel();
217 
218 
219         // Implementations for ListCellRenderer.
220 
getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)221         public Component getListCellRendererComponent(JList   list,
222                                                       Object  value,
223                                                       int     index,
224                                                       boolean isSelected,
225                                                       boolean cellHasFocus)
226         {
227             MyMemberSpecificationWrapper wrapper = (MyMemberSpecificationWrapper)value;
228 
229             MemberSpecification option = wrapper.memberSpecification;
230             String name       = option.name;
231             String descriptor = option.descriptor;
232 
233             label.setText(wrapper.isField ?
234                 (descriptor == null ? name == null ?
235                     "<fields>" :
236                     "***" + ' ' + name :
237                     ClassUtil.externalFullFieldDescription(0,
238                                                            name == null ? "*" : name,
239                                                            descriptor)) :
240                 (descriptor == null ? name == null ?
241                     "<methods>" :
242                     "***" + ' ' + name + "(...)" :
243                     ClassUtil.externalFullMethodDescription(ClassConstants.METHOD_NAME_INIT,
244                                                             0,
245                                                             name == null ? "*" : name,
246                                                             descriptor)));
247 
248             if (isSelected)
249             {
250                 label.setBackground(list.getSelectionBackground());
251                 label.setForeground(list.getSelectionForeground());
252             }
253             else
254             {
255                 label.setBackground(list.getBackground());
256                 label.setForeground(list.getForeground());
257             }
258 
259             label.setOpaque(true);
260 
261             return label;
262         }
263     }
264 
265 
266     /**
267      * Attaches the tool tip from the GUI resources that corresponds to the
268      * given key, to the given component.
269      */
tip(JComponent component, String messageKey)270     private static JComponent tip(JComponent component, String messageKey)
271     {
272         component.setToolTipText(msg(messageKey));
273 
274         return component;
275     }
276 
277 
278     /**
279      * Returns the message from the GUI resources that corresponds to the given
280      * key.
281      */
msg(String messageKey)282     private static String msg(String messageKey)
283     {
284          return GUIResources.getMessage(messageKey);
285     }
286 
287 
288     /**
289      * This class wraps a MemberSpecification, additionally storing whether
290      * the option refers to a field or to a method.
291      */
292     private static class MyMemberSpecificationWrapper
293     {
294         public MemberSpecification memberSpecification;
295         public final boolean             isField;
296 
MyMemberSpecificationWrapper(MemberSpecification memberSpecification, boolean isField)297         public MyMemberSpecificationWrapper(MemberSpecification memberSpecification,
298                                             boolean             isField)
299         {
300             this.memberSpecification = memberSpecification;
301             this.isField                  = isField;
302         }
303     }
304 }
305