1. /*
  2. * @(#)JPasswordField.java 1.50 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import javax.swing.text.*;
  9. import javax.swing.plaf.*;
  10. import javax.accessibility.*;
  11. import java.io.ObjectOutputStream;
  12. import java.io.ObjectInputStream;
  13. import java.io.IOException;
  14. /**
  15. * <code>JPasswordField</code> is a lightweight component that allows
  16. * the editing of a single line of text where the view indicates
  17. * something was typed, but does not show the original characters.
  18. * You can find further information and examples in
  19. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>,
  20. * a section in <em>The Java Tutorial.</em>
  21. * <p>
  22. * <code>JPasswordField</code> is intended
  23. * to be source-compatible with <code>java.awt.TextField</code>
  24. * used with <code>echoChar</code> set. It is provided separately
  25. * to make it easier to safely change the UI for the
  26. * <code>JTextField</code> without affecting password entries.
  27. * <p>
  28. * For the keyboard keys used by this component in the standard Look and
  29. * Feel (L&F) renditions, see the
  30. * <a href="doc-files/Key-Index.html#JPasswordField">JPasswordField</a>
  31. * key assignments.
  32. * <p>
  33. * <strong>Warning:</strong>
  34. * Serialized objects of this class will not be compatible with
  35. * future Swing releases. The current serialization support is
  36. * appropriate for short term storage or RMI between applications running
  37. * the same version of Swing. As of 1.4, support for long term storage
  38. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  39. * has been added to the <code>java.beans</code> package.
  40. * Please see {@link java.beans.XMLEncoder}.
  41. *
  42. * @beaninfo
  43. * attribute: isContainer false
  44. * description: Allows the editing of a line of text but doesn't show the characters.
  45. *
  46. * @author Timothy Prinzing
  47. * @version 1.50 01/23/03
  48. */
  49. public class JPasswordField extends JTextField {
  50. /**
  51. * Constructs a new <code>JPasswordField</code>,
  52. * with a default document, <code>null</code> starting
  53. * text string, and 0 column width.
  54. */
  55. public JPasswordField() {
  56. this(null,null,0);
  57. }
  58. /**
  59. * Constructs a new <code>JPasswordField</code> initialized
  60. * with the specified text. The document model is set to the
  61. * default, and the number of columns to 0.
  62. *
  63. * @param text the text to be displayed, <code>null</code> if none
  64. */
  65. public JPasswordField(String text) {
  66. this(null, text, 0);
  67. }
  68. /**
  69. * Constructs a new empty <code>JPasswordField</code> with the specified
  70. * number of columns. A default model is created, and the initial string
  71. * is set to <code>null</code>.
  72. *
  73. * @param columns the number of columns >= 0
  74. */
  75. public JPasswordField(int columns) {
  76. this(null, null, columns);
  77. }
  78. /**
  79. * Constructs a new <code>JPasswordField</code> initialized with
  80. * the specified text and columns. The document model is set to
  81. * the default.
  82. *
  83. * @param text the text to be displayed, <code>null</code> if none
  84. * @param columns the number of columns >= 0
  85. */
  86. public JPasswordField(String text, int columns) {
  87. this(null, text, columns);
  88. }
  89. /**
  90. * Constructs a new <code>JPasswordField</code> that uses the
  91. * given text storage model and the given number of columns.
  92. * This is the constructor through which the other constructors feed.
  93. * The echo character is set to '*'. If the document model is
  94. * <code>null</code>, a default one will be created.
  95. *
  96. * @param doc the text storage to use
  97. * @param txt the text to be displayed, <code>null</code> if none
  98. * @param columns the number of columns to use to calculate
  99. * the preferred width >= 0; if columns is set to zero, the
  100. * preferred width will be whatever naturally results from
  101. * the component implementation
  102. */
  103. public JPasswordField(Document doc, String txt, int columns) {
  104. super(doc, txt, columns);
  105. echoChar = '*';
  106. // We could either leave this on, which wouldn't be secure,
  107. // or obscure the composted text, which essentially makes displaying
  108. // it useless. Therefore, we turn off input methods.
  109. enableInputMethods(false);
  110. }
  111. /**
  112. * Returns the name of the L&F class that renders this component.
  113. *
  114. * @return the string "PasswordFieldUI"
  115. * @see JComponent#getUIClassID
  116. * @see UIDefaults#getUI
  117. */
  118. public String getUIClassID() {
  119. return uiClassID;
  120. }
  121. /**
  122. * Returns the character to be used for echoing. The default is '*'.
  123. *
  124. * @return the echo character, 0 if unset
  125. * @see #setEchoChar
  126. * @see #echoCharIsSet
  127. */
  128. public char getEchoChar() {
  129. return echoChar;
  130. }
  131. /**
  132. * Sets the echo character for this <code>JPasswordField</code>.
  133. * Note that this is largely a suggestion, since the
  134. * view that gets installed can use whatever graphic techniques
  135. * it desires to represent the field. Setting a value of 0 indicates
  136. * that you wish to see the text as it is typed, similar to
  137. * the behavior of a standard <code>JTextField</code>.
  138. *
  139. * @param c the echo character to display
  140. * @see #echoCharIsSet
  141. * @see #getEchoChar
  142. * @beaninfo
  143. * description: character to display in place of the real characters
  144. * attribute: visualUpdate true
  145. */
  146. public void setEchoChar(char c) {
  147. echoChar = c;
  148. repaint();
  149. revalidate();
  150. }
  151. /**
  152. * Returns true if this <code>JPasswordField</code> has a character
  153. * set for echoing. A character is considered to be set if the echo
  154. * character is not 0.
  155. *
  156. * @return true if a character is set for echoing
  157. * @see #setEchoChar
  158. * @see #getEchoChar
  159. */
  160. public boolean echoCharIsSet() {
  161. return echoChar != 0;
  162. }
  163. // --- JTextComponent methods ----------------------------------
  164. /**
  165. * Invokes <code>provideErrorFeedback</code> on the current
  166. * look and feel, which typically initiates an error beep.
  167. * The normal behavior of transferring the
  168. * currently selected range in the associated text model
  169. * to the system clipboard, and removing the contents from
  170. * the model, is not acceptable for a password field.
  171. */
  172. public void cut() {
  173. UIManager.getLookAndFeel().provideErrorFeedback(this);
  174. }
  175. /**
  176. * Invokes <code>provideErrorFeedback</code> on the current
  177. * look and feel, which typically initiates an error beep.
  178. * The normal behavior of transferring the
  179. * currently selected range in the associated text model
  180. * to the system clipboard, and leaving the contents from
  181. * the model, is not acceptable for a password field.
  182. */
  183. public void copy() {
  184. UIManager.getLookAndFeel().provideErrorFeedback(this);
  185. }
  186. /**
  187. * Returns the text contained in this <code>TextComponent</code>.
  188. * If the underlying document is <code>null</code>, will give a
  189. * <code>NullPointerException</code>.
  190. * <p>
  191. * For security reasons, this method is deprecated. Use the
  192. <code>* getPassword</code> method instead.
  193. * @deprecated As of Java 2 platform v1.2,
  194. * replaced by <code>getPassword</code>.
  195. * @return the text
  196. */
  197. public String getText() {
  198. return super.getText();
  199. }
  200. /**
  201. * Fetches a portion of the text represented by the
  202. * component. Returns an empty string if length is 0.
  203. * <p>
  204. * For security reasons, this method is deprecated. Use the
  205. * <code>getPassword</code> method instead.
  206. * @deprecated As of Java 2 platform v1.2,
  207. * replaced by <code>getPassword</code>.
  208. * @param offs the offset >= 0
  209. * @param len the length >= 0
  210. * @return the text
  211. * @exception BadLocationException if the offset or length are invalid
  212. */
  213. public String getText(int offs, int len) throws BadLocationException {
  214. return super.getText(offs, len);
  215. }
  216. /**
  217. * Returns the text contained in this <code>TextComponent</code>.
  218. * If the underlying document is <code>null</code>, will give a
  219. * <code>NullPointerException</code>. For stronger
  220. * security, it is recommended that the returned character array be
  221. * cleared after use by setting each character to zero.
  222. *
  223. * @return the text
  224. */
  225. public char[] getPassword() {
  226. Document doc = getDocument();
  227. Segment txt = new Segment();
  228. try {
  229. doc.getText(0, doc.getLength(), txt); // use the non-String API
  230. } catch (BadLocationException e) {
  231. return null;
  232. }
  233. char[] retValue = new char[txt.count];
  234. System.arraycopy(txt.array, txt.offset, retValue, 0, txt.count);
  235. return retValue;
  236. }
  237. /**
  238. * See readObject() and writeObject() in JComponent for more
  239. * information about serialization in Swing.
  240. */
  241. private void writeObject(ObjectOutputStream s) throws IOException {
  242. s.defaultWriteObject();
  243. if (getUIClassID().equals(uiClassID)) {
  244. byte count = JComponent.getWriteObjCounter(this);
  245. JComponent.setWriteObjCounter(this, --count);
  246. if (count == 0 && ui != null) {
  247. ui.installUI(this);
  248. }
  249. }
  250. }
  251. // --- variables -----------------------------------------------
  252. /**
  253. * @see #getUIClassID
  254. * @see #readObject
  255. */
  256. private static final String uiClassID = "PasswordFieldUI";
  257. private char echoChar;
  258. /**
  259. * Returns a string representation of this <code>JPasswordField</code>.
  260. * This method is intended to be used only for debugging purposes, and the
  261. * content and format of the returned string may vary between
  262. * implementations. The returned string may be empty but may not
  263. * be <code>null</code>.
  264. *
  265. * @return a string representation of this <code>JPasswordField</code>
  266. */
  267. protected String paramString() {
  268. return super.paramString() +
  269. ",echoChar=" + echoChar;
  270. }
  271. /////////////////
  272. // Accessibility support
  273. ////////////////
  274. /**
  275. * Returns the <code>AccessibleContext</code> associated with this
  276. * <code>JPasswordField</code>. For password fields, the
  277. * <code>AccessibleContext</code> takes the form of an
  278. * <code>AccessibleJPasswordField</code>.
  279. * A new <code>AccessibleJPasswordField</code> instance is created
  280. * if necessary.
  281. *
  282. * @return an <code>AccessibleJPasswordField</code> that serves as the
  283. * <code>AccessibleContext</code> of this
  284. * <code>JPasswordField</code>
  285. */
  286. public AccessibleContext getAccessibleContext() {
  287. if (accessibleContext == null) {
  288. accessibleContext = new AccessibleJPasswordField();
  289. }
  290. return accessibleContext;
  291. }
  292. /**
  293. * This class implements accessibility support for the
  294. * <code>JPasswordField</code> class. It provides an implementation of the
  295. * Java Accessibility API appropriate to password field user-interface
  296. * elements.
  297. * <p>
  298. * <strong>Warning:</strong>
  299. * Serialized objects of this class will not be compatible with
  300. * future Swing releases. The current serialization support is
  301. * appropriate for short term storage or RMI between applications running
  302. * the same version of Swing. As of 1.4, support for long term storage
  303. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  304. * has been added to the <code>java.beans</code> package.
  305. * Please see {@link java.beans.XMLEncoder}.
  306. */
  307. protected class AccessibleJPasswordField extends AccessibleJTextField {
  308. /**
  309. * Gets the role of this object.
  310. *
  311. * @return an instance of AccessibleRole describing the role of the
  312. * object (AccessibleRole.PASSWORD_TEXT)
  313. * @see AccessibleRole
  314. */
  315. public AccessibleRole getAccessibleRole() {
  316. return AccessibleRole.PASSWORD_TEXT;
  317. }
  318. }
  319. }