KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.*;
20 import de.schlichtherle.io.swing.*;
21
22 import java.awt.*;
23 import java.awt.event.*;
24 import java.lang.ref.*;
25 import java.util.*;
26
27 import javax.swing.*;
28 import javax.swing.text.*;
29
30 /**
31  * A panel displaying a password panel or a key file panel in order to let
32  * the user select an authentication method and enter the key.
33  *
34  * @author Christian Schlichtherle
35  * @since TrueZIP 6.0
36  * @version @version@
37  */

38 public class AuthenticationPanel extends JPanel {
39
40     private static final String JavaDoc CLASS_NAME
41             = "de/schlichtherle/key/passwd/swing/AuthenticationPanel".replace('/', '.'); // support code obfuscation!
42
private static final ResourceBundle resources
43             = ResourceBundle.getBundle(CLASS_NAME);
44     private static final File BASE_DIR = new File(".", ArchiveDetector.NULL);
45
46     private static SoftReference fileChooser;
47
48     /** The password authentication method. */
49     public static final int AUTH_PASSWD = 0;
50     
51     /** The key file authentication method. */
52     public static final int AUTH_KEY_FILE = 1;
53
54     /**
55      * Creates a new authentication panel.
56      * This version of the constructor does not remember the key file path.
57      */

58     public AuthenticationPanel() {
59         initComponents();
60
61         // Order is important here: The file combo box browser installs its
62
// own editor, so we have to adjust the columns last.
63
new FileComboBoxBrowser(keyFile).setDirectory(BASE_DIR);
64         ((JTextField) keyFile.getEditor().getEditorComponent()).setColumns(30);
65     }
66
67     /**
68      * Sets the panel which should be used to enter the password.
69      *
70      * @throws NullPointerException If <code>passwdPanel</code> is
71      * <code>null</code>.
72      */

73     public void setPasswdPanel(JPanel passwdPanel) {
74         if (passwdPanel == null)
75             throw new NullPointerException JavaDoc();
76
77         passwdPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
78         final String JavaDoc title = resources.getString("tab.passwd");
79         if (title.equals(tabs.getTitleAt(AUTH_PASSWD)))
80             tabs.removeTabAt(AUTH_PASSWD);
81         tabs.insertTab(title, null, passwdPanel, null, AUTH_PASSWD); // NOI18N
82
tabs.setSelectedIndex(AUTH_PASSWD);
83         revalidate();
84     }
85
86     Document getKeyFileDocument() {
87         return ((JTextComponent) keyFile.getEditor().getEditorComponent()).getDocument();
88     }
89
90     /**
91      * Returns the path of the key file.
92      * If the parameter <code>rememberPath</code> of the constructor was
93      * <code>true</code>, then the returned path is remembered in a static
94      * field for the next instance of this class.
95      */

96     public String JavaDoc getKeyFilePath() {
97         return (String JavaDoc) keyFile.getSelectedItem();
98     }
99
100     private void setKeyFilePath(final String JavaDoc path) {
101         final String JavaDoc oldPath = (String JavaDoc) keyFile.getSelectedItem();
102         if (path == oldPath || path != null && path.equals(oldPath))
103             return;
104
105         keyFile.setSelectedItem(path);
106         /*final Window window = SwingUtilities.getWindowAncestor(this);
107         if (window != null)
108             window.pack();*/

109     }
110
111     /**
112      * Returns the authentication method selected by the user.
113      *
114      * @return <code>AUTH_PASSWD</code> or <code>AUTH_KEY_FILE</code>.
115      */

116     public int getAuthenticationMethod() {
117         final int method = tabs.getSelectedIndex();
118         switch (method) {
119             case AUTH_PASSWD:
120                 assert resources.getString("tab.passwd").equals(tabs.getTitleAt(method));
121                 break;
122
123             case AUTH_KEY_FILE:
124                 assert resources.getString("tab.keyFile").equals(tabs.getTitleAt(method));
125                 break;
126
127             default:
128                 throw new AssertionError JavaDoc("Unsupported authentication method!");
129         }
130         return method;
131     }
132
133     /**
134      * Return a <code>JFileChooser</code> to use within this panel.
135      * The file chooser is stored in a cache for subsequent use.
136      * If the JVM gets short of storage, the cache is emptied and a new
137      * file chooser is instantiated on the next call to this method again.
138      * In any way, the file chooser will always remember its current directory.
139      * In addition, the returned file chooser has file hiding disabled.
140      * Note that the file chooser is a plain javax.swing.FileChooser which
141      * does <em>not</em> support archive browsing to prevent illegal recursion.
142      */

143     static javax.swing.JFileChooser JavaDoc getFileChooser() {
144         final SoftReference ref = fileChooser; // cache
145
javax.swing.JFileChooser JavaDoc fc = ref != null ? (javax.swing.JFileChooser JavaDoc) ref.get() : null;
146         if (fc == null) {
147             fc = new CustomFileChooser();
148             fileChooser = new SoftReference(fc);
149         }
150         return fc;
151     }
152
153     /** This method is called from within the constructor to
154      * initialize the form.
155      * WARNING: Do NOT modify this code. The content of this method is
156      * always regenerated by the Form Editor.
157      */

158     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
159
private void initComponents() {
160         java.awt.GridBagConstraints JavaDoc gridBagConstraints;
161
162         tabs = new javax.swing.JTabbedPane JavaDoc();
163         final javax.swing.JLabel JavaDoc keyFileLabel = new javax.swing.JLabel JavaDoc();
164
165         setLayout(new java.awt.GridBagLayout JavaDoc());
166
167         keyFilePanel.setLayout(new java.awt.GridBagLayout JavaDoc());
168
169         keyFilePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
170         keyFilePanel.addPanelListener(new de.schlichtherle.swing.event.PanelListener() {
171             public void ancestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {
172                 keyFilePanelAncestorWindowShown(evt);
173             }
174             public void ancestorWindowHidden(de.schlichtherle.swing.event.PanelEvent evt) {
175             }
176         });
177
178         keyFileLabel.setDisplayedMnemonic(resources.getString("keyFile").charAt(0));
179         keyFileLabel.setLabelFor(keyFile);
180         keyFileLabel.setText(resources.getString("keyFile")); // NOI18N
181
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
182         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
183         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
184         keyFilePanel.add(keyFileLabel, gridBagConstraints);
185
186         keyFile.setEditable(true);
187         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
188         gridBagConstraints.gridx = 0;
189         gridBagConstraints.gridy = 1;
190         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
191         gridBagConstraints.weightx = 1.0;
192         keyFilePanel.add(keyFile, gridBagConstraints);
193
194         keyFileChooser.setIcon(UIManager.getIcon("FileView.directoryIcon"));
195         keyFileChooser.setToolTipText(resources.getString("selectKeyFile.toolTip")); // NOI18N
196
keyFileChooser.setName("keyFileChooser");
197         keyFileChooser.addActionListener(new java.awt.event.ActionListener JavaDoc() {
198             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
199                 keyFileChooserActionPerformed(evt);
200             }
201         });
202
203         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
204         gridBagConstraints.gridx = 1;
205         gridBagConstraints.gridy = 1;
206         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 10, 0, 0);
207         keyFilePanel.add(keyFileChooser, gridBagConstraints);
208
209         tabs.addTab(resources.getString("tab.keyFile"), keyFilePanel); // NOI18N
210

