1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package unbbayes.gui.table;
22
23 import java.awt.Component;
24 import java.awt.Toolkit;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.KeyEvent;
27 import java.text.NumberFormat;
28 import java.text.ParseException;
29
30 import javax.swing.AbstractAction;
31 import javax.swing.DefaultCellEditor;
32 import javax.swing.JFormattedTextField;
33 import javax.swing.JOptionPane;
34 import javax.swing.JTable;
35 import javax.swing.JTextField;
36 import javax.swing.KeyStroke;
37 import javax.swing.SwingUtilities;
38 import javax.swing.text.DefaultFormatterFactory;
39 import javax.swing.text.NumberFormatter;
40
41
42
43
44
45 public class NumberEditor extends DefaultCellEditor {
46
47 private static final long serialVersionUID = 1L;
48
49 JFormattedTextField ftf;
50
51 NumberFormat numberFormat;
52
53 public NumberEditor() {
54 super(new JFormattedTextField());
55 ftf = (JFormattedTextField) getComponent();
56
57
58 numberFormat = NumberFormat.getNumberInstance();
59 numberFormat.setMinimumFractionDigits(2);
60 numberFormat.setMaximumFractionDigits(2);
61 numberFormat.setMinimumIntegerDigits(1);
62 NumberFormatter numberFormatter = new NumberFormatter(numberFormat);
63 numberFormatter.setFormat(numberFormat);
64
65 ftf.setFormatterFactory(new DefaultFormatterFactory(numberFormatter));
66 ftf.setHorizontalAlignment(JTextField.TRAILING);
67 ftf.setFocusLostBehavior(JFormattedTextField.PERSIST);
68
69
70
71
72 ftf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
73 "check");
74 ftf.getActionMap().put("check", new AbstractAction() {
75 public void actionPerformed(ActionEvent e) {
76 if (!ftf.isEditValid()) {
77 if (userSaysRevert()) {
78 ftf.postActionEvent();
79 }
80 } else
81 try {
82 ftf.commitEdit();
83 ftf.postActionEvent();
84 } catch (java.text.ParseException exc) {
85 }
86 }
87 });
88 }
89
90
91 public Component getTableCellEditorComponent(JTable table,
92 Object value, boolean isSelected, int row, int column) {
93 JFormattedTextField ftf = (JFormattedTextField) super
94 .getTableCellEditorComponent(table, value, isSelected, row,
95 column);
96 ftf.setValue(value);
97 return ftf;
98 }
99
100
101 public Object getCellEditorValue() {
102 JFormattedTextField ftf = (JFormattedTextField) getComponent();
103 Object o = ftf.getValue();
104 if (o instanceof Float || o instanceof Double) {
105 return o;
106 } else if (o instanceof Number) {
107 return new Float(((Number) o).floatValue());
108 } else {
109 try {
110 return numberFormat.parseObject(o.toString());
111 } catch (ParseException exc) {
112 System.err.println("getCellEditorValue: can't parse o: "
113 + o);
114 return null;
115 }
116 }
117 }
118
119
120
121
122
123
124 public boolean stopCellEditing() {
125 JFormattedTextField ftf = (JFormattedTextField) getComponent();
126 if (ftf.isEditValid()) {
127 try {
128 ftf.commitEdit();
129 } catch (java.text.ParseException exc) {
130 }
131
132 } else {
133 if (!userSaysRevert()) {
134 return false;
135 }
136 }
137 return super.stopCellEditing();
138 }
139
140
141
142
143
144
145 protected boolean userSaysRevert() {
146 Toolkit.getDefaultToolkit().beep();
147 ftf.selectAll();
148 Object[] options = { "Edit", "Revert" };
149 int answer = JOptionPane.showOptionDialog(SwingUtilities
150 .getWindowAncestor(ftf),
151 "The value must be a number.\n"
152 + "You can either continue editing "
153 + "or revert to the last valid value.",
154 "Invalid Text Entered", JOptionPane.YES_NO_OPTION,
155 JOptionPane.ERROR_MESSAGE, null, options, options[1]);
156
157 if (answer == 1) {
158 ftf.setValue(ftf.getValue());
159 return true;
160 }
161 return false;
162 }
163 }