KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > key > passwd > swing > OpenKeyPanel


1 /*
2  * Copyright 2006 Schlichtherle IT Services
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package de.schlichtherle.key.passwd.swing;
18
19 import de.schlichtherle.swing.EnhancedPanel;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import java.io.*;
24 import java.util.*;
25
26 import javax.swing.*;
27 import javax.swing.event.*;
28 import javax.swing.text.*;
29
30 /**
31  * This panel prompts the user for a key to open an existing protected
32  * resource.
33  * It currently supports password and key file authentication, but is
34  * extensible for use with certificate based authentication, too.
35  * <p>
36  * Note that the contents of the password and file path fields are stored in
37  * a static field from which they are restored when a new panel is created.
38  * This is very convenient for the user if she inadvertently entered a wrong
39  * key or shares the same key for multiple protected resources.
40  *
41  * @author Christian Schlichtherle
42  * @since TrueZIP 6.0
43  * @version @version@
44  */

45 public class OpenKeyPanel extends EnhancedPanel {
46
47     private static final String JavaDoc CLASS_NAME
48             = "de/schlichtherle/key/passwd/swing/OpenKeyPanel".replace('/', '.'); // beware of code obfuscation!
49
private static final ResourceBundle resources
50             = ResourceBundle.getBundle(CLASS_NAME);
51
52     private final Color defaultForeground;
53
54     private JComponent extraDataUI;
55
56     private Feedback feedback;
57     
58     /**
59      * Creates new form OpenKeyPanel
60      */

61     public OpenKeyPanel() {
62         initComponents();
63         final DocumentListener dl = new DocumentListener() {
64             public void insertUpdate(DocumentEvent e) {
65                 setError(null);
66             }
67
68             public void removeUpdate(DocumentEvent e) {
69                 setError(null);
70             }
71
72             public void changedUpdate(DocumentEvent e) {
73                 setError(null);
74             }
75         };
76         passwd.getDocument().addDocumentListener(dl);
77         authenticationPanel.getKeyFileDocument().addDocumentListener(dl);
78         defaultForeground = resourceID.getForeground();
79     }
80
81     private Font getBoldFont() {
82         return resourceID.getFont().deriveFont(Font.BOLD);
83     }
84
85     /**
86      * Setter for property <code>resourceID</code>.
87      *
88      * @param resourceID New value of property <code>resourceID</code>.
89      */

90     public void setResourceID(final String JavaDoc resourceID) {
91         final String JavaDoc lastResourceID = PromptingKeyProviderUI.lastResourceID;
92         if (!lastResourceID.equals(resourceID) && !"".equals(lastResourceID)) {
93             this.resourceID.setForeground(Color.RED);
94         } else {
95             this.resourceID.setForeground(defaultForeground);
96         }
97         this.resourceID.setText(resourceID);
98         PromptingKeyProviderUI.lastResourceID = resourceID;
99     }
100
101     /**
102      * Getter for property <code>resourceID</code>.
103      *
104      * @return Value of property <code>resourceID</code>.
105      */

106     public String JavaDoc getResourceID() {
107         return resourceID.getText();
108     }
109
110     /**
111      * Getter for property <code>error</code>.
112      */

113     public String JavaDoc getError() {
114         final String JavaDoc error = this.error.getText();
115         return error.trim().length() > 0 ? error : null;
116     }
117     
118     /**
119      * Setter for property error.
120      *
121      * @param error New value of property error.
122      */

123     public void setError(final String JavaDoc error) {
124         // Fix layout issue with GridBagLayout:
125
// If null is set, the layout seems to ignore the widthy = 1.0
126
// constraint for the component.
127
this.error.setText(error != null ? error : " ");
128     }
129
130     /**
131      * Getter for property <code>openKey</code>.
132      * If a key file is selected and an error occurs when accessing it,
133      * a descriptive message is set for the <code>error</code> property.
134      *
135      * @return Value of property <code>openKey</code>.
136      * May be <code>null</code> if a key file is selected and
137      * accessing it results in an exception.
138      */

139     public Object JavaDoc getOpenKey() {
140         switch (authenticationPanel.getAuthenticationMethod()) {
141             case AuthenticationPanel.AUTH_PASSWD:
142                 return passwd.getPassword();
143
144             case AuthenticationPanel.AUTH_KEY_FILE:
145                 final String JavaDoc keyFilePathname
146                         = authenticationPanel.getKeyFilePath();
147                 try {
148                     return PromptingKeyProviderUI.readKeyFile(keyFilePathname);
149                 } catch (EOFException failure) {
150                     setError(resources.getString("keyFile.eofException"));
151                     return null;
152                 } catch (FileNotFoundException failure) {
153                     setError(resources.getString("keyFile.fileNotFoundException"));
154                     return null;
155                 } catch (IOException failure) {
156                     setError(resources.getString("keyFile.ioException"));
157                     return null;
158                 }
159
160             default:
161                 throw new AssertionError JavaDoc("Unsupported authentication method!");
162         }
163     }
164
165     /**
166      * Setter for property changeKeyRequested.
167      *
168      * @param changeKeyRequested New value of property changeKeyRequested.
169      * @deprecated This method should be package private.
170      */

171     public void setKeyChangeRequested(final boolean changeKeyRequested) {
172         this.changeKey.setSelected(changeKeyRequested);
173     }
174
175     /**
176      * Getter for property changeKeyRequested.
177      *
178      * @return Value of property changeKeyRequested.
179      */

180     public boolean isKeyChangeRequested() {
181         return changeKey.isSelected();
182     }
183     
184     /**
185      * Getter for property <code>extraDataUI</code>.
186      *
187      * @return Value of property <code>extraDataUI</code>.
188      */

189     public JComponent getExtraDataUI() {
190         return extraDataUI;
191     }
192     
193     /**
194      * Setter for property <code>extraDataUI</code>.
195      * This component is placed below the password field and above the
196      * "change password / key file" check box.
197      * It may be used to prompt the user for additional data which may form
198      * part of the key or is separately stored in the key provider.
199      * The panel is automatically revalidated.
200      *
201      * @param extraDataUI New value of property <code>extraDataUI</code>.
202      */

203     public void setExtraDataUI(final JComponent extraDataUI) {
204         if (this.extraDataUI == extraDataUI)
205             return;
206
207         if (this.extraDataUI != null) {
208             remove(this.extraDataUI);
209         }
210         if (extraDataUI != null) {
211             java.awt.GridBagConstraints JavaDoc gridBagConstraints;
212             gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
213             gridBagConstraints.gridx = 0;
214             gridBagConstraints.gridy = 4;
215             gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
216             gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
217             gridBagConstraints.insets = new java.awt.Insets JavaDoc(15, 0, 0, 0);
218             add(extraDataUI, gridBagConstraints);
219         }
220         this.extraDataUI = extraDataUI;
221
222         revalidate();
223     }
224
225     /**
226      * Returns the feedback to run when this panel is shown in its ancestor
227      * window.
228      */

229     public Feedback getFeedback() {
230         return feedback;
231     }
232
233     /**
234      * Sets the feedback to run when this panel is shown in its ancestor
235      * window.
236      */

237     public void setFeedback(final Feedback feedback) {
238         this.feedback = feedback;
239     }
240
241     /** This method is called from within the constructor to
242      * initialize the form.
243      * WARNING: Do NOT modify this code. The content of this method is
244      * always regenerated by the Form Editor.
245      */

246     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
247
private void initComponents() {
248         java.awt.GridBagConstraints JavaDoc gridBagConstraints;
249
250         passwdPanel = new de.schlichtherle.swing.EnhancedPanel();
251         passwdLabel = new javax.swing.JLabel JavaDoc();
252         passwd = new javax.swing.JPasswordField JavaDoc();
253         final javax.swing.JLabel JavaDoc prompt = new javax.swing.JLabel JavaDoc();
254         resourceID = new javax.swing.JTextPane JavaDoc();
255         authenticationPanel = new de.schlichtherle.key.passwd.swing.AuthenticationPanel();
256         error = new javax.swing.JLabel JavaDoc();
257
258         passwdPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
259
260         passwdPanel.addPanelListener(new de.schlichtherle.swing.event.PanelListener() {
261             public void ancestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {
262                 passwdPanelAncestorWindowShown(evt);
263             }
264             public void ancestorWindowHidden(de.schlichtherle.swing.event.PanelEvent evt) {
265             }
266         });
267
268         passwdLabel.setDisplayedMnemonic(java.util.ResourceBundle.getBundle("de/schlichtherle/key/passwd/swing/OpenKeyPanel").getString("passwd").charAt(0));
269         passwdLabel.setLabelFor(passwd);
270         passwdLabel.setText(resources.getString("passwd")); // NOI18N
271
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
272         gridBagConstraints.gridx = 0;
273         gridBagConstraints.gridy = 0;
274         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 0, 5);
275         passwdPanel.add(passwdLabel, gridBagConstraints);
276
277         passwd.setColumns(20);
278         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
279         gridBagConstraints.gridx = 1;
280         gridBagConstraints.gridy = 0;
281         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
282         gridBagConstraints.weightx = 1.0;
283         passwdPanel.add(passwd, gridBagConstraints);
284
285         setLayout(new java.awt.GridBagLayout JavaDoc());
286
287         addPanelListener(new de.schlichtherle.swing.event.PanelListener() {
288             public void ancestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {
289                 formAncestorWindowShown(evt);
290             }
291             public void ancestorWindowHidden(de.schlichtherle.swing.event.PanelEvent evt) {
292             }
293         });
294
295         prompt.setLabelFor(resourceID);
296         prompt.setText(resources.getString("prompt")); // NOI18N
297
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
298         gridBagConstraints.gridx = 0;
299         gridBagConstraints.gridy = 0;
300         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
301         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
302         add(prompt, gridBagConstraints);
303
304         resourceID.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createEtchedBorder(), javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2)));
305         resourceID.setEditable(false);
306         resourceID.setFont(getBoldFont());
307         resourceID.setOpaque(false);
308         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
309         gridBagConstraints.gridx = 0;
310         gridBagConstraints.gridy = 1;
311         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
312         gridBagConstraints.weightx = 1.0;
313         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 15, 0);
314         add(resourceID, gridBagConstraints);
315
316         authenticationPanel.setPasswdPanel(passwdPanel);
317         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
318         gridBagConstraints.gridx = 0;
319         gridBagConstraints.gridy = 2;
320         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
321         add(authenticationPanel, gridBagConstraints);
322
323         changeKey.setText(resources.getString("changeKey")); // NOI18N
324
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
325         gridBagConstraints.gridx = 0;
326         gridBagConstraints.gridy = 3;
327         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
328         gridBagConstraints.insets = new java.awt.Insets JavaDoc(15, 0, 0, 0);
329         add(changeKey, gridBagConstraints);
330
331         error.setForeground(java.awt.Color.red);
332         error.setText(" ");
333         error.setName("error");
334         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
335         gridBagConstraints.gridx = 0;
336         gridBagConstraints.gridy = 5;
337         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
338         gridBagConstraints.weighty = 1.0;
339         gridBagConstraints.insets = new java.awt.Insets JavaDoc(15, 0, 0, 0);
340         add(error, gridBagConstraints);
341
342     }// </editor-fold>//GEN-END:initComponents
343