211         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
212         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
213         gridBagConstraints.weightx = 1.0;
214         gridBagConstraints.weighty = 1.0;
215         add(tabs, gridBagConstraints);
216
217     }// </editor-fold>//GEN-END:initComponents
218

219     private void keyFileChooserActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_keyFileChooserActionPerformed
220
final javax.swing.JFileChooser JavaDoc fc = getFileChooser();
221         if (fc.showOpenDialog(this) == javax.swing.JFileChooser.APPROVE_OPTION) {
222             final File file = new File(fc.getSelectedFile(), ArchiveDetector.NULL);
223             final String JavaDoc baseDirPath = BASE_DIR.getCanOrAbsPath();
224             String JavaDoc keyFilePath = file.getCanOrAbsPath();
225             if (keyFilePath.startsWith(baseDirPath)) {
226                 assert keyFilePath.charAt(baseDirPath.length()) == File.separatorChar;
227                 keyFilePath = keyFilePath.substring(baseDirPath.length() + 1); // skip file separator
228
}
229             setKeyFilePath(keyFilePath);
230         }
231     }//GEN-LAST:event_keyFileChooserActionPerformed
232

233     private void keyFilePanelAncestorWindowShown(de.schlichtherle.swing.event.PanelEvent evt) {//GEN-FIRST:event_keyFilePanelAncestorWindowShown
234
// These are the things I hate Swing for: All I want to do here is to
235
// set the focus to the passwd field in this panel when it shows.
236
// However, this can't be done in the constructor since the panel is
237
// not yet placed in a window which is actually showing.
238
// Right, then we use this event listener to do it. This listener
239
// method is called when the ancestor window is showing (and coding
240
// the event generation was a less than trivial task).
241
// But wait, simply setting the focus in this event listener here is
242
// not possible on Linux because the containing window (now we have
243
// one) didn't gain the focus yet.
244
// Strangely enough, this works on Windows.
245
// Even more strange, not even calling passwd.requestFocus() makes it
246
// work on Linux!
247
// So we add a window focus listener here and remove it when we
248
// receive a Focus Gained Event.
249
// But wait, then we still can't request the focus: This time it
250
// doesn't work on Windows, while it works on Linux.
251
// I still don't know the reason why, but it seems we're moving too
252
// fast, so I have to post a new event to the event queue which finally
253
// sets the focus.
254
// But wait, requesting the focus could still fail for some strange,
255
// undocumented reason - I wouldn't be surprised anymore.
256
// So we add a conditional to select the entire contents of the field
257
// only if we can really transfer the focus to it.
258
// Otherwise, users could get easily confused.
259
// If you carefully read the documentation for requestFocusInWindow()
260
// however, then you know that even if it returns true, there is still
261
// no guarantee that the focus gets actually transferred...
262
// This mess is insane (and I can hardly abstain from writing down
263
// all the other insulting scatology which comes to my mind)!
264
final Window window = evt.getAncestorWindow();
265         window.addWindowFocusListener(new WindowFocusListener() {
266             public void windowGainedFocus(WindowEvent e) {
267                 window.removeWindowFocusListener(this);
268                 EventQueue.invokeLater(new Runnable JavaDoc() {
269                     public void run() {
270                         if (keyFile.requestFocusInWindow())
271                             ((JTextComponent) keyFile.getEditor().getEditorComponent()).selectAll();
272                     }
273                 });
274             }
275
276             public void windowLostFocus(WindowEvent e) {
277             }
278         });
279     }//GEN-LAST:event_keyFilePanelAncestorWindowShown
280

