Subversion Repositories svn.mios

Rev

Rev 732 | Rev 753 | 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);
738 adamjking 120
 
732 adamjking 121
        File file = hexFileUpload.getFile();
738 adamjking 122
 
732 adamjking 123
        if (file != null) {
738 adamjking 124
 
732 adamjking 125
            fileName.setText(file.getPath());
126
        }
628 adamjking 127
 
128
        startButton = new JButton("Start");
129
        startButton.setActionCommand("start");
130
        startButton.addActionListener(this);
131
        startButton.setEnabled(false);
132
 
133
        stopButton = new JButton("Stop");
134
        stopButton.addActionListener(this);
135
        stopButton.setActionCommand("stop");
136
 
137
        queryButton = new JButton("Query");
138
        queryButton.addActionListener(this);
139
        queryButton.setActionCommand("query");
140
        queryButton.setEnabled(false);
141
 
142
        startButton.setAlignmentX(Component.LEFT_ALIGNMENT);
143
        stopButton.setAlignmentX(Component.LEFT_ALIGNMENT);
144
        queryButton.setAlignmentX(Component.LEFT_ALIGNMENT);
145
 
146
        JPanel fileButtonsPanel = new JPanel(new BorderLayout(2, 0));
147
        fileButtonsPanel.add(browseButton, BorderLayout.WEST);
148
        fileButtonsPanel.add(fileName, BorderLayout.CENTER);
149
        fileButtonsPanel.setBorder(BorderFactory.createEmptyBorder(7, 7, 5, 7));
150
 
151
        JPanel controlButtonsPanel = new JPanel();
152
        controlButtonsPanel.setLayout(new BoxLayout(controlButtonsPanel,
153
                BoxLayout.LINE_AXIS));
154
        controlButtonsPanel.add(startButton);
155
        controlButtonsPanel.add(Box.createRigidArea(new Dimension(15, 0)));
156
        controlButtonsPanel.add(stopButton);
157
        controlButtonsPanel.add(Box.createHorizontalGlue());
158
        controlButtonsPanel.add(queryButton);
159
        controlButtonsPanel.add(Box.createHorizontalGlue());
160
        controlButtonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
161
                5));
162
 
163
        JPanel progressMessagePanel = new JPanel();
164
        progressMessagePanel.setLayout(new BoxLayout(progressMessagePanel,
165
                BoxLayout.PAGE_AXIS));
166
 
167
        progressMessageTextArea = new JTextPane();
168
        progressMessageTextArea.setBackground(Color.WHITE);
169
 
170
        StyledDocument doc = progressMessageTextArea.getStyledDocument();
171
 
172
        Style def = StyleContext.getDefaultStyleContext().getStyle(
173
                StyleContext.DEFAULT_STYLE);
174
 
175
        Style regular = doc.addStyle("regular", def);
176
        StyleConstants.setFontFamily(def, "Monospaced");
177
 
178
        Style s = doc.addStyle("ack", regular);
179
        StyleConstants.setForeground(s, new Color(0, 150, 50));
180
 
181
        s = doc.addStyle("error", regular);
182
        StyleConstants.setForeground(s, new Color(150, 0, 50));
183
 
184
        progressMessageTextArea.setEditable(false);
185
        JScrollPane progressMessageTextAreaScrollPane = new JScrollPane(
186
                progressMessageTextArea);
187
        progressMessageTextAreaScrollPane
188
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
189
 
190
        // Make preferred width smaller than the other panel's minimum width.
191
        progressMessageTextAreaScrollPane.setPreferredSize(new Dimension(300,
192
                100));
193
 
194
        progressMessagePanel.add(progressMessageTextAreaScrollPane);
195
        progressMessagePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
196
                5));
197
 
198
        JPanel controlPanel = new JPanel();
199
        controlPanel
200
                .setLayout(new BoxLayout(controlPanel, BoxLayout.PAGE_AXIS));
201
        controlPanel.add(controlButtonsPanel);
202
        controlPanel.add(progressMessagePanel);
203
 
204
        controlPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
