xref: /titanic_44/usr/src/cmd/krb5/kadmin/gui/dataclasses/Defaults.java (revision 9dd0f810214fdc8e1af881a9a5c4b6927629ff9e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.util.*;
32 import java.text.*;
33 import java.io.*;
34 
35 /**
36  * Defaults class stores all defaults that are recorded locally on the
37  * client side.  It is also resonsible for showing the DefaultsFrame
38  * which allows the user to see and change these values.
39  */
40 public class Defaults {
41 
42   // These gui components are the actual components that go on the editing frame
43   // that  allows the user to change the defaults. The reason they are public is
44   // that they  need to be accessible to KdcGui so that it can set up the
45   // listeners for them in  setupDefaultsNormalListeners() and
46   // setupDefaultsHelpListeners().
47     public Checkbox disableAccount;
48     public Checkbox forcePasswordChange;
49     public Checkbox allowPostdatedTix;
50     public Checkbox allowForwardableTix;
51     public Checkbox allowRenewableTix;
52     public Checkbox allowProxiableTix;
53     public Checkbox allowServiceTix;
54     public Checkbox allowTGTAuth;
55     public Checkbox allowDupAuth;
56     public Checkbox requirePreauth;
57     public Checkbox requireHWAuth;
58 
59     public Checkbox serverSide;
60     public TextField maxTicketLife;
61     public TextField maxTicketRenewableLife;
62     public TextField accountExpiryDate;
63 
64     public Label maxTicketLifeLabel;
65     public Label maxTicketRenewableLifeLabel;
66     public Label accountExpiryDateLabel;
67 
68     public Checkbox showLists;
69     public Checkbox staticLists;
70     public TextField cacheTime;
71 
72     public Label cacheTimeLabel;
73 
74     public Button lifeMoreButton;
75     public Button renewalMoreButton;
76     public Button dateMoreButton;
77     public Button cacheMoreButton;
78 
79     public Button saveButton;
80     public Button applyButton;
81     public Button cancelButton;
82 
83     public MenuItem csHelp;
84 
85   // These data items correspond to fields in struct struct
86   // _kadm5_config_params
87     private Flags flags;
88 
89     private boolean serverSideValue;
90     private int maxTicketLifeValue;
91     private int maxTicketRenewableLifeValue;
92     private Date accountExpiryDateValue;
93 
94     private boolean showListsValue;
95     private boolean staticListsValue;
96     private long cacheTimeValue;
97 
98     private String defaultsFile;
99     private Color background;
100 
101     private EditingFrame frame = null;
102 
103     private boolean helpMode = false;
104 
105   // For I18N
106     private static DateFormat df;
107     private static NumberFormat nf;
108     private static ResourceBundle rb;
109   // no help data since help is handled by KdcGui class
110 
111     private static String neverString;
112 
113   // For debugging the window arrangement
114 
115     Color SEPERATOR_COLOR = Color.blue;
116     Color CHECKBOX_COLOR = Color.orange;
117     Color LABEL_COLOR = Color.pink;
118     Color PANEL_COLOR1 = Color.lightGray;
119     Color PANEL_COLOR2 = Color.darkGray;
120 
121     /**
122      * Constructor for Defaults.
123      * @param defaultsFile the file from which to read the defaults.
124      */
125     Defaults(String defaultsFile, Color background) {
126         this.defaultsFile = defaultsFile;
127         this.background = background;
128         flags = new Flags();
129         serverSideValue = true;
130         maxTicketLifeValue = 144000;
131         maxTicketRenewableLifeValue = 144000;
132         // set expiry to now + one year
133         Calendar c = Calendar.getInstance();
134         c.roll(Calendar.YEAR, true);
135         accountExpiryDateValue = c.getTime();
136         showListsValue = true;
137         staticListsValue = false;
138         cacheTimeValue = 300;
139         readFromFile();
140     }
141 
142     /**
143      * Constructor for Defaults.
144      * @param old an existing defaults object to clone
145      */
146     Defaults(Defaults old) {
147         defaultsFile = old.defaultsFile;
148         background = old.background;
149         flags = new Flags(old.flags.getBits());
150 
151         maxTicketLifeValue = old.maxTicketLifeValue;
152         maxTicketRenewableLifeValue = old.maxTicketRenewableLifeValue;
153         accountExpiryDateValue = old.accountExpiryDateValue;
154         showListsValue = old.showListsValue;
155         staticListsValue = old.staticListsValue;
156         cacheTimeValue = old.cacheTimeValue;
157     }
158 
159     public void restoreValues(Defaults old) {
160         flags = new Flags(old.flags.getBits());
161         maxTicketLifeValue = old.maxTicketLifeValue;
162         maxTicketRenewableLifeValue = old.maxTicketRenewableLifeValue;
163         accountExpiryDateValue = old.accountExpiryDateValue;
164         showListsValue = old.showListsValue;
165         staticListsValue = old.staticListsValue;
166         cacheTimeValue = old.cacheTimeValue;
167         updateGuiComponents();
168     }
169 
170     /**
171      * Returns a gui Frame with the defaults on it for editing.
172      */
173     public Frame getEditingFrame() {
174         if (frame == null) {
175        	    frame = new EditingFrame();
176 	    updateGuiComponents();
177        	    frame.setSize(500, 680);
178 	    frame.setResizable(true);
179 	    frame.setBackground(background);
180         }
181         return frame;
182     }
183 
184     /**
185      * Reread the defaults file in case it has changed, and refresh view
186      */
187     public void refreshDefaults() {
188         readFromFile();
189         updateGuiComponents();
190     }
191 
192 
193     /**
194      * Update the duration and date text fields from gui.
195      * Check to see if any one of them had a parse error.
196      * @return true if all is ok, false if an error occurs
197      */
198     // Quits as soon as the first error is detected. The method that
199     // detects the error also shows a dialog box with a message.
200     public final boolean updateFromGui() {
201         return (setMaxTicketLife() && setMaxTicketRenewableLife()
202 	      && setAccountExpiryDate()	&& setCacheTime());
203     }
204 
205     boolean setServerSide() {
206         serverSideValue = serverSide.getState();
207         enableTicketLifeFields(serverSideValue);
208         return true;
209     }
210 
211     private void enableTicketLifeFields(boolean fromServer) {
212         maxTicketLifeLabel.setEnabled(!fromServer);
213         maxTicketLife.setEnabled(!fromServer);
214         maxTicketRenewableLifeLabel.setEnabled(!fromServer);
215         maxTicketRenewableLife.setEnabled(!fromServer);
216         lifeMoreButton.setEnabled(!fromServer);
217         renewalMoreButton.setEnabled(!fromServer);
218     }
219 
220     boolean setMaxTicketLife() {
221         try {
222             maxTicketLifeValue =
223                 nf.parse(maxTicketLife.getText().trim()).intValue();
224         } catch (ParseException e) {
225             KdcGui.showDataFormatError(maxTicketLife, KdcGui.DURATION_DATA);
226             return false;
227         }
228 
229         return true;
230     }
231 
232     /**
233      * Sets the maxTicketRenewable field value from the corresponding text
234      * field.
235      */
236     boolean setMaxTicketRenewableLife() {
237         try {
238             maxTicketRenewableLifeValue =
239                 nf.parse(maxTicketRenewableLife.getText().trim()).intValue();
240         } catch (ParseException e) {
241             KdcGui.showDataFormatError(maxTicketRenewableLife,
242                                        KdcGui.DURATION_DATA);
243             return false;
244         }
245 
246         return true;
247     }
248 
249     /**
250      * Sets the accountExpiryDate field value from the corresponding text field.
251      */
252     boolean setAccountExpiryDate() {
253         String value = accountExpiryDate.getText().trim();
254         if (value.equalsIgnoreCase(neverString))
255             accountExpiryDateValue = new Date(0);
256         else {
257             try {
258         	accountExpiryDateValue = df.parse(value);
259             } catch (ParseException e) {
260         	KdcGui.showDataFormatError(accountExpiryDate, KdcGui.DATE_DATA);
261         	return false;
262             } catch (NullPointerException e) {
263         	// gets thrown when parse string begins with text
264         	// probable JDK bug
265         	KdcGui.showDataFormatError(accountExpiryDate, KdcGui.DATE_DATA);
266         	return false;
267             } catch (IndexOutOfBoundsException e) {
268         	// gets thrown when parse string contains only one number
269         	// probable JDK bug
270         	KdcGui.showDataFormatError(accountExpiryDate, KdcGui.DATE_DATA);
271         	return false;
272             }
273         }
274         return true;
275     }
276 
277     /**
278      * Sets the cacheTime field value from the corresponding text field.
279      */
280     boolean setCacheTime() {
281         try {
282             cacheTimeValue = nf.parse(cacheTime.getText().trim()).intValue();
283         } catch (ParseException e) {
284             KdcGui.showDataFormatError(cacheTime, KdcGui.DURATION_DATA);
285             return false;
286         }
287         return true;
288     }
289 
290     boolean setShowLists() {
291         showListsValue = showLists.getState();
292         return true;
293     }
294 
295     boolean setStaticLists() {
296         staticListsValue = staticLists.getState();
297         enableCacheTimeFields(staticListsValue);
298         return true;
299     }
300 
301     private void enableCacheTimeFields(boolean staticLists) {
302         cacheTime.setEnabled(!staticLists);
303         cacheTimeLabel.setEnabled(!staticLists);
304         cacheMoreButton.setEnabled(!staticLists);
305     }
306 
307     public boolean getServerSide() {
308         return serverSideValue;
309     }
310 
311     public Integer getMaxTicketLife() {
312         return new Integer(maxTicketLifeValue);
313     }
314 
315     public Integer getMaxTicketRenewableLife() {
316         return new Integer(maxTicketRenewableLifeValue);
317     }
318 
319     public Date getAccountExpiryDate() {
320         return new Date(accountExpiryDateValue.getTime());
321     }
322 
323     public boolean getShowLists() {
324         return showListsValue;
325     }
326 
327     public boolean getStaticLists() {
328         return staticListsValue;
329     }
330 
331     public boolean getCacheLists() {
332         return staticListsValue;
333     }
334 
335     public long getCacheTime() {
336         return cacheTimeValue;
337     }
338 
339     public Flags getFlags() {
340         return flags;
341     }
342 
343     /**
344      * Toggles the value of the  bit specified.
345      */
346     public void toggleFlag(int bitmask) {
347         flags.toggleFlags(bitmask);
348     }
349 
350     public void close(boolean save) {
351         if (frame != null)
352             frame.close(save);
353     }
354 
355 
356     /**
357      * Saves the fields onto a file.
358      */
359     private void saveToFile() {
360         try {
361             PrintWriter outFile = null;
362             outFile = new PrintWriter(
363                       new BufferedWriter(new FileWriter(defaultsFile)));
364             outFile.println(flags.getBits());
365             outFile.println(maxTicketRenewableLifeValue);
366             outFile.println(df.format(accountExpiryDateValue));
367             outFile.println((new Boolean(showListsValue)).toString());
368             outFile.println((new Boolean(staticListsValue)).toString());
369             outFile.println((new Long(cacheTimeValue)).toString());
370             outFile.println(serverSideValue);
371             outFile.println(maxTicketLifeValue);
372             outFile.flush();
373             outFile.close();
374         } catch (IOException e) { /* xxx: warn user */ }
375     }
376 
377     /**
378      * Reads the fields from a file.
379      */
380     private void readFromFile() {
381         try {
382             BufferedReader inFile = null;
383             inFile = new BufferedReader(new FileReader(defaultsFile));
384             flags = new Flags(new Integer(inFile.readLine()).intValue());
385             maxTicketRenewableLifeValue =
386                 new Integer(inFile.readLine()).intValue();
387             accountExpiryDateValue = df.parse(inFile.readLine());
388             String s;
389             s = inFile.readLine();
390             if (s == null)
391         	showListsValue = true;
392             else
393         	showListsValue = (new Boolean(s)).booleanValue();
394             s = inFile.readLine();
395             if (s == null)
396         	staticListsValue = false;
397             else
398         	staticListsValue = (new Boolean(s)).booleanValue();
399             s = inFile.readLine();
400             if (s == null)
401         	cacheTimeValue = 300;
402             else try {
403         	cacheTimeValue = nf.parse(s).longValue();
404             } catch (ParseException e) {
405         	cacheTimeValue = 300;
406             }
407             serverSideValue = new Boolean(inFile.readLine()).booleanValue();
408             maxTicketLifeValue = new Integer(inFile.readLine()).intValue();
409         } catch (FileNotFoundException e) {
410             /* default values. new file will be created automatically. */}
411         catch (IOException e) { /* will create new one */}
412         catch (ParseException e) { /* leave default values in */}
413         catch (NumberFormatException e) { /* leave default values in */}
414         catch (NullPointerException e) { /* leave default values in */}
415         catch (StringIndexOutOfBoundsException e) {
416             /* leave default values in */}
417     }
418 
419     /**
420      * Sets the value of the gui components from the instance variables
421      * that get filled from the defaultsFile.
422      */
423     public void updateGuiComponents() {
424         if (frame == null)
425             getEditingFrame();
426         else {
427             updateFlags();
428             serverSide.setState(serverSideValue);
429             enableTicketLifeFields(serverSideValue);
430             maxTicketLife.setText(nf.format(maxTicketLifeValue));
431             maxTicketRenewableLife.setText(
432                 nf.format(maxTicketRenewableLifeValue));
433             String text = (accountExpiryDateValue.getTime() == 0 ? neverString
434 		     : df.format(accountExpiryDateValue));
435             accountExpiryDate.setText(text);
436             showLists.setState(showListsValue);
437             staticLists.setState(staticListsValue);
438             enableCacheTimeFields(staticListsValue);
439             cacheTime.setText((new Long(cacheTimeValue)).toString());
440         }
441     }
442 
443     private void updateFlags() {
444         disableAccount.setState(flags.getFlag(Flags.DISALLOW_ALL_TIX));
445         forcePasswordChange.setState(flags.getFlag(Flags.REQUIRES_PWCHANGE));
446         allowPostdatedTix.setState(!flags.getFlag(Flags.DISALLOW_POSTDATED));
447         allowForwardableTix.setState(!flags.getFlag(
448             Flags.DISALLOW_FORWARDABLE));
449         allowRenewableTix.setState(!flags.getFlag(Flags.DISALLOW_RENEWABLE));
450         allowProxiableTix.setState(!flags.getFlag(Flags.DISALLOW_PROXIABLE));
451         allowServiceTix.setState(!flags.getFlag(Flags.DISALLOW_SVR));
452         allowTGTAuth.setState(!flags.getFlag(Flags.DISALLOW_TGT_BASED));
453         allowDupAuth.setState(!flags.getFlag(Flags.DISALLOW_DUP_SKEY));
454         requirePreauth.setState(flags.getFlag(Flags.REQUIRE_PRE_AUTH));
455         requireHWAuth.setState(flags.getFlag(Flags.REQUIRE_HW_AUTH));
456     }
457 
458     /**
459      * Call rb.getString(), but catch exception and return English
460      * key so that small spelling errors don't cripple the GUI
461      *
462      */
463     private static final String getString(String key) {
464         try {
465             String res = rb.getString(key);
466 	    return res;
467         } catch (MissingResourceException e) {
468 	    System.out.println("Missing resource "+key+", using English.");
469 	    return key;
470         }
471     }
472 
473     /*
474      **********************************************
475      *         I N N E R   C L A S S E S
476      **********************************************
477      */
478 
479     private class EditingFrame extends Frame {
480         public EditingFrame() {
481             super(getString("Properties"));
482             setLayout(new GridBagLayout());
483             GridBagConstraints gbc = new GridBagConstraints();
484             gbc.weightx = gbc.weighty = 1;
485             gbc.fill = GridBagConstraints.BOTH;
486             gbc.gridwidth = GridBagConstraints.REMAINDER;
487             Label l;
488             l = new Label(getString("Defaults for New Principals"),
489                                     Label.CENTER);
490             l.setFont(new Font("Dialog", Font.PLAIN, 16));
491             //            l.setBackground(LABEL_COLOR);
492             gbc.insets = new Insets(10, 10, 0, 10);
493             add(l, gbc);
494             addFlags();
495             gbc.insets = new Insets(10, 10, 10, 10);
496             add(new LineSeparator(), gbc);
497             addTextFields();
498             add(new LineSeparator(), gbc);
499 
500             gbc.insets = new Insets(0, 10, 10, 10);
501             l = new Label(getString("List Controls"), Label.CENTER);
502             l.setFont(new Font("Dialog", Font.PLAIN, 16));
503 
504             add(l, gbc);
505             gbc.insets = new Insets(0, 10, 10, 10);
506             add(new LineSeparator(), gbc);
507             addListFields();
508             addButtons();
509             addWindowListener(new WindowCloseListener());
510             addHelpMenu();
511         }
512 
513         /**
514          * Helper method for constructor to add checkboxes and labels for
515          * flags.
516          */
517         private void addFlags() {
518             Panel p = new Panel();
519             GridBagConstraints gbc = new GridBagConstraints();
520             gbc.weightx = gbc.weighty = 1;
521             gbc.fill = GridBagConstraints.BOTH;
522             gbc.gridwidth = GridBagConstraints.REMAINDER;
523             gbc.insets = new Insets(0, 10, 0, 10);
524             p.setLayout(new GridBagLayout());
525             add(p, gbc);
526 
527             disableAccount = new Checkbox();
528             forcePasswordChange = new Checkbox();
529             allowPostdatedTix = new Checkbox();
530             allowForwardableTix = new Checkbox();
531             allowRenewableTix = new Checkbox();
532             allowProxiableTix = new Checkbox();
533             allowServiceTix = new Checkbox();
534             allowTGTAuth = new Checkbox();
535             allowDupAuth = new Checkbox();
536             requirePreauth = new Checkbox();
537             requireHWAuth = new Checkbox();
538 
539             addSeperatorPanel(getString("Security"), p);
540 
541             gbc = new GridBagConstraints();
542             gbc.anchor  = GridBagConstraints.WEST;
543 
544             addFlag(disableAccount,
545     		    Flags.DISALLOW_ALL_TIX, p, gbc, false);
546             addFlag(forcePasswordChange,
547 		    Flags.REQUIRES_PWCHANGE,  p, gbc, true);
548 
549             addSeperatorPanel(getString("Ticket"), p);
550             addFlag(allowPostdatedTix,
551 		    Flags.DISALLOW_POSTDATED,  p, gbc, false);
552             addFlag(allowForwardableTix,
553 		    Flags.DISALLOW_FORWARDABLE,  p, gbc, true);
554             addFlag(allowRenewableTix,
555 		    Flags.DISALLOW_RENEWABLE,  p, gbc, false);
556             addFlag(allowProxiableTix,
557 		    Flags.DISALLOW_PROXIABLE,  p, gbc, true);
558             addFlag(allowServiceTix,
559       		    Flags.DISALLOW_SVR,  p, gbc, true);
560 
561             addSeperatorPanel(getString("Miscellaneous"), p);
562             addFlag(allowTGTAuth,
563 		    Flags.DISALLOW_TGT_BASED,  p, gbc, false);
564             addFlag(allowDupAuth,
565 		    Flags.DISALLOW_DUP_SKEY,  p, gbc, true);
566             addFlag(requirePreauth,
567 		    Flags.REQUIRE_PRE_AUTH,  p, gbc, false);
568             addFlag(requireHWAuth,
569 		    Flags.REQUIRE_HW_AUTH,  p, gbc, true);
570         }
571 
572     /**
573      * Helper method for addFlags. It adds a line seperator with text
574      * inside it.
575      * @param text the text to put in the line seperator
576      * @p the panel to which this line seperator must be added
577      */
578     private void addSeperatorPanel(String text, Panel p) {
579         GridBagConstraints gbc = new GridBagConstraints();
580         gbc.weightx = gbc.weighty = 1;
581         gbc.fill = GridBagConstraints.BOTH;
582         gbc.gridwidth = GridBagConstraints.REMAINDER;
583         gbc.insets = new Insets(7, 0, 7, 0);
584 
585         Panel subP = new Panel();
586         //            subP.setBackground(SEPERATOR_COLOR);
587         subP.setLayout(new GridBagLayout());
588         p.add(subP, gbc);
589 
590         gbc = new GridBagConstraints();
591         gbc.fill = GridBagConstraints.BOTH;
592         gbc.weightx = gbc.weighty = .02;
593         subP.add(new LineSeparator(), gbc);
594 
595         gbc.weightx = gbc.weighty = .001;
596         gbc.fill = GridBagConstraints.NONE;
597         gbc.anchor = GridBagConstraints.EAST;
598         Label l = new Label(text);
599         l.setFont(new Font("Dialog", Font.ITALIC, 12));
600         subP.add(l, gbc);
601 
602         gbc.gridwidth = GridBagConstraints.REMAINDER;
603         gbc.weightx = gbc.weighty = 1;
604         gbc.fill = GridBagConstraints.BOTH;
605         gbc.anchor = GridBagConstraints.WEST;
606         subP.add(new LineSeparator(), gbc);
607     }
608 
609     /**
610      * Helper method for addFlags. It adds the label and the checkbox
611      * corresponding to the flag specified by the single bit that is set
612      * in mask.
613      * @param cb the Checkbox which has to be added corresponding to
614      *     this flag
615      * @param mask the flag
616      * @param p the panel to add this to
617      */
618     private void addFlag(Checkbox cb, int mask, Panel p,
619 			    GridBagConstraints gbc, boolean eol) {
620       //      cb.setBackground(CHECKBOX_COLOR);
621         cb.setState(flags.getFlag(mask));
622         cb.setLabel(Flags.getLabel(mask));
623         if (eol)
624             gbc.gridwidth = GridBagConstraints.REMAINDER;
625         else
626             gbc.gridwidth = 1;
627         p.add(cb, gbc);
628     }
629 
630     /**
631      * Helper method for constructor - adds Max ticket time, max renewal and def
632      * account expiry.
633      */
634     private void addTextFields() {
635         GridBagConstraints gbc = new GridBagConstraints();
636         gbc.weightx = gbc.weighty = 1;
637 
638         Panel p = new Panel();
639         //      p.setBackground(PANEL_COLOR1);
640         p.setLayout(new GridBagLayout());
641         gbc.fill = GridBagConstraints.VERTICAL;
642         gbc.gridwidth = GridBagConstraints.REMAINDER;
643         gbc.anchor = GridBagConstraints.WEST;
644         gbc.insets = new Insets(0, 10, 0, 10);
645         add(p, gbc);
646 
647         gbc = new GridBagConstraints();
648         gbc.weightx = gbc.weighty = 1;
649 
650         gbc.anchor = GridBagConstraints.EAST;
651         gbc.weightx = 0;
652         gbc.gridx = 0;
653         gbc.gridy = 0;
654         accountExpiryDateLabel = new Label(getString("Account Expiry:"));
655         //      accountExpiryDateLabel.setBackground(LABEL_COLOR);
656         p.add(accountExpiryDateLabel, gbc);
657         gbc.gridy = 2;
658         maxTicketLifeLabel =
659 		new Label(getString("Maximum Ticket Lifetime (seconds):"));
660         //      maxTicketLifeLabel.setBackground(LABEL_COLOR);
661         p.add(maxTicketLifeLabel, gbc);
662         gbc.gridy = 3;
663         maxTicketRenewableLifeLabel =
664 		new Label(getString("Maximum Ticket Renewal (seconds):"));
665         //      maxTicketRenewableLifeLabel.setBackground(LABEL_COLOR);
666         p.add(maxTicketRenewableLifeLabel, gbc);
667 
668         gbc.gridx = 1;
669         gbc.gridy = 0;
670         gbc.fill = GridBagConstraints.NONE;
671         gbc.anchor = GridBagConstraints.WEST;
672         accountExpiryDate = new TextField("1-Jan-70 00:00:00 PM");
673         accountExpiryDate.setColumns(22);
674         p.add(accountExpiryDate, gbc);
675         gbc.gridy = 2;
676         maxTicketLife = new TextField("144000");
677         maxTicketLife.setColumns(22);
678         p.add(maxTicketLife, gbc);
679         gbc.gridy = 3;
680         maxTicketRenewableLife = new TextField("144000");
681         maxTicketRenewableLife.setColumns(22);
682         p.add(maxTicketRenewableLife, gbc);
683 
684         gbc = new GridBagConstraints();
685         gbc.weightx = gbc.weighty = 0;
686         gbc.gridwidth = GridBagConstraints.REMAINDER;
687         gbc.anchor = GridBagConstraints.WEST;
688         gbc.gridx = 2;
689         gbc.gridy = 0;
690         dateMoreButton = new Button("...");
691         p.add(dateMoreButton, gbc);
692         gbc.gridy = 2;
693         lifeMoreButton = new Button("...");
694         p.add(lifeMoreButton, gbc);
695         gbc.gridy = 3;
696         renewalMoreButton = new Button("...");
697         p.add(renewalMoreButton, gbc);
698 
699         serverSide = new Checkbox();
700         //      serverSide.setBackground(CHECKBOX_COLOR);
701         serverSide.setLabel(getString(
702             "Let the KDC control the ticket lifetime values"));
703 
704         gbc = new GridBagConstraints();
705         gbc.anchor = GridBagConstraints.WEST;
706         gbc.gridwidth = GridBagConstraints.REMAINDER;
707         gbc.gridx = 0;
708         gbc.gridy = 1;
709         p.add(serverSide, gbc);
710 
711     }
712 
713     private void addListFields() {
714         Panel p = new Panel();
715         GridBagConstraints gbc = new GridBagConstraints();
716         gbc.weightx = gbc.weighty = 1;
717         gbc.fill = GridBagConstraints.VERTICAL;
718         gbc.anchor = GridBagConstraints.WEST;
719         gbc.gridwidth = GridBagConstraints.REMAINDER;
720         //      p.setBackground(PANEL_COLOR1);
721         gbc.insets = new Insets(0, 10, 0, 10);
722         p.setLayout(new GridBagLayout());
723         add(p, gbc);
724 
725         gbc = new GridBagConstraints();
726         gbc.anchor = GridBagConstraints.WEST;
727         gbc.gridwidth = GridBagConstraints.REMAINDER;
728         showLists = new Checkbox();
729         //      showLists.setBackground(CHECKBOX_COLOR);
730         showLists.setLabel(getString("Show Lists"));
731         p.add(showLists, gbc);
732 
733         gbc.gridwidth = 1;
734         gbc.anchor = GridBagConstraints.EAST;
735         staticLists = new Checkbox();
736         //      staticLists.setBackground(CHECKBOX_COLOR);
737         staticLists.setLabel(getString("Cache Lists Forever"));
738         p.add(staticLists, gbc);
739 
740         gbc.anchor = GridBagConstraints.EAST;
741         cacheTimeLabel = new Label(getString("List Cache Timeout (seconds):"));
742         //      cacheTimeLabel.setBackground(Color.green);
743         p.add(cacheTimeLabel, gbc);
744 
745         gbc.anchor = GridBagConstraints.WEST;
746         cacheTime = new TextField("300", 8);
747         //      cacheTime.setBackground(Color.cyan);
748         p.add(cacheTime, gbc);
749 
750         gbc.gridwidth = GridBagConstraints.REMAINDER;
751         gbc.weightx = gbc.weighty = 0;
752         cacheMoreButton = new Button("...");
753         p.add(cacheMoreButton, gbc);
754     }
755 
756 
757     /**
758      * Helper method for constructor - adds Save and Cancel
759      * buttons.
760      */
761     private void addButtons() {
762         GridBagConstraints gbc = new GridBagConstraints();
763         gbc.weightx = gbc.weighty = 1;
764 
765         Panel p = new Panel();
766         p.setLayout(new GridBagLayout());
767         gbc.fill = GridBagConstraints.BOTH;
768         gbc.gridwidth = GridBagConstraints.REMAINDER;
769         gbc.insets = new Insets(10, 10, 10, 10);
770         add(new LineSeparator(), gbc);
771         gbc.insets = new Insets(0, 0, 10, 0);
772         add(p, gbc);
773 
774         gbc = new GridBagConstraints();
775         gbc.weightx = gbc.weighty = 1;
776 
777         saveButton = new Button(getString("Save"));
778         p.add(saveButton, gbc);
779         applyButton = new Button(getString("Apply"));
780         p.add(applyButton, gbc);
781         cancelButton = new Button(getString("Cancel"));
782         p.add(cancelButton, gbc);
783     }
784 
785     private void addHelpMenu() {
786         MenuBar mb = new MenuBar();
787         setMenuBar(mb);
788 
789         Menu m = new Menu(getString("Help"));
790         mb.setHelpMenu(m);
791 
792         csHelp = new MenuItem(getString("Context-Sensitive Help"));
793         m.add(csHelp);
794     }
795 
796         /**
797          * Decides whether to save/discard edits and then closes
798          * window. If errors exist in the values entered in the fields, then
799          * it will not exit.
800          */
801         public void close(boolean save) {
802             if (save) {
803       	        if (!Defaults.this.updateFromGui())
804 	            return;
805     	        else
806 	            Defaults.this.saveToFile();
807             }
808             setVisible(false);
809         }
810 
811         // Listeners for the gui components:
812         private  class WindowCloseListener extends  WindowAdapter {
813             public void windowClosing(WindowEvent e) {
814     	        close(false);
815             }
816         }
817 
818     } // class EditingFrame
819 
820     public static void main(String argv[]) {
821         Defaults d = new Defaults("SomeFile", Color.white);
822         Frame f = d.getEditingFrame();
823         d.showLists.setSize(new Dimension(18, 22));
824         d.staticLists.setSize(new Dimension(18, 22));
825         f.setVisible(true);
826         System.out.println(d.disableAccount.getSize().toString()); // XXX
827         System.out.println(d.showLists.getSize().toString()); // XXX
828     }
829 
830     static {
831         df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
832                                             DateFormat.MEDIUM);
833         nf = NumberFormat.getInstance();
834         rb = ResourceBundle.getBundle("GuiResource" /* NOI18N */);
835         neverString = getString("Never");
836     }
837 
838 }
839