281     // Variables declaration - do not modify//GEN-BEGIN:variables
282
private final javax.swing.JComboBox JavaDoc keyFile = new javax.swing.JComboBox JavaDoc();
283     private final javax.swing.JButton JavaDoc keyFileChooser = new javax.swing.JButton JavaDoc();
284     private final de.schlichtherle.swing.EnhancedPanel keyFilePanel = new de.schlichtherle.swing.EnhancedPanel();
285     private javax.swing.JTabbedPane JavaDoc tabs;
286     // End of variables declaration//GEN-END:variables
287

288     private static class CustomFileChooser extends javax.swing.JFileChooser JavaDoc {
289         private static java.io.File JavaDoc lastCurrentDir = BASE_DIR;
290         
291         public CustomFileChooser() {
292             super(lastCurrentDir);
293
294             setDialogTitle(resources.getString("fileChooser.title"));
295             setFileHidingEnabled(false);
296         }
297
298         public void setCurrentDirectory(java.io.File JavaDoc dir) {
299             super.setCurrentDirectory(dir);
300             lastCurrentDir = dir;
301         }
302
303         public java.io.File JavaDoc getCurrentDirectory() {
304             return lastCurrentDir = super.getCurrentDirectory();
305         }
306     }
307 }
308
Popular Tags