de.schlichtherle.truezip.key.pbe.swing.AuthenticationPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truezip-driver-zip Show documentation
Show all versions of truezip-driver-zip Show documentation
The file system driver family for ZIP and related archive file types.
Add the JAR artifact of this module to the run time class path to
make its file system drivers available for service location in the
client API modules.
/*
* Copyright (C) 2005-2013 Schlichtherle IT Services.
* All rights reserved. Use is subject to license terms.
*/
package de.schlichtherle.truezip.key.pbe.swing;
import de.schlichtherle.truezip.io.swing.FileComboBoxBrowser;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.File;
import java.util.ResourceBundle;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
/**
* A panel displaying a password panel or a key file panel in order to let
* the user select an authentication method and enter a key.
*
* @author Christian Schlichtherle
*/
public class AuthenticationPanel extends JPanel {
private static final long serialVersionUID = 3876515923659236921L;
private static final String CLASS_NAME = AuthenticationPanel.class.getName();
private static final ResourceBundle
resources = ResourceBundle.getBundle(CLASS_NAME);
private static final File
BASE_DIR = FileSystemView.getFileSystemView().getDefaultDirectory();
/** The password authentication method. */
static final int AUTH_PASSWD = 0;
/** The key file authentication method. */
static final int AUTH_KEY_FILE = 1;
/**
* Constructs a new authentication panel.
* This version of the constructor does not remember the key file path.
*/
@SuppressWarnings("unchecked")
public AuthenticationPanel() {
initComponents();
// Order is important here: The file combo box browser installs its
// own editor, so we have to adjust the columns last.
new FileComboBoxBrowser(keyFile).setDirectory(BASE_DIR);
((JTextField) keyFile.getEditor().getEditorComponent()).setColumns(30);
}
/**
* Sets the panel which should be used to enter the password.
*
* @throws NullPointerException If {@code passwdPanel} is
* {@code null}.
*/
public void setPasswdPanel(JPanel passwdPanel) {
if (passwdPanel == null)
throw new NullPointerException();
passwdPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
final String title = resources.getString("tab.passwd");
if (title.equals(tabs.getTitleAt(AUTH_PASSWD)))
tabs.removeTabAt(AUTH_PASSWD);
tabs.insertTab(title, null, passwdPanel, null, AUTH_PASSWD); // NOI18N
tabs.setSelectedIndex(AUTH_PASSWD);
revalidate();
}
Document getKeyFileDocument() {
return ((JTextComponent) keyFile.getEditor().getEditorComponent()).getDocument();
}
/**
* Returns the key file.
*
* @return The key file.
*/
public File getKeyFile() {
String path = (String) keyFile.getSelectedItem();
File file = new File(path);
return file.isAbsolute() ? file : new File(BASE_DIR.getPath(), path);
}
private void setKeyFile(final File file) {
String newPath = file.getPath();
{
final String baseDirPath = BASE_DIR.getPath();
if (newPath.startsWith(baseDirPath))
newPath = newPath.substring(baseDirPath.length() + 1); // cut off file separator, too.
}
final String oldPath = (String) keyFile.getSelectedItem();
if (newPath.equals(oldPath)) return;
keyFile.setSelectedItem(newPath);
}
/**
* Returns the authentication method selected by the user.
*
* @return {@code AUTH_PASSWD} or {@code AUTH_KEY_FILE}.
*/
public int getAuthenticationMethod() {
final int method = tabs.getSelectedIndex();
switch (method) {
case AUTH_PASSWD:
assert resources.getString("tab.passwd").equals(tabs.getTitleAt(method));
break;
case AUTH_KEY_FILE:
assert resources.getString("tab.keyFile").equals(tabs.getTitleAt(method));
break;
default:
throw new AssertionError("Unsupported authentication method!");
}
return method;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// //GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
tabs = new javax.swing.JTabbedPane();
final javax.swing.JLabel keyFileLabel = new javax.swing.JLabel();
setLayout(new java.awt.GridBagLayout());
keyFilePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
keyFilePanel.addPanelListener(new de.schlichtherle.truezip.swing.PanelListener() {
public void ancestorWindowShown(de.schlichtherle.truezip.swing.PanelEvent evt) {
keyFilePanelAncestorWindowShown(evt);
}
public void ancestorWindowHidden(de.schlichtherle.truezip.swing.PanelEvent evt) {
}
});
keyFilePanel.setLayout(new java.awt.GridBagLayout());
keyFileLabel.setDisplayedMnemonic(resources.getString("keyFile").charAt(0));
keyFileLabel.setLabelFor(keyFile);
keyFileLabel.setText(resources.getString("keyFile")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
keyFilePanel.add(keyFileLabel, gridBagConstraints);
keyFile.setEditable(true);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
keyFilePanel.add(keyFile, gridBagConstraints);
keyFileChooser.setIcon(UIManager.getIcon("FileView.directoryIcon"));
keyFileChooser.setToolTipText(resources.getString("selectKeyFile.toolTip")); // NOI18N
keyFileChooser.setName("keyFileChooser"); // NOI18N
keyFileChooser.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
keyFileChooserActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0);
keyFilePanel.add(keyFileChooser, gridBagConstraints);
tabs.addTab(resources.getString("tab.keyFile"), keyFilePanel); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
add(tabs, gridBagConstraints);
}// //GEN-END:initComponents
private void keyFileChooserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keyFileChooserActionPerformed
final JFileChooser fc = newFileChooser();
if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(this))
setKeyFile(fc.getSelectedFile());
}//GEN-LAST:event_keyFileChooserActionPerformed
private static JFileChooser newFileChooser() {
final JFileChooser fc = new JFileChooser(BASE_DIR);
fc.setDialogTitle(resources.getString("fileChooser.title"));
fc.setFileHidingEnabled(false);
return fc;
}
private void keyFilePanelAncestorWindowShown(de.schlichtherle.truezip.swing.PanelEvent evt) {//GEN-FIRST:event_keyFilePanelAncestorWindowShown
// These are the things I hate Swing for: All I want to do here is to
// set the focus to the passwd field in this panel when it shows.
// However, this can't be done in the constructor since the panel is
// not yet placed in a window which is actually showing.
// Right, then I use this event listener to do it. This listener
// method is called when the ancestor window is showing (and coding
// the event generation was a less than trivial task).
// But wait, simply setting the focus in this event listener here is
// not possible on Linux because the containing window (now there is
// one) didn't gain the focus yet.
// Strangely enough, this works on Windows.
// Even more strange, not even calling passwd.requestFocus() makes it
// work on Linux!
// So I add a window focus listener here and remove it when a Focus
// Gained Event occurs.
// But wait, then I still can't request the focus: This time it
// doesn't work on Windows, while it works on Linux.
// I still don't know the reason why, but it seems it's moving too
// fast, so I have to post a new event to the event queue which finally
// sets the focus.
// But wait, requesting the focus could still fail for some strange,
// undocumented reason - I wouldn't be surprised anymore.
// So I add a conditional to select the entire contents of the field
// only if I can really transfer the focus to it.
// Otherwise, users could get easily confused.
// If you carefully read the documentation for requestFocusInWindow()
// however, then you know that even if it returns true, there is still
// no guarantee that the focus gets actually transferred...
// This mess is insane!
final Window window = evt.getSource().getAncestorWindow();
window.addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowGainedFocus(WindowEvent e) {
window.removeWindowFocusListener(this);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (keyFile.requestFocusInWindow())
((JTextComponent) keyFile.getEditor().getEditorComponent()).selectAll();
}
});
}
@Override
public void windowLostFocus(WindowEvent e) {
}
});
}//GEN-LAST:event_keyFilePanelAncestorWindowShown
// Variables declaration - do not modify//GEN-BEGIN:variables
private final javax.swing.JComboBox keyFile = new javax.swing.JComboBox();
private final javax.swing.JButton keyFileChooser = new javax.swing.JButton();
private final de.schlichtherle.truezip.swing.EnhancedPanel keyFilePanel = new de.schlichtherle.truezip.swing.EnhancedPanel();
private javax.swing.JTabbedPane tabs;
// End of variables declaration//GEN-END:variables
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy