1 | public class DataTypeDouble extends FloatingPointBase↵ | | 1 | public class DataTypeFloat extends FloatingPointBase↵
|
2 | implements IDataTypeComponent↵ | | 2 | implements IDataTypeComponent↵
|
3 | {↵ | | 3 | {↵
|
|
4 | /** Logger for this class. */↵ | | 4 | /** Logger for this class. */↵
|
5 | private static ILogger s_log = LoggerController.createLogger(DataTypeBigDecimal.class);↵ | | 5 | private static ILogger s_log = LoggerController.createLogger(DataTypeFloat.class);↵
|
|
|
6 | /* the whole column definition */↵ | | 6 | /* the whole column definition */↵
|
7 | private ColumnDisplayDefinition _colDef;↵ | | 7 | private ColumnDisplayDefinition _colDef;↵
|
|
8 | /* whether nulls are allowed or not */↵ | | 8 | /* whether nulls are allowed or not */↵
|
9 | private boolean _isNullable;↵ | | 9 | private boolean _isNullable;↵
|
|
10 | /* table of which we are part (needed for creating popup dialog) */↵ | | 10 | /* table of which we are part (needed for creating popup dialog) */↵
|
11 | private JTable _table;↵ | | 11 | private JTable _table;↵
|
|
12 | /* The JTextComponent that is being used for editing */↵ | | 12 | /* The JTextComponent that is being used for editing */↵
|
13 | private IRestorableTextComponent _textComponent;↵ | | 13 | private IRestorableTextComponent _textComponent;↵
|
|
14 | /* The CellRenderer used for this data type */↵ | | 14 | /* The CellRenderer used for this data type */↵
|
15 | //??? For now, use the same renderer as everyone else.↵ | | 15 | //??? For now, use the same renderer as everyone else.↵
|
16 | //??↵ | | 16 | //??↵
|
17 | //?? IN FUTURE: change this to use a new instance of renederer↵ | | 17 | //?? IN FUTURE: change this to use a new instance of renederer↵
|
18 | //?? for this data type.↵ | | 18 | //?? for this data type.↵
|
19 | private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance();↵ | | 19 | private DefaultColumnRenderer _renderer = DefaultColumnRenderer.getInstance();↵
|
|
20 | // The NumberFormat object to use for all locale-dependent formatting.↵ | | 20 | // The NumberFormat object to use for all locale-dependent formatting.↵
|
21 | private NumberFormat _numberFormat;↵ | | 21 | private NumberFormat _numberFormat;↵
|
22 | private boolean _renderExceptionHasBeenLogged;↵ | | 22 | private boolean _renderExceptionHasBeenLogged;↵
|
|
|
23 | /**↵ | | 23 | /**↵
|
24 | * Constructor - save the data needed by this data type.↵ | | 24 | * Constructor - save the data needed by this data type.↵
|
25 | */↵ | | 25 | */↵
|
26 | public DataTypeDouble(JTable table, ColumnDisplayDefinition colDef) {↵ | | 26 | public DataTypeFloat(JTable table, ColumnDisplayDefinition colDef) {↵
|
27 | _table = table;↵ | | 27 | _table = table;↵
|
28 | _colDef = colDef;↵ | | 28 | _colDef = colDef;↵
|
29 | _isNullable = colDef.isNullable();↵ | | 29 | _isNullable = colDef.isNullable();↵
|
30 | _numberFormat = NumberFormat.getInstance();↵ | | 30 | _numberFormat = NumberFormat.getInstance();↵
|
|
|
31 | // This is a bit hard coded but if we use _scale here↵ | | 31 | // This is a bit hard coded but if we use _scale here↵
|
32 | // some number displays go crazy.↵ | | 32 | // some number displays go crazy.↵
|
33 | _numberFormat.setMaximumFractionDigits(5);↵ | | 33 | _numberFormat.setMaximumFractionDigits(5);↵
|
|
|
34 | _numberFormat.setMinimumFractionDigits(0);↵ | | 34 | _numberFormat.setMinimumFractionDigits(0);↵
|
|
|
35 | }↵ | | 35 | }↵
|
|
36 | /**↵ | | 36 | /**↵
|
37 | * Return the name of the java class used to hold this data type.↵ | | 37 | * Return the name of the java class used to hold this data type.↵
|
38 | */↵ | | 38 | */↵
|
39 | public String getClassName() {↵ | | 39 | public String getClassName() {↵
|
40 | return "java.lang.Double";↵ | | 40 | return "java.lang.Float";↵
|
41 | }↵ | | 41 | }↵
|
|
42 | /**↵ | | 42 | /**↵
|
43 | * Determine if two objects of this data type contain the same value.↵ | | 43 | * Determine if two objects of this data type contain the same value.↵
|
44 | * Neither of the objects is null↵ | | 44 | * Neither of the objects is null↵
|
45 | */↵ | | 45 | */↵
|
46 | public boolean areEqual(Object obj1, Object obj2) {↵ | | 46 | public boolean areEqual(Object obj1, Object obj2) {↵
|
47 | return obj1.equals(obj2);↵ | | 47 | return obj1.equals(obj2);↵
|
48 | }↵ | | 48 | }↵
|
|
49 | /*↵ | | 49 | /*↵
|
50 | * First we have the methods for in-cell and Text-table operations↵ | | 50 | * First we have the methods for in-cell and Text-table operations↵
|
51 | */↵ | | 51 | */↵
|
|
52 | /**↵ | | 52 | /**↵
|
53 | * Render a value into text for this DataType.↵ | | 53 | * Render a value into text for this DataType.↵
|
54 | */↵ | | 54 | */↵
|
55 | public String renderObject(Object value) {↵ | | 55 | public String renderObject(Object value) {↵
|
|
|
56 | //return (String)_renderer.renderObject(value);↵ | | 56 | //return (String)_renderer.renderObject(value);↵
|
|
57 | if (value == null || useJavaDefaultFormat)↵ | | 57 | if (value == null || useJavaDefaultFormat)↵
|
58 | {↵ | | 58 | {↵
|
59 | return (String)_renderer.renderObject(value);↵ | | 59 | return (String)_renderer.renderObject(value);↵
|
60 | }↵ | | 60 | }↵
|
61 | else↵ | | 61 | else↵
|
62 | {↵ | | 62 | {↵
|
|
63 | try↵ | | 63 | try↵
|
64 | {↵ | | 64 | {↵
|
65 | return (String)_renderer.renderObject(_numberFormat.format(value));↵ | | 65 | return (String)_renderer.renderObject(_numberFormat.format(value));↵
|
66 | }↵ | | 66 | }↵
|
67 | catch (Exception e)↵ | | 67 | catch (Exception e)↵
|
68 | {↵ | | 68 | {↵
|
69 | if(false == _renderExceptionHasBeenLogged)↵ | | 69 | if(false == _renderExceptionHasBeenLogged)↵
|
70 | {↵ | | 70 | {↵
|
71 | _renderExceptionHasBeenLogged = true;↵ | | 71 | _renderExceptionHasBeenLogged = true;↵
|
72 | s_log.error("Could not format \"" + value + "\" as number type", e);↵ | | 72 | s_log.error("Could not format \"" + value + "\" as number type", e);↵
|
73 | }↵ | | 73 | }↵
|
74 | return (String) _renderer.renderObject(value);↵ | | 74 | return (String) _renderer.renderObject(value);↵
|
75 | }↵ | | 75 | }↵
|
|
|
76 | }↵ | | 76 | }↵
|
|
77 | }↵ | | 77 | }↵
|
|
78 | /**↵ | | 78 | /**↵
|
79 | * This Data Type can be edited in a table cell.↵ | | 79 | * This Data Type can be edited in a table cell.↵
|
80 | */↵ | | 80 | */↵
|
81 | public boolean isEditableInCell(Object originalValue) {↵ | | 81 | public boolean isEditableInCell(Object originalValue) {↵
|
82 | return true;↵ | | 82 | return true;↵
|
83 | }↵ | | 83 | }↵
|
|
84 | /**↵ | | 84 | /**↵
|
85 | * See if a value in a column has been limited in some way and↵ | | 85 | * See if a value in a column has been limited in some way and↵
|
86 | * needs to be re-read before being used for editing.↵ | | 86 | * needs to be re-read before being used for editing.↵
|
87 | * For read-only tables this may actually return true since we want↵ | | 87 | * For read-only tables this may actually return true since we want↵
|
88 | * to be able to view the entire contents of the cell even if it was not↵ | | 88 | * to be able to view the entire contents of the cell even if it was not↵
|
89 | * completely loaded during the initial table setup.↵ | | 89 | * completely loaded during the initial table setup.↵
|
90 | */↵ | | 90 | */↵
|
91 | public boolean needToReRead(Object originalValue) {↵ | | 91 | public boolean needToReRead(Object originalValue) {↵
|
92 | // this DataType does not limit the data read during the initial load of the table,↵ | | 92 | // this DataType does not limit the data read during the initial load of the table,↵
|
93 | // so there is no need to re-read the complete data later↵ | | 93 | // so there is no need to re-read the complete data later↵
|
94 | return false;↵ | | 94 | return false;↵
|
95 | }↵ | | 95 | }↵
|
|
96 | /**↵ | | 96 | /**↵
|
97 | * Return a JTextField usable in a CellEditor.↵ | | 97 | * Return a JTextField usable in a CellEditor.↵
|
98 | */↵ | | 98 | */↵
|
99 | public JTextField getJTextField() {↵ | | 99 | public JTextField getJTextField() {↵
|
100 | _textComponent = new RestorableJTextField();↵ | | 100 | _textComponent = new RestorableJTextField();↵
|
|
101 | // special handling of operations while editing this data type↵ | | 101 | // special handling of operations while editing this data type↵
|
102 | ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler());↵ | | 102 | ((RestorableJTextField)_textComponent).addKeyListener(new KeyTextHandler());↵
|
|
103 | //↵ | | 103 | //↵
|
104 | // handle mouse events for double-click creation of popup dialog.↵ | | 104 | // handle mouse events for double-click creation of popup dialog.↵
|
105 | // This happens only in the JTextField, not the JTextArea, so we can↵ | | 105 | // This happens only in the JTextField, not the JTextArea, so we can↵
|
106 | // make this an inner class within this method rather than a separate↵ | | 106 | // make this an inner class within this method rather than a separate↵
|
107 | // inner class as is done with the KeyTextHandler class.↵ | | 107 | // inner class as is done with the KeyTextHandler class.↵
|
108 | //↵ | | 108 | //↵
|
109 | ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter()↵ | | 109 | ((RestorableJTextField)_textComponent).addMouseListener(new MouseAdapter()↵
|
110 | {↵ | | 110 | {↵
|
111 | public void mousePressed(MouseEvent evt)↵ | | 111 | public void mousePressed(MouseEvent evt)↵
|
112 | {↵ | | 112 | {↵
|
113 | if (evt.getClickCount() == 2)↵ | | 113 | if (evt.getClickCount() == 2)↵
|
114 | {↵ | | 114 | {↵
|
115 | MouseEvent tableEvt = SwingUtilities.convertMouseEvent(↵ | | 115 | MouseEvent tableEvt = SwingUtilities.convertMouseEvent(↵
|
116 | (RestorableJTextField)DataTypeDouble.this._textComponent,↵ | | 116 | (RestorableJTextField)DataTypeFloat.this._textComponent,↵
|
117 | evt, DataTypeDouble.this._table);↵ | | 117 | evt, DataTypeFloat.this._table);↵
|
118 | CellDataPopup.showDialog(DataTypeDouble.this._table,↵ | | 118 | CellDataPopup.showDialog(DataTypeFloat.this._table,↵
|
119 | DataTypeDouble.this._colDef, tableEvt, true);↵ | | 119 | DataTypeFloat.this._colDef, tableEvt, true);↵
|
120 | }↵ | | 120 | }↵
|
121 | }↵ | | 121 | }↵
|
122 | }); // end of mouse listener↵ | | 122 | }); // end of mouse listener↵
|
|
123 | return (JTextField)_textComponent;↵ | | 123 | return (JTextField)_textComponent;↵
|
124 | }↵ | | 124 | }↵
|
|
125 | /**↵ | | 125 | /**↵
|
126 | * Implement the interface for validating and converting to internal object.↵ | | 126 | * Implement the interface for validating and converting to internal object.↵
|
127 | * Null is a valid successful return, so errors are indicated only by↵ | | 127 | * Null is a valid successful return, so errors are indicated only by↵
|
128 | * existance or not of a message in the messageBuffer.↵ | | 128 | * existance or not of a message in the messageBuffer.↵
|
129 | */↵ | | 129 | */↵
|
130 | public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {↵ | | 130 | public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {↵
|
131 | // handle null, which is shown as the special string "<null>"↵ | | 131 | // handle null, which is shown as the special string "<null>"↵
|
132 | if (value.equals("<null>") || value.equals(""))↵ | | 132 | if (value.equals("<null>") || value.equals(""))↵
|
133 | return null;↵ | | 133 | return null;↵
|
|
134 | // Do the conversion into the object in a safe manner↵ | | 134 | // Do the conversion into the object in a safe manner↵
|
135 | try↵ | | 135 | try↵
|
136 | {↵ | | 136 | {↵
|
137 | Double obj;↵ | | 137 | Float obj;↵
|
|
138 | if(useJavaDefaultFormat)↵ | | 138 | if(useJavaDefaultFormat)↵
|
139 | {↵ | | 139 | {↵
|
140 | obj = new Double(value);↵ | | 140 | obj = new Float(value);↵
|
141 | }↵ | | 141 | }↵
|
142 | else↵ | | 142 | else↵
|
143 | {↵ | | 143 | {↵
|
144 | obj = new Double("" + _numberFormat.parse(value));↵ | | 144 | obj = new Float("" + _numberFormat.parse(value));↵
|
145 | }↵ | | 145 | }↵
|
|
146 | return obj;↵ | | 146 | return obj;↵
|
147 | }↵ | | 147 | }↵
|
148 | catch (Exception e)↵ | | 148 | catch (Exception e)↵
|
149 | {↵ | | 149 | {↵
|
150 | messageBuffer.append(e.toString() + "\n");↵ | | 150 | messageBuffer.append(e.toString() + "\n");↵
|
151 | //?? do we need the message also, or is it automatically part of the toString()?↵ | | 151 | //?? do we need the message also, or is it automatically part of the toString()?↵
|
152 | //messageBuffer.append(e.getMessage());↵ | | 152 | //messageBuffer.append(e.getMessage());↵
|
153 | return null;↵ | | 153 | return null;↵
|
154 | }↵ | | 154 | }↵
|
155 | }↵ | | 155 | }↵
|
|
156 | /**↵ | | 156 | /**↵
|
157 | * If true, this tells the PopupEditableIOPanel to use the↵ | | 157 | * If true, this tells the PopupEditableIOPanel to use the↵
|
158 | * binary editing panel rather than a pure text panel.↵ | | 158 | * binary editing panel rather than a pure text panel.↵
|
159 | * The binary editing panel assumes the data is an array of bytes,↵ | | 159 | * The binary editing panel assumes the data is an array of bytes,↵
|
160 | * converts it into text form, allows the user to change how that↵ | | 160 | * converts it into text form, allows the user to change how that↵
|
161 | * data is displayed (e.g. Hex, Decimal, etc.), and converts↵ | | 161 | * data is displayed (e.g. Hex, Decimal, etc.), and converts↵
|
162 | * the data back from text to bytes when the user editing is completed.↵ | | 162 | * the data back from text to bytes when the user editing is completed.↵
|
163 | * If this returns false, this DataType class must↵ | | 163 | * If this returns false, this DataType class must↵
|
164 | * convert the internal data into a text string that↵ | | 164 | * convert the internal data into a text string that↵
|
165 | * can be displayed (and edited, if allowed) in a TextField↵ | | 165 | * can be displayed (and edited, if allowed) in a TextField↵
|
166 | * or TextArea, and must handle all↵ | | 166 | * or TextArea, and must handle all↵
|
167 | * user key strokes related to editing of that data.↵ | | 167 | * user key strokes related to editing of that data.↵
|
168 | */↵ | | 168 | */↵
|
169 | public boolean useBinaryEditingPanel() {↵ | | 169 | public boolean useBinaryEditingPanel() {↵
|
170 | return false;↵ | | 170 | return false;↵
|
171 | }↵ | | 171 | }↵
|
|
|
172 | /*↵ | | 172 | /*↵
|
173 | * Now the functions for the Popup-related operations.↵ | | 173 | * Now the functions for the Popup-related operations.↵
|
174 | */↵ | | 174 | */↵
|
|
175 | /**↵ | | 175 | /**↵
|
176 | * Returns true if data type may be edited in the popup,↵ | | 176 | * Returns true if data type may be edited in the popup,↵
|
177 | * false if not.↵ | | 177 | * false if not.↵
|
178 | */↵ | | 178 | */↵
|
179 | public boolean isEditableInPopup(Object originalValue) {↵ | | 179 | public boolean isEditableInPopup(Object originalValue) {↵
|
180 | return true;↵ | | 180 | return true;↵
|
181 | }↵ | | 181 | }↵
|
|
182 | /*↵ | | 182 | /*↵
|
183 | * Return a JTextArea usable in the CellPopupDialog↵ | | 183 | * Return a JTextArea usable in the CellPopupDialog↵
|
184 | * and fill in the value.↵ | | 184 | * and fill in the value.↵
|
185 | */↵ | | 185 | */↵
|
186 | public JTextArea getJTextArea(Object value) {↵ | | 186 | public JTextArea getJTextArea(Object value) {↵
|
187 | _textComponent = new RestorableJTextArea();↵ | | 187 | _textComponent = new RestorableJTextArea();↵
|
|
188 | // value is a simple string representation of the data,↵ | | 188 | // value is a simple string representation of the data,↵
|
189 | // the same one used in Text and in-cell operations.↵ | | 189 | // the same one used in Text and in-cell operations.↵
|
190 | ((RestorableJTextArea)_textComponent).setText(renderObject(value));↵ | | 190 | ((RestorableJTextArea)_textComponent).setText(renderObject(value));↵
|
|
191 | // special handling of operations while editing this data type↵ | | 191 | // special handling of operations while editing this data type↵
|
192 | ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler());↵ | | 192 | ((RestorableJTextArea)_textComponent).addKeyListener(new KeyTextHandler());↵
|
|
193 | return (RestorableJTextArea)_textComponent;↵ | | 193 | return (RestorableJTextArea)_textComponent;↵
|
194 | }↵ | | 194 | }↵
|
|
195 | /**↵ | | 195 | /**↵
|
196 | * Validating and converting in Popup is identical to cell-related operation.↵ | | 196 | * Validating and converting in Popup is identical to cell-related operation.↵
|
197 | */↵ | | 197 | */↵
|
198 | public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) {↵ | | 198 | public Object validateAndConvertInPopup(String value, Object originalValue, StringBuffer messageBuffer) {↵
|
199 | return validateAndConvert(value, originalValue, messageBuffer);↵ | | 199 | return validateAndConvert(value, originalValue, messageBuffer);↵
|
200 | }↵ | | 200 | }↵
|
|
201 | /*↵ | | 201 | /*↵
|
202 | * The following is used in both cell and popup operations.↵ | | 202 | * The following is used in both cell and popup operations.↵
|
203 | */↵ | | 203 | */↵
|
|
204 | /*↵ | | 204 | /*↵
|
205 | * Internal class for handling key events during editing↵ | | 205 | * Internal class for handling key events during editing↵
|
206 | * of both JTextField and JTextArea.↵ | | 206 | * of both JTextField and JTextArea.↵
|
207 | */↵ | | 207 | */↵
|
208 | private class KeyTextHandler extends BaseKeyTextHandler {↵ | | 208 | private class KeyTextHandler extends BaseKeyTextHandler {↵
|
209 | public void keyTyped(KeyEvent e) {↵ | | 209 | public void keyTyped(KeyEvent e) {↵
|
210 | char c = e.getKeyChar();↵ | | 210 | char c = e.getKeyChar();↵
|
|
211 | // as a coding convenience, create a reference to the text component↵ | | 211 | // as a coding convenience, create a reference to the text component↵
|
212 | // that is typecast to JTextComponent. this is not essential, as we↵ | | 212 | // that is typecast to JTextComponent. this is not essential, as we↵
|
213 | // could typecast every reference, but this makes the code cleaner↵ | | 213 | // could typecast every reference, but this makes the code cleaner↵
|
214 | JTextComponent _theComponent = (JTextComponent)DataTypeDouble.this._textComponent;↵ | | 214 | JTextComponent _theComponent = (JTextComponent)DataTypeFloat.this._textComponent;↵
|
215 | String text = _theComponent.getText();↵ | | 215 | String text = _theComponent.getText();↵
|
|
216 | // tabs and newlines get put into the text before this check,↵ | | 216 | // tabs and newlines get put into the text before this check,↵
|
217 | // so remove them↵ | | 217 | // so remove them↵
|
218 | // This only applies to Popup editing since these chars are↵ | | 218 | // This only applies to Popup editing since these chars are↵
|
219 | // not passed to this level by the in-cell editor.↵ | | 219 | // not passed to this level by the in-cell editor.↵
|
220 | if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) {↵ | | 220 | if (c == KeyEvent.VK_TAB || c == KeyEvent.VK_ENTER) {↵
|
221 | // remove all instances of the offending char↵ | | 221 | // remove all instances of the offending char↵
|
222 | int index = text.indexOf(c);↵ | | 222 | int index = text.indexOf(c);↵
|
223 | if (index != -1) {↵ | | 223 | if (index != -1) {↵
|
224 | if (index == text.length() -1) {↵ | | 224 | if (index == text.length() -1) {↵
|
225 | text = text.substring(0, text.length()-1); // truncate string↵ | | 225 | text = text.substring(0, text.length()-1); // truncate string↵
|
226 | }↵ | | 226 | }↵
|
227 | else {↵ | | 227 | else {↵
|
228 | text = text.substring(0, index) + text.substring(index+1);↵ | | 228 | text = text.substring(0, index) + text.substring(index+1);↵
|
229 | }↵ | | 229 | }↵
|
230 | ((IRestorableTextComponent)_theComponent).updateText( text);↵ | | 230 | ((IRestorableTextComponent)_theComponent).updateText( text);↵
|
231 | _beepHelper.beep(_theComponent);↵ | | 231 | _beepHelper.beep(_theComponent);↵
|
232 | }↵ | | 232 | }↵
|
233 | e.consume();↵ | | 233 | e.consume();↵
|
234 | }↵ | | 234 | }↵
|
|
|
235 | if ( ! ( Character.isDigit(c) ||↵ | | 235 | if ( ! ( Character.isDigit(c) ||↵
|
236 | (c == '-') || (c == '+') ||↵ | | 236 | (c == '-') || (c == '+') ||↵
|
237 | (c == 'e') || (c == 'E') ||↵ | | 237 | (c == 'e') || (c == 'E') ||↵
|
238 | (c == 'f') || (c == 'F') ||↵ | | 238 | (c == 'f') || (c == 'F') ||↵
|
239 | (c == 'd') || (c == 'D') ||↵ | | |
|
240 | (c == '.') || (c == ',') || // several number formats use '.' as decimal separator, others use ','↵ | | 239 | (c == '.') || (c == ',') || // several number formats use '.' as decimal separator, others use ','↵
|
241 | (c == KeyEvent.VK_BACK_SPACE) ||↵ | | 240 | (c == KeyEvent.VK_BACK_SPACE) ||↵
|
242 | (c == KeyEvent.VK_DELETE) ) ) {↵ | | 241 | (c == KeyEvent.VK_DELETE) ) ) {↵
|
243 | _beepHelper.beep(_theComponent);↵ | | 242 | _beepHelper.beep(_theComponent);↵
|
244 | e.consume();↵ | | 243 | e.consume();↵
|
245 | }↵ | | 244 | }↵
|
|
246 | // handle cases of null↵ | | 245 | // handle cases of null↵
|
247 | // The processing is different when nulls are allowed and when they are not.↵ | | 246 | // The processing is different when nulls are allowed and when they are not.↵
|
248 | //↵ | | 247 | //↵
|
|
249 | if ( DataTypeDouble.this._isNullable) {↵ | | 248 | if ( DataTypeFloat.this._isNullable) {↵
|
|
250 | // user enters something when field is null↵ | | 249 | // user enters something when field is null↵
|
251 | if (text.equals("<null>")) {↵ | | 250 | if (text.equals("<null>")) {↵
|
252 | if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {↵ | | 251 | if ((c==KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {↵
|
253 | // delete when null => original value↵ | | 252 | // delete when null => original value↵
|
254 | DataTypeDouble.this._textComponent.restoreText();↵ | | 253 | DataTypeFloat.this._textComponent.restoreText();↵
|
255 | e.consume();↵ | | 254 | e.consume();↵
|
256 | }↵ | | 255 | }↵
|
257 | else {↵ | | 256 | else {↵
|
258 | // non-delete when null => clear field and add text↵ | | 257 | // non-delete when null => clear field and add text↵
|
259 | DataTypeDouble.this._textComponent.updateText("");↵ | | 258 | DataTypeFloat.this._textComponent.updateText("");↵
|
260 | // fall through to normal processing of this key stroke↵ | | 259 | // fall through to normal processing of this key stroke↵
|
261 | }↵ | | 260 | }↵
|
262 | }↵ | | 261 | }↵
|
263 | else {↵ | | 262 | else {↵
|
264 | // check for user deletes last thing in field↵ | | 263 | // check for user deletes last thing in field↵
|
265 | if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {↵ | | 264 | if ((c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)) {↵
|
266 | if (text.length() <= 1 ) {↵ | | 265 | if (text.length() <= 1 ) {↵
|
267 | // about to delete last thing in field, so replace with null↵ | | 266 | // about to delete last thing in field, so replace with null↵
|
268 | DataTypeDouble.this._textComponent.updateText("<null>");↵ | | 267 | DataTypeFloat.this._textComponent.updateText("<null>");↵
|
269 | e.consume();↵ | | 268 | e.consume();↵
|
270 | }↵ | | 269 | }↵
|
271 | }↵ | | 270 | }↵
|
272 | }↵ | | 271 | }↵
|
273 | }↵ | | 272 | }↵
|
274 | else {↵ | | 273 | else {↵
|
275 | // field is not nullable↵ | | 274 | // field is not nullable↵
|
276 | //↵ | | 275 | //↵
|
277 | handleNotNullableField(text, c, e, _textComponent);↵ | | 276 | handleNotNullableField(text, c, e, _textComponent);↵
|
278 | }↵ | | 277 | }↵
|
279 | }↵ | | 278 | }↵
|
280 | }↵ | | 279 | }↵
|
|
|
|
|
281 | /*↵ | | 280 | /*↵
|
282 | * DataBase-related functions↵ | | 281 | * DataBase-related functions↵
|
283 | */↵ | | 282 | */↵
|
|
284 | /**↵ | | 283 | /**↵
|
285 | * On input from the DB, read the data from the ResultSet into the appropriate↵ | | 284 | * On input from the DB, read the data from the ResultSet into the appropriate↵
|
286 | * type of object to be stored in the table cell.↵ | | 285 | * type of object to be stored in the table cell.↵
|
287 | */↵ | | 286 | */↵
|
288 | public Object readResultSet(ResultSet rs, int index, boolean limitDataRead)↵ | | 287 | public Object readResultSet(ResultSet rs, int index, boolean limitDataRead)↵
|
289 | throws java.sql.SQLException {↵ | | 288 | throws java.sql.SQLException {↵
|
|
290 | double data = rs.getDouble(index);↵ | | 289 | float data = rs.getFloat(index);↵
|
291 | if (rs.wasNull())↵ | | 290 | if (rs.wasNull())↵
|
292 | return null;↵ | | 291 | return null;↵
|
293 | else return new Double(data);↵ | | 292 | else return new Float(data);↵
|
294 | }↵ | | 293 | }↵
|
|
295 | /**↵ | | 294 | /**↵
|
296 | * When updating the database, generate a string form of this object value↵ | | 295 | * When updating the database, generate a string form of this object value↵
|
297 | * that can be used in the WHERE clause to match the value in the database.↵ | | 296 | * that can be used in the WHERE clause to match the value in the database.↵
|
298 | * A return value of null means that this column cannot be used in the WHERE↵ | | 297 | * A return value of null means that this column cannot be used in the WHERE↵
|
299 | * clause, while a return of "null" (or "is null", etc) means that the column↵ | | 298 | * clause, while a return of "null" (or "is null", etc) means that the column↵
|
300 | * can be used in the WHERE clause and the value is actually a null value.↵ | | 299 | * can be used in the WHERE clause and the value is actually a null value.↵
|
301 | * This function must also include the column label so that its output↵ | | 300 | * This function must also include the column label so that its output↵
|
302 | * is of the form:↵ | | 301 | * is of the form:↵
|
303 | * "columnName = value"↵ | | 302 | * "columnName = value"↵
|
304 | * or↵ | | 303 | * or↵
|
305 | * "columnName is null"↵ | | 304 | * "columnName is null"↵
|
306 | * or whatever is appropriate for this column in the database.↵ | | 305 | * or whatever is appropriate for this column in the database.↵
|
307 | */↵ | | 306 | */↵
|
308 | public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) {↵ | | 307 | public String getWhereClauseValue(Object value, ISQLDatabaseMetaData md) {↵
|
309 | if (value == null || value.toString() == null || value.toString().length() == 0)↵ | | 308 | if (value == null || value.toString() == null || value.toString().length() == 0)↵
|
310 | return _colDef.getLabel() + " IS NULL";↵ | | 309 | return _colDef.getLabel() + " IS NULL";↵
|
311 | else↵ | | 310 | else↵
|
312 | // since we cannot do exact matches on floating point↵ | | 311 | // since we cannot do exact matches on floating point↵
|
313 | // numbers, we cannot use this field in the WHERE clause.↵ | | 312 | // numbers, we cannot use this field in the WHERE clause.↵
|
314 | return null;↵ | | 313 | return "";↵
|
315 | // return _colDef.getLabel() + "=" + value.toString();↵ | | 314 | // return _colDef.getLabel() + "=" + value.toString();↵
|
316 | }↵ | | 315 | }↵
|
|
|
317 | /**↵ | | 316 | /**↵
|
318 | * When updating the database, insert the appropriate datatype into the↵ | | 317 | * When updating the database, insert the appropriate datatype into the↵
|
319 | * prepared statment at the given variable position.↵ | | 318 | * prepared statment at the given variable position.↵
|
320 | */↵ | | 319 | */↵
|
321 | public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)↵ | | 320 | public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)↵
|
322 | throws java.sql.SQLException {↵ | | 321 | throws java.sql.SQLException {↵
|
323 | if (value == null) {↵ | | 322 | if (value == null) {↵
|
324 | pstmt.setNull(position, _colDef.getSqlType());↵ | | 323 | pstmt.setNull(position, _colDef.getSqlType());↵
|
325 | }↵ | | 324 | }↵
|
326 | else {↵ | | 325 | else {↵
|
327 | pstmt.setDouble(position, ((Double)value).floatValue());↵ | | 326 | pstmt.setFloat(position, ((Float)value).floatValue());↵
|
328 | }↵ | | 327 | }↵
|
329 | }↵ | | 328 | }↵
|
|
330 | /**↵ | | 329 | /**↵
|
331 | * Get a default value for the table used to input data for a new row↵ | | 330 | * Get a default value for the table used to input data for a new row↵
|
332 | * to be inserted into the DB.↵ | | 331 | * to be inserted into the DB.↵
|
333 | */↵ | | 332 | */↵
|
334 | public Object getDefaultValue(String dbDefaultValue) {↵ | | 333 | public Object getDefaultValue(String dbDefaultValue) {↵
|
335 | if (dbDefaultValue != null) {↵ | | 334 | if (dbDefaultValue != null) {↵
|
336 | // try to use the DB default value↵ | | 335 | // try to use the DB default value↵
|
337 | StringBuffer mbuf = new StringBuffer();↵ | | 336 | StringBuffer mbuf = new StringBuffer();↵
|
338 | Object newObject = validateAndConvert(dbDefaultValue, null, mbuf);↵ | | 337 | Object newObject = validateAndConvert(dbDefaultValue, null, mbuf);↵
|
|
339 | // if there was a problem with converting, then just fall through↵ | | 338 | // if there was a problem with converting, then just fall through↵
|
340 | // and continue as if there was no default given in the DB.↵ | | 339 | // and continue as if there was no default given in the DB.↵
|
341 | // Otherwise, use the converted object↵ | | 340 | // Otherwise, use the converted object↵
|
342 | if (mbuf.length() == 0)↵ | | 341 | if (mbuf.length() == 0)↵
|
343 | return newObject;↵ | | 342 | return newObject;↵
|
344 | }↵ | | 343 | }↵
|
|
345 | // no default in DB. If nullable, use null.↵ | | 344 | // no default in DB. If nullable, use null.↵
|
346 | if (_isNullable)↵ | | 345 | if (_isNullable)↵
|
347 | return null;↵ | | 346 | return null;↵
|
|
348 | // field is not nullable, so create a reasonable default value↵ | | 347 | // field is not nullable, so create a reasonable default value↵
|
349 | return new Double(0);↵ | | 348 | return new Float(0);↵
|
350 | }↵ | | 349 | }↵
|
|
|
351 | /*↵ | | 350 | /*↵
|
352 | * File IO related functions↵ | | 351 | * File IO related functions↵
|
353 | */↵ | | 352 | */↵
|
|
|
354 | /**↵ | | 353 | /**↵
|
355 | * Say whether or not object can be exported to and imported from↵ | | 354 | * Say whether or not object can be exported to and imported from↵
|
356 | * a file. We put both export and import together in one test↵ | | 355 | * a file. We put both export and import together in one test↵
|
357 | * on the assumption that all conversions can be done both ways.↵ | | 356 | * on the assumption that all conversions can be done both ways.↵
|
358 | */↵ | | 357 | */↵
|
359 | public boolean canDoFileIO() {↵ | | 358 | public boolean canDoFileIO() {↵
|
360 | return true;↵ | | 359 | return true;↵
|
361 | }↵ | | 360 | }↵
|
|
362 | /**↵ | | 361 | /**↵
|
363 | * Read a file and construct a valid object from its contents.↵ | | 362 | * Read a file and construct a valid object from its contents.↵
|
364 | * Errors are returned by throwing an IOException containing the↵ | | 363 | * Errors are returned by throwing an IOException containing the↵
|
365 | * cause of the problem as its message.↵ | | 364 | * cause of the problem as its message.↵
|
366 | * <P>↵ | | 365 | * <P>↵
|
367 | * DataType is responsible for validating that the imported↵ | | 366 | * DataType is responsible for validating that the imported↵
|
368 | * data can be converted to an object, and then must return↵ | | 367 | * data can be converted to an object, and then must return↵
|
369 | * a text string that can be used in the Popup window text area.↵ | | 368 | * a text string that can be used in the Popup window text area.↵
|
370 | * This object-to-text conversion is the same as is done by↵ | | 369 | * This object-to-text conversion is the same as is done by↵
|
371 | * the DataType object internally in the getJTextArea() method.↵ | | 370 | * the DataType object internally in the getJTextArea() method.↵
|
372 | *↵ | | 371 | *↵
|
373 | * <P>↵ | | 372 | * <P>↵
|
374 | * File is assumed to be and ASCII string of digits↵ | | 373 | * File is assumed to be and ASCII string of digits↵
|
375 | * representing a value of this data type.↵ | | 374 | * representing a value of this data type.↵
|
376 | */↵ | | 375 | */↵
|
377 | public String importObject(FileInputStream inStream)↵ | | 376 | public String importObject(FileInputStream inStream)↵
|
378 | throws IOException {↵ | | 377 | throws IOException {↵
|
|
379 | InputStreamReader inReader = new InputStreamReader(inStream);↵ | | 378 | InputStreamReader inReader = new InputStreamReader(inStream);↵
|
|
380 | int fileSize = inStream.available();↵ | | 379 | int fileSize = inStream.available();↵
|
|
381 | char charBuf[] = new char[fileSize];↵ | | 380 | char charBuf[] = new char[fileSize];↵
|
|
382 | int count = inReader.read(charBuf, 0, fileSize);↵ | | 381 | int count = inReader.read(charBuf, 0, fileSize);↵
|
|
383 | if (count != fileSize)↵ | | 382 | if (count != fileSize)↵
|
384 | throw new IOException(↵ | | 383 | throw new IOException(↵
|
385 | "Could read only "+ count +↵ | | 384 | "Could read only "+ count +↵
|
386 | " chars from a total file size of " + fileSize +↵ | | 385 | " chars from a total file size of " + fileSize +↵
|
387 | ". Import failed.");↵ | | 386 | ". Import failed.");↵
|
|
388 | // convert file text into a string↵ | | 387 | // convert file text into a string↵
|
389 | // Special case: some systems tack a newline at the end of↵ | | 388 | // Special case: some systems tack a newline at the end of↵
|
390 | // the text read. Assume that if last char is a newline that↵ | | 389 | // the text read. Assume that if last char is a newline that↵
|
391 | // we want everything else in the line.↵ | | 390 | // we want everything else in the line.↵
|
392 | String fileText;↵ | | 391 | String fileText;↵
|
393 | if (charBuf[count-1] == KeyEvent.VK_ENTER)↵ | | 392 | if (charBuf[count-1] == KeyEvent.VK_ENTER)↵
|
394 | fileText = new String(charBuf, 0, count-1);↵ | | 393 | fileText = new String(charBuf, 0, count-1);↵
|
395 | else fileText = new String(charBuf);↵ | | 394 | else fileText = new String(charBuf);↵
|
|
396 | // test that the string is valid by converting it into an↵ | | 395 | // test that the string is valid by converting it into an↵
|
397 | // object of this data type↵ | | 396 | // object of this data type↵
|
398 | StringBuffer messageBuffer = new StringBuffer();↵ | | 397 | StringBuffer messageBuffer = new StringBuffer();↵
|
399 | validateAndConvertInPopup(fileText, null, messageBuffer);↵ | | 398 | validateAndConvertInPopup(fileText, null, messageBuffer);↵
|
400 | if (messageBuffer.length() > 0) {↵ | | 399 | if (messageBuffer.length() > 0) {↵
|
401 | // convert number conversion issue into IO issue for consistancy↵ | | 400 | // convert number conversion issue into IO issue for consistancy↵
|
402 | throw new IOException(↵ | | 401 | throw new IOException(↵
|
403 | "Text does not represent data of type "+getClassName()+↵ | | 402 | "Text does not represent data of type "+getClassName()+↵
|
404 | ". Text was:\n"+fileText);↵ | | 403 | ". Text was:\n"+fileText);↵
|
405 | }↵ | | 404 | }↵
|
|
406 | // return the text from the file since it does↵ | | 405 | // return the text from the file since it does↵
|
407 | // represent a valid data value↵ | | 406 | // represent a valid data value↵
|
408 | return fileText;↵ | | 407 | return fileText;↵
|
409 | }↵ | | 408 | }↵
|
|
|
410 | /**↵ | | 409 | /**↵
|
411 | * Construct an appropriate external representation of the object↵ | | 410 | * Construct an appropriate external representation of the object↵
|
412 | * and write it to a file.↵ | | 411 | * and write it to a file.↵
|
413 | * Errors are returned by throwing an IOException containing the↵ | | 412 | * Errors are returned by throwing an IOException containing the↵
|
414 | * cause of the problem as its message.↵ | | 413 | * cause of the problem as its message.↵
|
415 | * <P>↵ | | 414 | * <P>↵
|
416 | * DataType is responsible for validating that the given text↵ | | 415 | * DataType is responsible for validating that the given text↵
|
417 | * text from a Popup JTextArea can be converted to an object.↵ | | 416 | * text from a Popup JTextArea can be converted to an object.↵
|
418 | * This text-to-object conversion is the same as validateAndConvertInPopup,↵ | | 417 | * This text-to-object conversion is the same as validateAndConvertInPopup,↵
|
419 | * which may be used internally by the object to do the validation.↵ | | 418 | * which may be used internally by the object to do the validation.↵
|
420 | * <P>↵ | | 419 | * <P>↵
|
421 | * The DataType object must flush and close the output stream before returning.↵ | | 420 | * The DataType object must flush and close the output stream before returning.↵
|
422 | * Typically it will create another object (e.g. an OutputWriter), and↵ | | 421 | * Typically it will create another object (e.g. an OutputWriter), and↵
|
423 | * that is the object that must be flushed and closed.↵ | | 422 | * that is the object that must be flushed and closed.↵
|
424 | *↵ | | 423 | *↵
|
425 | * <P>↵ | | 424 | * <P>↵
|
426 | * File is assumed to be and ASCII string of digits↵ | | 425 | * File is assumed to be and ASCII string of digits↵
|
427 | * representing a value of this data type.↵ | | 426 | * representing a value of this data type.↵
|
428 | */↵ | | 427 | */↵
|
429 | public void exportObject(FileOutputStream outStream, String text)↵ | | 428 | public void exportObject(FileOutputStream outStream, String text)↵
|
430 | throws IOException {↵ | | 429 | throws IOException {↵
|
|
431 | OutputStreamWriter outWriter = new OutputStreamWriter(outStream);↵ | | 430 | OutputStreamWriter outWriter = new OutputStreamWriter(outStream);↵
|
|
432 | // check that the text is a valid representation↵ | | 431 | // check that the text is a valid representation↵
|
433 | StringBuffer messageBuffer = new StringBuffer();↵ | | 432 | StringBuffer messageBuffer = new StringBuffer();↵
|
434 | validateAndConvertInPopup(text, null, messageBuffer);↵ | | 433 | validateAndConvertInPopup(text, null, messageBuffer);↵
|
435 | if (messageBuffer.length() > 0) {↵ | | 434 | if (messageBuffer.length() > 0) {↵
|
436 | // there was an error in the conversion↵ | | 435 | // there was an error in the conversion↵
|
437 | throw new IOException(new String(messageBuffer));↵ | | 436 | throw new IOException(new String(messageBuffer));↵
|
438 | }↵ | | 437 | }↵
|
|
439 | // just send the text to the output file↵ | | 438 | // just send the text to the output file↵
|
440 | outWriter.write(text);↵ | | 439 | outWriter.write(text);↵
|
441 | outWriter.flush();↵ | | 440 | outWriter.flush();↵
|
442 | outWriter.close() | | 441 | outWriter.close()
|