You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ValidatingJTextField.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /*
  2. * Copyright (c) 2006-2013 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.ui_swing.components.validating;
  23. import com.dmdirc.addons.ui_swing.UIUtilities;
  24. import com.dmdirc.ui.IconManager;
  25. import com.dmdirc.util.validators.ValidationResponse;
  26. import com.dmdirc.util.validators.Validator;
  27. import java.awt.Color;
  28. import java.awt.Font;
  29. import java.awt.event.KeyListener;
  30. import java.awt.event.MouseListener;
  31. import javax.swing.Icon;
  32. import javax.swing.JComponent;
  33. import javax.swing.JLabel;
  34. import javax.swing.JTextField;
  35. import javax.swing.TransferHandler;
  36. import javax.swing.event.DocumentEvent;
  37. import javax.swing.event.DocumentListener;
  38. import javax.swing.text.BadLocationException;
  39. import javax.swing.text.Document;
  40. import net.miginfocom.swing.MigLayout;
  41. /**
  42. * Validating Text field.
  43. */
  44. public class ValidatingJTextField extends JComponent implements DocumentListener {
  45. /**
  46. * A version number for this class. It should be changed whenever the class
  47. * structure is changed (or anything else that would prevent serialized
  48. * objects being unserialized with the new class).
  49. */
  50. private static final long serialVersionUID = 1;
  51. /** TextField. */
  52. private final JTextField textField;
  53. /** Validator. */
  54. private Validator<String> validator;
  55. /** Error icon. */
  56. private final JLabel errorIcon;
  57. /**
  58. * Instantiates a new Validating text field.
  59. *
  60. * @param iconManager Icon manager
  61. * @param validator Validator instance
  62. */
  63. public ValidatingJTextField(final IconManager iconManager,
  64. final Validator<String> validator) {
  65. this(iconManager, new JTextField(), validator);
  66. }
  67. /**
  68. * Instantiates a new Validating text field.
  69. *
  70. * @param iconManager Icon manager
  71. * @param textField JTextField to wrap
  72. * @param validator Validator instance
  73. */
  74. public ValidatingJTextField(final IconManager iconManager,
  75. final JTextField textField, final Validator<String> validator) {
  76. this(iconManager.getIcon("input-error"), textField, validator);
  77. }
  78. /**
  79. * Instantiates a new Validating text field.
  80. *
  81. * @param icon Icon to show on error
  82. * @param textField JTextField to wrap
  83. * @param validator Validator instance
  84. */
  85. public ValidatingJTextField(final Icon icon,
  86. final JTextField textField, final Validator<String> validator) {
  87. super();
  88. this.textField = textField;
  89. this.validator = validator;
  90. errorIcon = new JLabel(icon);
  91. setLayout(new MigLayout("fill, ins 0, hidemode 3, gap 0"));
  92. add(textField, "grow, pushx");
  93. add(errorIcon);
  94. checkError();
  95. textField.getDocument().addDocumentListener(this);
  96. }
  97. /**
  98. * Updates the validator for this textfield.
  99. *
  100. * @param validator new validator
  101. */
  102. public void setValidator(final Validator<String> validator) {
  103. this.validator = validator;
  104. checkError();
  105. }
  106. /**
  107. * Checks the text for errors and sets the error state accordingly.
  108. */
  109. public void checkError() {
  110. if (textField.isEnabled()) {
  111. final ValidationResponse vr =
  112. validator.validate(textField.getText());
  113. errorIcon.setToolTipText(vr.getFailureReason());
  114. firePropertyChange("validationResult", !errorIcon.isVisible(), !vr.isFailure());
  115. errorIcon.setVisible(vr.isFailure());
  116. } else {
  117. firePropertyChange("validationResult", !errorIcon.isVisible(), true);
  118. errorIcon.setVisible(false);
  119. }
  120. }
  121. /**
  122. * Checks if the text validates.
  123. *
  124. * @see com.dmdirc.ui.swing.components.validating.Validator#validate(Object)
  125. *
  126. * @return true iif the text validates
  127. */
  128. public boolean validateText() {
  129. if (textField.isEnabled()) {
  130. return !validator.validate(getText()).isFailure();
  131. } else {
  132. return true;
  133. }
  134. }
  135. /** {@inheritDoc} */
  136. @Override
  137. public void changedUpdate(final DocumentEvent e) {
  138. checkError();
  139. }
  140. /** {@inheritDoc} */
  141. @Override
  142. public void insertUpdate(final DocumentEvent e) {
  143. checkError();
  144. }
  145. /** {@inheritDoc} */
  146. @Override
  147. public void removeUpdate(final DocumentEvent e) {
  148. checkError();
  149. }
  150. /** {@inheritDoc} */
  151. @Override
  152. public void setToolTipText(final String text) {
  153. textField.setToolTipText(text);
  154. }
  155. /** {@inheritDoc} */
  156. @Override
  157. public void setEnabled(final boolean enabled) {
  158. textField.setEnabled(enabled);
  159. checkError();
  160. }
  161. /** {@inheritDoc} */
  162. @Override
  163. public void requestFocus() {
  164. textField.requestFocus();
  165. }
  166. /** {@inheritDoc} */
  167. @Override
  168. public boolean requestFocusInWindow() {
  169. return textField.requestFocusInWindow();
  170. }
  171. /**
  172. * Sets the text in the textfield.
  173. *
  174. * @see javax.swing.JTextField#setText(String)
  175. *
  176. * @param t Text to set
  177. */
  178. public void setText(final String t) {
  179. textField.setText(t);
  180. }
  181. /**
  182. * Sets the selection start.
  183. *
  184. * @see javax.swing.JTextField#setSelectionStart(int)
  185. *
  186. * @param selectionStart Start of the selection
  187. */
  188. public void setSelectionStart(final int selectionStart) {
  189. textField.setSelectionStart(selectionStart);
  190. }
  191. /**
  192. * Sets the selection end.
  193. *
  194. * @see javax.swing.JTextField#setSelectionEnd(int)
  195. *
  196. * @param selectionEnd End of the selection
  197. */
  198. public void setSelectionEnd(final int selectionEnd) {
  199. textField.setSelectionEnd(selectionEnd);
  200. }
  201. /**
  202. * Sets whether the component is editable.
  203. *
  204. * @see javax.swing.JTextField#setEditable(boolean)
  205. *
  206. * @param b editable state for the component
  207. */
  208. public void setEditable(final boolean b) {
  209. textField.setEditable(b);
  210. }
  211. /**
  212. * Selects all text in the textfield.
  213. *
  214. * @see javax.swing.JTextField#selectAll()
  215. */
  216. public void selectAll() {
  217. textField.selectAll();
  218. }
  219. /**
  220. * Selects the specified text in the textfield.
  221. *
  222. * @see javax.swing.JTextField#select(int, int)
  223. *
  224. * @param selectionStart Selection start
  225. * @param selectionEnd Selection end
  226. */
  227. public void select(final int selectionStart, final int selectionEnd) {
  228. textField.select(selectionStart, selectionEnd);
  229. }
  230. /**
  231. * Replaces the textfields selection with the specified content.
  232. *
  233. * @see javax.swing.JTextField#replaceSelection(String)
  234. *
  235. * @param content Text to replace selection with
  236. */
  237. public void replaceSelection(final String content) {
  238. textField.replaceSelection(content);
  239. }
  240. /**
  241. * Paste's the system clipboard into the textfield.
  242. *
  243. * @see javax.swing.JTextField#paste()
  244. */
  245. public void paste() {
  246. textField.paste();
  247. }
  248. /**
  249. * Checks if the textfield is editable.
  250. *
  251. * @see javax.swing.JTextField#isEditable()
  252. *
  253. * @return true iif the textfield is editable
  254. */
  255. public boolean isEditable() {
  256. return textField.isEditable();
  257. }
  258. /**
  259. * Returns the text in the textfield.
  260. *
  261. * @see javax.swing.JTextField#getText()
  262. *
  263. * @return Textfield content
  264. */
  265. public String getText() {
  266. return textField.getText();
  267. }
  268. /**
  269. * Returns the specified section of text in the textfield.
  270. *
  271. * @see javax.swing.JTextField#getText(int, int)
  272. *
  273. * @param offs Start offset
  274. * @param len section length
  275. *
  276. * @return Specified textfield content
  277. *
  278. * @throws javax.swing.text.BadLocationException
  279. */
  280. public String getText(final int offs, final int len) throws BadLocationException {
  281. return textField.getText(offs, len);
  282. }
  283. /**
  284. * Returns the start of the selection in the textfield.
  285. *
  286. * @see javax.swing.JTextField#getSelectionStart()
  287. *
  288. * @return Selection start
  289. */
  290. public int getSelectionStart() {
  291. return textField.getSelectionStart();
  292. }
  293. /**
  294. * Returns the end of the textfield selection.
  295. *
  296. * @see javax.swing.JTextField#getSelectionEnd()
  297. *
  298. * @return Selection end
  299. */
  300. public int getSelectionEnd() {
  301. return textField.getSelectionEnd();
  302. }
  303. /**
  304. * Returns the selected text in the textfield.
  305. *
  306. * @see javax.swing.JTextField#getSelectedText()
  307. *
  308. * @return Selected text
  309. */
  310. public String getSelectedText() {
  311. return textField.getSelectedText();
  312. }
  313. /**
  314. * Returns the textfield's document.
  315. *
  316. * @see javax.swing.JTextField#getDocument()
  317. *
  318. * @return Textfield's document
  319. */
  320. public Document getDocument() {
  321. return textField.getDocument();
  322. }
  323. /**
  324. * Cuts the selected text from the textfield into the clipboard.
  325. *
  326. * @see javax.swing.JTextField#cut()
  327. */
  328. public void cut() {
  329. textField.cut();
  330. }
  331. /**
  332. * Copies the selected text from the textfield into the clipboard.
  333. *
  334. * @see javax.swing.JTextField#copy()
  335. */
  336. public void copy() {
  337. textField.copy();
  338. }
  339. /**
  340. * Returns the font for the textfield.
  341. *
  342. * @see javax.swing.JTextField#copy()
  343. */
  344. @Override
  345. public Font getFont() {
  346. return textField.getFont();
  347. }
  348. /** {@inheritDoc} */
  349. @Override
  350. public synchronized void addKeyListener(final KeyListener l) {
  351. textField.addKeyListener(l);
  352. }
  353. /** {@inheritDoc} */
  354. @Override
  355. public synchronized void removeKeyListener(final KeyListener l) {
  356. textField.removeKeyListener(l);
  357. }
  358. /** {@inheritDoc} */
  359. @Override
  360. public synchronized void addMouseListener(final MouseListener l) {
  361. textField.addMouseListener(l);
  362. }
  363. /** {@inheritDoc} */
  364. @Override
  365. public synchronized void removeMouseListener(final MouseListener l) {
  366. textField.removeMouseListener(l);
  367. }
  368. /**
  369. * Sets the drag enabled property on the textfield.
  370. *
  371. * @param enabled Enabled?
  372. */
  373. public void setDragEnabled(final boolean enabled) {
  374. textField.setDragEnabled(enabled);
  375. }
  376. /** {@inheritDoc} */
  377. @Override
  378. public void setTransferHandler(final TransferHandler newHandler) {
  379. textField.setTransferHandler(newHandler);
  380. }
  381. /**
  382. * Returns the validator used by this text field.
  383. *
  384. * @since 0.6.3m1
  385. *
  386. * @return This field's validator
  387. */
  388. public Validator<String> getValidator() {
  389. return validator;
  390. }
  391. /**
  392. * Returns the text field used by this validating text field.
  393. *
  394. * @since 0.6.3m1
  395. *
  396. * @return This field's text field
  397. */
  398. public JTextField getTextField() {
  399. return textField;
  400. }
  401. /**
  402. * Sets the caret colour to the specified coloour.
  403. *
  404. * @param optionColour Colour for the caret
  405. */
  406. public void setCaretColor(final Color optionColour) {
  407. UIUtilities.invokeLater(new Runnable() {
  408. /** {@inheritDoc} */
  409. @Override
  410. public void run() {
  411. textField.setCaretColor(optionColour);
  412. }
  413. });
  414. }
  415. /**
  416. * Sets the foreground colour to the specified coloour.
  417. *
  418. * @param optionColour Colour for the foreground
  419. */
  420. @Override
  421. public void setForeground(final Color optionColour) {
  422. UIUtilities.invokeLater(new Runnable() {
  423. /** {@inheritDoc} */
  424. @Override
  425. public void run() {
  426. textField.setForeground(optionColour);
  427. }
  428. });
  429. }
  430. /**
  431. * Sets the disabled text colour to the specified coloour.
  432. *
  433. * @param optionColour Colour for the disabled text
  434. */
  435. public void setDisabledTextColour(final Color optionColour) {
  436. UIUtilities.invokeLater(new Runnable() {
  437. /** {@inheritDoc} */
  438. @Override
  439. public void run() {
  440. textField.setDisabledTextColor(optionColour);
  441. }
  442. });
  443. }
  444. /**
  445. * Sets the background colour to the specified coloour.
  446. *
  447. * @param optionColour Colour for the caret
  448. */
  449. @Override
  450. public void setBackground(final Color optionColour) {
  451. UIUtilities.invokeLater(new Runnable() {
  452. /** {@inheritDoc} */
  453. @Override
  454. public void run() {
  455. textField.setBackground(optionColour);
  456. }
  457. });
  458. }
  459. }