View Javadoc

1   /********************************************************************************
2    * InternetCafe is a software solution that helps the management of Cybercafes 
3    * according with the ITALIAN DECREE LAW ON ANTI-TERROR MEASURES, 27 JULY 2005.
4    * Copyright (C) 2006  Guido Angelo Ingenito
5   
6    * This program is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU General Public License
8    * as published by the Free Software Foundation; either version 2
9    * of the License, or (at your option) any later version.
10  
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   * 
16   * You should have received a copy of the GNU General Public License
17   * along with this program; if not, write to the Free Software
18   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19   *******************************************************************************/
20  package ui.util;
21  
22  import java.awt.Component;
23  import java.awt.Toolkit;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.KeyEvent;
26  import java.text.NumberFormat;
27  import java.text.ParseException;
28  
29  import javax.swing.AbstractAction;
30  import javax.swing.DefaultCellEditor;
31  import javax.swing.JFormattedTextField;
32  import javax.swing.JOptionPane;
33  import javax.swing.JTable;
34  import javax.swing.JTextField;
35  import javax.swing.KeyStroke;
36  import javax.swing.SwingUtilities;
37  import javax.swing.text.DefaultFormatterFactory;
38  import javax.swing.text.NumberFormatter;
39  
40  /***
41   * Implements a cell editor that uses a formatted text field to edit Integer
42   * values.
43   */
44  @SuppressWarnings("serial")
45  public class IntegerEditor extends DefaultCellEditor {
46  	JFormattedTextField ftf;
47  
48  	NumberFormat integerFormat;
49  
50  	private Integer minimum, maximum;
51  
52  	private boolean DEBUG = false;
53  
54  	public IntegerEditor(int min, int max) {
55  		super(new JFormattedTextField());
56  		ftf = (JFormattedTextField) getComponent();
57  		minimum = new Integer(min);
58  		maximum = new Integer(max);
59  
60  		// Set up the editor for the integer cells.
61  		integerFormat = NumberFormat.getIntegerInstance();
62  		NumberFormatter intFormatter = new NumberFormatter(integerFormat);
63  		intFormatter.setFormat(integerFormat);
64  		intFormatter.setMinimum(minimum);
65  		intFormatter.setMaximum(maximum);
66  
67  		ftf.setFormatterFactory(new DefaultFormatterFactory(intFormatter));
68  		ftf.setValue(minimum);
69  		ftf.setHorizontalAlignment(JTextField.TRAILING);
70  		ftf.setFocusLostBehavior(JFormattedTextField.PERSIST);
71  
72  		// React when the user presses Enter while the editor is
73  		// active. (Tab is handled as specified by
74  		// JFormattedTextField's focusLostBehavior property.)
75  		ftf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
76  				"check");
77  		ftf.getActionMap().put("check", new AbstractAction() {
78  			public void actionPerformed(ActionEvent e) {
79  				if (!ftf.isEditValid()) { // The text is invalid.
80  					if (userSaysRevert()) { // reverted
81  						ftf.postActionEvent(); // inform the editor
82  					}
83  				} else
84  					try { // The text is valid,
85  						ftf.commitEdit(); // so use it.
86  						ftf.postActionEvent(); // stop editing
87  					} catch (java.text.ParseException exc) {
88  					}
89  			}
90  		});
91  	}
92  
93  	// Override to invoke setValue on the formatted text field.
94  	public Component getTableCellEditorComponent(JTable table, Object value,
95  			boolean isSelected, int row, int column) {
96  		JFormattedTextField ftf = (JFormattedTextField) super
97  				.getTableCellEditorComponent(table, value, isSelected, row,
98  						column);
99  		ftf.setValue(value);
100 		return ftf;
101 	}
102 
103 	// Override to ensure that the value remains an Integer.
104 	public Object getCellEditorValue() {
105 		JFormattedTextField ftf = (JFormattedTextField) getComponent();
106 		Object o = ftf.getValue();
107 		if (o instanceof Integer) {
108 			return o;
109 		} else if (o instanceof Number) {
110 			return new Integer(((Number) o).intValue());
111 		} else {
112 			if (DEBUG) {
113 				System.out.println("getCellEditorValue: o isn't a Number");
114 			}
115 			try {
116 				return integerFormat.parseObject(o.toString());
117 			} catch (ParseException exc) {
118 				System.err.println("getCellEditorValue: can't parse o: " + o);
119 				return null;
120 			}
121 		}
122 	}
123 
124 	// Override to check whether the edit is valid,
125 	// setting the value if it is and complaining if
126 	// it isn't. If it's OK for the editor to go
127 	// away, we need to invoke the superclass's version
128 	// of this method so that everything gets cleaned up.
129 	public boolean stopCellEditing() {
130 		JFormattedTextField ftf = (JFormattedTextField) getComponent();
131 		if (ftf.isEditValid()) {
132 			try {
133 				ftf.commitEdit();
134 			} catch (java.text.ParseException exc) {
135 			}
136 
137 		} else { // text is invalid
138 			if (!userSaysRevert()) { // user wants to edit
139 				return false; // don't let the editor go away
140 			}
141 		}
142 		return super.stopCellEditing();
143 	}
144 
145 	/***
146 	 * Lets the user know that the text they entered is bad. Returns true if the
147 	 * user elects to revert to the last good value. Otherwise, returns false,
148 	 * indicating that the user wants to continue editing.
149 	 */
150 	protected boolean userSaysRevert() {
151 		Toolkit.getDefaultToolkit().beep();
152 		ftf.selectAll();
153 		Object[] options = { "Edit", "Revert" };
154 		int answer = JOptionPane.showOptionDialog(SwingUtilities
155 				.getWindowAncestor(ftf),
156 				"The value must be an integer between " + minimum + " and "
157 						+ maximum + ".\n" + "You can either continue editing "
158 						+ "or revert to the last valid value.",
159 				"Invalid Text Entered", JOptionPane.YES_NO_OPTION,
160 				JOptionPane.ERROR_MESSAGE, null, options, options[1]);
161 
162 		if (answer == 1) { // Revert!
163 			ftf.setValue(ftf.getValue());
164 			return true;
165 		}
166 		return false;
167 	}
168 }