1. package org.jr.swing.text;
  2. /**
  3. * Copyright: Copyright (c) 2002-2004
  4. * Company: JavaResearch(http://www.javaresearch.org)
  5. * 最后更新日期:2003年2月12日
  6. * @author Cherami
  7. */
  8. import java.awt.*;
  9. import javax.swing.text.*;
  10. /**
  11. * 只能输入数字的Swing文档模型。
  12. * 可以设置可以保存的数字的最大值和最小值。
  13. * @since 0.1
  14. */
  15. public class NumberOnlyDocument
  16. extends PlainDocument {
  17. private boolean haveDot = false;
  18. private int length = 0;
  19. private double max = Double.MIN_VALUE, min = Double.MAX_VALUE;
  20. private boolean isLimit = false;
  21. /**
  22. * 构造一个缺省的NumberOnlyDocument。
  23. * @since 0.1
  24. */
  25. public NumberOnlyDocument() {
  26. }
  27. /**
  28. * 构造一个限制数字大小的NumberOnlyDocument。
  29. * 只有在max不小于min的情况下max和min的设置才生效。
  30. * @param max 最大值
  31. * @param min 最小值
  32. * @since 0.3
  33. */
  34. public NumberOnlyDocument(double max, double min) {
  35. if (max >= min) {
  36. this.max = max;
  37. this.min = min;
  38. }
  39. this.isLimit = true;
  40. }
  41. /**
  42. * 构造一个限制数字大小的NumberOnlyDocument。
  43. * 只有在max不小于min的情况下max和min的设置才生效。
  44. * @param max 最大值
  45. * @param min 最小值
  46. * @param isLimit 是否限制数字大小
  47. * @since 0.3
  48. */
  49. public NumberOnlyDocument(double max, double min, boolean isLimit) {
  50. if (max >= min) {
  51. this.max = max;
  52. this.min = min;
  53. }
  54. this.isLimit = isLimit;
  55. }
  56. /**
  57. * 设置是否限制数字的大小。
  58. * 如果参数是true时只有在原来的最大值大于最小值是这个设置才起效,否则此方法调用没有任何效果。
  59. * 如果参数值是false则取消输入数字大小的限制
  60. * @param isLimit 是否限制输入数字的大小
  61. * @since 0.3
  62. */
  63. public void setLimit(boolean isLimit) {
  64. if (isLimit == true && max >= min) {
  65. this.isLimit = isLimit;
  66. }
  67. else if (isLimit == false) {
  68. this.isLimit = isLimit;
  69. }
  70. }
  71. /**
  72. * 设置可以输入的值的范围。
  73. * 如果max小于min则可以输入的最大值和最小值的限制无效,作为没有大小限制的情况处理。
  74. * @param max 可以输入的最大值
  75. * @param min 可以输入的最小值
  76. * @since 0.3
  77. */
  78. public void setRange(double max, double min) {
  79. if (max >= min) {
  80. this.max = max;
  81. this.min = min;
  82. isLimit = true;
  83. }
  84. }
  85. /**
  86. * 是否限制数字的大小。
  87. * @return 限制输入大小时返回true,否则返回false。
  88. * @since 0.3
  89. */
  90. public boolean isLimit() {
  91. return isLimit;
  92. }
  93. /**
  94. * 返回限制的最大值。
  95. * @return 限制的最大值。如果是不限制则返回Double.MIN_VALUE。
  96. * @since 0.3
  97. */
  98. public double getLimitedMax() {
  99. if (!isLimit) {
  100. return Double.MIN_VALUE;
  101. }
  102. else {
  103. return max;
  104. }
  105. }
  106. /**
  107. * 返回限制的最小值。
  108. * @return 限制的最小值。如果是不限制则返回Double.MAX_VALUE。
  109. * @since 0.3
  110. */
  111. public double getLimitedMin() {
  112. if (!isLimit) {
  113. return Double.MAX_VALUE;
  114. }
  115. else {
  116. return min;
  117. }
  118. }
  119. /**
  120. * 插入某些内容到文档中。
  121. * 只有当输入的是数字或者和数字相关的“.”、“-”等符号并且符合构成合法数字的规则时才被插入。
  122. * 此方法是线程安全的。
  123. * @param offs 插入位置的偏移量
  124. * @param str 插入内容
  125. * @param a 属性集合
  126. * @throws BadLocationException 给出的插入位置不是文档中的有效位置
  127. * @since 0.1
  128. */
  129. public void insertString(int offs, String str, AttributeSet a) throws
  130. BadLocationException {
  131. if (str == null) {
  132. return;
  133. }
  134. char[] number = str.toCharArray();
  135. for (int i = 0; i < number.length; i++) {
  136. if (offs == 0) {
  137. if (! (number[i] >= '0' && number[i] <= '9' || number[i] == '.' ||
  138. number[i] == '-' || number[i] == '+')) {
  139. if (offs == length - 1) {
  140. remove(offs + i, 1);
  141. }
  142. else {
  143. return;
  144. }
  145. }
  146. else {
  147. length++;
  148. }
  149. }
  150. else {
  151. if (!haveDot) {
  152. if (! (number[i] >= '0' && number[i] <= '9' || number[i] == '.')) {
  153. if (offs == length - 1) {
  154. remove(offs + i, 1);
  155. }
  156. else {
  157. return;
  158. }
  159. }
  160. else {
  161. if (number[i] == '.') {
  162. haveDot = true;
  163. }
  164. length++;
  165. }
  166. }
  167. else {
  168. if (! (number[i] >= '0' && number[i] <= '9')) {
  169. if (offs == length - 1) {
  170. remove(offs + i, 1);
  171. }
  172. else {
  173. Toolkit.getDefaultToolkit().beep();
  174. return;
  175. }
  176. }
  177. else {
  178. length++;
  179. }
  180. }
  181. }
  182. }
  183. if (isLimit == true) {
  184. String text = getText(0, offs) + str + getText(offs, getLength());
  185. double result = Double.parseDouble(text);
  186. if (result > max || result < min) {
  187. return;
  188. }
  189. }
  190. super.insertString(offs, new String(number), a);
  191. }
  192. }