MNDigitField.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4. import javax.swing.text.*;
  5. import javax.swing.event.*;
  6. //***************************************************************************
  7. // This is a class that allows you to create a text field with only digits
  8. // and with a maximum of N digits. Once the number of digits becomes M, an
  9. // MAction is performed on the MComponent. And once the number of digits
  10. // is not M anymore, an MReaction is performed. The same is true for N. Once
  11. // the number of digits becomes N, an NAction is performed on the NComponent.
  12. //
  13. // Author: Ali Badereddin
  14. // Date: September 11, 2005
  15. //
  16. //***************************************************************************
  17. public class MNDigitField extends JTextField
  18. {
  19. // Represents the current length of ht etext in this text field
  20. private static int currentLength = 0;
  21. // The value that causes MActor to act
  22. private static int M;
  23. // The maximum number of digits the field can hold
  24. // Also, this is the value that triggers the NAction
  25. private static int N;
  26. // Represents M Component Actor
  27. private static ComponentActor MComponentActor;
  28. // Represents N Component Actor
  29. private static ComponentActor NComponentActor;
  30. //---------------------------------------------------------------------
  31. // Constructor...
  32. //---------------------------------------------------------------------
  33. public MNDigitField (int m, int n, JComponent mComp, JComponent nComp,
  34. int cols)
  35. {
  36. // Specify the width of the text field in terms of columns
  37. super (cols);
  38. // Set M and N
  39. this.M = m;
  40. this.N = n;
  41. // create component actors
  42. this.MComponentActor = new ComponentActor (mComp);
  43. this.NComponentActor = new ComponentActor (nComp);
  44. // Set the action type to ENABLE (This is default type, but I'm
  45. // resetting to emphasize the idea)
  46. this.MComponentActor.setActionType (ComponentActor.ENABLE);
  47. this.NComponentActor.setActionType (ComponentActor.ENABLE);
  48. // Add document listener to the text field
  49. this.getDocument().addDocumentListener (new MNDocumentListener ());
  50. }
  51. //---------------------------------------------------------------------
  52. // Tells how many digits there are in the text field.
  53. //---------------------------------------------------------------------
  54. public int howManyDigits ()
  55. {
  56. return this.getText().length ();
  57. }
  58. //---------------------------------------------------------------------
  59. // Sets M (the value that triggers the MAction).
  60. //---------------------------------------------------------------------
  61. public void setM (int m)
  62. {
  63. this.M = m;
  64. }
  65. //---------------------------------------------------------------------
  66. // Gets M (the value that triggers the MAction).
  67. //---------------------------------------------------------------------
  68. public int getM ()
  69. {
  70. return this.M;
  71. }
  72. //---------------------------------------------------------------------
  73. // Sets N (the value that triggers the NAction).
  74. //---------------------------------------------------------------------
  75. public void setN (int n)
  76. {
  77. this.N = n;
  78. }
  79. //---------------------------------------------------------------------
  80. // Gets N (the value that triggers the NAction).
  81. //---------------------------------------------------------------------
  82. public int getN ()
  83. {
  84. return this.N;
  85. }
  86. //*********************************************************************
  87. // This class is responsible for not allowing characters other than
  88. // digits to be entered, and for not allowing the number of characters
  89. // to exceed N.
  90. //*********************************************************************
  91. static class NDigitDocument extends PlainDocument
  92. {
  93. public void insertString (int offs, String str, AttributeSet a)
  94. throws BadLocationException
  95. {
  96. if (str == null)
  97. return;
  98. // Don't allow number of characters to exceed N
  99. // (The +1 is because insertString is called before insertupdate)
  100. if (currentLength + 1 > N)
  101. return;
  102. // Validate that the characters of the string are digits
  103. for (int i = 0; i < str.length(); i++)
  104. {
  105. if (!Character.isDigit (str.charAt (i)))
  106. return;
  107. }
  108. super.insertString(offs, str, a);
  109. }
  110. }
  111. //---------------------------------------------------------------------
  112. // This is necessary for out text field to have hte properties
  113. // of the NDigitDocument.
  114. //---------------------------------------------------------------------
  115. protected Document createDefaultModel()
  116. {
  117. return new NDigitDocument ();
  118. }
  119. //*********************************************************************
  120. // This class listens to user's interaction with the textfield,
  121. // and decides what to do based on the number of characters in the
  122. // text field.
  123. //*********************************************************************
  124. class MNDocumentListener implements DocumentListener
  125. {
  126. //-----------------------------------------------------------------
  127. // Called when users insert characters.
  128. //-----------------------------------------------------------------
  129. public void insertUpdate (DocumentEvent e)
  130. {
  131. decide (e);
  132. }
  133. //-----------------------------------------------------------------
  134. // Called when users remove characters (DEL or Back Space).
  135. //-----------------------------------------------------------------
  136. public void removeUpdate (DocumentEvent e)
  137. {
  138. decide (e);
  139. }
  140. //-----------------------------------------------------------------
  141. // Not called by plain document .
  142. // This is used when style changes, but we don't need it here.
  143. //-----------------------------------------------------------------
  144. public void changedUpdate (DocumentEvent e) {}
  145. //-----------------------------------------------------------------
  146. // Do an action based on the values of M and N. In our case, the
  147. // action is to enable or disable (reaction) the MComponent
  148. // and NComponent.
  149. //-----------------------------------------------------------------
  150. public void decide (DocumentEvent e)
  151. {
  152. Document doc = (Document)e.getDocument();
  153. currentLength = doc.getLength ();
  154. // Enable MComponent if M digits reached
  155. // Otherwise, disable it.
  156. MComponentActor.decide (currentLength == M);
  157. // Enable NComponent if N digits reached
  158. // Otherwise, disable it.
  159. NComponentActor.decide (currentLength == N);
  160. }
  161. }
  162. //---------------------------------------------------------------------
  163. // Checks out my work...
  164. //---------------------------------------------------------------------
  165. public static void main (String[] args)
  166. {
  167. JFrame frame = new JFrame ("Test");
  168. frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  169. // create buttons
  170. JButton button1 = new JButton ("Button 1");
  171. JButton button2 = new JButton ("Button 2");
  172. // Set buttons to be initially disabled
  173. button1.setEnabled (false);
  174. button2.setEnabled (false);
  175. // Set background to white and layout to flow layout
  176. frame.setBackground (Color.white);
  177. frame.setLayout (new FlowLayout ());
  178. // add buttons and text field
  179. frame.getContentPane().add (new MNDigitField (11, 12, button1, button2, 8));
  180. frame.getContentPane().add (button1);
  181. frame.getContentPane().add (button2);
  182. // Pack and show the window (frame)
  183. frame.pack();
  184. frame.setVisible (true);
  185. }
  186. }