205
                .createEmptyBorder(5, 5, 5, 5), BorderFactory
206
                .createTitledBorder("Upload Control")));
207
 
208
        JPanel protocolPanel = new JPanel();
209
 
210
        protocolPanel.setBorder(BorderFactory.createCompoundBorder(
211
                BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory
212
                        .createTitledBorder("Upload Options")));
213
 
214
        protocolPanel.setLayout(new GridBagLayout());
215
 
216
        GridBagConstraints gbc = new GridBagConstraints();
217
        gbc.gridx = 0;
218
        gbc.gridy = 0;
219
        gbc.gridwidth = 1;
220
        gbc.gridheight = 1;
221
        gbc.anchor = GridBagConstraints.WEST;
222
        gbc.insets = new Insets(2, 2, 2, 2);
223
 
224
        deviceIDLabel = new JLabel("Device ID:");
225
        protocolPanel.add(deviceIDLabel, gbc);
226
        gbc.gridx++;
227
 
228
        deviceIDSpinner = new JSpinner(new SpinnerNumberModel(hexFileUpload
229
                .getDeviceID(), 0, 127, 1));
230
        deviceIDSpinner.addChangeListener(this);
231
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) deviceIDSpinner
232
                .getEditor();
233
        JFormattedTextField tf = editor.getTextField();
234
        tf.setFormatterFactory(new HexFormatterFactory());
235
        protocolPanel.add(deviceIDSpinner, gbc);
236
        gbc.gridx++;
237
 
238
        gbc.insets = new Insets(2, 15, 2, 2);
239
 
721 adamjking 240
        MIOS32Check = new JCheckBox("MIOS32", hexFileUpload.isMIOS32Mode());
628 adamjking 241
        MIOS32Check.addActionListener(this);
242
        protocolPanel.add(MIOS32Check, gbc);
243
 
244
        gbc.gridx = 0;
245
        gbc.gridy++;
246
 
247
        gbc.gridwidth = 4;
248
        waitForUploadRequestCheck = new JCheckBox(
249
                "Wait for upload request before starting upload", hexFileUpload
250
                        .isWaitForUploadRequest());
251
        waitForUploadRequestCheck.addActionListener(this);
252
        protocolPanel.add(waitForUploadRequestCheck, gbc);
253
        gbc.gridy++;
254
 
255
        smartModeButton = new JRadioButton(
256
                "Smart Mode - Use feedback from core", hexFileUpload
257
                        .getUploadMode() == HexFileUpload.SMART_MODE);
258
        smartModeButton.addActionListener(this);
259
        protocolPanel.add(smartModeButton, gbc);
260
        gbc.gridy++;
261
 
262
        dumbModeButton = new JRadioButton(
263
                "Manual Mode - Don't use feedback from core", hexFileUpload
264
                        .getUploadMode() == HexFileUpload.DUMB_MODE);
265
        dumbModeButton.addActionListener(this);
266
        protocolPanel.add(dumbModeButton, gbc);
267
        gbc.gridy++;
268
 
269
        buttonGroup = new ButtonGroup();
270
        buttonGroup.add(dumbModeButton);
271
        buttonGroup.add(smartModeButton);
272
 
273
        gbc.insets = new Insets(2, 15, 2, 2);
274
 
275
        JPanel timePanel = new JPanel(new FlowLayout(0, 5, 0));
276
 
277
        delayTimeLabel = new JLabel("Delay between SysEx messages (ms):");
278
        timePanel.add(delayTimeLabel);
279
 
280
        delayTimeSpinner = new JSpinner(new SpinnerNumberModel(hexFileUpload
281
                .getDelayTime(), 10, 2000, 1));
282
        delayTimeSpinner.addChangeListener(this);
283
        timePanel.add(delayTimeSpinner);
284
 
285
        protocolPanel.add(timePanel, gbc);
286
 
287
        gbc.gridy++;
288
 
289
        gbc.weighty = 1.0;
290
        protocolPanel.add(new JPanel(), gbc);
291
 
292
        add(fileButtonsPanel, BorderLayout.PAGE_START);
