KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > gui > ClassSpecificationDialog


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 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
26 import javax.swing.*;
27 import javax.swing.border.*;
28 import javax.swing.border.Border JavaDoc;
29
30 import java.util.List JavaDoc;
31
32 import proguard.*;
33 import proguard.classfile.ClassConstants;
34 import proguard.classfile.util.ClassUtil;
35
36 /**
37  * This <code>JDialog</code> allows the user to enter a String.
38  *
39  * @author Eric Lafortune
40  */

41 class ClassSpecificationDialog extends JDialog
42 {
43     /**
44      * Return value if the dialog is canceled (with the Cancel button or by
45      * closing the dialog window).
46      */

47     public static final int CANCEL_OPTION = 1;
48
49     /**
50      * Return value if the dialog is approved (with the Ok button).
51      */

52     public static final int APPROVE_OPTION = 0;
53
54
55     private JTextArea commentsTextArea = new JTextArea(4, 20);
56
57     private JRadioButton keepClassesAndMembersRadioButton = new JRadioButton(GUIResources.getMessage("keep"));
58     private JRadioButton keepClassMembersRadioButton = new JRadioButton(GUIResources.getMessage("keepClassMembers"));
59     private JRadioButton keepClassesWithMembersRadioButton = new JRadioButton(GUIResources.getMessage("keepClassesWithMembers"));
60
61     private JRadioButton allowShrinkingRadioButton = new JRadioButton(GUIResources.getMessage("allowShrinking"));
62     private JRadioButton allowOptimizationRadioButton = new JRadioButton(GUIResources.getMessage("allowOptimization"));
63     private JRadioButton allowObfuscationRadioButton = new JRadioButton(GUIResources.getMessage("allowObfuscation"));
64
65
66     private JRadioButton[] publicRadioButtons;
67     private JRadioButton[] finalRadioButtons;
68     private JRadioButton[] interfaceRadioButtons;
69     private JRadioButton[] abstractRadioButtons;
70
71     private JTextField annotationTypeTextField = new JTextField(20);
72     private JTextField classNameTextField = new JTextField(20);
73     private JTextField extendsAnnotationTypeTextField = new JTextField(20);
74     private JTextField extendsClassNameTextField = new JTextField(20);
75
76     private MemberSpecificationsPanel memberSpecificationsPanel;
77
78     private int returnValue;
79
80
81     public ClassSpecificationDialog(JFrame owner, boolean fullKeepOptions)
82     {
83         super(owner, true);
84         setResizable(true);
85
86         // Create some constraints that can be reused.
87
GridBagConstraints constraints = new GridBagConstraints();
88         constraints.anchor = GridBagConstraints.WEST;
89         constraints.insets = new Insets(1, 2, 1, 2);
90
91         GridBagConstraints constraintsStretch = new GridBagConstraints();
92         constraintsStretch.fill = GridBagConstraints.HORIZONTAL;
93         constraintsStretch.weightx = 1.0;
94         constraintsStretch.anchor = GridBagConstraints.WEST;
95         constraintsStretch.insets = constraints.insets;
96
97         GridBagConstraints constraintsLast = new GridBagConstraints();
98         constraintsLast.gridwidth = GridBagConstraints.REMAINDER;
99         constraintsLast.anchor = GridBagConstraints.WEST;
100         constraintsLast.insets = constraints.insets;
101
102         GridBagConstraints constraintsLastStretch = new GridBagConstraints();
103         constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER;
104         constraintsLastStretch.fill = GridBagConstraints.HORIZONTAL;
105         constraintsLastStretch.weightx = 1.0;
106         constraintsLastStretch.anchor = GridBagConstraints.WEST;
107         constraintsLastStretch.insets = constraints.insets;
108
109         GridBagConstraints panelConstraints = new GridBagConstraints();
110         panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
111         panelConstraints.fill = GridBagConstraints.HORIZONTAL;
112         panelConstraints.weightx = 1.0;
113         panelConstraints.weighty = 0.0;
114         panelConstraints.anchor = GridBagConstraints.NORTHWEST;
115         panelConstraints.insets = constraints.insets;
116
117         GridBagConstraints stretchPanelConstraints = new GridBagConstraints();
118         stretchPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;
119         stretchPanelConstraints.fill = GridBagConstraints.BOTH;
120         stretchPanelConstraints.weightx = 1.0;
121         stretchPanelConstraints.weighty = 1.0;
122         stretchPanelConstraints.anchor = GridBagConstraints.NORTHWEST;
123         stretchPanelConstraints.insets = constraints.insets;
124
125         GridBagConstraints labelConstraints = new GridBagConstraints();
126         labelConstraints.anchor = GridBagConstraints.CENTER;
127         labelConstraints.insets = new Insets(2, 10, 2, 10);
128
129         GridBagConstraints lastLabelConstraints = new GridBagConstraints();
130         lastLabelConstraints.gridwidth = GridBagConstraints.REMAINDER;
131         lastLabelConstraints.anchor = GridBagConstraints.CENTER;
132         lastLabelConstraints.insets = labelConstraints.insets;
133
134         GridBagConstraints okButtonConstraints = new GridBagConstraints();
135         okButtonConstraints.weightx = 1.0;
136         okButtonConstraints.weighty = 1.0;
137         okButtonConstraints.anchor = GridBagConstraints.SOUTHEAST;
138         okButtonConstraints.insets = new Insets(4, 4, 8, 4);
139
140         GridBagConstraints cancelButtonConstraints = new GridBagConstraints();
141         cancelButtonConstraints.gridwidth = GridBagConstraints.REMAINDER;
142         cancelButtonConstraints.weighty = 1.0;
143         cancelButtonConstraints.anchor = GridBagConstraints.SOUTHEAST;
144         cancelButtonConstraints.insets = okButtonConstraints.insets;
145
146         GridBagLayout layout = new GridBagLayout();
147
148         Border JavaDoc etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
149
150         // Create the comments panel.
151
JPanel commentsPanel = new JPanel(layout);
152         commentsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
153                                                                  GUIResources.getMessage("comments")));
154
155         JScrollPane commentsScrollPane = new JScrollPane(commentsTextArea);
156         commentsScrollPane.setBorder(classNameTextField.getBorder());
157
158         commentsPanel.add(commentsScrollPane, constraintsLastStretch);
159
160         // Create the keep option panel.
161
ButtonGroup keepButtonGroup = new ButtonGroup();
162         keepButtonGroup.add(keepClassesAndMembersRadioButton);
163         keepButtonGroup.add(keepClassMembersRadioButton);
164         keepButtonGroup.add(keepClassesWithMembersRadioButton);
165
166         JPanel keepOptionPanel = new JPanel(layout);
167         keepOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
168                                                                    GUIResources.getMessage("keepTitle")));
169
170         keepOptionPanel.add(keepClassesAndMembersRadioButton, constraintsLastStretch);
171         keepOptionPanel.add(keepClassMembersRadioButton, constraintsLastStretch);
172         keepOptionPanel.add(keepClassesWithMembersRadioButton, constraintsLastStretch);
173
174         // Create the allow option panel.
175
JPanel allowOptionPanel = new JPanel(layout);
176         allowOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
177                                                                    GUIResources.getMessage("allowTitle")));
178
179         allowOptionPanel.add(allowShrinkingRadioButton, constraintsLastStretch);
180         allowOptionPanel.add(allowOptimizationRadioButton, constraintsLastStretch);
181         allowOptionPanel.add(allowObfuscationRadioButton, constraintsLastStretch);
182
183         // Create the access panel.
184
JPanel accessPanel = new JPanel(layout);
185         accessPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
186                                                                GUIResources.getMessage("access")));
187
188         accessPanel.add(Box.createGlue(), labelConstraints);
189         accessPanel.add(new JLabel(GUIResources.getMessage("required")), labelConstraints);
190         accessPanel.add(new JLabel(GUIResources.getMessage("not")), labelConstraints);
191         accessPanel.add(new JLabel(GUIResources.getMessage("dontCare")), labelConstraints);
192         accessPanel.add(Box.createGlue(), constraintsLastStretch);
193
194         publicRadioButtons = addRadioButtonTriplet("Public", accessPanel);
195         finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
196         interfaceRadioButtons = addRadioButtonTriplet("Interface", accessPanel);
197         abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
198
199         // Create the annotation type panel.
200
JPanel annotationTypePanel = new JPanel(layout);
201         annotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
202                                                                        GUIResources.getMessage("annotation")));
203
204         annotationTypePanel.add(annotationTypeTextField, constraintsLastStretch);
205
206         // Create the class name panel.
207
JPanel classNamePanel = new JPanel(layout);
208         classNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
209                                                                   GUIResources.getMessage("class")));
210
211         classNamePanel.add(classNameTextField, constraintsLastStretch);
212
213         // Create the extends annotation type panel.
214
JPanel extendsAnnotationTypePanel = new JPanel(layout);
215         extendsAnnotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
216                                                                               GUIResources.getMessage("extendsImplementsAnnotation")));
217
218         extendsAnnotationTypePanel.add(extendsAnnotationTypeTextField, constraintsLastStretch);
219
220         // Create the extends class name panel.
221
JPanel extendsClassNamePanel = new JPanel(layout);
222         extendsClassNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
223                                                                          GUIResources.getMessage("extendsImplementsClass")));
224
225         extendsClassNamePanel.add(extendsClassNameTextField, constraintsLastStretch);
226
227
228         // Create the class member list panel.
229
memberSpecificationsPanel = new MemberSpecificationsPanel(this, fullKeepOptions);
230         memberSpecificationsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
231                                                                      GUIResources.getMessage("classMembers")));
232
233         // Create the Ok button.
234
JButton okButton = new JButton(GUIResources.getMessage("ok"));
235         okButton.addActionListener(new ActionListener()
236         {
237             public void actionPerformed(ActionEvent e)
238             {
239                 returnValue = APPROVE_OPTION;
240                 hide();
241             }
242         });
243
244         // Create the Cancel button.
245
JButton cancelButton = new JButton(GUIResources.getMessage("cancel"));
246         cancelButton.addActionListener(new ActionListener()
247         {
248             public void actionPerformed(ActionEvent e)
249             {
250                 hide();
251             }
252         });
253
254         // Add all panels to the main panel.
255
JPanel mainPanel = new JPanel(layout);
256         mainPanel.add(commentsPanel, panelConstraints);
257         if (fullKeepOptions)
258         {
259             mainPanel.add(keepOptionPanel, panelConstraints);
260             mainPanel.add(allowOptionPanel, panelConstraints);
261         }
262         mainPanel.add(accessPanel, panelConstraints);
263         mainPanel.add(annotationTypePanel, panelConstraints);
264         mainPanel.add(classNamePanel, panelConstraints);
265         mainPanel.add(extendsAnnotationTypePanel, panelConstraints);
266         mainPanel.add(extendsClassNamePanel, panelConstraints);
267         mainPanel.add(memberSpecificationsPanel, stretchPanelConstraints);
268
269         mainPanel.add(okButton, okButtonConstraints);
270         mainPanel.add(cancelButton, cancelButtonConstraints);
271
272         getContentPane().add(mainPanel);
273     }
274
275
276     /**
277      * Adds a JLabel and three JRadioButton instances in a ButtonGroup to the
278      * given panel with a GridBagLayout, and returns the buttons in an array.
279      */

