Subversion Repositories svn.mios

Rev

Rev 628 | Rev 732 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
628 adamjking 1
/*
2
 * @(#)HexFileUploadGUI.java    beta8   2006/04/23
3
 *
4
 * Copyright (C) 2008   Adam King (adamjking@optusnet.com.au)
5
 *
6
 * This application is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This application 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 application; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
 
21
package org.midibox.mios.gui;
22
 
23
import java.awt.BorderLayout;
24
import java.awt.Color;
25
import java.awt.Component;
26
import java.awt.Dimension;
27
import java.awt.FlowLayout;
28
import java.awt.GridBagConstraints;
29
import java.awt.GridBagLayout;
30
import java.awt.Insets;
31
import java.awt.event.ActionEvent;
32
import java.awt.event.ActionListener;
33
import java.io.File;
34
import java.util.Observable;
35
import java.util.Observer;
36
 
37
import javax.swing.BorderFactory;
38
import javax.swing.Box;
39
import javax.swing.BoxLayout;
40
import javax.swing.ButtonGroup;
41
import javax.swing.JButton;
42
import javax.swing.JCheckBox;
43
import javax.swing.JFileChooser;
44
import javax.swing.JFormattedTextField;
45
import javax.swing.JLabel;
46
import javax.swing.JOptionPane;
47
import javax.swing.JPanel;
48
import javax.swing.JRadioButton;
49
import javax.swing.JScrollPane;
50
import javax.swing.JSpinner;
51
import javax.swing.JTextField;
52
import javax.swing.JTextPane;
53
import javax.swing.SpinnerNumberModel;
54
import javax.swing.event.ChangeEvent;
55
import javax.swing.event.ChangeListener;
56
import javax.swing.text.Style;
57
import javax.swing.text.StyleConstants;
58
import javax.swing.text.StyleContext;
59
import javax.swing.text.StyledDocument;
60
 
61
import org.midibox.mios.HexFileUpload;
62
import org.midibox.utils.gui.HexFormatterFactory;
63
import org.midibox.utils.gui.ImageLoader;
64
import org.midibox.utils.gui.SimpleFileChooserFilter;
65
 
66
public class HexFileUploadGUI extends JPanel implements ActionListener,
67
        ChangeListener, Observer {
68
 
69
    private static String currentDirectory = "";
70
 
71
    private static JFileChooser fc = null;
72
 
73
    private HexFileUpload hexFileUpload;
74
 
75
    // GUI components
76
 
77
    private JButton browseButton;
78
 
79
    private JTextField fileName;
80
 
81
    private JButton startButton;
82
 
83
    private JButton stopButton;
84
 
85
    private JButton queryButton;
86
 
87
    private JTextPane progressMessageTextArea;
88
 
89
    private JLabel deviceIDLabel;
90
 
91
    private JSpinner deviceIDSpinner;
92
 
93
    private JRadioButton smartModeButton;
94
 
95
    private JRadioButton dumbModeButton;
96
 
97
    private ButtonGroup buttonGroup;
98
 
99
    private JCheckBox waitForUploadRequestCheck;
100
 
721 adamjking 101
    private JCheckBox MIOS32Check;
628 adamjking 102
 
103
    private JLabel delayTimeLabel;
104
 
105
    private JSpinner delayTimeSpinner;
106
 
107
    public HexFileUploadGUI(HexFileUpload hexUploadTask) {
108
        super(new BorderLayout());
109
 
110
        this.hexFileUpload = hexUploadTask;
111
        hexUploadTask.addObserver(this);
112
 
113
        browseButton = new JButton("Hex File", ImageLoader
114
                .getImageIcon("open.png"));
115
        browseButton.setActionCommand("browse");
116
        browseButton.addActionListener(this);
117
 
118
        fileName = new JTextField();
119
        fileName.setEditable(false);
120
 
121
        startButton = new JButton("Start");
122
        startButton.setActionCommand("start");
123
        startButton.addActionListener(this);
124
        startButton.setEnabled(false);
125
 
126
        stopButton = new JButton("Stop");
127
        stopButton.addActionListener(this);
128
        stopButton.setActionCommand("stop");
129
 
130
        queryButton = new JButton("Query");
131
        queryButton.addActionListener(this);
132
        queryButton.setActionCommand("query");
133
        queryButton.setEnabled(false);
134
 
135
        startButton.setAlignmentX(Component.LEFT_ALIGNMENT);
136
        stopButton.setAlignmentX(Component.LEFT_ALIGNMENT);
137
        queryButton.setAlignmentX(Component.LEFT_ALIGNMENT);
138
 
139
        JPanel fileButtonsPanel = new JPanel(new BorderLayout(2, 0));
140
        fileButtonsPanel.add(browseButton, BorderLayout.WEST);
141
        fileButtonsPanel.add(fileName, BorderLayout.CENTER);
142
        fileButtonsPanel.setBorder(BorderFactory.createEmptyBorder(7, 7, 5, 7));
143
 
144
        JPanel controlButtonsPanel = new JPanel();
145
        controlButtonsPanel.setLayout(new BoxLayout(controlButtonsPanel,
146
                BoxLayout.LINE_AXIS));
147
        controlButtonsPanel.add(startButton);
148
        controlButtonsPanel.add(Box.createRigidArea(new Dimension(15, 0)));
149
        controlButtonsPanel.add(stopButton);
150
        controlButtonsPanel.add(Box.createHorizontalGlue());
151
        controlButtonsPanel.add(queryButton);
152
        controlButtonsPanel.add(Box.createHorizontalGlue());
153
        controlButtonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
154
                5));
155
 
156
        JPanel progressMessagePanel = new JPanel();
157
        progressMessagePanel.setLayout(new BoxLayout(progressMessagePanel,
158
                BoxLayout.PAGE_AXIS));
159
 
160
        progressMessageTextArea = new JTextPane();
161
        progressMessageTextArea.setBackground(Color.WHITE);
162
 
163
        StyledDocument doc = progressMessageTextArea.getStyledDocument();
164
 
165
        Style def = StyleContext.getDefaultStyleContext().getStyle(
166
                StyleContext.DEFAULT_STYLE);
167
 
168
        Style regular = doc.addStyle("regular", def);
169
        StyleConstants.setFontFamily(def, "Monospaced");
170
 
171
        Style s = doc.addStyle("ack", regular);
172
        StyleConstants.setForeground(s, new Color(0, 150, 50));
173
 
174
        s = doc.addStyle("error", regular);
175
        StyleConstants.setForeground(s, new Color(150, 0, 50));
176
 
177
        progressMessageTextArea.setEditable(false);
178
        JScrollPane progressMessageTextAreaScrollPane = new JScrollPane(
179
                progressMessageTextArea);
180
        progressMessageTextAreaScrollPane
181
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
182
 
183
        // Make preferred width smaller than the other panel's minimum width.
184
        progressMessageTextAreaScrollPane.setPreferredSize(new Dimension(300,
185
                100));
186
 
187
        progressMessagePanel.add(progressMessageTextAreaScrollPane);
188
        progressMessagePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
189
                5));
190
 
191
        JPanel controlPanel = new JPanel();
192
        controlPanel
193
                .setLayout(new BoxLayout(controlPanel, BoxLayout.PAGE_AXIS));
194
        controlPanel.add(controlButtonsPanel);
195
        controlPanel.add(progressMessagePanel);
196
 
197
        controlPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
198
                .createEmptyBorder(5, 5, 5, 5), BorderFactory
199
                .createTitledBorder("Upload Control")));
200
 
201
        JPanel protocolPanel = new JPanel();
202
 
203
        protocolPanel.setBorder(BorderFactory.createCompoundBorder(
204
                BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory
205
                        .createTitledBorder("Upload Options")));
206
 
207
        protocolPanel.setLayout(new GridBagLayout());
208
 
209
        GridBagConstraints gbc = new GridBagConstraints();
210
        gbc.gridx = 0;
211
        gbc.gridy = 0;
212
        gbc.gridwidth = 1;
213
        gbc.gridheight = 1;
214
        gbc.anchor = GridBagConstraints.WEST;
215
        gbc.insets = new Insets(2, 2, 2, 2);
216
 
217
        deviceIDLabel = new JLabel("Device ID:");
218
        protocolPanel.add(deviceIDLabel, gbc);
219
        gbc.gridx++;
220
 
221
        deviceIDSpinner = new JSpinner(new SpinnerNumberModel(hexFileUpload
222
                .getDeviceID(), 0, 127, 1));
223
        deviceIDSpinner.addChangeListener(this);
224
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) deviceIDSpinner
225
                .getEditor();
226
        JFormattedTextField tf = editor.getTextField();
227
        tf.setFormatterFactory(new HexFormatterFactory());
228
        protocolPanel.add(deviceIDSpinner, gbc);
229
        gbc.gridx++;
230
 
231
        gbc.insets = new Insets(2, 15, 2, 2);
232
 
721 adamjking 233
        MIOS32Check = new JCheckBox("MIOS32", hexFileUpload.isMIOS32Mode());
628 adamjking 234
        MIOS32Check.addActionListener(this);
235
        protocolPanel.add(MIOS32Check, gbc);
236
 
237
        gbc.gridx = 0;
238
        gbc.gridy++;
239
 
240
        gbc.gridwidth = 4;
241
        waitForUploadRequestCheck = new JCheckBox(
242
                "Wait for upload request before starting upload", hexFileUpload
243
                        .isWaitForUploadRequest());
244
        waitForUploadRequestCheck.addActionListener(this);
245
        protocolPanel.add(waitForUploadRequestCheck, gbc);
246
        gbc.gridy++;
247
 
248
        smartModeButton = new JRadioButton(
249
                "Smart Mode - Use feedback from core", hexFileUpload
250
                        .getUploadMode() == HexFileUpload.SMART_MODE);
251
        smartModeButton.addActionListener(this);
252
        protocolPanel.add(smartModeButton, gbc);
253
        gbc.gridy++;
254
 
255
        dumbModeButton = new JRadioButton(
256
                "Manual Mode - Don't use feedback from core", hexFileUpload
257
                        .getUploadMode() == HexFileUpload.DUMB_MODE);
258
        dumbModeButton.addActionListener(this);
259
        protocolPanel.add(dumbModeButton, gbc);
260
        gbc.gridy++;
261
 
262
        buttonGroup = new ButtonGroup();
263
        buttonGroup.add(dumbModeButton);
264
        buttonGroup.add(smartModeButton);
265
 
266
        gbc.insets = new Insets(2, 15, 2, 2);
267
 
268
        JPanel timePanel = new JPanel(new FlowLayout(0, 5, 0));
269
 
270
        delayTimeLabel = new JLabel("Delay between SysEx messages (ms):");
271
        timePanel.add(delayTimeLabel);
272
 
273
        delayTimeSpinner = new JSpinner(new SpinnerNumberModel(hexFileUpload
274
                .getDelayTime(), 10, 2000, 1));
275
        delayTimeSpinner.addChangeListener(this);
276
        timePanel.add(delayTimeSpinner);
277
 
278
        protocolPanel.add(timePanel, gbc);
279
 
280
        gbc.gridy++;
281
 
282
        gbc.weighty = 1.0;
283
        protocolPanel.add(new JPanel(), gbc);
284
 
285
        add(fileButtonsPanel, BorderLayout.PAGE_START);
286
        add(controlPanel, BorderLayout.CENTER);
287
        add(protocolPanel, BorderLayout.EAST);
288
 
289
        updateUploadControls();
290
    }
291
 
292
    public static String getCurrentDirectory() {
293
        return currentDirectory;
294
    }
295
 
296
    public static void setCurrentDirectory(String currentDirectory) {
297
        HexFileUploadGUI.currentDirectory = currentDirectory;
298
    }
299
 
300
    public HexFileUpload getHexFileUpload() {
301
        return hexFileUpload;
302
    }
303
 
304
    protected void onOpenHexFile() {
305
 
306
        if (fc == null) {
307
            fc = new JFileChooser(currentDirectory);
308
            SimpleFileChooserFilter fileFilter = new SimpleFileChooserFilter(
309
                    "Hex files", "hex", "Compliled Hex file");
310
            fc.addChoosableFileFilter(fileFilter);
311
            fc.setAcceptAllFileFilterUsed(false);
312
        }
313
 
314
        File noFile = new File("");
315
        File noFiles[] = { noFile };
316
        fc.setSelectedFile(noFile);
317
        fc.setSelectedFiles(noFiles);
318
 
319
        int nRetVal = fc.showOpenDialog(this);
320
 
321
        if (nRetVal == JFileChooser.APPROVE_OPTION) {
322
            File file = fc.getSelectedFile();
323
            hexFileUpload.setFile(file);
324
            currentDirectory = fc.getCurrentDirectory().toString();
325
        }
326
    }
327
 
328
    public void updateUploadControls() {
329
 
330
        boolean bUploading = (!hexFileUpload.isCancelled() && !hexFileUpload
331
                .isDone());
332
 
333
        deviceIDLabel.setEnabled(!bUploading);
334
        deviceIDSpinner.setEnabled(!bUploading);
335
 
336
        MIOS32Check.setEnabled(!bUploading);
337
 
721 adamjking 338
        if (hexFileUpload.isMIOS32Mode()) {
628 adamjking 339
            smartModeButton.setEnabled(false);
340
            dumbModeButton.setEnabled(false);
341
            waitForUploadRequestCheck.setEnabled(false);
342
            delayTimeLabel.setEnabled(false);
343
            delayTimeSpinner.setEnabled(false);
344
        } else {
345
            smartModeButton.setEnabled(!bUploading);
346
            dumbModeButton.setEnabled(!bUploading);
347
 
348
            waitForUploadRequestCheck.setEnabled(!bUploading);
349
 
350
            delayTimeLabel
351
                    .setEnabled(!bUploading
352
                            && hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
353
 
354
            delayTimeSpinner
355
                    .setEnabled(!bUploading
356
                            && hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
357
        }
358
 
359
        startButton.setEnabled(!bUploading && hexFileUpload.getFile() != null);
360
        stopButton.setEnabled(bUploading);
721 adamjking 361
        queryButton.setEnabled(!bUploading && hexFileUpload.isMIOS32Mode());
628 adamjking 362
    }
363
 
364
    public void stateChanged(ChangeEvent e) {
365
 
366
        Object source = e.getSource();
367
 
368
        if (source == deviceIDSpinner) {
369
            hexFileUpload.setDeviceID(((Integer) deviceIDSpinner.getValue())
370
                    .intValue());
371
 
372
        } else if (source == delayTimeSpinner) {
373
            hexFileUpload.setDelayTime(((Integer) delayTimeSpinner.getValue())
374
                    .intValue());
375
        }
376
    }
377
 
378
    public void actionPerformed(ActionEvent e) {
379
 
380
        String command = e.getActionCommand();
381
        Object source = e.getSource();
382
 
383
        if (command.equals("start")) {
384
            if (hexFileUpload.fileChanged()) {
385
 
386
                int nRet = JOptionPane.showConfirmDialog(null, "The file '"
387
                        + hexFileUpload.getFile().getPath()
388
                        + "' has changed.\n"
389
                        + "Do you wish to reload this file?",
390
                        "File has changed", JOptionPane.YES_NO_OPTION,
391
                        JOptionPane.INFORMATION_MESSAGE, null);
392
 
393
                if (nRet == JOptionPane.YES_OPTION) {
394
                    hexFileUpload.setFile(hexFileUpload.getFile());
395
                }
396
            }
397
 
398
            progressMessageTextArea.setText("");
399
 
400
            Thread t = new Thread() {
401
                public void run() {
402
                    hexFileUpload.createUpload();
403
                }
404
            };
405
 
406
            t.start();
407
 
408
        } else if (command.equals("query")) {
409
            progressMessageTextArea.setText("");
410
 
411
            Thread t = new Thread() {
412
                public void run() {
413
                    hexFileUpload.createQuery();
414
                }
415
            };
416
 
417
            t.start();
418
 
419
        } else if (command.equals("stop")) {
420
            hexFileUpload.cancel();
421
 
422
        } else if (command.equals("browse")) {
423
            onOpenHexFile();
424
 
425
        } else if (source == smartModeButton || source == dumbModeButton) {
426
            hexFileUpload
427
                    .setUploadMode(smartModeButton.isSelected() ? HexFileUpload.SMART_MODE
428
                            : HexFileUpload.DUMB_MODE);
429
 
430
        } else if (source == MIOS32Check) {
721 adamjking 431
            hexFileUpload.setMIOS32Mode(MIOS32Check.isSelected());
628 adamjking 432
 
433
        } else if (source == waitForUploadRequestCheck) {
434
            hexFileUpload.setWaitForUploadRequest(waitForUploadRequestCheck
435
                    .isSelected());
436
        }
437
    }
438
 
439
    public void update(Observable observable, Object object) {
440
        if (observable == hexFileUpload) {
441
            if (object == HexFileUpload.MESSAGES
442
                    || object == HexFileUpload.WORKER) {
443
                while (!hexFileUpload.getMessages().isEmpty()) {
444
                    try {
445
                        String message = (String) hexFileUpload.getMessages()
446
                                .removeFirst();
447
                        StyledDocument doc = progressMessageTextArea
448
                                .getStyledDocument();
449
                        String style = "regular";
450
 
451
                        if (message.startsWith("Error")
452
                                || message.startsWith("Received error")
453
                                || message.endsWith("errors")
454
                                || message.endsWith("Error")) {
455
                            style = "error";
456
                        } else if (message.startsWith("Received")) {
457
                            style = "ack";
458
                        }
459
 
460
                        doc.insertString(doc.getLength(), message + "\n", doc
461
                                .getStyle(style));
462
                        progressMessageTextArea.setCaretPosition(doc
463
                                .getLength());
464
                    } catch (Exception e) {
465
 
466
                    }
467
                }
468
            } else if (object == HexFileUpload.FILE) {
469
                fileName.setText(hexFileUpload.getFile().getPath());
470
 
471
            } else if (object == HexFileUpload.DELAY_TIME) {
472
                delayTimeSpinner.setValue(new Integer(hexFileUpload
473
                        .getDelayTime()));
474
 
475
            } else if (object == HexFileUpload.DEVICE_ID) {
476
                deviceIDSpinner.setValue(new Integer(hexFileUpload
477
                        .getDeviceID()));
478
 
479
            } else if (object == HexFileUpload.UPLOAD_MODE) {
480
                smartModeButton
481
                        .setSelected(hexFileUpload.getUploadMode() == HexFileUpload.SMART_MODE);
482
 
483
                dumbModeButton
484
                        .setSelected(hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
485
 
486
            } else if (object == HexFileUpload.MIOS32_MODE) {
721 adamjking 487
                MIOS32Check.setSelected(hexFileUpload.isMIOS32Mode());
628 adamjking 488
            } else if (object == HexFileUpload.WAIT_FOR_UPLOAD) {
489
                waitForUploadRequestCheck.setSelected(hexFileUpload
490
                        .isWaitForUploadRequest());
491
            }
492
 
493
            updateUploadControls();
494
        }
495
    }
496
}