Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
628 adamjking 1
/*
2
 * @(#)LCDMessageGUI.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.Font;
26
import java.awt.GridBagConstraints;
27
import java.awt.GridBagLayout;
28
import java.awt.GridLayout;
29
import java.awt.Insets;
30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32
import java.awt.event.FocusAdapter;
33
import java.awt.event.FocusEvent;
34
import java.util.Observable;
35
import java.util.Observer;
36
import java.util.regex.Matcher;
37
import java.util.regex.Pattern;
38
 
39
import javax.swing.ButtonGroup;
40
import javax.swing.JButton;
41
import javax.swing.JCheckBox;
42
import javax.swing.JFormattedTextField;
43
import javax.swing.JLabel;
44
import javax.swing.JPanel;
45
import javax.swing.JRadioButton;
46
import javax.swing.JScrollPane;
47
import javax.swing.JSpinner;
48
import javax.swing.JTextArea;
49
import javax.swing.SpinnerNumberModel;
50
import javax.swing.SwingConstants;
51
import javax.swing.border.BevelBorder;
52
import javax.swing.event.ChangeEvent;
53
import javax.swing.event.ChangeListener;
54
import javax.swing.text.AttributeSet;
55
import javax.swing.text.BadLocationException;
56
import javax.swing.text.PlainDocument;
57
 
58
import org.midibox.mios.LCDMessage;
59
import org.midibox.utils.gui.HexFormatterFactory;
60
 
61
public class LCDMessageGUI extends JPanel implements ActionListener,
62
        ChangeListener, Observer {
63
 
64
    private LCDMessage lcdMessage;
65
 
66
    private JPanel deviceIDPanel;
67
 
68
    private JLabel deviceIDLabel;
69
 
70
    private JSpinner deviceIDSpinner;
71
 
72
    private JPanel lcdPanel;
73
 
74
    private JLabel widthLabel;
75
 
76
    private JLabel heightLabel;
77
 
78
    private JSpinner lcdWidthSpinner;
79
 
80
    private JSpinner lcdHeightSpinner;
81
 
82
    private JTextArea lcdTextArea;
83
 
84
    private JRadioButton clearScreen;
85
 
86
    private JRadioButton currentPos;
87
 
88
    private JRadioButton coOrds;
89
 
90
    private JLabel posXLabel;
91
 
92
    private JLabel posYLabel;
93
 
94
    private JSpinner posX;
95
 
96
    private JSpinner posY;
97
 
98
    private JButton sendMessage;
99
 
100
    private JButton stopMessage;
101
 
102
    private JCheckBox loop;
103
 
104
    public LCDMessageGUI(LCDMessage lcdMessage) {
105
        super(new BorderLayout());
106
 
107
        this.lcdMessage = lcdMessage;
108
        lcdMessage.addObserver(this);
109
 
110
        JScrollPane scrollPane = new JScrollPane(createLCDPanel());
111
        scrollPane
112
                .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
113
        scrollPane
114
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
115
        add(scrollPane, BorderLayout.CENTER);
116
 
117
        updateLCDControls();
118
    }
119
 
120
    private JPanel createLCDPanel() {
121
 
122
        lcdPanel = new JPanel(new GridBagLayout());
123
        lcdPanel.setOpaque(true);
124
        lcdTextArea = new JTextArea(lcdMessage.getLcdHeight(), lcdMessage
125
                .getLcdWidth());
126
        lcdTextArea.setBackground(Color.GREEN);
127
        lcdTextArea.setForeground(Color.BLACK);
128
        lcdTextArea.setBorder(new BevelBorder(BevelBorder.LOWERED));
129
        lcdTextArea.setFont(new Font("Monospaced", Font.BOLD, 20));
130
        lcdTextArea.setLineWrap(false);
131
        lcdTextArea.setWrapStyleWord(false);
132
        lcdTextArea.addFocusListener(new FocusAdapter() {
133
            public void focusLost(FocusEvent fe) {
134
                lcdMessage.setMessageText(lcdTextArea.getText());
135
            }
136
        });
137
 
138
        lcdTextArea.setDocument(new PlainDocument() {
139
 
140
            public void insertString(int off, String text, AttributeSet a)
141
                    throws BadLocationException {
142
 
143
                StringBuffer buffer = new StringBuffer(getText(0, getLength()));
144
 
145
                buffer.insert(off, text);
146
 
147
                Pattern p1 = Pattern.compile("(^)(.+)($)", Pattern.MULTILINE);
148
                Matcher m = p1.matcher(buffer.toString());
149
 
150
                int pos = 0;
151
                int offset = 0;
152
                int length1 = buffer.length();
153
 
154
                while (m.find(pos)) {
155
                    pos = m.end();
156
                    buffer.delete(m.start() + offset, m.end() + offset);
157
                    buffer.insert(m.start() + offset, m.group(1)
158
                            + m.group(2).substring(
159
                                    0,
160
                                    Math.min(m.group(2).length(), lcdMessage
161
                                            .getLcdWidth())) + m.group(3));
162
                    offset = buffer.length() - length1;
163
                }
164
 
165
                p1 = Pattern.compile("\n");
166
                m = p1.matcher(buffer.toString());
167
 
168
                pos = 0;
169
                int noLines = 0;
170
 
171
                while (m.find(pos) && noLines < lcdMessage.getLcdHeight()) {
172
                    noLines++;
173
                    pos = m.end();
174
                }
175
 
176
                if (noLines >= lcdMessage.getLcdHeight()) {
177
                    buffer.delete(pos - 1, buffer.length());
178
                }
179
 
180
                remove(0, getLength());
181
                super.insertString(0, buffer.toString(), a);
182
                lcdTextArea.setCaretPosition(Math.min(getLength(), off
183
                        + text.length()));
184
            }
185
 
186
            public void remove(int offs, int len) throws BadLocationException {
187
                super.remove(offs, len);
188
                lcdTextArea.setText(lcdTextArea.getText());
189
                lcdTextArea.setCaretPosition(offs);
190
            }
191
        });
192
 
193
        JPanel buttonPanel = new JPanel(new GridBagLayout());
194
 
195
        GridBagConstraints gbc = new GridBagConstraints();
196
        gbc.gridx = 0;
197
        gbc.gridy = 0;
198
        gbc.gridwidth = 1;
199
        gbc.gridheight = 1;
200
        gbc.insets = new Insets(4, 4, 4, 4);
201
 
202
        JPanel sizePanel = new JPanel(new GridBagLayout());
203
 
204
        sizePanel.add(widthLabel = new JLabel("LCD Width: "), gbc);
205
        gbc.gridx++;
206
 
207
        lcdWidthSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
208
                .getLcdWidth(), 1, 80, 1));
209
        lcdWidthSpinner.addChangeListener(this);
210
 
211
        sizePanel.add(lcdWidthSpinner, gbc);
212
        gbc.gridx++;
213
 
214
        sizePanel.add(heightLabel = new JLabel(" Height: "), gbc);
215
        gbc.gridx++;
216
 
217
        lcdHeightSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
218
                .getLcdHeight(), 1, 8, 1));
219
        lcdHeightSpinner.addChangeListener(this);
220
        sizePanel.add(lcdHeightSpinner, gbc);
221
 
222
        gbc.gridx = 0;
223
        gbc.anchor = GridBagConstraints.WEST;
224
 
225
        ButtonGroup bg = new ButtonGroup();
226
 
227
        clearScreen = new JRadioButton("Clear Screen",
228
                lcdMessage.getMode() == LCDMessage.CLEAR_SCREEN_MODE);
229
        clearScreen.addActionListener(this);
230
        bg.add(clearScreen);
231
        buttonPanel.add(clearScreen, gbc);
232
        gbc.gridy++;
233
 
234
        currentPos = new JRadioButton("Current Cursor Position", lcdMessage
235
                .getMode() == LCDMessage.CURRENT_POS_MODE);
236
        currentPos.addActionListener(this);
237
        bg.add(currentPos);
238
        buttonPanel.add(currentPos, gbc);
239
        gbc.gridy++;
240
 
241
        coOrds = new JRadioButton("Offset",
242
                lcdMessage.getMode() == LCDMessage.COORDS_MODE);
243
        coOrds.addActionListener(this);
244
        bg.add(coOrds);
245
        buttonPanel.add(coOrds, gbc);
246
        gbc.gridy++;
247
 
248
        gbc.fill = GridBagConstraints.NONE;
249
        JPanel cordsPanel = new JPanel(new GridLayout(2, 2, 4, 4));
250
 
251
        cordsPanel.add(posXLabel = new JLabel("X: ", SwingConstants.RIGHT));
252
        posX = new JSpinner(new SpinnerNumberModel(lcdMessage.getPosX(), 0,
253
                127, 1));
254
        posX.addChangeListener(this);
255
        cordsPanel.add(posX);
256
 
257
        cordsPanel.add(posYLabel = new JLabel("Y: ", SwingConstants.RIGHT));
258
        posY = new JSpinner(new SpinnerNumberModel(lcdMessage.getPosY(), 0,
259
                127, 1));
260
        posY.addChangeListener(this);
261
        cordsPanel.add(posY);
262
 
263
        buttonPanel.add(cordsPanel, gbc);
264
 
265
        gbc.gridwidth = 1;
266
        gbc.gridy++;
267
 
268
        deviceIDPanel = new JPanel(new GridBagLayout());
269
        GridBagConstraints gbc2 = new GridBagConstraints();
270
 
271
        gbc2.gridx = 0;
272
        gbc2.gridy = 0;
273
        gbc2.insets = new Insets(2, 5, 2, 5);
274
        gbc2.weightx = 1.0;
275
        gbc2.fill = GridBagConstraints.HORIZONTAL;
276
 
277
        loop = new JCheckBox("Loop message", lcdMessage.isLoop());
278
        loop.addActionListener(this);
279
        deviceIDPanel.add(loop, gbc2);
280
        gbc2.gridx++;
281
 
282
        gbc2.weightx = 0.0;
283
        gbc2.fill = GridBagConstraints.NONE;
284
 
285
        deviceIDLabel = new JLabel("Device ID:");
286
        deviceIDPanel.add(deviceIDLabel, gbc2);
287
        gbc2.gridx++;
288
 
289
        deviceIDSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
290
                .getDeviceID(), 0, 127, 1));
291
        deviceIDSpinner.addChangeListener(this);
292
 
293
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) deviceIDSpinner
294
                .getEditor();
295
 
296
        JFormattedTextField tf = editor.getTextField();
297
        tf.setFormatterFactory(new HexFormatterFactory());
298
 
299
        deviceIDPanel.add(deviceIDSpinner, gbc2);
300
        gbc2.gridx++;
301
 
302
        gbc.fill = GridBagConstraints.HORIZONTAL;
303
        buttonPanel.add(deviceIDPanel, gbc);
304
        gbc.gridy++;
305
 
306
        JPanel buttons = new JPanel(new GridLayout(1, 2, 4, 4));
307
 
308
        sendMessage = new JButton("Send LCD Message");
309
        sendMessage.addActionListener(this);
310
        buttons.add(sendMessage);
311
 
312
        stopMessage = new JButton("Stop LCD Message");
313
        stopMessage.addActionListener(this);
314
        buttons.add(stopMessage, gbc);
315
 
316
        buttonPanel.add(buttons, gbc);
317
 
318
        gbc.gridx = 0;
319
        gbc.gridy = 0;
320
        gbc.gridwidth = 1;
321
        gbc.gridheight = 1;
322
        gbc.insets = new Insets(4, 4, 4, 4);
323
 
324
        gbc.fill = GridBagConstraints.NONE;
325
        gbc.anchor = GridBagConstraints.CENTER;
326
 
327
        lcdPanel.add(sizePanel, gbc);
328
        gbc.gridy++;
329
 
330
        lcdPanel.add(lcdTextArea, gbc);
331
        gbc.gridy++;
332
 
333
        lcdPanel.add(buttonPanel, gbc);
334
        gbc.gridy++;
335
 
336
        gbc.weighty = 1.0;
337
        gbc.fill = GridBagConstraints.VERTICAL;
338
 
339
        lcdPanel.add(new JPanel(), gbc);
340
 
341
        return lcdPanel;
342
    }
343
 
344
    private void updateLCDControls() {
345
 
346
        boolean isRunning = (!lcdMessage.isCancelled() && !lcdMessage.isDone());
347
 
348
        widthLabel.setEnabled(!isRunning);
349
        lcdWidthSpinner.setEnabled(!isRunning);
350
 
351
        heightLabel.setEnabled(!isRunning);
352
        lcdHeightSpinner.setEnabled(!isRunning);
353
 
354
        lcdTextArea.setEnabled(!isRunning);
355
 
356
        sendMessage.setEnabled(!isRunning);
357
 
358
        clearScreen.setEnabled(!isRunning);
359
 
360
        currentPos.setEnabled(!isRunning);
361
 
362
        coOrds.setEnabled(!isRunning);
363
 
364
        posXLabel.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
365
                && !isRunning);
366
        posX.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
367
                && !isRunning);
368
 
369
        posYLabel.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
370
                && !isRunning);
371
        posY.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
372
                && !isRunning);
373
 
374
        loop.setEnabled(!isRunning);
375
 
376
        deviceIDLabel.setEnabled(!isRunning);
377
        deviceIDSpinner.setEnabled(!isRunning);
378
    }
379
 
380
    public void stateChanged(ChangeEvent ce) {
381
 
382
        Object source = ce.getSource();
383
 
384
        if (source == lcdWidthSpinner) {
385
            lcdMessage.setLcdWidth(((Integer) lcdWidthSpinner.getValue())
386
                    .intValue());
387
 
388
        } else if (source == lcdHeightSpinner) {
389
            lcdMessage.setLcdHeight(((Integer) lcdHeightSpinner.getValue())
390
                    .intValue());
391
 
392
        } else if (source == deviceIDSpinner) {
393
            lcdMessage.setDeviceID(((Integer) deviceIDSpinner.getValue())
394
                    .intValue());
395
 
396
        } else if (source == posX) {
397
            lcdMessage.setPosX(((Integer) posX.getValue()).intValue());
398
 
399
        } else if (source == posY) {
400
            lcdMessage.setPosY(((Integer) posY.getValue()).intValue());
401
 
402
        }
403
    }
404
 
405
    public void actionPerformed(ActionEvent ae) {
406
 
407
        Object source = ae.getSource();
408
 
409
        if (source == lcdTextArea) {
410
            lcdMessage.setMessageText(lcdTextArea.getText());
411
 
412
        } else if (source == clearScreen) {
413
            lcdMessage.setMode(LCDMessage.CLEAR_SCREEN_MODE);
414
 
415
        } else if (source == currentPos) {
416
            lcdMessage.setMode(LCDMessage.CURRENT_POS_MODE);
417
 
418
        } else if (source == coOrds) {
419
            lcdMessage.setMode(LCDMessage.COORDS_MODE);
420
 
421
        } else if (source == loop) {
422
            lcdMessage.setLoop(loop.isSelected());
423
 
424
        } else if (source == sendMessage) {
425
 
426
            Thread t = new Thread() {
427
                public void run() {
428
                    lcdMessage.createMessage();
429
                }
430
            };
431
 
432
            t.start();
433
 
434
        } else if (source == stopMessage) {
435
 
436
            Thread t = new Thread() {
437
                public void run() {
438
 
439
                    lcdMessage.cancelMessage();
440
                }
441
            };
442
 
443
            t.start();
444
        }
445
    }
446
 
447
    public void update(Observable observable, Object object) {
448
 
449
        if (object == LCDMessage.LCD_WIDTH) {
450
            String text = lcdTextArea.getText();
451
            lcdTextArea.setText("");
452
            lcdTextArea.setColumns(lcdMessage.getLcdWidth());
453
            lcdTextArea.setText(text);
454
            lcdPanel.setVisible(false);
455
            lcdPanel.setVisible(true);
456
 
457
        } else if (object == LCDMessage.LCD_HEIGHT) {
458
            String text = lcdTextArea.getText();
459
            lcdTextArea.setText("");
460
            lcdTextArea.setRows(lcdMessage.getLcdHeight());
461
            lcdTextArea.setText(text);
462
            lcdPanel.setVisible(false);
463
            lcdPanel.setVisible(true);
464
 
465
        } else if (object == LCDMessage.MESSAGE_TEXT) {
466
            lcdTextArea.setText(lcdMessage.getMessageText());
467
 
468
        } else if (object == LCDMessage.MODE) {
469
            clearScreen
470
                    .setSelected(lcdMessage.getMode() == LCDMessage.CLEAR_SCREEN_MODE);
471
 
472
            currentPos
473
                    .setSelected(lcdMessage.getMode() == LCDMessage.CURRENT_POS_MODE);
474
 
475
            coOrds.setSelected(lcdMessage.getMode() == LCDMessage.COORDS_MODE);
476
 
477
        } else if (object == LCDMessage.POS_X) {
478
            posX.setValue(new Integer(lcdMessage.getPosX()));
479
 
480
        } else if (object == LCDMessage.POS_Y) {
481
            posY.setValue(new Integer(lcdMessage.getPosY()));
482
 
483
        } else if (object == LCDMessage.LOOP) {
484
            loop.setSelected(lcdMessage.isLoop());
485
 
486
        } else if (object == LCDMessage.DEVICE_ID) {
487
            deviceIDSpinner.setValue(new Integer(lcdMessage.getDeviceID()));
488
 
489
        }
490
 
491
        updateLCDControls();
492
    }
493
}