1. /*
  2. * @(#)PasswordView.java 1.10 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.text;
  8. import java.awt.*;
  9. import javax.swing.JPasswordField;
  10. /**
  11. * Implements a View suitable for use in JPasswordField
  12. * UI implementations. This is basically a field ui that
  13. * renders its contents as the echo character specified
  14. * in the associated component (if it can narrow the
  15. * component to a JPasswordField).
  16. *
  17. * @author Timothy Prinzing
  18. * @version 1.10 11/29/01
  19. * @see View
  20. */
  21. public class PasswordView extends FieldView {
  22. /**
  23. * Constructs a new view wrapped on an element.
  24. *
  25. * @param elem the element
  26. */
  27. public PasswordView(Element elem) {
  28. super(elem);
  29. }
  30. /**
  31. * Renders the given range in the model as normal unselected
  32. * text. This sets the foreground color and echos the characters
  33. * using the value returned by getEchoChar().
  34. *
  35. * @param g the graphics context
  36. * @param x the starting X coordinate >= 0
  37. * @param y the starting Y coordinate >= 0
  38. * @param p0 the starting offset in the model >= 0
  39. * @param p1 the ending offset in the model >= p0
  40. * @returns the X location of the end of the range >= 0
  41. * @exception BadLocationException if p0 or p1 are out of range
  42. */
  43. protected int drawUnselectedText(Graphics g, int x, int y,
  44. int p0, int p1) throws BadLocationException {
  45. Container c = getContainer();
  46. if (c instanceof JPasswordField) {
  47. JPasswordField f = (JPasswordField) c;
  48. g.setColor(f.getForeground());
  49. char echoChar = f.getEchoChar();
  50. int n = p1 - p0;
  51. for (int i = 0; i < n; i++) {
  52. x = drawEchoCharacter(g, x, y, echoChar);
  53. }
  54. }
  55. return x;
  56. }
  57. /**
  58. * Renders the given range in the model as selected text. This
  59. * is implemented to render the text in the color specified in
  60. * the hosting component. It assumes the highlighter will render
  61. * the selected background. Uses the result of getEchoChar() to
  62. * display the characters.
  63. *
  64. * @param g the graphics context
  65. * @param x the starting X coordinate >= 0
  66. * @param y the starting Y coordinate >= 0
  67. * @param p0 the starting offset in the model >= 0
  68. * @param p1 the ending offset in the model >= p0
  69. * @returns the X location of the end of the range >= 0.
  70. * @exception BadLocationException if p0 or p1 are out of range
  71. */
  72. protected int drawSelectedText(Graphics g, int x,
  73. int y, int p0, int p1) throws BadLocationException {
  74. g.setColor(selected);
  75. Container c = getContainer();
  76. if (c instanceof JPasswordField) {
  77. JPasswordField f = (JPasswordField) c;
  78. g.setColor(f.getSelectedTextColor());
  79. char echoChar = f.getEchoChar();
  80. int n = p1 - p0;
  81. for (int i = 0; i < n; i++) {
  82. x = drawEchoCharacter(g, x, y, echoChar);
  83. }
  84. }
  85. return x;
  86. }
  87. /**
  88. * Renders the echo character, or whatever graphic should be used
  89. * to display the password characters. The color in the Graphics
  90. * object is set to the appropriate foreground color for selected
  91. * or unselected text.
  92. *
  93. * @param g the graphics context
  94. * @param x the starting X coordinate >= 0
  95. * @param y the starting Y coordinate >= 0
  96. * @param c the echo character
  97. * @return the updated X position >= 0
  98. */
  99. protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
  100. ONE[0] = c;
  101. g.drawChars(ONE, 0, 1, x, y);
  102. return x + g.getFontMetrics().charWidth(c);
  103. }
  104. /**
  105. * Provides a mapping from the document model coordinate space
  106. * to the coordinate space of the view mapped to it.
  107. *
  108. * @param pos the position to convert >= 0
  109. * @param a the allocated region to render into
  110. * @return the bounding box of the given position
  111. * @exception BadLocationException if the given position does not
  112. * represent a valid location in the associated document
  113. * @see View#modelToView
  114. */
  115. public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
  116. Container c = getContainer();
  117. if (c instanceof JPasswordField) {
  118. JPasswordField f = (JPasswordField) c;
  119. char echoChar = f.getEchoChar();
  120. FontMetrics m = f.getFontMetrics(f.getFont());
  121. Rectangle alloc = adjustAllocation(a).getBounds();
  122. int dx = (pos - getStartOffset()) * m.charWidth(echoChar);
  123. alloc.x += dx;
  124. alloc.width = 1;
  125. return alloc;
  126. }
  127. return null;
  128. }
  129. /**
  130. * Provides a mapping from the view coordinate space to the logical
  131. * coordinate space of the model.
  132. *
  133. * @param fx the X coordinate >= 0.0f
  134. * @param fy the Y coordinate >= 0.0f
  135. * @param a the allocated region to render into
  136. * @return the location within the model that best represents the
  137. * given point in the view
  138. * @see View#viewToModel
  139. */
  140. public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
  141. bias[0] = Position.Bias.Forward;
  142. int n = 0;
  143. Container c = getContainer();
  144. if (c instanceof JPasswordField) {
  145. JPasswordField f = (JPasswordField) c;
  146. char echoChar = f.getEchoChar();
  147. FontMetrics m = f.getFontMetrics(f.getFont());
  148. a = adjustAllocation(a);
  149. Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a :
  150. a.getBounds();
  151. n = ((int)fx - alloc.x) / m.charWidth(echoChar);
  152. if (n < 0) {
  153. n = 0;
  154. }
  155. else if (n > (getStartOffset() + getDocument().getLength())) {
  156. n = getDocument().getLength() - getStartOffset();
  157. }
  158. }
  159. return getStartOffset() + n;
  160. }
  161. static char[] ONE = new char[1];
  162. }