Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.swing / org.gvsig.expressionevaluator.swing.impl / src / main / java / org / gvsig / expressionevaluator / swing / impl / DefaultCalculatorController.java @ 44644

History | View | Annotate | Download (10.7 KB)

1 44076 jjdelcerro
package org.gvsig.expressionevaluator.swing.impl;
2
3 44080 jjdelcerro
import java.awt.Color;
4
import java.awt.event.ActionEvent;
5
import java.awt.event.ActionListener;
6
import java.awt.event.FocusEvent;
7
import java.awt.event.FocusListener;
8 44098 jjdelcerro
import java.awt.event.KeyAdapter;
9
import java.awt.event.KeyEvent;
10 44076 jjdelcerro
import org.gvsig.expressionevaluator.swing.CalculatorController;
11
import java.util.Objects;
12 44080 jjdelcerro
import javax.swing.AbstractAction;
13
import javax.swing.Action;
14
import javax.swing.JPopupMenu;
15 44098 jjdelcerro
import javax.swing.Timer;
16
import javax.swing.event.ChangeEvent;
17
import javax.swing.event.ChangeListener;
18
import javax.swing.event.DocumentEvent;
19
import javax.swing.event.DocumentListener;
20 44076 jjdelcerro
import javax.swing.text.JTextComponent;
21 44080 jjdelcerro
import org.apache.commons.lang3.StringUtils;
22
import org.gvsig.expressionevaluator.Expression;
23 44076 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
24
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
25 44098 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
26 44076 jjdelcerro
import org.gvsig.expressionevaluator.MutableSymbolTable;
27
import org.gvsig.expressionevaluator.SymbolTable;
28 44080 jjdelcerro
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
29 44076 jjdelcerro
import org.gvsig.tools.dataTypes.DataTypes;
30
import org.gvsig.tools.ToolsLocator;
31
import org.gvsig.tools.dataTypes.CoercionException;
32
import org.gvsig.tools.dataTypes.DataTypesManager;
33 44080 jjdelcerro
import org.gvsig.tools.i18n.I18nManager;
34 44098 jjdelcerro
import org.gvsig.tools.swing.api.ChangeListenerHelper;
35 44080 jjdelcerro
import org.gvsig.tools.swing.api.ToolsSwingLocator;
36
import org.gvsig.tools.swing.api.ToolsSwingManager;
37
import org.gvsig.tools.swing.api.windowmanager.Dialog;
38
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
39
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
40 44098 jjdelcerro
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42 44076 jjdelcerro
43
/**
44
 *
45
 * @author jjdelcerro
46
 */
47 44080 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
48 44098 jjdelcerro
class DefaultCalculatorController<T>
49
        implements CalculatorController<T> , ChangeListenerHelper
50
    {
51
52
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCalculatorController.class);
53 44076 jjdelcerro
54 44080 jjdelcerro
    private static final Color COLOR_ERROR = new Color(255,225,232);
55
56 44076 jjdelcerro
    private final JTextComponent text;
57
    private final int dataType;
58
    private final MutableSymbolTable defaultSymbolTable;
59 44098 jjdelcerro
    private final Color color_ok;
60
    private final ExpressionEvaluatorSwingManager swingManager;
61 44080 jjdelcerro
    private DefaultExpressionBuilderConfig config;
62
    private Expression expression;
63 44098 jjdelcerro
    private boolean warning;
64
    private final ChangeListenerHelper changeListenerHelper;
65
    private final Timer fireChangeTimer;
66
    private String lastText;
67
    private final ExpressionEvaluatorManager manager;
