Subversion Repositories public

Rev

Rev 89 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
87 luk 1
/*
2
 * TaskTableModel.java - implementation of tracked tasks table model
3
 *
4
 * Copyright (c) 2006 Lukas Jelinek, http://www.aiken.cz
5
 *
6
 * ==========================================================================
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License Version 2 as
10
 * published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 *
21
 * ==========================================================================
22
 */
23
 
24
package cz.aiken.util.lwtt;
25
 
26
import javax.swing.*;
27
import javax.swing.table.*;
28
import java.util.*;
29
import java.io.*;
30
import java.awt.event.*;
31
 
32
/**
33
 * This class represents the task table model.
34
 * @author luk
35
 */
36
public class TaskTableModel extends AbstractTableModel implements ActionListener {
37
 
38
    private ArrayList<Task> tasks = new ArrayList<Task>();
39
    private javax.swing.Timer timer = new javax.swing.Timer(300000, this);
40
 
41
    /**
42
     * Creates a new instance of TaskTableModel
43
     */
44
    public TaskTableModel() {
45
        loadFromFile();
46
        timer.start();
47
    }
48
 
49
    /**
50
     * Returns the value at the given coordinates.
51
     * @param rowIndex row index
52
     * @param columnIndex column index
53
     * @return appropriate cell value; if the arguments are invalid
54
     * it returns <CODE>null</CODE>
55
     */
56
    public Object getValueAt(int rowIndex, int columnIndex) {
57
        switch (columnIndex) {
58
            case 0: return tasks.get(rowIndex).getName();
59
            case 1: return new Long(tasks.get(rowIndex).getConsumption() / 60000);
60
            default: return null;
61
        }
62
    }
63
 
64
    /**
65
     * Returns the row count.
66
     * @return row count
67
     */
68
    public int getRowCount() {
69
        return tasks.size();
70
    }
71
 
72
    /**
73
     * Returns the column count (currently 2).
74
     * @return column count
75
     */
76
    public int getColumnCount() {
77
        return 2;
78
    }
79
 
80
    /**
81
     * Sets a new value of the given cell. If at least one of the
82
     * coordinates is invalid it does nothing.
83
     * @param aValue new value
84
     * @param rowIndex row index
85
     * @param columnIndex column index
86
     */
87
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
88
        switch (columnIndex) {
89
            case 0: tasks.get(rowIndex).setName((String) aValue);
90
                break;
91
            case 1: tasks.get(rowIndex).setConsumption(((Long) aValue).longValue());
92
                break;
93
        }
94
    }
95
 
96
    /**
97
     * Returns the name of the given column.
98
     * @param column column index
99
     * @return column name; if the index is invalid it returns an empty
100
     * string
101
     */
102
    public String getColumnName(int column) {
103
        switch (column) {
104
            case 0: return "Task name";
105
            case 1: return "Time consumption [min]";
106
            default: return "";
107
        }
108
    }
109
 
110
    /**
111
     * Returns the class of the given column.
112
     * @param columnIndex column index
113
     * @return appropriate class object; if the column index is invalid
114
     * it returns <CODE>Void.class</CODE>.
115
     */
116
    public Class<?> getColumnClass(int columnIndex) {
117
        switch (columnIndex) {
118
            case 0: return String.class;
119
            case 1: return Long.class;
120
            default: return Void.class;
121
        }
122
    }
123
 
124
    /**
125
     * Checks whether the given cell is editable.
126
     * @param rowIndex row index
127
     * @param columnIndex column index
128
     * @return <CODE>true</CODE> for the first column (index 0),
129
     * <CODE>false</CODE> otherwise
130
     */
131
    public boolean isCellEditable(int rowIndex, int columnIndex) {
132
        return columnIndex == 0;
133
    }
134
 
135
    /**
136
     * Creates a new task.
137
     */
138
    public void addNewTask() {
139
        Task t = new Task();
140
        t.setActionListener(this);
141
        tasks.add(t);
142
 
143
        int row = tasks.size()-1;
144
        fireTableRowsInserted(row, row);
145
    }
146
 
147
    /**
148
     * Removes the given tasks.
149
     * @param start start index
150
     * @param end end index (including)
151
     */
152
    public void removeTasks(int start, int end) {
153
        for (int i=end; i>=start; i--) {
154
            Task t = tasks.remove(i);
155
            t.stop();
156
            t.setActionListener(null);
157
        }
158
 
159
        fireTableRowsDeleted(start, end);
160
    }
161
 
162
    /**
163
     * Starts the given tasks.
164
     * @param start start index
165
     * @param end end index (including)
166
     */
167
    public void startTasks(int start, int end) {
168
        for (int i=start; i<=end; i++) {
169
            Task t = tasks.get(i);
170
            t.start();
171
            fireTableCellUpdated(i, 1);
172
        }        
173
    }
174
 
175
    /**
176
     * Stops the given tasks.
177
     * @param start start index
178
     * @param end end index (including)
179
     */
180
    public void stopTasks(int start, int end) {
181
        for (int i=start; i<=end; i++) {
182
            Task t = tasks.get(i);
183
            t.stop();
184
            fireTableCellUpdated(i, 1);
185
        }
186
    }
187
 
188
    /**
189
     * Stops all tasks.
190
     */
191
    public void stopAllTasks() {
192
        Iterator<Task> it = tasks.iterator();
193
        while (it.hasNext()) {
194
            it.next().stop();
195
        }
196
 
197
        fireTableDataChanged();
198
    }
199
 
200
    /**
201
     * Destroys the timer controlling automatic data saving.
202
     */
203
    public void cancelAutoSave() {
204
        timer.stop();
205
    }
206
 
207
    /**
208
     * Returns the absolute path to the directory where LWTT data should be
209
     * saved.
210
     * @return directory path
211
     */
212
    public static File getDir() {
213
        Properties sys = System.getProperties();
214
        return new File(sys.getProperty("user.home"), ".lwtt");
215
    }
216
 
217
    /**
218
     * Returns the absolute path to the file where LWTT data should be
219
     * saved.
220
     * @return absolute file path
221
     */
222
    public static File getPath() {
223
        return new File(getDir(), "data.xml");
224
    }
225
 
226
    /**
227
     * Checks whether the given task is running.
228
     * @param index task index
229
     * @return <CODE>true</CODE> for running task,
230
     * <CODE>false</CODE> otherwise
231
     */
232
    public boolean isRunning(int index) {
233
        return tasks.get(index).isRunning();
234
    }
235
 
236
    /**
237
     * Loads application's data from the file.
238
     */
239
    public synchronized void loadFromFile() {
240
        tasks.clear();
241
 
242
        File file = getPath();
243
        if (!file.exists())
244
            return;
245
 
246
        try {
247
            FileInputStream is = new FileInputStream(file);
248
            Properties props = new Properties();
249
            props.loadFromXML(is);
250
            is.close();
251
 
252
            Iterator<Object> it = props.keySet().iterator();
253
            while (it.hasNext()) {
254
                String key = (String) it.next();
255
                if (key.endsWith(".name")) {
256
                    String ids = key.substring(0, key.length() - 5);
257
                    String name = props.getProperty(ids + ".name");
258
                    String cons = props.getProperty(ids + ".consumption");
259
                    try {
260
                        int id = Integer.parseInt(ids);
261
                        long cn = Long.parseLong(cons);
262
                        Task t = new Task(id, name, cn);
263
                        t.setActionListener(this);
264
                        tasks.add(t);
265
                    } catch (NumberFormatException e) {
266
                        JOptionPane.showMessageDialog(null, "Cannot load data from file (bad format).", "Error", JOptionPane.ERROR_MESSAGE);
267
                    }                    
268
                }
269
            }
270
 
271
            Collections.sort(tasks);
272
 
273
            fireTableDataChanged();
274
 
275
        } catch (Exception e) {
276
            e.printStackTrace();
277
        }
278
    }
279
 
280
    /**
281
     * Saves application's data to the file.
282
     */
283
    public synchronized void saveToFile() {
284
        File dir = getDir();
285
        if (!dir.exists()) {
286
            if (!dir.mkdir()) {
287
                JOptionPane.showMessageDialog(null, "Cannot save data to file (cannot create data directory).", "Error", JOptionPane.ERROR_MESSAGE);
288
                return;
289
            }
290
        }
291
 
292
        Properties props = new Properties();
293
        for (int i=0; i<tasks.size(); i++) {
294
            Task t = tasks.get(i);
295
            String id = Integer.toString(t.getId());
296
            props.setProperty(id + ".name", t.getName());
297
            props.setProperty(id + ".consumption", Long.toString(t.getConsumption()));
298
        }
299
 
300
        try {
301
            FileOutputStream os = new FileOutputStream(getPath());
302
            props.storeToXML(os, "LWTT task data");
303
            os.close();
304
        } catch (IOException e) {
305
            JOptionPane.showMessageDialog(null, "Cannot save data to file (" + e.getLocalizedMessage() + ").", "Error", JOptionPane.ERROR_MESSAGE);
306
        }
307
    }
308
 
309
    /**
310
     * Processes an action event.
311
     *
312
     * If the event has been generated by the auto-save timer it saves
313
     * the data. Otherwise (a button action occurred) it updates
314
     * the appropriate table cell.
315
     * @param e action event
316
     */
317
    public void actionPerformed(ActionEvent e) {
318
        Object src = e.getSource();
319
        if (src == timer) {
320
            saveToFile();
321
        }
322
        else {
323
            int row = tasks.indexOf(src);
324
            fireTableCellUpdated(row, 1);
325
        }
326
    }
327
 
328
}