Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
628 adamjking 1
/*
2
 * @(#)SysexSendReceiveGUI.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.midi.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.GridBagConstraints;
28
import java.awt.GridBagLayout;
29
import java.awt.Insets;
30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32
import java.awt.event.ItemEvent;
33
import java.awt.event.ItemListener;
34
import java.io.File;
35
import java.util.Observable;
36
import java.util.Observer;
845 tk 37
import java.util.StringTokenizer;
846 tk 38
import java.util.LinkedList;
628 adamjking 39
 
40
import javax.swing.BorderFactory;
41
import javax.swing.JButton;
42
import javax.swing.JFileChooser;
43
import javax.swing.JLabel;
44
import javax.swing.JPanel;
45
import javax.swing.JScrollPane;
46
import javax.swing.JSpinner;
47
import javax.swing.JTextField;
48
import javax.swing.JTextPane;
845 tk 49
import javax.swing.JOptionPane;
628 adamjking 50
import javax.swing.SpinnerNumberModel;
51
import javax.swing.event.ChangeEvent;
52
import javax.swing.event.ChangeListener;
53
import javax.swing.text.Style;
54
import javax.swing.text.StyleConstants;
55
import javax.swing.text.StyleContext;
56
import javax.swing.text.StyledDocument;
845 tk 57
import javax.swing.text.Segment;
628 adamjking 58
 
59
import org.midibox.midi.MidiUtils;
60
import org.midibox.midi.SysexSendReceive;
61
import org.midibox.utils.gui.ImageLoader;
62
import org.midibox.utils.gui.SimpleFileChooserFilter;
63
 
64
public class SysexSendReceiveGUI extends JPanel implements ActionListener,
65
        ItemListener, ChangeListener, Observer {
66
 
800 adamjking 67
    private static String currentDirectory = "";
628 adamjking 68
 
69
    private static JFileChooser fc = null;
70
 
71
    private SysexSendReceive sysexSendReceive;
72
 
73
    // GUI components
74
 
846 tk 75
    private JButton sendBrowseButton;
76
    private JTextField sendFileName;
77
    private JButton sendStartButton;
78
    private JButton sendStopButton;
79
    private JButton sendClearButton;
628 adamjking 80
 
846 tk 81
    private JButton receiveBrowseButton;
82
    private JTextField receiveFileName;
83
    private JButton receiveStartButton;
84
    private JButton receiveStopButton;
85
    private JButton receiveClearButton;
628 adamjking 86
 
87
    private JTextPane sysexSendTextArea;
88
 
89
    private JTextPane sysexReceiveTextArea;
90
 
845 tk 91
    private JSpinner sendDelayTimeSpinner;
628 adamjking 92
 
93
    public SysexSendReceiveGUI(SysexSendReceive sysexSendReceive) {
94
        super(new BorderLayout());
95
 
96
        this.sysexSendReceive = sysexSendReceive;
97
        sysexSendReceive.addObserver(this);
98
 
846 tk 99
        sendBrowseButton = new JButton("Open File", ImageLoader
800 adamjking 100
                .getImageIcon("open.png"));
846 tk 101
        sendFileName = new JTextField();
102
        sendFileName.setEditable(false);
103
        sendBrowseButton.setActionCommand("sendBrowse");
104
        sendBrowseButton.addActionListener(this);
628 adamjking 105
 
846 tk 106
        sendStartButton = new JButton("Start");
107
        sendStartButton.setActionCommand("sendStart");
108
        sendStartButton.addActionListener(this);
109
        sendStartButton.setAlignmentX(Component.LEFT_ALIGNMENT);
110
        sendStopButton = new JButton("Stop");
111
        sendStopButton.addActionListener(this);
112
        sendStopButton.setActionCommand("sendStop");
113
        sendStopButton.setAlignmentX(Component.LEFT_ALIGNMENT);
114
        sendClearButton = new JButton("Clear");
115
        sendClearButton.addActionListener(this);
116
        sendClearButton.setActionCommand("sendClear");
117
        sendClearButton.setAlignmentX(Component.LEFT_ALIGNMENT);
628 adamjking 118
 
119
 
846 tk 120
        receiveBrowseButton = new JButton("Save File", ImageLoader
121
                .getImageIcon("open.png"));
122
        receiveFileName = new JTextField();
123
        receiveFileName.setEditable(false);
124
        receiveBrowseButton.setActionCommand("receiveBrowse");
125
        receiveBrowseButton.addActionListener(this);
628 adamjking 126
 
846 tk 127
        receiveStartButton = new JButton("Start");
128
        receiveStartButton.setActionCommand("receiveStart");
129
        receiveStartButton.addActionListener(this);
130
        receiveStartButton.setAlignmentX(Component.LEFT_ALIGNMENT);
131
        receiveStopButton = new JButton("Stop");
132
        receiveStopButton.addActionListener(this);
133
        receiveStopButton.setActionCommand("receiveStop");
134
        receiveStopButton.setAlignmentX(Component.LEFT_ALIGNMENT);
135
        receiveClearButton = new JButton("Clear");
136
        receiveClearButton.addActionListener(this);
137
        receiveClearButton.setActionCommand("receiveClear");
138
        receiveClearButton.setAlignmentX(Component.LEFT_ALIGNMENT);
628 adamjking 139
 
846 tk 140
 
141
 
142
        JPanel sendFileButtonsPanel = new JPanel(new BorderLayout(2, 2));
143
        sendFileButtonsPanel.add(sendBrowseButton, BorderLayout.WEST);
144
        sendFileButtonsPanel.add(sendFileName, BorderLayout.CENTER);
145
        sendFileButtonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
146
 
147
        JPanel sendControlButtonsPanel = new JPanel(new GridBagLayout());
628 adamjking 148
        GridBagConstraints gbc = new GridBagConstraints();
149
        gbc.gridx = 0;
150
        gbc.gridy = 0;
151
        gbc.gridwidth = 1;
152
        gbc.gridheight = 1;
153
 
154
        gbc.insets = new Insets(5, 5, 5, 5);
155
 
846 tk 156
        sendControlButtonsPanel.add(sendStartButton, gbc);
628 adamjking 157
        gbc.gridx++;
158
 
159
        gbc.insets = new Insets(5, 13, 5, 5);
160
 
846 tk 161
        sendControlButtonsPanel.add(sendStopButton, gbc);
628 adamjking 162
        gbc.gridx++;
163
 
846 tk 164
        gbc.insets = new Insets(5, 13, 5, 5);
165
 
166
        sendControlButtonsPanel.add(sendClearButton, gbc);
167
        gbc.gridx++;
168
 
628 adamjking 169
        gbc.insets = new Insets(2, 2, 2, 2);
170
 
171
        gbc.weightx = 1.0;
846 tk 172
        sendControlButtonsPanel.add(new JPanel(), gbc);
628 adamjking 173
        gbc.gridx++;
174
        gbc.weightx = 0.0;
175
 
176
        gbc.fill = GridBagConstraints.NONE;
177
 
846 tk 178
        JLabel label = new JLabel("Delay between SysEx messages (ms): ");
179
        sendControlButtonsPanel.add(label, gbc);
628 adamjking 180
        gbc.gridx++;
181
 
845 tk 182
        sendDelayTimeSpinner = new JSpinner(new SpinnerNumberModel(
183
                sysexSendReceive.getSendDelayTime(), 1, 1000, 1));
184
        sendDelayTimeSpinner.addChangeListener(this);
846 tk 185
        sendControlButtonsPanel.add(sendDelayTimeSpinner, gbc);
628 adamjking 186
 
846 tk 187
 
188
 
189
        JPanel receiveFileButtonsPanel = new JPanel(new BorderLayout(2, 2));
190
        receiveFileButtonsPanel.add(receiveBrowseButton, BorderLayout.WEST);
191
        receiveFileButtonsPanel.add(receiveFileName, BorderLayout.CENTER);
192
        receiveFileButtonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
193
 
194
        JPanel receiveControlButtonsPanel = new JPanel(new GridBagLayout());
195
        gbc.gridx = 0;
196
        gbc.gridy = 0;
197
        gbc.gridwidth = 1;
198
        gbc.gridheight = 1;
199
 
200
        gbc.insets = new Insets(5, 5, 5, 5);
201
 
202
        receiveControlButtonsPanel.add(receiveStartButton, gbc);
203
        gbc.gridx++;
204
        gbc.insets = new Insets(5, 13, 5, 5);
205
        receiveControlButtonsPanel.add(receiveStopButton, gbc);
206
        gbc.gridx++;
207
        receiveControlButtonsPanel.add(receiveClearButton, gbc);
208
 
209
 
210
 
628 adamjking 211
        JPanel sendPanel = new JPanel(new GridBagLayout());
212
 
213
        gbc.fill = GridBagConstraints.BOTH;
214
        gbc.weightx = 1.0;
215
 
216
        sendPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
217
                .createEmptyBorder(2, 2, 2, 2), BorderFactory
218
                .createTitledBorder("Send")));
219
 
220
        sysexSendTextArea = new JTextPane();
221
        sysexSendTextArea.setBackground(Color.WHITE);
845 tk 222
        sysexSendTextArea.setEditable(true);
628 adamjking 223
 
224
        StyledDocument doc = sysexSendTextArea.getStyledDocument();
225
 
226
        Style def = StyleContext.getDefaultStyleContext().getStyle(
227
                StyleContext.DEFAULT_STYLE);
228
 
229
        doc.addStyle("regular", def);
230
        StyleConstants.setFontFamily(def, "Monospaced");
231
 
232
        JScrollPane sysexSendTextAreaScrollPane = new JScrollPane(
233
                sysexSendTextArea);
234
        sysexSendTextAreaScrollPane
235
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
236
 
237
        // Make preferred width smaller than the other panel's minimum width.
238
        sysexSendTextAreaScrollPane.setPreferredSize(new Dimension(300, 100));
239
 
846 tk 240
        gbc.insets = new Insets(5, 5, 5, 5);
241
        gbc.gridy = 0;
242
        gbc.gridx = 0;
243
        sendPanel.add(sendFileButtonsPanel, gbc);
628 adamjking 244
        gbc.gridy++;
245
        gbc.weighty = 1.0;
846 tk 246
        sendPanel.add(sendControlButtonsPanel, gbc);
247
        gbc.gridy++;
248
        gbc.weighty = 1.0;
628 adamjking 249
        sendPanel.add(sysexSendTextAreaScrollPane, gbc);
250
 
846 tk 251
 
628 adamjking 252
        JPanel receivePanel = new JPanel(new GridBagLayout());
253
        receivePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
254
                .createEmptyBorder(2, 2, 2, 2), BorderFactory
255
                .createTitledBorder("Receive")));
256
 
257
        sysexReceiveTextArea = new JTextPane();
258
        sysexReceiveTextArea.setBackground(Color.WHITE);
259
 
845 tk 260
        sysexReceiveTextArea.setEditable(true);
628 adamjking 261
        JScrollPane sysexReceiveTextAreaScrollPane = new JScrollPane(
262
                sysexReceiveTextArea);
263
        sysexReceiveTextAreaScrollPane
264
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
265
 
266
        // Make preferred width smaller than the other panel's minimum width.
267
        sysexReceiveTextAreaScrollPane
268
                .setPreferredSize(new Dimension(300, 100));
269
 
846 tk 270
        gbc.insets = new Insets(5, 5, 5, 5);
628 adamjking 271
        gbc.gridy = 0;
846 tk 272
        gbc.gridx = 0;
273
        gbc.weighty = 1.0;
274
        receivePanel.add(receiveFileButtonsPanel, gbc);
275
        gbc.gridx = 0;
276
        gbc.gridy++;
277
        gbc.weighty = 1.0;
278
        gbc.fill = GridBagConstraints.NONE;
279
        gbc.anchor = GridBagConstraints.WEST;
280
        receivePanel.add(receiveControlButtonsPanel, gbc);
281
        gbc.anchor = GridBagConstraints.CENTER;
282
        gbc.fill = GridBagConstraints.BOTH;
283
        gbc.gridy++;
284
        gbc.weighty = 1.0;
628 adamjking 285
        receivePanel.add(sysexReceiveTextAreaScrollPane, gbc);
286
 
287
        JPanel mainPanel = new JPanel(new GridBagLayout());
288
 
289
        gbc.gridx = 0;
290
        gbc.gridy = 0;
291
        gbc.insets = new Insets(4, 4, 4, 4);
292
 
293
        gbc.weighty = 1.0;
294
        mainPanel.add(sendPanel, gbc);
295
        gbc.gridy++;
296
        mainPanel.add(receivePanel, gbc);
297
 
800 adamjking 298
        add(mainPanel, BorderLayout.CENTER);
628 adamjking 299
 
300
        UIUpdate();
301
    }
302
 
303
    public void UIUpdate() {
846 tk 304
        boolean bUploading = (!sysexSendReceive.isSendCancelled() && !sysexSendReceive.isSendDone());
305
        boolean bReceiving = !sysexSendReceive.isReceiveStopped();
628 adamjking 306
 
846 tk 307
        sendBrowseButton.setEnabled(!bUploading);
308
        sendStartButton.setEnabled(!bUploading);
309
        sendStopButton.setEnabled(bUploading);
310
        sendClearButton.setEnabled(!bUploading);
845 tk 311
        sendDelayTimeSpinner.setEnabled(!bUploading);
312
        sysexSendTextArea.setEnabled(!bUploading);
846 tk 313
 
314
        receiveBrowseButton.setEnabled(!bReceiving);
315
        receiveStartButton.setEnabled(!bReceiving);
316
        receiveStopButton.setEnabled(bReceiving);
317
        //receiveClearButton.setEnabled(!bReceiving); // better to allow clear while receiving
318
        sysexReceiveTextArea.setEnabled(!bReceiving);
628 adamjking 319
    }
320
 
845 tk 321
 
628 adamjking 322
    public void actionPerformed(ActionEvent e) {
846 tk 323
        if (e.getActionCommand() == "sendStart") {
845 tk 324
            byte[] sysexData = new byte[sysexSendReceive.getSendBufferSize()];
325
            int sysexDataOffset = 0;
628 adamjking 326
 
845 tk 327
            StyledDocument doc = sysexSendTextArea.getStyledDocument();
328
            int len = doc.getLength();
329
 
330
            if( len > 0 ) {
331
                int nleft = len;
332
                Segment text = new Segment();
333
                int offs = 0;
334
                text.setPartialReturn(true);  
335
                while (nleft > 0) {
336
                    try {
337
                        doc.getText(offs, nleft, text);
338
                    } catch (Exception ex) {
339
                        JOptionPane.showMessageDialog(null, "Error while parsing hex digits!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
340
                        return;
341
                    }
342
 
343
                    StringTokenizer st = new StringTokenizer(text.toString());
344
                    while (st.hasMoreTokens()) {
345
                        int value;
346
 
347
                        try {
348
                            value = (int)java.lang.Integer.parseInt(st.nextToken(), 16);
349
                            sysexData[sysexDataOffset++] = (byte)value;
350
                        } catch(Exception ex) {
351
                            JOptionPane.showMessageDialog(null, "Found invalid hexadecimal digit!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
352
                            return;
353
                        }
354
                    }
355
 
356
                    nleft -= text.count;
357
                    offs += text.count;
358
                }
359
 
360
                if( sysexDataOffset > 0 ) {
361
                    final byte[] finalSysexData = sysexData;
362
                    final int finalSysexDataOffset = sysexDataOffset;
363
 
364
                    Thread t = new Thread() {
365
                            public void run() {
366
                                sysexSendReceive.startSend(finalSysexData, finalSysexDataOffset);
367
                            }
368
                        };
369
 
370
                    t.start();
371
                }
372
            }
373
 
846 tk 374
        } else if (e.getActionCommand() == "sendStop") {
375
            sysexSendReceive.sendCancel();
628 adamjking 376
 
846 tk 377
        } else if (e.getActionCommand() == "sendClear") {
378
            sysexSendTextArea.setText("");
379
 
380
        } else if (e.getActionCommand() == "sendBrowse") {
628 adamjking 381
            onOpenSysexFile();
846 tk 382
 
383
        } else if (e.getActionCommand() == "receiveStart") {
384
            sysexSendReceive.setReceiveStopped(false);
385
 
386
        } else if (e.getActionCommand() == "receiveStop") {
387
            sysexSendReceive.setReceiveStopped(true);
388
 
389
        } else if (e.getActionCommand() == "receiveClear") {
390
            sysexReceiveTextArea.setText("");
391
 
392
        } else if (e.getActionCommand() == "receiveBrowse") {
393
            onSaveSysexFile();
628 adamjking 394
        }
845 tk 395
 
396
        UIUpdate();
628 adamjking 397
    }
398
 
399
    protected void onOpenSysexFile() {
400
 
401
        if (fc == null) {
402
            fc = new JFileChooser(currentDirectory);
403
            fc.addChoosableFileFilter(new SimpleFileChooserFilter(
846 tk 404
                    "SysEx files (*.syx)", "syx", "SysEx File"));
628 adamjking 405
        }
406
 
407
        File noFile = new File("");
408
        File noFiles[] = { noFile };
409
        fc.setSelectedFile(noFile);
410
        fc.setSelectedFiles(noFiles);
411
 
412
        int nRetVal = fc.showOpenDialog(this);
413
 
414
        if (nRetVal == JFileChooser.APPROVE_OPTION) {
415
            File file = fc.getSelectedFile();
846 tk 416
            sysexSendReceive.setSendFile(file);
628 adamjking 417
            currentDirectory = fc.getCurrentDirectory().toString();
418
        }
419
    }
420
 
846 tk 421
    protected void onSaveSysexFile() {
422
 
423
        if (fc == null) {
424
            fc = new JFileChooser(currentDirectory);
425
            fc.addChoosableFileFilter(new SimpleFileChooserFilter(
426
                    "SysEx files (*.syx)", "syx", "SysEx File"));
427
        }
428
 
429
        File noFile = new File("");
430
        File noFiles[] = { noFile };
431
        fc.setSelectedFile(noFile);
432
        fc.setSelectedFiles(noFiles);
433
 
434
        int nRetVal = fc.showSaveDialog(this);
435
 
436
        if (nRetVal == JFileChooser.APPROVE_OPTION) {
437
            File file = fc.getSelectedFile();
438
            sysexSendReceive.setReceiveFile(file);
439
            currentDirectory = fc.getCurrentDirectory().toString();
440
 
441
            int maxSysexDataLen = 200000; // TODO: find better method... linked list?
442
            byte[] sysexData = new byte[maxSysexDataLen];
443
            int sysexDataOffset = 0;
444
 
445
            StyledDocument doc = sysexReceiveTextArea.getStyledDocument();
446
            int len = doc.getLength();
447
 
448
            if( len > 0 ) {
449
                int nleft = len;
450
                Segment text = new Segment();
451
                int offs = 0;
452
                text.setPartialReturn(true);
453
                while (nleft > 0) {
454
                    try {
455
                        doc.getText(offs, nleft, text);
456
                    } catch (Exception ex) {
457
                        JOptionPane.showMessageDialog(null, "Error while parsing hex digits!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
458
                        return;
459
                    }
460
 
461
                    StringTokenizer st = new StringTokenizer(text.toString());
462
                    while (st.hasMoreTokens()) {
463
                        int value;
464
 
465
                        if( sysexDataOffset >= maxSysexDataLen ) {
466
                            JOptionPane.showMessageDialog(null, "Too many SysEx bytes!", "Parsing Error", JOptionPane.ERROR_MESSAGE);
467
                            return;
468
                        }
469
 
470
                        try {
471
                            value = (int)java.lang.Integer.parseInt(st.nextToken(), 16);
472
                            sysexData[sysexDataOffset++] = (byte)value;
473
                        } catch(Exception ex) {
474
                            JOptionPane.showMessageDialog(null, "Found invalid hexadecimal digit!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
475
                            return;
476
                        }
477
                    }
478
 
479
                    nleft -= text.count;
480
                    offs += text.count;
481
                }
482
 
483
                if( sysexDataOffset > 0 ) {
484
                    if( !sysexSendReceive.writeSysexFile(file, sysexData, sysexDataOffset) ) {
485
                        JOptionPane.showMessageDialog(null, "Error while writing file!", "File Access Error", JOptionPane.ERROR_MESSAGE);
486
                        return;
487
                    }
488
                }
489
            }
490
        }
491
    }
492
 
628 adamjking 493
    public void itemStateChanged(ItemEvent e) {
494
        UIUpdate();
495
    }
496
 
497
    public void stateChanged(ChangeEvent e) {
498
 
845 tk 499
        Object source = e.getSource();
500
 
501
        if (source == sendDelayTimeSpinner) {
502
            sysexSendReceive.setSendDelayTime(((Integer) sendDelayTimeSpinner.getValue()).intValue());
503
        }
504
 
628 adamjking 505
        UIUpdate();
506
    }
507
 
508
    public void update(Observable observable, Object object) {
509
        if (observable == sysexSendReceive) {
845 tk 510
            if (object == sysexSendReceive.WORKER ) {
846 tk 511
            } else if (object == sysexSendReceive.getSendFile()) {
512
                sendFileName.setText(sysexSendReceive.getSendFile().getPath());
628 adamjking 513
                sysexSendTextArea.setText("");
514
                StyledDocument doc = sysexSendTextArea.getStyledDocument();
515
                try {
516
                    doc
517
                            .insertString(0, MidiUtils
518
                                    .getHexString(sysexSendReceive
519
                                            .getSysexFile().getData()), doc
520
                                    .getStyle("regular"));
521
                } catch (Exception e) {
522
                }
523
            } else if (object == sysexSendReceive.getReceivedBytes()) {
846 tk 524
                StyledDocument doc = sysexReceiveTextArea.getStyledDocument();
628 adamjking 525
 
846 tk 526
                LinkedList l = sysexSendReceive.getReceivedBytes();
527
                int i;
528
                for(i=0; i<l.size(); ++i) {
529
                    byte[] data = (byte[])l.get(i);
530
                    try {
531
                        if( doc.getLength() > 0 )
532
                            doc.insertString(doc.getLength(), "\n", doc.getStyle("regular"));
533
                        doc.insertString(doc.getLength(), "F0 ", doc.getStyle("regular"));
534
                        doc.insertString(doc.getLength(), MidiUtils.getHexString(data), doc.getStyle("regular"));
535
                    } catch (Exception e) {
536
                    }
537
                }
538
                sysexSendReceive.clearReceivedBytes();
539
 
540
            } else if (object == sysexSendReceive.getReceiveFile()) {
541
                receiveFileName.setText(sysexSendReceive.getReceiveFile().getPath());
628 adamjking 542
            }
845 tk 543
 
544
            UIUpdate();
628 adamjking 545
        }
546
    }
547
 
548
    public SysexSendReceive getSysexSendReceive() {
549
        return sysexSendReceive;
550
    }
800 adamjking 551
 
552
    public static String getCurrentDirectory() {
553
        return currentDirectory;
554
    }
555
 
556
    public static void setCurrentDirectory(String currentDirectory) {
557
        SysexSendReceiveGUI.currentDirectory = currentDirectory;
558
    }
808 adamjking 559
 
628 adamjking 560
}