Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / gui / command / CommandStackDialog.java @ 40558

History | View | Annotate | Download (12.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.gui.command;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Color;
28
import java.awt.Component;
29
import java.awt.Dimension;
30

    
31
import javax.swing.ImageIcon;
32
import javax.swing.JLabel;
33
import javax.swing.JPanel;
34
import javax.swing.JScrollBar;
35
import javax.swing.JScrollPane;
36
import javax.swing.JSlider;
37
import javax.swing.JTable;
38
import javax.swing.ListSelectionModel;
39
import javax.swing.table.DefaultTableCellRenderer;
40
import javax.swing.table.TableColumn;
41

    
42
import org.gvsig.andami.IconThemeHelper;
43
import org.gvsig.andami.PluginServices;
44
import org.gvsig.andami.ui.mdiManager.IWindowListener;
45
import org.gvsig.andami.ui.mdiManager.SingletonWindow;
46
import org.gvsig.andami.ui.mdiManager.WindowInfo;
47
import org.gvsig.app.ApplicationLocator;
48
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
49
import org.gvsig.gui.beans.DefaultBean;
50
import org.gvsig.tools.observer.Observable;
51
import org.gvsig.tools.observer.Observer;
52
import org.gvsig.tools.undo.UndoRedoInfo;
53
import org.gvsig.tools.undo.UndoRedoStack;
54

    
55

    
56
@SuppressWarnings("serial")
57
public class CommandStackDialog extends DefaultBean implements SingletonWindow, IWindowListener, Observer{
58

    
59
        private JTable commandTable = null;
60
        private JPanel topPanel = null;
61
        private UndoRedoStack undoRedoStack;
62
        private JSlider commandSlider = null;
63
        
64
        private int lowLimit;
65
        private int currentValue = -1;
66
        private int currentSliderValue = -1;
67
        private JPanel sliderPanel = null;
68
        protected boolean refreshing;
69
        private JPanel centerPanel = null;
70
        private JScrollPane jScrollPane = null;
71
        private JPanel tablePanel = null;
72
        
73
        private static final ImageIcon imodify = IconThemeHelper.getImageIcon("edit-undo-redo-actions-modify"); 
74
        private static final ImageIcon iadd = IconThemeHelper.getImageIcon("edit-undo-redo-actions-add");
75
        private static final ImageIcon idel = IconThemeHelper.getImageIcon("edit-undo-redo-actions-delete");
76

    
77
        private CommandTableModel commandTableModel = null;
78
        /**
79
         * This is the default constructor
80
         */
81
        public CommandStackDialog() {
82
                super();
83
                initialize();
84
        }
85
        
86
        public void setModel(UndoRedoStack cr1) {
87
        if (this.undoRedoStack != null) {
88
            if (this.undoRedoStack.equals(cr1)) {
89
                return;
90
            } else {
91
                this.undoRedoStack.deleteObserver(this);
92
            }
93
                }
94
                this.undoRedoStack = cr1;
95
                this.undoRedoStack.addObserver(this);
96
                initTable();
97
                initSlider();
98
                currentValue = commandTableModel.getPos();
99
            refreshControls();
100
                refreshSliderSize();
101
        }
102
        
103
        /**
104
         * This method initializes this
105
         *
106
         * @return void
107
         */
108
        private void initialize() {
109
                this.setLayout(new BorderLayout());
110
                this.setSize(328, 229);                
111
                this.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
112
        }
113

    
114
        /**
115
         * This method initializes jList
116
         *
117
         * @return javax.swing.JList
118
         */
119
        private JTable getTable() {
120
                if (commandTable == null) {
121
                        commandTable = new JTable();
122
                }
123
                return commandTable;
124
        }
125
        
126
        private void initTable(){
127
                commandTableModel = new CommandTableModel(undoRedoStack);
128
                commandTable.setModel(commandTableModel);
129
                commandTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
130
                commandTable.setSelectionBackground(Color.orange);
131
                commandTable.setSelectionForeground(Color.black);
132
                commandTable.setShowGrid(false);
133
                commandTable.getTableHeader().setBackground(Color.white);
134
                TableColumn tc = commandTable.getColumnModel().getColumn(0);
135
                tc.setCellRenderer(new DefaultTableCellRenderer() {
136
                           public Component getTableCellRendererComponent(JTable table,
137
                                                                       Object value,
138
                                                                       boolean isSelected,
139
                                                                       boolean hasFocus,
140
                                                                       int row,
141
                                                                       int column)
142
                              {
143
                                 JLabel label = (JLabel)
144
                                    super.getTableCellRendererComponent
145
                                       (table, value, isSelected, hasFocus, row, column);
146
                                    UndoRedoInfo info = (UndoRedoInfo) value;
147
                                    switch (info.getType()) {
148
                            case UndoRedoInfo.INSERT:
149
                                label.setIcon(iadd);
150
                                break;
151
                            case UndoRedoInfo.DELETE:
152
                                label.setIcon(idel);
153
                                break;
154
                            default:
155
                                label.setIcon(imodify);
156
                        }
157
                                 if (commandTableModel.getPos()<row){
158
                                         label.setBackground(Color.lightGray);
159
                                 }else {
160
                                                label.setBackground(Color.orange);
161
                                 }
162
                                    return label;
163
                              }
164
                        });
165

    
166
                commandTable.addMouseListener(new java.awt.event.MouseAdapter() {
167
                        public void mousePressed(java.awt.event.MouseEvent e) {
168
                                int newpos = commandTable.getSelectedRow();        
169
                                if (newpos >= 0){
170
                                    commandTableModel.setPos(newpos);                                
171
                                    ApplicationLocator.getManager().refreshMenusAndToolBars();
172
                                }
173
                        }
174
                });
175
        }
176
        /**
177
         * This method initializes jPanel
178
         *
179
         * @return javax.swing.JPanel
180
         */
181
        private JPanel getTopPanel() {
182
                if (topPanel == null) {
183
                        topPanel = new JPanel();        
184
                }
185
                return topPanel;
186
        }
187

    
188
        public WindowInfo getWindowInfo() {
189
                WindowInfo m_viewinfo = new WindowInfo(WindowInfo.ICONIFIABLE |
190
                                WindowInfo.MODELESSDIALOG | WindowInfo.RESIZABLE | WindowInfo.PALETTE);
191
                m_viewinfo.setTitle(PluginServices.getText(this,
192
                                "pila_de_comandos"));
193
                return m_viewinfo;
194
        }
195

    
196
        public Object getWindowModel() {
197
                return commandTableModel.getClass().getName();
198
        }
199

    
200
        public void windowActivated() {
201
                this.validateTree();
202
        }
203

    
204
        public void windowClosed() {
205
                
206
        }
207

    
208
        public void commandRepaint() {
209
                setValue(commandTableModel.getPos(), true);
210
                refreshSliderSize();
211
        }
212

    
213
    /**
214
     * Refreshes all the mutable controls in this component.
215
     */
216
    private void refreshControls() {
217
        int normalizedValue = (int) (((commandTableModel.getRowCount() - (currentValue + 1)) / (float)commandTableModel.getRowCount()) * 100);
218
        //Adding the 50% od the interval
219
        if (commandTableModel.getRowCount() > 0){
220
            normalizedValue = normalizedValue + (100 / (commandTableModel.getRowCount() * 2));
221
        }
222
        refreshSlider(normalizedValue);
223
        commandTable.repaint();
224
    }
225
    
226
    /**
227
     * Sets the slider to the correct (scaled) position.
228
     * @param normalizedValue
229
     */
230
    private void refreshSlider(int normalizedValue) {
231
        if (!refreshing){
232
            refreshing = true;
233
            getJSlider().setValue(normalizedValue);
234
            refreshing = false; 
235
        }
236
    }    
237
    
238
    private void refreshSliderSize(){
239
        if (!refreshing){
240
            Dimension size = new Dimension(commandSlider.getPreferredSize().width,
241
                ((commandTableModel.getRowCount() + 1) * getTable().getRowHeight()));
242
            JScrollBar verticalScrollBar = getJScrollPane().getVerticalScrollBar();
243
            verticalScrollBar.setValue(commandTableModel.getPos()*getTable().getRowHeight());
244
            commandSlider.setPreferredSize(size);
245
            commandSlider.setSize(size);
246
            validateTree();
247
        }
248
    }
249
    
250
        
251
        /**
252
         * This method initializes jSlider
253
         *
254
         * @return javax.swing.JSlider
255
         */
256
        private JSlider getJSlider() {
257
                if (commandSlider == null) {
258
                        commandSlider = new JSlider(JSlider.VERTICAL, 0, 100, 0);        
259
                }
260
                return commandSlider;
261
        }
262
        
263
        private void initSlider(){                
264
                commandSlider.setPreferredSize(
265
                    new Dimension(commandSlider.getPreferredSize().width,
266
                        ((getTable().getRowCount())*getTable().getRowHeight())));
267

    
268
                commandSlider.addChangeListener(new javax.swing.event.ChangeListener() {
269
                                public synchronized void stateChanged(javax.swing.event.ChangeEvent e) {
270
                                    if (!refreshing){
271
                                        int value = getTablePosFromSlider();  
272
                                        //currentSliderValue controls the same event thrown by the
273
                                        //slider. currentValue controls the event thrown by the table
274
                                        if (currentSliderValue != value){
275
                                            refreshing = true;        
276
                                            currentSliderValue = value;
277
                                            commandTableModel.setPos(value);
278
                                            ApplicationLocator.getManager().refreshMenusAndToolBars();
279
                                            refreshing = false;    
280
                                        }
281
                                    }
282
                            }
283
                    });
284
            setValue(commandTableModel.getRowCount() - 1 - commandTableModel.getPos(),true);
285
        }
286
        
287
        private int getTablePosFromSlider(){          
288
            if (commandTableModel.getRowCount() == 0){
289
                return -1;
290
            }
291
            
292
            int value = getJSlider().getValue();
293
            value = (int) ((value * 0.01) * commandTableModel.getRowCount());
294

    
295
            //The bottom part of the slider starts in 100: take the reverse value
296
            value = (commandTableModel.getRowCount() - 1) - value;
297
            
298
            if (value == -1){
299
                return 0;
300
            }
301
            return value;
302
        }
303
        
304
    public void setValue(int number, boolean fireEvent) {
305
        int rowCount = commandTableModel.getRowCount();
306
               
307
        if (number < lowLimit) {
308
                        number = lowLimit;
309
                }
310
        if (number > (rowCount - 1)) {
311
                        number = rowCount;
312
                }
313
        if (number != currentValue) {
314
                currentValue = number;
315
                if (fireEvent) {
316
                                callValueChanged(new Integer(currentValue));
317
                        }
318
        }
319
        /*
320
         * This needs to be refreshed also when same number is set
321
         * Example: select one feature and click 'delete' key
322
         */
323
        refreshControls();
324
    }
325

    
326
        /**
327
         * This method initializes jPanel1
328
         *
329
         * @return javax.swing.JPanel
330
         */
331
        private JPanel getSliderPanel() {
332
                if (sliderPanel == null) {
333
                        sliderPanel = new JPanel();
334
                        sliderPanel.add(getJSlider());
335
                }
336
                return sliderPanel;
337
        }
338

    
339
        /**
340
         * This method initializes pCenter
341
         *
342
         * @return javax.swing.JPanel
343
         */
344
        private JPanel getCenterPanel() {
345
                if (centerPanel == null) {
346
                        centerPanel = new JPanel();
347
                        centerPanel.setLayout(new BorderLayout());                        
348
                        centerPanel.add(getTablePanel(), java.awt.BorderLayout.CENTER);
349
                        centerPanel.add(getSliderPanel(), java.awt.BorderLayout.WEST);
350
                }
351
                return centerPanel;
352
        }
353
        
354
        private JPanel getTablePanel() {
355
            if (tablePanel == null) {
356
                tablePanel = new JPanel();
357
                tablePanel.setLayout(new BorderLayout());
358
                tablePanel.add(getTable(), java.awt.BorderLayout.CENTER);                
359
                tablePanel.add(getTopPanel(), java.awt.BorderLayout.NORTH);
360
            }
361
            return tablePanel;
362
        }
363

    
364
        /**
365
         * This method initializes jScrollPane
366
         *
367
         * @return javax.swing.JScrollPane
368
         */
369
        private JScrollPane getJScrollPane() {
370
                if (jScrollPane == null) {
371
                        jScrollPane = new JScrollPane();
372
                        jScrollPane.setViewportView(getCenterPanel());
373
                }
374
                return jScrollPane;
375
        }
376
        
377
        public void update(Observable observable, Object notification) {
378
                if (notification instanceof FeatureStoreNotification){
379
                        FeatureStoreNotification featureStoreNotification =
380
                                        (FeatureStoreNotification) notification;
381
                        //If the edition finish the command stack disappears
382
                        String type = featureStoreNotification.getType();
383
                        if (FeatureStoreNotification.AFTER_FINISHEDITING.equals(type) ||
384
                                        FeatureStoreNotification.AFTER_CANCELEDITING.equals(type)){                                                        
385
                                ApplicationLocator.getManager().getUIManager().closeWindow(this);                                
386
                                featureStoreNotification.getSource().deleteObserver(this);
387
                                return;
388
                        }
389
                        //Only repaint if the event is a selection event or an edition event
390
                        if (FeatureStoreNotification.AFTER_INSERT.equals(type) ||
391
                FeatureStoreNotification.AFTER_DELETE.equals(type) ||
392
                FeatureStoreNotification.AFTER_UPDATE.equals(type) ||
393
                FeatureStoreNotification.SELECTION_CHANGE.equals(type) ||
394
                FeatureStoreNotification.AFTER_REDO.equals(type) ||
395
                FeatureStoreNotification.AFTER_UNDO.equals(type)) {                   
396
                            commandRepaint();
397
                        }                        
398
                }
399
        }
400

    
401
        public Object getWindowProfile() {
402
                return WindowInfo.DIALOG_PROFILE;
403
        }
404
}