293
        add(controlPanel, BorderLayout.CENTER);
294
        add(protocolPanel, BorderLayout.EAST);
295
 
296
        updateUploadControls();
297
    }
298
 
299
    public static String getCurrentDirectory() {
300
        return currentDirectory;
301
    }
302
 
303
    public static void setCurrentDirectory(String currentDirectory) {
304
        HexFileUploadGUI.currentDirectory = currentDirectory;
305
    }
306
 
307
    public HexFileUpload getHexFileUpload() {
308
        return hexFileUpload;
309
    }
310
 
311
    protected void onOpenHexFile() {
312
 
313
        if (fc == null) {
314
            fc = new JFileChooser(currentDirectory);
315
            SimpleFileChooserFilter fileFilter = new SimpleFileChooserFilter(
316
                    "Hex files", "hex", "Compliled Hex file");
317
            fc.addChoosableFileFilter(fileFilter);
318
            fc.setAcceptAllFileFilterUsed(false);
319
        }
320
 
321
        File noFile = new File("");
322
        File noFiles[] = { noFile };
323
        fc.setSelectedFile(noFile);
324
        fc.setSelectedFiles(noFiles);
325
 
326
        int nRetVal = fc.showOpenDialog(this);
327
 
328
        if (nRetVal == JFileChooser.APPROVE_OPTION) {
329
            File file = fc.getSelectedFile();
330
            hexFileUpload.setFile(file);
331
            currentDirectory = fc.getCurrentDirectory().toString();
332
        }
333
    }
334
 