68 44076 jjdelcerro
69 44080 jjdelcerro
    public DefaultCalculatorController(ExpressionEvaluatorSwingManager manager, final JTextComponent text, int dataType) {
70 44098 jjdelcerro
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
71 44080 jjdelcerro
        I18nManager i18n = ToolsLocator.getI18nManager();
72
73 44098 jjdelcerro
        this.swingManager = manager;
74
        this.manager = ExpressionEvaluatorLocator.getManager();
75 44080 jjdelcerro
        this.config = null;
76
        this.expression = null;
77 44098 jjdelcerro
        this.warning = false;
78
        this.changeListenerHelper = toolsSwingManager.createChangeListenerHelper();
79
80 44076 jjdelcerro
        this.text = text;
81
        this.dataType = dataType;
82 44098 jjdelcerro
        this.color_ok = this.text.getBackground();
83 44076 jjdelcerro
        this.defaultSymbolTable = ExpressionEvaluatorLocator.getManager().createSymbolTable();
84 44098 jjdelcerro
        this.text.addKeyListener(new KeyAdapter() {
85
            @Override
86
            public void keyPressed(KeyEvent e) {
87
                   if( e.getKeyCode()==KeyEvent.VK_C && e.isControlDown() ) {
88
                       doCalculate(true);
89
                   }
90
            }
91
        });
92
        this.text.getDocument().addDocumentListener(new DocumentListener() {
93
            @Override
94
            public void insertUpdate(DocumentEvent e) {
95
                fireChangeEvent();
96
            }
97
98
            @Override
99
            public void removeUpdate(DocumentEvent e) {
100
                fireChangeEvent();
101
            }
102
103
            @Override
104
            public void changedUpdate(DocumentEvent e) {
105
                fireChangeEvent();
106
            }
107
        });
108 44080 jjdelcerro
        this.text.addFocusListener(new FocusListener() {
109
            @Override
110
            public void focusLost(FocusEvent e) {
111 44098 jjdelcerro
                doCalculate(true);
112 44080 jjdelcerro
            }
113
114
            @Override
115
            public void focusGained(FocusEvent e) {
116 44098 jjdelcerro
                doCalculate(true);
117 44080 jjdelcerro
            }
118
        });
119 44098 jjdelcerro
        toolsSwingManager.addClearButton(this.text, new ActionListener() {
120 44080 jjdelcerro
            @Override
121
            public void actionPerformed(ActionEvent e) {
122
                set(null);
123
            }
124
        });
125 44098 jjdelcerro
        toolsSwingManager.setDefaultPopupMenu(this.text);
126 44080 jjdelcerro
        JPopupMenu popupMenu = this.text.getComponentPopupMenu();
127
        Action showExpressionBuilderAction = new AbstractAction(i18n.getTranslation("_Show_expression_builder")) {
128
            @Override
129
            public void actionPerformed(ActionEvent e) {
130
                doShowExpressionBuilder();
131
            }
132
        };
133
        popupMenu.addSeparator();
134
        popupMenu.add(showExpressionBuilderAction);
135 44098 jjdelcerro
        this.fireChangeTimer = new Timer(100, new ActionListener() {
136
            @Override
137
            public void actionPerformed(ActionEvent e) {
138
                fireEvent();
139
            }
140
        });
141 44076 jjdelcerro
    }
142
143 44098 jjdelcerro
    private void fireChangeEvent() {
144
        this.fireChangeTimer.setRepeats(false);
145
        this.fireChangeTimer.restart();
146
    }
147
148 44080 jjdelcerro
    private void doShowExpressionBuilder() {
149
        if( this.config == null ) {
150 44098 jjdelcerro
            this.config = new DefaultExpressionBuilderConfig(this.swingManager);
151 44080 jjdelcerro
            this.config.addSymbolTable(this.defaultSymbolTable);
152
        }
153
        if( this.expression == null ) {
154
            this.expression = ExpressionEvaluatorLocator.getManager().createExpression();
155
        }
156
        expression.setPhrase(this.text.getText());
157
158 44098 jjdelcerro
        DefaultJExpressionBuilder panel = new DefaultJExpressionBuilder(this.swingManager, this.config);
159 44080 jjdelcerro
        panel.setExpression(this.expression);
160
161
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
162
        Dialog dialog = windowManager.createDialog(
163
                panel.asJComponent(),
164
                "Expression builder",
165
                null,
166
                WindowManager_v2.BUTTONS_OK_CANCEL
167
        );
168
        dialog.show(WindowManager.MODE.DIALOG);
169
        if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
170
            this.text.setText(panel.getExpression().getPhrase());
171
        }
172
    }
173
174 44076 jjdelcerro
    @Override
175
    public void addSymbolTable(SymbolTable symbolTable) {
176
        this.defaultSymbolTable.addSymbolTable(symbolTable);
177
    }
178
179
    @Override
180
    public MutableSymbolTable getSymbolTable() {
181
        return this.defaultSymbolTable;
182
    }