344     private void formAncestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {//GEN-FIRST:event_formAncestorWindowShown
345
final Feedback feedback = getFeedback();
346         if (feedback != null) {
347             feedback.setPanel(this);
348             feedback.run();
349         }
350     }//GEN-LAST:event_formAncestorWindowShown
351

352     private void passwdPanelAncestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {//GEN-FIRST:event_passwdPanelAncestorWindowShown
353
// These are the things I hate Swing for: All I want to do here is to
354
// set the focus to the passwd field in this panel when it shows.
355
// However, this can't be done in the constructor since the panel is
356
// not yet placed in a window which is actually showing.
357
// Right, then we use this event listener to do it. This listener
358
// method is called when the ancestor window is showing (and coding
359
// the event generation was a less than trivial task).
360
// But wait, simply setting the focus in this event listener here is
361
// not possible on Linux because the containing window (now we have
362
// one) didn't gain the focus yet.
363
// Strangely enough, this works on Windows.
364
// Even more strange, not even calling passwd.requestFocus() makes it
365
// work on Linux!
366
// So we add a window focus listener here and remove it when we
367
// receive a Focus Gained Event.
368
// But wait, then we still can't request the focus: This time it
369
// doesn't work on Windows, while it works on Linux.
370
// I still don't know the reason why, but it seems we're moving too
371
// fast, so I have to post a new event to the event queue which finally
372
// sets the focus.
373
// But wait, requesting the focus could still fail for some strange,
374
// undocumented reason - I wouldn't be surprised anymore.
375
// So we add a conditional to select the entire contents of the field
376
// only if we can really transfer the focus to it.
377
// Otherwise, users could get easily confused.
378
// If you carefully read the documentation for requestFocusInWindow()
379
// however, then you know that even if it returns true, there is still
380
// no guarantee that the focus gets actually transferred...
381
// This mess is insane (and I can hardly abstain from writing down
382
// all the other insulting scatology which comes to my mind)!
383
final Window window = evt.getAncestorWindow();
384         window.addWindowFocusListener(new WindowFocusListener() {
385             public void windowGainedFocus(WindowEvent e) {
386                 window.removeWindowFocusListener(this);
387                 EventQueue.invokeLater(new Runnable JavaDoc() {
388                     public void run() {
389                         if (passwd.requestFocusInWindow())
390                             passwd.selectAll();
391                     }
392                 });
393             }
394
395             public void windowLostFocus(WindowEvent e) {
396             }
397         });
398     }//GEN-LAST:event_passwdPanelAncestorWindowShown
399

400     // Variables declaration - do not modify//GEN-BEGIN:variables
401
private de.schlichtherle.key.passwd.swing.AuthenticationPanel authenticationPanel;
402     private final javax.swing.JCheckBox JavaDoc changeKey = new javax.swing.JCheckBox JavaDoc();
403     private javax.swing.JLabel JavaDoc error;
404     private javax.swing.JPasswordField JavaDoc passwd;
405     private javax.swing.JLabel JavaDoc passwdLabel;
406     private de.schlichtherle.swing.EnhancedPanel passwdPanel;
407     private javax.swing.JTextPane JavaDoc resourceID;
408     // End of variables declaration//GEN-END:variables
409
}
410
Popular Tags