280     private JRadioButton[] addRadioButtonTriplet(String JavaDoc labelText,
281                                                  JPanel panel)
282     {
283         GridBagConstraints labelConstraints = new GridBagConstraints();
284         labelConstraints.anchor = GridBagConstraints.WEST;
285         labelConstraints.insets = new Insets(2, 10, 2, 10);
286
287         GridBagConstraints buttonConstraints = new GridBagConstraints();
288         buttonConstraints.insets = labelConstraints.insets;
289
290         GridBagConstraints lastGlueConstraints = new GridBagConstraints();
291         lastGlueConstraints.gridwidth = GridBagConstraints.REMAINDER;
292         lastGlueConstraints.weightx = 1.0;
293
294         // Create the radio buttons.
295
JRadioButton radioButton0 = new JRadioButton();
296         JRadioButton radioButton1 = new JRadioButton();
297         JRadioButton radioButton2 = new JRadioButton();
298
299         // Put them in a button group.
300
ButtonGroup buttonGroup = new ButtonGroup();
301         buttonGroup.add(radioButton0);
302         buttonGroup.add(radioButton1);
303         buttonGroup.add(radioButton2);
304
305         // Add the label and the buttons to the panel.
306
panel.add(new JLabel(labelText), labelConstraints);
307         panel.add(radioButton0, buttonConstraints);
308         panel.add(radioButton1, buttonConstraints);
309         panel.add(radioButton2, buttonConstraints);
310         panel.add(Box.createGlue(), lastGlueConstraints);
311
312         return new JRadioButton[]
313         {
314              radioButton0,
315              radioButton1,
316              radioButton2
317         };
318     }
319
320
321     /**
322      * Sets the KeepSpecification to be represented in this dialog.
323      */