183
184 44098 jjdelcerro
    private Object doCalculate(boolean updateText) {
185 44148 jjdelcerro
        if( !this.text.isEditable() ||!this.text.isEnabled() ) {
186 44098 jjdelcerro
            return null;
187 44080 jjdelcerro
        }
188
        String source = this.text.getText();
189
        try {
190
            if( !StringUtils.isBlank(source) ) {
191 44098 jjdelcerro
                final Object value = this.manager.evaluate(this.defaultSymbolTable, source);
192
                if( updateText ) {
193
                    String s = Utils.repr(value);
194
                    if( !StringUtils.equals(s, this.lastText) ) {
195
                        this.setWarning(false);
196
                        this.lastText = s;
197
                        this.text.setText(this.lastText);
198
                    }
199
                }
200
                return value;
201 44080 jjdelcerro
            }
202 44098 jjdelcerro
            this.setWarning(false);
203
        } catch (ExpressionSyntaxException ex) {
204
            this.setWarning(true, ex.getDescription());
205 44080 jjdelcerro
        } catch (Exception ex) {
206 44098 jjdelcerro
            this.setWarning(true);
207
        }
208
        return null;
209
    }
210
211
    public void setWarning(boolean warning) {
212
        this.setWarning(warning, null);
213
    }
214
215
    public void setWarning(boolean warning, String description) {
216
        this.warning = warning;
217
        if( warning ) {
218 44080 jjdelcerro
            this.text.setBackground(COLOR_ERROR);
219 44098 jjdelcerro
            this.text.setToolTipText(description==null?"":description);
220
        } else {
221
            this.text.setBackground(this.color_ok);
222
            this.text.setToolTipText("");
223 44080 jjdelcerro
        }
224
    }
225 44098 jjdelcerro
226
    @Override
227
    public boolean getWarning() {
228
        return warning;
229
    }
230 44152 jjdelcerro
231
    @Override
232
    public T get(T defaultValue) {
233
        T v = this.get();
234
        if( v==null ) {
235
            return defaultValue;
236
        }
237
        return v;
238
    }
239 44080 jjdelcerro
240 44076 jjdelcerro
    @Override
241
    public T get() {
242 44148 jjdelcerro
        Object value;
243
        if( !this.text.isEditable() ||!this.text.isEnabled() ) {
244
            value = this.text.getText();
245
        } else {
246
            value = doCalculate(false);
247
        }
248 44076 jjdelcerro
        try {
249 44080 jjdelcerro
            DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
250
            value = dataManager.coerce(this.dataType, value);
251 44076 jjdelcerro
            return (T) value;
252
        } catch (CoercionException ex) {
253
            return null;
254
        }
255
    }
256
257
    @Override
258
    public void set(T value) {
259
        this.text.setText(Objects.toString(value, ""));
260 44098 jjdelcerro
        this.text.setBackground(this.color_ok);
261 44076 jjdelcerro
    }
262
263
    @Override
264
    public void coerceAndSet(Object value) {
265
        if (this.dataType != DataTypes.OBJECT) {
266
            DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
267
            try {
268
                value = dataManager.coerce(this.dataType, value);
269
            } catch (CoercionException ex) {
270
            }
271
        }
272
        this.text.setText(Objects.toString(value, ""));
273 44098 jjdelcerro
        this.text.setBackground(this.color_ok);
274 44076 jjdelcerro
    }
275
276
    @Override
277
    public void setEnabled(boolean enabled) {
278
        this.text.setEnabled(enabled);
279
    }
280
281
    @Override
282
    public boolean isEnabled() {
283
        return this.text.isEnabled();
284
    }
285
286 44080 jjdelcerro
    @Override
287
    public void setEditable(boolean editable) {
288
        this.text.setEditable(editable);
289
    }
290
291
    @Override
292
    public boolean isEditable() {
293
        return this.text.isEditable();
294
    }
295 44098 jjdelcerro
296
    @Override
297
    public void addChangeListener(ChangeListener cl) {
298
        this.changeListenerHelper.addChangeListener(cl);
299
    }
300
301
    @Override
302
    public ChangeListener[] getChangeListeners() {
303
        return this.changeListenerHelper.getChangeListeners();
304
    }
305
306
    @Override
307
    public void removeChangeListener(ChangeListener cl) {
308
        this.changeListenerHelper.removeAllChangeListener();
309
    }
310
311
    @Override
312
    public void removeAllChangeListener() {
313
        this.changeListenerHelper.removeAllChangeListener();
314
    }
315
316
    @Override
317
    public boolean hasChangeListeners() {
318
        return this.changeListenerHelper.hasChangeListeners();
319
    }
320
321
    @Override
322
    public void fireEvent() {
323
        this.changeListenerHelper.fireEvent();
324
    }
325
326
    @Override
327
    public void fireEvent(ChangeEvent ce) {
328
        this.changeListenerHelper.fireEvent(ce);
329
    }
330 44080 jjdelcerro
331 44076 jjdelcerro
}