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

History | View | Annotate | Download (10.5 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.FocusEvent;
6
import java.awt.event.FocusListener;
7
import java.awt.event.KeyAdapter;
8
import java.awt.event.KeyEvent;
9
import org.gvsig.expressionevaluator.swing.CalculatorController;
10
import java.util.Objects;
11
import javax.swing.AbstractAction;
12
import javax.swing.Action;
13
import javax.swing.JPopupMenu;
14
import javax.swing.Timer;
15
import javax.swing.event.ChangeEvent;
16
import javax.swing.event.ChangeListener;
17
import javax.swing.event.DocumentEvent;
18
import javax.swing.event.DocumentListener;
19
import javax.swing.text.JTextComponent;
20
import org.apache.commons.lang3.StringUtils;
21
import org.gvsig.expressionevaluator.Expression;
22
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
23
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
24
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
25
import org.gvsig.expressionevaluator.MutableSymbolTable;
26
import org.gvsig.expressionevaluator.SymbolTable;
27
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
28
import org.gvsig.tools.dataTypes.DataTypes;
29
import org.gvsig.tools.ToolsLocator;
30
import org.gvsig.tools.dataTypes.CoercionException;
31
import org.gvsig.tools.dataTypes.DataTypesManager;
32
import org.gvsig.tools.i18n.I18nManager;
33
import org.gvsig.tools.swing.api.ChangeListenerHelper;
34
import org.gvsig.tools.swing.api.ToolsSwingLocator;
35
import org.gvsig.tools.swing.api.ToolsSwingManager;
36
import org.gvsig.tools.swing.api.windowmanager.Dialog;
37
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
38
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

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

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

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

    
72
        this.swingManager = manager;
73
        this.manager = ExpressionEvaluatorLocator.getManager();
74
        this.config = null;
75
        this.expression = null;
76
        this.warning = false;
77
        this.changeListenerHelper = toolsSwingManager.createChangeListenerHelper();
78
        
79
        this.text = text;
80
        this.dataType = dataType;
81
        this.color_ok = this.text.getBackground();
82
        this.defaultSymbolTable = ExpressionEvaluatorLocator.getManager().createSymbolTable();
83
        this.text.addKeyListener(new KeyAdapter() {
84
            @Override
85
            public void keyPressed(KeyEvent e) {
86
                   if( e.getKeyCode()==KeyEvent.VK_R && e.isControlDown() ) {
87
                       doCalculate(true);
88
                   } 
89
            }
90
        });
91
        this.text.getDocument().addDocumentListener(new DocumentListener() {
92
            @Override
93
            public void insertUpdate(DocumentEvent e) {
94
                fireChangeEvent();
95
            }
96

    
97
            @Override
98
            public void removeUpdate(DocumentEvent e) {
99
                fireChangeEvent();
100
            }
101

    
102
            @Override
103
            public void changedUpdate(DocumentEvent e) {
104
                fireChangeEvent();
105
            }
106
        });
107
        this.text.addFocusListener(new FocusListener() {
108
            @Override
109
            public void focusLost(FocusEvent e) {
110
                doCalculate(true);
111
            }
112

    
113
            @Override
114
            public void focusGained(FocusEvent e) {
115
                doCalculate(true);
116
            }
117
        });
118
        toolsSwingManager.addClearButton(this.text, (ActionEvent e) -> {
119
            set(null);
120
        });
121
        toolsSwingManager.setDefaultPopupMenu(this.text);
122
        JPopupMenu popupMenu = this.text.getComponentPopupMenu();
123
        Action showExpressionBuilderAction = new AbstractAction(i18n.getTranslation("_Show_expression_builder")) {
124
            @Override
125
            public void actionPerformed(ActionEvent e) {
126
                doShowExpressionBuilder();
127
            }
128
        };  
129
        popupMenu.addSeparator();
130
        popupMenu.add(showExpressionBuilderAction);
131
        this.fireChangeTimer = new Timer(100, (ActionEvent e) -> {
132
            fireEvent();
133
        });
134
    }
135

    
136
    private void fireChangeEvent() {
137
        this.fireChangeTimer.setRepeats(false);
138
        this.fireChangeTimer.restart();
139
    }
140
    
141
    private void doShowExpressionBuilder() {
142
        if( this.config == null ) {
143
            this.config = new DefaultExpressionBuilderConfig(this.swingManager);
144
            this.config.addSymbolTable(this.defaultSymbolTable);
145
        }
146
        if( this.expression == null ) {
147
            this.expression = ExpressionEvaluatorLocator.getManager().createExpression();
148
        }
149
        expression.setPhrase(this.text.getText());
150
        JExpressionBuilder panel = this.swingManager.createJExpressionBuilder(config);
151
        panel.setExpression(this.expression);
152
        
153
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
154
        Dialog dialog = windowManager.createDialog(
155
                panel.asJComponent(),
156
                "Expression builder",
157
                null, 
158
                WindowManager_v2.BUTTONS_OK_CANCEL
159
        );
160
        dialog.show(WindowManager.MODE.DIALOG);
161
        if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
162
            this.text.setText(panel.getExpression().getPhrase());
163
        }        
164
    }
165
    
166
    @Override
167
    public void addSymbolTable(SymbolTable symbolTable) {
168
        this.defaultSymbolTable.addSymbolTable(symbolTable);
169
    }
170

    
171
    @Override
172
    public MutableSymbolTable getSymbolTable() {
173
        return this.defaultSymbolTable;
174
    }
175

    
176
    private Object doCalculate(boolean updateText) {
177
        if( !this.text.isEditable() ||!this.text.isEnabled() ) {
178
            return null;
179
        }
180
        String source = this.text.getText();
181
        try {
182
            if( !StringUtils.isBlank(source) ) {
183
                final Object value = this.manager.evaluate(this.defaultSymbolTable, source);
184
                if( updateText ) {
185
                    String s = Utils.repr(value);
186
                    if( !StringUtils.equals(s, this.lastText) ) {
187
                        this.setWarning(false);
188
                        this.lastText = s;
189
                        this.text.setText(this.lastText);
190
                    }
191
                }
192
                return value;
193
            }
194
            this.setWarning(false);
195
        } catch (ExpressionSyntaxException ex) {
196
            this.setWarning(true, ex.getDescription());
197
        } catch (Exception ex) {
198
            this.setWarning(true);
199
        }
200
        return null;
201
    }
202

    
203
    @Override
204
    public void setWarning(boolean warning) {
205
        this.setWarning(warning, null);
206
    }
207
    
208
    @Override
209
    public void setWarning(boolean warning, String description) {
210
        this.warning = warning;
211
        if( warning ) {
212
            this.text.setBackground(COLOR_ERROR);
213
            this.text.setToolTipText(description==null?"":description);
214
        } else {
215
            this.text.setBackground(this.color_ok);
216
            this.text.setToolTipText("");
217
        }
218
    }
219

    
220
    @Override
221
    public boolean getWarning() {
222
        return warning;
223
    }
224

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

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

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

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

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

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

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

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

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

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

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

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

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