324     public void setKeepSpecification(KeepSpecification keepSpecification)
325     {
326         boolean markClasses = keepSpecification.markClasses;
327         boolean markConditionally = keepSpecification.markConditionally;
328         boolean allowShrinking = keepSpecification.allowShrinking;
329         boolean allowOptimization = keepSpecification.allowOptimization;
330         boolean allowObfuscation = keepSpecification.allowObfuscation;
331
332         // Figure out the proper keep radio button and set it.
333
JRadioButton keepOptionRadioButton =
334             markConditionally ? keepClassesWithMembersRadioButton :
335             markClasses ? keepClassesAndMembersRadioButton :
336                                 keepClassMembersRadioButton;
337
338         keepOptionRadioButton.setSelected(true);
339
340         // Set the allow radio buttons.
341
allowShrinkingRadioButton .setSelected(allowShrinking);
342         allowOptimizationRadioButton.setSelected(allowOptimization);
343         allowObfuscationRadioButton .setSelected(allowObfuscation);
344
345         setClassSpecification(keepSpecification);
346     }
347
348
349     /**
350      * Sets the ClassSpecification to be represented in this dialog.
351      */

352     public void setClassSpecification(ClassSpecification classSpecification)
353     {
354         String JavaDoc comments = classSpecification.comments;
355         String JavaDoc annotationType = classSpecification.annotationType;
356         String JavaDoc className = classSpecification.className;
357         String JavaDoc extendsAnnotationType = classSpecification.extendsAnnotationType;
358         String JavaDoc extendsClassName = classSpecification.extendsClassName;
359         List JavaDoc keepFieldOptions = classSpecification.fieldSpecifications;
360         List JavaDoc keepMethodOptions = classSpecification.methodSpecifications;
361
362         // Set the comments text area.
363
commentsTextArea.setText(comments == null ? "" : comments);
364
365         // Set the access radio buttons.
366
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
367         setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
368         setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
369         setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
370
371         // Set the class and annotation text fields.
372
annotationTypeTextField .setText(annotationType == null ? "" : ClassUtil.externalType(annotationType));
373         classNameTextField .setText(className == null ? "*" : ClassUtil.externalClassName(className));
374         extendsAnnotationTypeTextField.setText(extendsAnnotationType == null ? "" : ClassUtil.externalType(extendsAnnotationType));
375         extendsClassNameTextField .setText(extendsClassName == null ? "" : ClassUtil.externalClassName(extendsClassName));
376
377         // Set the keep class member option list.
378
memberSpecificationsPanel.setMemberSpecifications(keepFieldOptions, keepMethodOptions);
379     }
380
381
382     /**
383      * Returns the KeepSpecification currently represented in this dialog.
384      */

