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.*;
24 import proguard.classfile.ClassConstants;
25 import proguard.classfile.util.ClassUtil;
26 
27 import javax.swing.*;
28 import javax.swing.border.*;
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.util.List;
32 
33 /**
34  * This <code>JDialog</code> allows the user to enter a String.
35  *
36  * @author Eric Lafortune
37  */
38 final class ClassSpecificationDialog extends JDialog
39 {
40     /**
41      * Return value if the dialog is canceled (with the Cancel button or by
42      * closing the dialog window).
43      */
44     public static final int CANCEL_OPTION = 1;
45 
46     /**
47      * Return value if the dialog is approved (with the Ok button).
48      */
49     public static final int APPROVE_OPTION = 0;
50 
51 
52     private final JTextArea commentsTextArea = new JTextArea(4, 20);
53 
54     private final JRadioButton keepClassesAndMembersRadioButton  = new JRadioButton(msg("keep"));
55     private final JRadioButton keepClassMembersRadioButton       = new JRadioButton(msg("keepClassMembers"));
56     private final JRadioButton keepClassesWithMembersRadioButton = new JRadioButton(msg("keepClassesWithMembers"));
57 
58     private final JCheckBox keepDescriptorClassesCheckBox = new JCheckBox(msg("keepDescriptorClasses"));
59 
60     private final JCheckBox allowShrinkingCheckBox    = new JCheckBox(msg("allowShrinking"));
61     private final JCheckBox allowOptimizationCheckBox = new JCheckBox(msg("allowOptimization"));
62     private final JCheckBox allowObfuscationCheckBox  = new JCheckBox(msg("allowObfuscation"));
63 
64 
65     private final JRadioButton[] publicRadioButtons;
66     private final JRadioButton[] finalRadioButtons;
67     private final JRadioButton[] abstractRadioButtons;
68     private final JRadioButton[] interfaceRadioButtons;
69     private final JRadioButton[] annotationRadioButtons;
70     private final JRadioButton[] enumRadioButtons;
71     private final JRadioButton[] syntheticRadioButtons;
72 
73     private final JTextField annotationTypeTextField        = new JTextField(20);
74     private final JTextField classNameTextField             = new JTextField(20);
75     private final JTextField extendsAnnotationTypeTextField = new JTextField(20);
76     private final JTextField extendsClassNameTextField      = new JTextField(20);
77 
78     private final MemberSpecificationsPanel memberSpecificationsPanel;
79 
80     private int returnValue;
81 
82 
ClassSpecificationDialog(JFrame owner, boolean fullKeepOptions)83     public ClassSpecificationDialog(JFrame owner, boolean fullKeepOptions)
84     {
85         super(owner, msg("specifyClasses"), true);
86         setResizable(true);
87 
88         // Create some constraints that can be reused.
89         GridBagConstraints constraints = new GridBagConstraints();
90         constraints.anchor = GridBagConstraints.WEST;
91         constraints.insets = new Insets(1, 2, 1, 2);
92 
93         GridBagConstraints constraintsStretch = new GridBagConstraints();
94         constraintsStretch.fill    = GridBagConstraints.HORIZONTAL;
95         constraintsStretch.weightx = 1.0;
96         constraintsStretch.anchor  = GridBagConstraints.WEST;
97         constraintsStretch.insets  = constraints.insets;
98 
99         GridBagConstraints constraintsLast = new GridBagConstraints();
100         constraintsLast.gridwidth = GridBagConstraints.REMAINDER;
101         constraintsLast.anchor    = GridBagConstraints.WEST;
102         constraintsLast.insets    = constraints.insets;
103 
104         GridBagConstraints constraintsLastStretch = new GridBagConstraints();
105         constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER;
106         constraintsLastStretch.fill      = GridBagConstraints.HORIZONTAL;
107         constraintsLastStretch.weightx   = 1.0;
108         constraintsLastStretch.anchor    = GridBagConstraints.WEST;
109         constraintsLastStretch.insets    = constraints.insets;
110 
111         GridBagConstraints panelConstraints = new GridBagConstraints();
112         panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
113         panelConstraints.fill      = GridBagConstraints.HORIZONTAL;
114         panelConstraints.weightx   = 1.0;
115         panelConstraints.weighty   = 0.0;
116         panelConstraints.anchor    = GridBagConstraints.NORTHWEST;
117         panelConstraints.insets    = constraints.insets;
118 
119         GridBagConstraints stretchPanelConstraints = new GridBagConstraints();
120         stretchPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;
121         stretchPanelConstraints.fill      = GridBagConstraints.BOTH;
122         stretchPanelConstraints.weightx   = 1.0;
123         stretchPanelConstraints.weighty   = 1.0;
124         stretchPanelConstraints.anchor    = GridBagConstraints.NORTHWEST;
125         stretchPanelConstraints.insets    = constraints.insets;
126 
127         GridBagConstraints labelConstraints = new GridBagConstraints();
128         labelConstraints.anchor = GridBagConstraints.CENTER;
129         labelConstraints.insets = new Insets(2, 10, 2, 10);
130 
131         GridBagConstraints lastLabelConstraints = new GridBagConstraints();
132         lastLabelConstraints.gridwidth = GridBagConstraints.REMAINDER;
133         lastLabelConstraints.anchor    = GridBagConstraints.CENTER;
134         lastLabelConstraints.insets    = labelConstraints.insets;
135 
136         GridBagConstraints advancedButtonConstraints = new GridBagConstraints();
137         advancedButtonConstraints.weightx = 1.0;
138         advancedButtonConstraints.weighty = 1.0;
139         advancedButtonConstraints.anchor  = GridBagConstraints.SOUTHWEST;
140         advancedButtonConstraints.insets  = new Insets(4, 4, 8, 4);
141 
142         GridBagConstraints okButtonConstraints = new GridBagConstraints();
143         okButtonConstraints.weightx = 1.0;
144         okButtonConstraints.weighty = 1.0;
145         okButtonConstraints.anchor  = GridBagConstraints.SOUTHEAST;
146         okButtonConstraints.insets  = advancedButtonConstraints.insets;
147 
148         GridBagConstraints cancelButtonConstraints = new GridBagConstraints();
149         cancelButtonConstraints.gridwidth = GridBagConstraints.REMAINDER;
150         cancelButtonConstraints.weighty   = 1.0;
151         cancelButtonConstraints.anchor    = GridBagConstraints.SOUTHEAST;
152         cancelButtonConstraints.insets    = advancedButtonConstraints.insets;
153 
154         GridBagLayout layout = new GridBagLayout();
155 
156         Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
157 
158         // Create the comments panel.
159         JPanel commentsPanel = new JPanel(layout);
160         commentsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
161                                                                  msg("comments")));
162 
163         JScrollPane commentsScrollPane = new JScrollPane(commentsTextArea);
164         commentsScrollPane.setBorder(classNameTextField.getBorder());
165 
166         commentsPanel.add(tip(commentsScrollPane, "commentsTip"), constraintsLastStretch);
167 
168         // Create the keep option panel.
169         ButtonGroup keepButtonGroup = new ButtonGroup();
170         keepButtonGroup.add(keepClassesAndMembersRadioButton);
171         keepButtonGroup.add(keepClassMembersRadioButton);
172         keepButtonGroup.add(keepClassesWithMembersRadioButton);
173 
174         JPanel keepOptionPanel = new JPanel(layout);
175         keepOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
176                                                                    msg("keepTitle")));
177 
178         keepOptionPanel.add(tip(keepClassesAndMembersRadioButton,  "keepTip"),                   constraintsLastStretch);
179         keepOptionPanel.add(tip(keepClassMembersRadioButton,       "keepClassMembersTip"),       constraintsLastStretch);
180         keepOptionPanel.add(tip(keepClassesWithMembersRadioButton, "keepClassesWithMembersTip"), constraintsLastStretch);
181         keepOptionPanel.add(tip(keepDescriptorClassesCheckBox,  "keepDescriptorClassesTip"),  constraintsLastStretch);
182 
183         // Create the also keep panel.
184         final JPanel alsoKeepOptionPanel = new JPanel(layout);
185         alsoKeepOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
186                                                                        msg("alsoKeepTitle")));
187 
188         alsoKeepOptionPanel.add(tip(keepDescriptorClassesCheckBox, "keepDescriptorClassesTip"),    constraintsLastStretch);
189 
190         // Create the allow option panel.
191         final JPanel allowOptionPanel = new JPanel(layout);
192         allowOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
193                                                                     msg("allowTitle")));
194 
195         allowOptionPanel.add(tip(allowShrinkingCheckBox,    "allowShrinkingTip"),    constraintsLastStretch);
196         allowOptionPanel.add(tip(allowOptimizationCheckBox, "allowOptimizationTip"), constraintsLastStretch);
197         allowOptionPanel.add(tip(allowObfuscationCheckBox,  "allowObfuscationTip"),  constraintsLastStretch);
198 
199         // Create the access panel.
200         JPanel accessPanel = new JPanel(layout);
201         accessPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
202                                                                msg("access")));
203 
204         accessPanel.add(Box.createGlue(),                                labelConstraints);
205         accessPanel.add(tip(new JLabel(msg("required")), "requiredTip"), labelConstraints);
206         accessPanel.add(tip(new JLabel(msg("not")),      "notTip"),      labelConstraints);
207         accessPanel.add(tip(new JLabel(msg("dontCare")), "dontCareTip"), labelConstraints);
208         accessPanel.add(Box.createGlue(),                                constraintsLastStretch);
209 
210         publicRadioButtons     = addRadioButtonTriplet("Public",     accessPanel);
211         finalRadioButtons      = addRadioButtonTriplet("Final",      accessPanel);
212         abstractRadioButtons   = addRadioButtonTriplet("Abstract",   accessPanel);
213         interfaceRadioButtons  = addRadioButtonTriplet("Interface",  accessPanel);
214         annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
215         enumRadioButtons       = addRadioButtonTriplet("Enum",       accessPanel);
216         syntheticRadioButtons  = addRadioButtonTriplet("Synthetic",  accessPanel);
217 
218         // Create the annotation type panel.
219         final JPanel annotationTypePanel = new JPanel(layout);
220         annotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
221                                                                        msg("annotation")));
222 
223         annotationTypePanel.add(tip(annotationTypeTextField, "classNameTip"), constraintsLastStretch);
224 
225         // Create the class name panel.
226         JPanel classNamePanel = new JPanel(layout);
227         classNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
228                                                                   msg("class")));
229 
230         classNamePanel.add(tip(classNameTextField, "classNameTip"), constraintsLastStretch);
231 
232         // Create the extends annotation type panel.
233         final JPanel extendsAnnotationTypePanel = new JPanel(layout);
234         extendsAnnotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
235                                                                               msg("extendsImplementsAnnotation")));
236 
237         extendsAnnotationTypePanel.add(tip(extendsAnnotationTypeTextField, "classNameTip"), constraintsLastStretch);
238 
239         // Create the extends class name panel.
240         JPanel extendsClassNamePanel = new JPanel(layout);
241         extendsClassNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
242                                                                          msg("extendsImplementsClass")));
243 
244         extendsClassNamePanel.add(tip(extendsClassNameTextField, "classNameTip"), constraintsLastStretch);
245 
246 
247         // Create the class member list panel.
248         memberSpecificationsPanel = new MemberSpecificationsPanel(this, fullKeepOptions);
249         memberSpecificationsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
250                                                                              msg("classMembers")));
251 
252         // Create the Advanced button.
253         final JButton advancedButton = new JButton(msg("basic"));
254         advancedButton.addActionListener(new ActionListener()
255         {
256             public void actionPerformed(ActionEvent e)
257             {
258                 boolean visible = !alsoKeepOptionPanel.isVisible();
259 
260                 alsoKeepOptionPanel       .setVisible(visible);
261                 allowOptionPanel          .setVisible(visible);
262                 annotationTypePanel       .setVisible(visible);
263                 extendsAnnotationTypePanel.setVisible(visible);
264 
265                 advancedButton.setText(msg(visible ? "basic" : "advanced"));
266 
267                 pack();
268             }
269         });
270         advancedButton.doClick();
271 
272         // Create the Ok button.
273         JButton okButton = new JButton(msg("ok"));
274         okButton.addActionListener(new ActionListener()
275         {
276             public void actionPerformed(ActionEvent e)
277             {
278                 returnValue = APPROVE_OPTION;
279                 hide();
280             }
281         });
282 
283         // Create the Cancel button.
284         JButton cancelButton = new JButton(msg("cancel"));
285         cancelButton.addActionListener(new ActionListener()
286         {
287             public void actionPerformed(ActionEvent e)
288             {
289                 hide();
290             }
291         });
292 
293         // Add all panels to the main panel.
294         JPanel mainPanel = new JPanel(layout);
295         mainPanel.add(tip(commentsPanel,              "commentsTip"),                    panelConstraints);
296         if (fullKeepOptions)
297         {
298             mainPanel.add(tip(keepOptionPanel,        "keepTitleTip"),                   panelConstraints);
299             mainPanel.add(tip(alsoKeepOptionPanel,    "alsoKeepTitleTip"),               panelConstraints);
300             mainPanel.add(tip(allowOptionPanel,       "allowTitleTip"),                  panelConstraints);
301         }
302         mainPanel.add(tip(accessPanel,                "accessTip"),                      panelConstraints);
303         mainPanel.add(tip(annotationTypePanel,        "annotationTip"),                  panelConstraints);
304         mainPanel.add(tip(classNamePanel,             "classTip"),                       panelConstraints);
305         mainPanel.add(tip(extendsAnnotationTypePanel, "extendsImplementsAnnotationTip"), panelConstraints);
306         mainPanel.add(tip(extendsClassNamePanel,      "extendsImplementsClassTip"),      panelConstraints);
307         mainPanel.add(tip(memberSpecificationsPanel,  "classMembersTip"),                stretchPanelConstraints);
308 
309         mainPanel.add(tip(advancedButton, "advancedTip"), advancedButtonConstraints);
310         mainPanel.add(okButton,                           okButtonConstraints);
311         mainPanel.add(cancelButton,                       cancelButtonConstraints);
312 
313         getContentPane().add(new JScrollPane(mainPanel));
314     }
315 
316 
317     /**
318      * Adds a JLabel and three JRadioButton instances in a ButtonGroup to the
319      * given panel with a GridBagLayout, and returns the buttons in an array.
320      */
addRadioButtonTriplet(String labelText, JPanel panel)321     private JRadioButton[] addRadioButtonTriplet(String labelText,
322                                                  JPanel panel)
323     {
324         GridBagConstraints labelConstraints = new GridBagConstraints();
325         labelConstraints.anchor = GridBagConstraints.WEST;
326         labelConstraints.insets = new Insets(2, 10, 2, 10);
327 
328         GridBagConstraints buttonConstraints = new GridBagConstraints();
329         buttonConstraints.insets = labelConstraints.insets;
330 
331         GridBagConstraints lastGlueConstraints = new GridBagConstraints();
332         lastGlueConstraints.gridwidth = GridBagConstraints.REMAINDER;
333         lastGlueConstraints.weightx   = 1.0;
334 
335         // Create the radio buttons.
336         JRadioButton radioButton0 = new JRadioButton();
337         JRadioButton radioButton1 = new JRadioButton();
338         JRadioButton radioButton2 = new JRadioButton();
339 
340         // Put them in a button group.
341         ButtonGroup buttonGroup = new ButtonGroup();
342         buttonGroup.add(radioButton0);
343         buttonGroup.add(radioButton1);
344         buttonGroup.add(radioButton2);
345 
346         // Add the label and the buttons to the panel.
347         panel.add(new JLabel(labelText), labelConstraints);
348         panel.add(radioButton0,          buttonConstraints);
349         panel.add(radioButton1,          buttonConstraints);
350         panel.add(radioButton2,          buttonConstraints);
351         panel.add(Box.createGlue(),      lastGlueConstraints);
352 
353         return new JRadioButton[]
354         {
355              radioButton0,
356              radioButton1,
357              radioButton2
358         };
359     }
360 
361 
362     /**
363      * Sets the KeepClassSpecification to be represented in this dialog.
364      */
setKeepSpecification(KeepClassSpecification keepClassSpecification)365     public void setKeepSpecification(KeepClassSpecification keepClassSpecification)
366     {
367         boolean markClasses           = keepClassSpecification.markClasses;
368         boolean markConditionally     = keepClassSpecification.markConditionally;
369         boolean markDescriptorClasses = keepClassSpecification.markDescriptorClasses;
370         boolean allowShrinking        = keepClassSpecification.allowShrinking;
371         boolean allowOptimization     = keepClassSpecification.allowOptimization;
372         boolean allowObfuscation      = keepClassSpecification.allowObfuscation;
373 
374         // Figure out the proper keep radio button and set it.
375         JRadioButton keepOptionRadioButton =
376             markConditionally ? keepClassesWithMembersRadioButton :
377             markClasses       ? keepClassesAndMembersRadioButton  :
378                                 keepClassMembersRadioButton;
379 
380         keepOptionRadioButton.setSelected(true);
381 
382         // Set the other check boxes.
383         keepDescriptorClassesCheckBox.setSelected(markDescriptorClasses);
384         allowShrinkingCheckBox       .setSelected(allowShrinking);
385         allowOptimizationCheckBox    .setSelected(allowOptimization);
386         allowObfuscationCheckBox     .setSelected(allowObfuscation);
387 
388         setClassSpecification(keepClassSpecification);
389     }
390 
391 
392     /**
393      * Sets the ClassSpecification to be represented in this dialog.
394      */
setClassSpecification(ClassSpecification classSpecification)395     public void setClassSpecification(ClassSpecification classSpecification)
396     {
397         String comments              = classSpecification.comments;
398         String annotationType        = classSpecification.annotationType;
399         String className             = classSpecification.className;
400         String extendsAnnotationType = classSpecification.extendsAnnotationType;
401         String extendsClassName      = classSpecification.extendsClassName;
402         List   keepFieldOptions      = classSpecification.fieldSpecifications;
403         List   keepMethodOptions     = classSpecification.methodSpecifications;
404 
405         // Set the comments text area.
406         commentsTextArea.setText(comments == null ? "" : comments);
407 
408         // Set the access radio buttons.
409         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_PUBLIC,      publicRadioButtons);
410         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_FINAL,       finalRadioButtons);
411         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ABSTRACT,    abstractRadioButtons);
412         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_INTERFACE,   interfaceRadioButtons);
413         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ANNOTATTION, annotationRadioButtons);
414         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ENUM,        enumRadioButtons);
415         setClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_SYNTHETIC,   syntheticRadioButtons);
416 
417         // Set the class and annotation text fields.
418         annotationTypeTextField       .setText(annotationType        == null ? ""  : ClassUtil.externalType(annotationType));
419         classNameTextField            .setText(className             == null ? "*" : ClassUtil.externalClassName(className));
420         extendsAnnotationTypeTextField.setText(extendsAnnotationType == null ? ""  : ClassUtil.externalType(extendsAnnotationType));
421         extendsClassNameTextField     .setText(extendsClassName      == null ? ""  : ClassUtil.externalClassName(extendsClassName));
422 
423         // Set the keep class member option list.
424         memberSpecificationsPanel.setMemberSpecifications(keepFieldOptions, keepMethodOptions);
425     }
426 
427 
428     /**
429      * Returns the KeepClassSpecification currently represented in this dialog.
430      */
getKeepSpecification()431     public KeepClassSpecification getKeepSpecification()
432     {
433         boolean markClasses           = !keepClassMembersRadioButton     .isSelected();
434         boolean markConditionally     = keepClassesWithMembersRadioButton.isSelected();
435         boolean markDescriptorClasses = keepDescriptorClassesCheckBox    .isSelected();
436         boolean allowShrinking        = allowShrinkingCheckBox           .isSelected();
437         boolean allowOptimization     = allowOptimizationCheckBox        .isSelected();
438         boolean allowObfuscation      = allowObfuscationCheckBox         .isSelected();
439 
440         return new KeepClassSpecification(markClasses,
441                                           markConditionally,
442                                           markDescriptorClasses,
443                                           allowShrinking,
444                                           allowOptimization,
445                                           allowObfuscation,
446                                           getClassSpecification());
447     }
448 
449 
450     /**
451      * Returns the ClassSpecification currently represented in this dialog.
452      */
getClassSpecification()453     public ClassSpecification getClassSpecification()
454     {
455         String comments              = commentsTextArea.getText();
456         String annotationType        = annotationTypeTextField.getText();
457         String className             = classNameTextField.getText();
458         String extendsAnnotationType = extendsAnnotationTypeTextField.getText();
459         String extendsClassName      = extendsClassNameTextField.getText();
460 
461         ClassSpecification classSpecification =
462             new ClassSpecification(comments.equals("")              ? null : comments,
463                                    0,
464                                    0,
465                                    annotationType.equals("")        ? null : ClassUtil.internalType(annotationType),
466                                    className.equals("") ||
467                                    className.equals("*")            ? null : ClassUtil.internalClassName(className),
468                                    extendsAnnotationType.equals("") ? null : ClassUtil.internalType(extendsAnnotationType),
469                                    extendsClassName.equals("")      ? null : ClassUtil.internalClassName(extendsClassName));
470 
471         // Also get the access radio button settings.
472         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_PUBLIC,      publicRadioButtons);
473         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_FINAL,       finalRadioButtons);
474         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ABSTRACT,    abstractRadioButtons);
475         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_INTERFACE,   interfaceRadioButtons);
476         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ANNOTATTION, annotationRadioButtons);
477         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_ENUM,        enumRadioButtons);
478         getClassSpecificationRadioButtons(classSpecification, ClassConstants.ACC_SYNTHETIC,   syntheticRadioButtons);
479 
480         // Get the keep class member option lists.
481         classSpecification.fieldSpecifications  = memberSpecificationsPanel.getMemberSpecifications(true);
482         classSpecification.methodSpecifications = memberSpecificationsPanel.getMemberSpecifications(false);
483 
484         return classSpecification;
485     }
486 
487 
488     /**
489      * Shows this dialog. This method only returns when the dialog is closed.
490      *
491      * @return <code>CANCEL_OPTION</code> or <code>APPROVE_OPTION</code>,
492      *         depending on the choice of the user.
493      */
showDialog()494     public int showDialog()
495     {
496         returnValue = CANCEL_OPTION;
497 
498         // Open the dialog in the right place, then wait for it to be closed,
499         // one way or another.
500         pack();
501         setLocationRelativeTo(getOwner());
502         show();
503 
504         return returnValue;
505     }
506 
507 
508     /**
509      * Sets the appropriate radio button of a given triplet, based on the access
510      * flags of the given keep option.
511      */
setClassSpecificationRadioButtons(ClassSpecification classSpecification, int flag, JRadioButton[] radioButtons)512     private void setClassSpecificationRadioButtons(ClassSpecification classSpecification,
513                                                    int                flag,
514                                                    JRadioButton[]     radioButtons)
515     {
516         int index = (classSpecification.requiredSetAccessFlags   & flag) != 0 ? 0 :
517                     (classSpecification.requiredUnsetAccessFlags & flag) != 0 ? 1 :
518                                                                                  2;
519         radioButtons[index].setSelected(true);
520     }
521 
522 
523     /**
524      * Updates the access flag of the given keep option, based on the given radio
525      * button triplet.
526      */
getClassSpecificationRadioButtons(ClassSpecification classSpecification, int flag, JRadioButton[] radioButtons)527     private void getClassSpecificationRadioButtons(ClassSpecification classSpecification,
528                                                    int                flag,
529                                                    JRadioButton[]     radioButtons)
530     {
531         if      (radioButtons[0].isSelected())
532         {
533             classSpecification.requiredSetAccessFlags   |= flag;
534         }
535         else if (radioButtons[1].isSelected())
536         {
537             classSpecification.requiredUnsetAccessFlags |= flag;
538         }
539     }
540 
541 
542     /**
543      * Attaches the tool tip from the GUI resources that corresponds to the
544      * given key, to the given component.
545      */
tip(JComponent component, String messageKey)546     private static JComponent tip(JComponent component, String messageKey)
547     {
548         component.setToolTipText(msg(messageKey));
549 
550         return component;
551     }
552 
553 
554     /**
555      * Returns the message from the GUI resources that corresponds to the given
556      * key.
557      */
msg(String messageKey)558     private static String msg(String messageKey)
559     {
560          return GUIResources.getMessage(messageKey);
561     }
562 }
563