/* JpasswordField.java This class defines a password input field object. Created: 12 Jul 1996 Module By: Navin Manohar ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2013 The University of Texas at Austin Ganymede is a registered trademark of The University of Texas at Austin Contact information Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package arlut.csd.JDataComponent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.rmi.RemoteException; import javax.swing.JComponent; import javax.swing.JPasswordField; /*------------------------------------------------------------------------------ class JpasswordField ------------------------------------------------------------------------------*/ /** * <p>This class defines a single-entry field that is capable of handling * password strings. It is also possible to restrict the characters * which are accepted by this gui component. Furthermore, the maximum * size of the string that can be entered into this JstringField can * be preset.</p> */ public class JpasswordField extends JPasswordField implements FocusListener, ActionListener { public static final boolean debug = false; public static int DEFAULT_COLS = 15; public static int DEFAULT_SIZE = 4096; // --- private int size = DEFAULT_SIZE; private String value = null; private String allowedChars = null; private String disallowedChars = null; private JsetValueCallback my_parent; private boolean allowCallback = false, changed = false; /* -- */ /** * Base constructor for JpasswordField * * @param columns number of colums in the JpasswordField * @param is_editable true if this JpasswordField is editable */ public JpasswordField(int columns, int maxstrlen, boolean is_editable, boolean invisible, String allowed, String disallowed) { super(columns); if (maxstrlen <= 0) { throw new IllegalArgumentException("Invalid Parameter: maximum string size is negative or zero"); } size = maxstrlen; setEditable(is_editable); // will this JpasswordField be editable or not? setEchoChar('*'); if (allowed != null) { setAllowedChars(allowed); } if (disallowed != null) { setDisallowedChars(disallowed); } addActionListener(this); addFocusListener(this); } public boolean isChanged() { return changed; } /** * Constructor which uses default fonts,no parent, * default column size, and default foregound/background * colors. */ public JpasswordField() { this(JpasswordField.DEFAULT_COLS, JpasswordField.DEFAULT_SIZE, true, false, null, null); } /** * Simple constructor. */ public JpasswordField(int cols, boolean is_editable) { this(cols, JpasswordField.DEFAULT_SIZE, is_editable, false, null, null); } /** * Constructor that allows for the creation of a JpasswordField * that knows about its parent. * * @param cols number of colums in the JpasswordField * @param callback An interface for the container within which this * JpasswordField is typically contained. The JpasswordField will * call this interface to pass password change notifications. */ public JpasswordField(int cols, int maxstrlen, boolean is_editable, boolean invisible, String allowed, String disallowed, JsetValueCallback callback) { this(cols, maxstrlen, is_editable, invisible, allowed, disallowed); setCallback(callback); } /** * sets the parent of this component for callback purposes */ public void setCallback(JsetValueCallback parent) { if (parent == null) { throw new IllegalArgumentException("Invalid Parameter: parent cannot be null"); } my_parent = parent; allowCallback = true; } /** * Sets the JpasswordField to a specific value * * @param str value to which the JpasswordField is set */ public void setText(String str) { if (str == null) { value = ""; super.setText(""); changed = true; } else { if (str.length() > size) { throw new IllegalArgumentException("string too long"); } for (int i = 0; i < str.length(); i++) { if (!isAllowed(str.charAt(i))) { throw new IllegalArgumentException("invalid char in string: " + str.charAt(i)); } } super.setText(str); value = str; changed = true; } } /** * Returns the value of the member variable value */ public String getValue() { return value; } /** * Returns the character located at position n in the JpasswordField value * * @param n position in the JpasswordField value from which to retrieve character */ public char getCharAt(int n) { return this.getPassword()[n]; } /** * Assigns a set of characters which are valid within the JpasswordField * * @param s each character in this string will be considered an allowed character */ public void setAllowedChars(String s) { this.allowedChars = s; } /** * Assigns a set of characters which are invalid within the JpasswordField * * @param s each character in this string will be considered a disallowed character */ public void setDisallowedChars(String s) { this.disallowedChars = s; } /** * Returns the set of allowed characters as a String object */ public String getAllowedChars() { return this.allowedChars; } /** * Returns the set of disallowed characters as a String object */ public String getDisallowedChars() { return this.disallowedChars; } /** * Returns the maximum size of the string that can be placed in this * JpasswordField */ public int getMaxStringSize() { return this.size; } /** * Determines whether a given character is valid or invalid for a * JpasswordField * * @param ch the character which is being tested for its validity */ private boolean isAllowed(char ch) { if (disallowedChars != null) { if (disallowedChars.indexOf(ch) != -1) { return false; } } if (allowedChars != null) { if (allowedChars.indexOf(ch) == -1) { return false; } } return true; } public void sendCallback() { String str; // if nothing in the JpasswordField has changed, // we don't need to worry about this event. str = new String(getPassword()); if (value != null) { if (debug) { System.err.println("JpasswordField.sendCallback(): old value != null"); } changed = !value.equals(str); } else { if (debug) { System.err.println("JpasswordField.sendCallback(): old value == null"); } changed = true; } if (!changed) { if (debug) { System.err.println("JpasswordField.sendCallback(): no change, ignoring"); } return; } if (allowCallback) { boolean b = false; try { if (debug) { System.err.println("JpasswordField.sendCallback(): making callback"); } b = my_parent.setValuePerformed(new JSetValueObject(this, str)); } catch (RemoteException re) { } if (!b) { if (debug) { System.err.println("JpasswordField.sendCallback(): setValue rejected"); if (value == null) { System.err.println("JpasswordField.sendCallback(): resetting to empty string"); } else { System.err.println("JpasswordField.sendCallback(): resetting to " + value); } } if (value == null) { super.setText(""); } else { super.setText(value); } changed = false; } else { if (debug) { System.err.println("JpasswordField.sendCallback(): setValue accepted"); } value = str; changed = true; } } } // FocusListener methods public void focusGained(FocusEvent e) { JComponent parent = (JComponent) this.getParent(); if (parent != null) { parent.scrollRectToVisible(this.getBounds()); } } public void focusLost(FocusEvent e) { sendCallback(); } public void actionPerformed(ActionEvent e) { transferFocus(); } }