385     public KeepSpecification getKeepSpecification()
386     {
387         boolean markClasses = !keepClassMembersRadioButton .isSelected();
388         boolean markConditionally = keepClassesWithMembersRadioButton.isSelected();
389         boolean allowShrinking = allowShrinkingRadioButton .isSelected();
390         boolean allowOptimization = allowOptimizationRadioButton .isSelected();
391         boolean allowObfuscation = allowObfuscationRadioButton .isSelected();
392
393         return new KeepSpecification(markClasses,
394                                      markConditionally,
395                                      allowShrinking,
396                                      allowOptimization,
397                                      allowObfuscation,
398                                      getClassSpecification());
399     }
400
401
402     /**
403      * Returns the ClassSpecification currently represented in this dialog.
404      */

405     public ClassSpecification getClassSpecification()
406     {
407         String JavaDoc comments = commentsTextArea.getText();
408         String JavaDoc annotationType = annotationTypeTextField.getText();
409         String JavaDoc className = classNameTextField.getText();
410         String JavaDoc extendsAnnotationType = extendsAnnotationTypeTextField.getText();
411         String JavaDoc extendsClassName = extendsClassNameTextField.getText();
412
413         ClassSpecification classSpecification =
414             new ClassSpecification(comments.equals("") ? null : comments,
415                                    0,
416                                    0,
417                                    annotationType.equals("") ? null : ClassUtil.internalType(annotationType),
418                                    className.equals("") ||
419                                    className.equals("*") ? null : ClassUtil.internalClassName(className),
420                                    extendsAnnotationType.equals("") ? null : ClassUtil.internalType(extendsAnnotationType),
421                                    extendsClassName.equals("") ? null : ClassUtil.internalClassName(extendsClassName));
422
423         // Also get the access radio button settings.
424
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
425         getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
426         getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
427         getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
428
429         // Get the keep class member option lists.
430
classSpecification.fieldSpecifications = memberSpecificationsPanel.getMemberSpecifications(true);
431         classSpecification.methodSpecifications = memberSpecificationsPanel.getMemberSpecifications(false);
432
433         return classSpecification;
434     }
435
436
437     /**
438      * Shows this dialog. This method only returns when the dialog is closed.
439      *
440      * @return <code>CANCEL_OPTION</code> or <code>APPROVE_OPTION</code>,
441      * depending on the choice of the user.
442      */

443     public int showDialog()
444     {
445         returnValue = CANCEL_OPTION;
446
447         // Open the dialog in the right place, then wait for it to be closed,
448
// one way or another.
449
pack();
450         setLocationRelativeTo(getOwner());
451         show();
452
453         return returnValue;
454     }
455
456
457     /**
458      * Sets the appropriate radio button of a given triplet, based on the access
459      * flags of the given keep option.
460      */

461     private void setClassSpecificationRadioButtons(ClassSpecification classSpecification,
462                                                     int flag,
463                                                     JRadioButton[] radioButtons)
464     {
465         int index = (classSpecification.requiredSetAccessFlags & flag) != 0 ? 0 :
466                     (classSpecification.requiredUnsetAccessFlags & flag) != 0 ? 1 :
467                                                                                  2;
468         radioButtons[index].setSelected(true);
469     }
470
471
472     /**
473      * Updates the access flag of the given keep option, based on the given radio
474      * button triplet.
475      */

476     private void getClassSpecificationRadioButtons(ClassSpecification classSpecification,
477                                                     int flag,
478                                                     JRadioButton[] radioButtons)
479     {
480         if (radioButtons[0].isSelected())
481         {
482             classSpecification.requiredSetAccessFlags |= flag;
483         }
484         else if (radioButtons[1].isSelected())
485         {
486             classSpecification.requiredUnsetAccessFlags |= flag;
487         }
488     }
489 }
490
Popular Tags