335
    public void updateUploadControls() {
336
 
337
        boolean bUploading = (!hexFileUpload.isCancelled() && !hexFileUpload
338
                .isDone());
339
 
340
        deviceIDLabel.setEnabled(!bUploading);
341
        deviceIDSpinner.setEnabled(!bUploading);
342
 
343
        MIOS32Check.setEnabled(!bUploading);
344
 
721 adamjking 345
        if (hexFileUpload.isMIOS32Mode()) {
628 adamjking 346
            smartModeButton.setEnabled(false);
347
            dumbModeButton.setEnabled(false);
348
            waitForUploadRequestCheck.setEnabled(false);
349
            delayTimeLabel.setEnabled(false);
350
            delayTimeSpinner.setEnabled(false);
351
        } else {
352
            smartModeButton.setEnabled(!bUploading);
353
            dumbModeButton.setEnabled(!bUploading);
354
 
355
            waitForUploadRequestCheck.setEnabled(!bUploading);
356
 
357
            delayTimeLabel
358
                    .setEnabled(!bUploading
359
                            && hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
360
 
361
            delayTimeSpinner
362
                    .setEnabled(!bUploading
363
                            && hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
364
        }
365
 
366
        startButton.setEnabled(!bUploading && hexFileUpload.getFile() != null);
367
        stopButton.setEnabled(bUploading);
721 adamjking 368
        queryButton.setEnabled(!bUploading && hexFileUpload.isMIOS32Mode());
628 adamjking 369
    }
370
 
371
    public void stateChanged(ChangeEvent e) {
372
 
373
        Object source = e.getSource();
374
 
375
        if (source == deviceIDSpinner) {
376
            hexFileUpload.setDeviceID(((Integer) deviceIDSpinner.getValue())
377
                    .intValue());
378
 
379
        } else if (source == delayTimeSpinner) {
380
            hexFileUpload.setDelayTime(((Integer) delayTimeSpinner.getValue())
381
                    .intValue());
382
        }
383
    }
384
 
385
    public void actionPerformed(ActionEvent e) {
386
 
387
        String command = e.getActionCommand();
388
        Object source = e.getSource();
389
 
390
        if (command.equals("start")) {
391
            if (hexFileUpload.fileChanged()) {
392
 
393
                int nRet = JOptionPane.showConfirmDialog(null, "The file '"
394
                        + hexFileUpload.getFile().getPath()
395
                        + "' has changed.\n"
396
                        + "Do you wish to reload this file?",
397
                        "File has changed", JOptionPane.YES_NO_OPTION,
398
                        JOptionPane.INFORMATION_MESSAGE, null);
399
 
400
                if (nRet == JOptionPane.YES_OPTION) {
401
                    hexFileUpload.setFile(hexFileUpload.getFile());
402
                }
403
            }
404
 
405
            progressMessageTextArea.setText("");
406
 
407
            Thread t = new Thread() {
408
                public void run() {
409
                    hexFileUpload.createUpload();
410
                }
411
            };
412
 
413
            t.start();
414
 
415
        } else if (command.equals("query")) {
416
            progressMessageTextArea.setText("");
417
 
418
            Thread t = new Thread() {
419
                public void run() {
420
                    hexFileUpload.createQuery();
421
                }
422
            };
423
 
424
            t.start();
425
 
426
        } else if (command.equals("stop")) {
427
            hexFileUpload.cancel();
428
 
429
        } else if (command.equals("browse")) {
430
            onOpenHexFile();
431
 
432
        } else if (source == smartModeButton || source == dumbModeButton) {
433
            hexFileUpload
434
                    .setUploadMode(smartModeButton.isSelected() ? HexFileUpload.SMART_MODE
435
                            : HexFileUpload.DUMB_MODE);
436
 
437
        } else if (source == MIOS32Check) {
721 adamjking 438
            hexFileUpload.setMIOS32Mode(MIOS32Check.isSelected());
628 adamjking 439
 
440
        } else if (source == waitForUploadRequestCheck) {
441
            hexFileUpload.setWaitForUploadRequest(waitForUploadRequestCheck
442
                    .isSelected());
443
        }
444
    }
445
 
446
    public void update(Observable observable, Object object) {
447
        if (observable == hexFileUpload) {
448
            if (object == HexFileUpload.MESSAGES
449
                    || object == HexFileUpload.WORKER) {
450
                while (!hexFileUpload.getMessages().isEmpty()) {
451
                    try {
452
                        String message = (String) hexFileUpload.getMessages()
453
                                .removeFirst();
454
                        StyledDocument doc = progressMessageTextArea
455
                                .getStyledDocument();
456
                        String style = "regular";
457
 
458
                        if (message.startsWith("Error")
459
                                || message.startsWith("Received error")
460
                                || message.endsWith("errors")
461
                                || message.endsWith("Error")) {
462
                            style = "error";
463
                        } else if (message.startsWith("Received")) {
464
                            style = "ack";
465
                        }
466
 
467
                        doc.insertString(doc.getLength(), message + "\n", doc
468
                                .getStyle(style));
469
                        progressMessageTextArea.setCaretPosition(doc
470
                                .getLength());
471
                    } catch (Exception e) {
472
 
473
                    }
474
                }
475
            } else if (object == HexFileUpload.FILE) {
476
                fileName.setText(hexFileUpload.getFile().getPath());
477
 
478
            } else if (object == HexFileUpload.DELAY_TIME) {
479
                delayTimeSpinner.setValue(new Integer(hexFileUpload
480
                        .getDelayTime()));
481
 
482
            } else if (object == HexFileUpload.DEVICE_ID) {
483
                deviceIDSpinner.setValue(new Integer(hexFileUpload
484
                        .getDeviceID()));
485
 
486
            } else if (object == HexFileUpload.UPLOAD_MODE) {
487
                smartModeButton
488
                        .setSelected(hexFileUpload.getUploadMode() == HexFileUpload.SMART_MODE);
489
 
490
                dumbModeButton
491
                        .setSelected(hexFileUpload.getUploadMode() == HexFileUpload.DUMB_MODE);
492
 
493
            } else if (object == HexFileUpload.MIOS32_MODE) {
721 adamjking 494
                MIOS32Check.setSelected(hexFileUpload.isMIOS32Mode());
628 adamjking 495
            } else if (object == HexFileUpload.WAIT_FOR_UPLOAD) {
496
                waitForUploadRequestCheck.setSelected(hexFileUpload
497
                        .isWaitForUploadRequest());
498
            }
499
 
500
            updateUploadControls();
501
        }
502
    }
503
}