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 @ 44148

History | View | Annotate | Download (10.6 KB)

1
package org.gvsig.expressionevaluator.swing.impl;
2

    
3
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
import java.awt.event.KeyAdapter;
9
import java.awt.event.KeyEvent;
10
import org.gvsig.expressionevaluator.swing.CalculatorController;
11
import java.util.Objects;
12
import javax.swing.AbstractAction;
13
import javax.swing.Action;
14
import javax.swing.JPopupMenu;
15
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
import javax.swing.text.JTextComponent;
21
import org.apache.commons.lang3.StringUtils;
22
import org.gvsig.expressionevaluator.Expression;
23
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
24
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
25
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
26
import org.gvsig.expressionevaluator.MutableSymbolTable;
27
import org.gvsig.expressionevaluator.SymbolTable;
28
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager;
29
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
import org.gvsig.tools.i18n.I18nManager;
34
import org.gvsig.tools.swing.api.ChangeListenerHelper;
35
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
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

    
43
/**
44
 *
45
 * @author jjdelcerro
46
 */
47
@SuppressWarnings("UseSpecificCatch")
48
class DefaultCalculatorController<T> 
49
        implements CalculatorController<T> , ChangeListenerHelper
50
    {
51

    
52
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCalculatorController.class);
53
    
54
    private static final Color COLOR_ERROR = new Color(255,225,232);
55
    
56
    private final JTextComponent text;
57
    private final int dataType;
58
    private final MutableSymbolTable defaultSymbolTable;
59
    private final Color color_ok;
60
    private final ExpressionEvaluatorSwingManager swingManager;
61
    private DefaultExpressionBuilderConfig config;
62
    private Expression expression;
63
    private boolean warning;
64
    private final ChangeListenerHelper changeListenerHelper;
65
    private final Timer fireChangeTimer;
66
    private String lastText;
67
    private final ExpressionEvaluatorManager manager;
68

    
69
    public DefaultCalculatorController(ExpressionEvaluatorSwingManager manager, final JTextComponent text, int dataType) {
70
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
71
        I18nManager i18n = ToolsLocator.getI18nManager();
72

    
73
        this.swingManager = manager;
74
        this.manager = ExpressionEvaluatorLocator.getManager();
75
        this.config = null;
76
        this.expression = null;
77
        this.warning = false;
78
        this.changeListenerHelper = toolsSwingManager.createChangeListenerHelper();
79
        
80
        this.text = text;
81
        this.dataType = dataType;
82
        this.color_ok = this.text.getBackground();
83
        this.defaultSymbolTable = ExpressionEvaluatorLocator.getManager().createSymbolTable();
84
        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
        this.text.addFocusListener(new FocusListener() {
109
            @Override
110
            public void focusLost(FocusEvent e) {
111
                doCalculate(true);
112
            }
113

    
114
            @Override
115
            public void focusGained(FocusEvent e) {
116
                doCalculate(true);
117
            }
118
        });
119
        toolsSwingManager.addClearButton(this.text, new ActionListener() {
120
            @Override
121
            public void actionPerformed(ActionEvent e) {
122
                set(null);
123
            }
124
        });
125
        toolsSwingManager.setDefaultPopupMenu(this.text);
126
        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
        this.fireChangeTimer = new Timer(100, new ActionListener() {
136
            @Override
137
            public void actionPerformed(ActionEvent e) {
138
                fireEvent();
139
            }
140
        });
141
    }
142

    
143
    private void fireChangeEvent() {
144
        this.fireChangeTimer.setRepeats(false);
145
        this.fireChangeTimer.restart();
146
    }
147
    
148
    private void doShowExpressionBuilder() {
149
        if( this.config == null ) {
150
            this.config = new DefaultExpressionBuilderConfig(this.swingManager);
151
            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
        DefaultJExpressionBuilder panel = new DefaultJExpressionBuilder(this.swingManager, this.config);
159
        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
    @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
    private Object doCalculate(boolean updateText) {
185
        if( !this.text.isEditable() ||!this.text.isEnabled() ) {
186
            return null;
187
        }
188
        String source = this.text.getText();
189
        try {
190
            if( !StringUtils.isBlank(source) ) {
191
                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
            }
202
            this.setWarning(false);
203
        } catch (ExpressionSyntaxException ex) {
204
            this.setWarning(true, ex.getDescription());
205
        } catch (Exception ex) {
206
            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
            this.text.setBackground(COLOR_ERROR);
219
            this.text.setToolTipText(description==null?"":description);
220
        } else {
221
            this.text.setBackground(this.color_ok);
222
            this.text.setToolTipText("");
223
        }
224
    }
225

    
226
    @Override
227
    public boolean getWarning() {
228
        return warning;
229
    }
230
    
231
    
232
    @Override
233
    public T get() {
234
        Object value;
235
        if( !this.text.isEditable() ||!this.text.isEnabled() ) {
236
            value = this.text.getText();
237
        } else {
238
            value = doCalculate(false);
239
        }
240
        try {
241
            DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
242
            value = dataManager.coerce(this.dataType, value);
243
            return (T) value;
244
        } catch (CoercionException ex) {
245
            return null;
246
        }
247
    }
248

    
249
    @Override
250
    public void set(T value) {
251
        this.text.setText(Objects.toString(value, ""));
252
        this.text.setBackground(this.color_ok);
253
    }
254

    
255
    @Override
256
    public void coerceAndSet(Object value) {
257
        if (this.dataType != DataTypes.OBJECT) {
258
            DataTypesManager dataManager = ToolsLocator.getDataTypesManager();
259
            try {
260
                value = dataManager.coerce(this.dataType, value);
261
            } catch (CoercionException ex) {
262
            }
263
        }
264
        this.text.setText(Objects.toString(value, ""));
265
        this.text.setBackground(this.color_ok);
266
    }
267

    
268
    @Override
269
    public void setEnabled(boolean enabled) {
270
        this.text.setEnabled(enabled);
271
    }
272

    
273
    @Override
274
    public boolean isEnabled() {
275
        return this.text.isEnabled();
276
    }
277
    
278
    @Override
279
    public void setEditable(boolean editable) {
280
        this.text.setEditable(editable);
281
    }
282

    
283
    @Override
284
    public boolean isEditable() {
285
        return this.text.isEditable();
286
    }
287

    
288
    @Override
289
    public void addChangeListener(ChangeListener cl) {
290
        this.changeListenerHelper.addChangeListener(cl);
291
    }
292

    
293
    @Override
294
    public ChangeListener[] getChangeListeners() {
295
        return this.changeListenerHelper.getChangeListeners();
296
    }
297

    
298
    @Override
299
    public void removeChangeListener(ChangeListener cl) {
300
        this.changeListenerHelper.removeAllChangeListener();
301
    }
302

    
303
    @Override
304
    public void removeAllChangeListener() {
305
        this.changeListenerHelper.removeAllChangeListener();
306
    }
307

    
308
    @Override
309
    public boolean hasChangeListeners() {
310
        return this.changeListenerHelper.hasChangeListeners();
311
    }
312

    
313
    @Override
314
    public void fireEvent() {
315
        this.changeListenerHelper.fireEvent();
316
    }
317

    
318
    @Override
319
    public void fireEvent(ChangeEvent ce) {
320
        this.changeListenerHelper.fireEvent(ce);
321
    }
322
    
323
}