Subversion Repositories svn.mios

Rev

Rev 873 | Details | Compare with Previous | 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);
732 adamjking 124
 
628 adamjking 125
        lcdTextArea = new JTextArea(lcdMessage.getLcdHeight(), lcdMessage
126
                .getLcdWidth());
738 adamjking 127
 
628 adamjking 128
        lcdTextArea.setBackground(Color.GREEN);
129
        lcdTextArea.setForeground(Color.BLACK);
130
        lcdTextArea.setBorder(new BevelBorder(BevelBorder.LOWERED));
131
        lcdTextArea.setFont(new Font("Monospaced", Font.BOLD, 20));
132
        lcdTextArea.setLineWrap(false);
133
        lcdTextArea.setWrapStyleWord(false);
738 adamjking 134
 
628 adamjking 135
        lcdTextArea.addFocusListener(new FocusAdapter() {
136
            public void focusLost(FocusEvent fe) {
137
                lcdMessage.setMessageText(lcdTextArea.getText());
138
            }
139
        });
140
 
141
        lcdTextArea.setDocument(new PlainDocument() {
142
 
143
            public void insertString(int off, String text, AttributeSet a)
144
                    throws BadLocationException {
145
 
146
                StringBuffer buffer = new StringBuffer(getText(0, getLength()));
147
 
148
                buffer.insert(off, text);
149
 
150
                Pattern p1 = Pattern.compile("(^)(.+)($)", Pattern.MULTILINE);
151
                Matcher m = p1.matcher(buffer.toString());
152
 
153
                int pos = 0;
154
                int offset = 0;
155
                int length1 = buffer.length();
156
 
157
                while (m.find(pos)) {
158
                    pos = m.end();
159
                    buffer.delete(m.start() + offset, m.end() + offset);
160
                    buffer.insert(m.start() + offset, m.group(1)
161
                            + m.group(2).substring(
162
                                    0,
163
                                    Math.min(m.group(2).length(), lcdMessage
164
                                            .getLcdWidth())) + m.group(3));
165
                    offset = buffer.length() - length1;
166
                }
167
 
168
                p1 = Pattern.compile("\n");
169
                m = p1.matcher(buffer.toString());
170
 
171
                pos = 0;
172
                int noLines = 0;
173
 
174
                while (m.find(pos) && noLines < lcdMessage.getLcdHeight()) {
175
                    noLines++;
176
                    pos = m.end();
177
                }
178
 
179
                if (noLines >= lcdMessage.getLcdHeight()) {
180
                    buffer.delete(pos - 1, buffer.length());
181
                }
182
 
183
                remove(0, getLength());
184
                super.insertString(0, buffer.toString(), a);
185
                lcdTextArea.setCaretPosition(Math.min(getLength(), off
186
                        + text.length()));
187
            }
188
 
189
            public void remove(int offs, int len) throws BadLocationException {
190
                super.remove(offs, len);
191
                lcdTextArea.setText(lcdTextArea.getText());
192
                lcdTextArea.setCaretPosition(offs);
193
            }
194
        });
195
 
732 adamjking 196
        String message = lcdMessage.getMessageText();
738 adamjking 197
 
732 adamjking 198
        if (message != null) {
738 adamjking 199
 
732 adamjking 200
            lcdTextArea.setText(message);
201
        }
202
 
628 adamjking 203
        JPanel buttonPanel = new JPanel(new GridBagLayout());
204
 
205
        GridBagConstraints gbc = new GridBagConstraints();
206
        gbc.gridx = 0;
207
        gbc.gridy = 0;
208
        gbc.gridwidth = 1;
209
        gbc.gridheight = 1;
210
        gbc.insets = new Insets(4, 4, 4, 4);
211
 
212
        JPanel sizePanel = new JPanel(new GridBagLayout());
213
 
214
        sizePanel.add(widthLabel = new JLabel("LCD Width: "), gbc);
215
        gbc.gridx++;
216
 
217
        lcdWidthSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
218
                .getLcdWidth(), 1, 80, 1));
219
        lcdWidthSpinner.addChangeListener(this);
220
 
221
        sizePanel.add(lcdWidthSpinner, gbc);
222
        gbc.gridx++;
223
 
224
        sizePanel.add(heightLabel = new JLabel(" Height: "), gbc);
225
        gbc.gridx++;
226
 
227
        lcdHeightSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
228
                .getLcdHeight(), 1, 8, 1));
229
        lcdHeightSpinner.addChangeListener(this);
230
        sizePanel.add(lcdHeightSpinner, gbc);
231
 
232
        gbc.gridx = 0;
233
        gbc.anchor = GridBagConstraints.WEST;
234
 
235
        ButtonGroup bg = new ButtonGroup();
236
 
237
        clearScreen = new JRadioButton("Clear Screen",
238
                lcdMessage.getMode() == LCDMessage.CLEAR_SCREEN_MODE);
239
        clearScreen.addActionListener(this);
240
        bg.add(clearScreen);
241
        buttonPanel.add(clearScreen, gbc);
242
        gbc.gridy++;
243
 
244
        currentPos = new JRadioButton("Current Cursor Position", lcdMessage
245
                .getMode() == LCDMessage.CURRENT_POS_MODE);
246
        currentPos.addActionListener(this);
247
        bg.add(currentPos);
248
        buttonPanel.add(currentPos, gbc);
249
        gbc.gridy++;
250
 
251
        coOrds = new JRadioButton("Offset",
252
                lcdMessage.getMode() == LCDMessage.COORDS_MODE);
253
        coOrds.addActionListener(this);
254
        bg.add(coOrds);
255
        buttonPanel.add(coOrds, gbc);
256
        gbc.gridy++;
257
 
258
        gbc.fill = GridBagConstraints.NONE;
259
        JPanel cordsPanel = new JPanel(new GridLayout(2, 2, 4, 4));
260
 
261
        cordsPanel.add(posXLabel = new JLabel("X: ", SwingConstants.RIGHT));
262
        posX = new JSpinner(new SpinnerNumberModel(lcdMessage.getPosX(), 0,
263
                127, 1));
264
        posX.addChangeListener(this);
265
        cordsPanel.add(posX);
266
 
267
        cordsPanel.add(posYLabel = new JLabel("Y: ", SwingConstants.RIGHT));
268
        posY = new JSpinner(new SpinnerNumberModel(lcdMessage.getPosY(), 0,
269
                127, 1));
270
        posY.addChangeListener(this);
271
        cordsPanel.add(posY);
272
 
273
        buttonPanel.add(cordsPanel, gbc);
274
 
275
        gbc.gridwidth = 1;
276
        gbc.gridy++;
277
 
278
        deviceIDPanel = new JPanel(new GridBagLayout());
279
        GridBagConstraints gbc2 = new GridBagConstraints();
280
 
281
        gbc2.gridx = 0;
282
        gbc2.gridy = 0;
283
        gbc2.insets = new Insets(2, 5, 2, 5);
284
        gbc2.weightx = 1.0;
285
        gbc2.fill = GridBagConstraints.HORIZONTAL;
286
 
287
        loop = new JCheckBox("Loop message", lcdMessage.isLoop());
288
        loop.addActionListener(this);
289
        deviceIDPanel.add(loop, gbc2);
290
        gbc2.gridx++;
291
 
292
        gbc2.weightx = 0.0;
293
        gbc2.fill = GridBagConstraints.NONE;
294
 
295
        deviceIDLabel = new JLabel("Device ID:");
296
        deviceIDPanel.add(deviceIDLabel, gbc2);
297
        gbc2.gridx++;
298
 
299
        deviceIDSpinner = new JSpinner(new SpinnerNumberModel(lcdMessage
300
                .getDeviceID(), 0, 127, 1));
301
        deviceIDSpinner.addChangeListener(this);
302
 
303
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) deviceIDSpinner
304
                .getEditor();
305
 
306
        JFormattedTextField tf = editor.getTextField();
307
        tf.setFormatterFactory(new HexFormatterFactory());
308
 
309
        deviceIDPanel.add(deviceIDSpinner, gbc2);
310
        gbc2.gridx++;
311
 
312
        gbc.fill = GridBagConstraints.HORIZONTAL;
313
        buttonPanel.add(deviceIDPanel, gbc);
314
        gbc.gridy++;
315
 
316
        JPanel buttons = new JPanel(new GridLayout(1, 2, 4, 4));
317
 
318
        sendMessage = new JButton("Send LCD Message");
319
        sendMessage.addActionListener(this);
320
        buttons.add(sendMessage);
321
 
322
        stopMessage = new JButton("Stop LCD Message");
323
        stopMessage.addActionListener(this);
324
        buttons.add(stopMessage, gbc);
325
 
326
        buttonPanel.add(buttons, gbc);
327
 
328
        gbc.gridx = 0;
329
        gbc.gridy = 0;
330
        gbc.gridwidth = 1;
331
        gbc.gridheight = 1;
332
        gbc.insets = new Insets(4, 4, 4, 4);
333
 
334
        gbc.fill = GridBagConstraints.NONE;
335
        gbc.anchor = GridBagConstraints.CENTER;
336
 
337
        lcdPanel.add(sizePanel, gbc);
338
        gbc.gridy++;
339
 
340
        lcdPanel.add(lcdTextArea, gbc);
341
        gbc.gridy++;
342
 
343
        lcdPanel.add(buttonPanel, gbc);
344
        gbc.gridy++;
345
 
346
        gbc.weighty = 1.0;
347
        gbc.fill = GridBagConstraints.VERTICAL;
348
 
349
        lcdPanel.add(new JPanel(), gbc);
350
 
351
        return lcdPanel;
352
    }
353
 
354
    private void updateLCDControls() {
355
 
356
        boolean isRunning = (!lcdMessage.isCancelled() && !lcdMessage.isDone());
357
 
358
        widthLabel.setEnabled(!isRunning);
359
        lcdWidthSpinner.setEnabled(!isRunning);
360
 
361
        heightLabel.setEnabled(!isRunning);
362
        lcdHeightSpinner.setEnabled(!isRunning);
363
 
364
        lcdTextArea.setEnabled(!isRunning);
365
 
366
        sendMessage.setEnabled(!isRunning);
367
 
368
        clearScreen.setEnabled(!isRunning);
369
 
370
        currentPos.setEnabled(!isRunning);
371
 
372
        coOrds.setEnabled(!isRunning);
373
 
374
        posXLabel.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
375
                && !isRunning);
376
        posX.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
377
                && !isRunning);
378
 
379
        posYLabel.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
380
                && !isRunning);
381
        posY.setEnabled(lcdMessage.getMode() == LCDMessage.COORDS_MODE
382
                && !isRunning);
383
 
384
        loop.setEnabled(!isRunning);
385
 
386
        deviceIDLabel.setEnabled(!isRunning);
387
        deviceIDSpinner.setEnabled(!isRunning);
388
    }
389
 
390
    public void stateChanged(ChangeEvent ce) {
391
 
392
        Object source = ce.getSource();
393
 
394
        if (source == lcdWidthSpinner) {
395
            lcdMessage.setLcdWidth(((Integer) lcdWidthSpinner.getValue())
396
                    .intValue());
397
 
398
        } else if (source == lcdHeightSpinner) {
399
            lcdMessage.setLcdHeight(((Integer) lcdHeightSpinner.getValue())
400
                    .intValue());
401
 
402
        } else if (source == deviceIDSpinner) {
403
            lcdMessage.setDeviceID(((Integer) deviceIDSpinner.getValue())
404
                    .intValue());
405
 
406
        } else if (source == posX) {
407
            lcdMessage.setPosX(((Integer) posX.getValue()).intValue());
408
 
409
        } else if (source == posY) {
410
            lcdMessage.setPosY(((Integer) posY.getValue()).intValue());
411
 
412
        }
413
    }
414
 
415
    public void actionPerformed(ActionEvent ae) {
416
 
417
        Object source = ae.getSource();
418
 
419
        if (source == lcdTextArea) {
420
            lcdMessage.setMessageText(lcdTextArea.getText());
421
 
422
        } else if (source == clearScreen) {
423
            lcdMessage.setMode(LCDMessage.CLEAR_SCREEN_MODE);
424
 
425
        } else if (source == currentPos) {
426
            lcdMessage.setMode(LCDMessage.CURRENT_POS_MODE);
427
 
428
        } else if (source == coOrds) {
429
            lcdMessage.setMode(LCDMessage.COORDS_MODE);
430
 
431
        } else if (source == loop) {
432
            lcdMessage.setLoop(loop.isSelected());
433
 
434
        } else if (source == sendMessage) {
435
 
436
            Thread t = new Thread() {
437
                public void run() {
438
                    lcdMessage.createMessage();
439
                }
440
            };
441
 
874 adamjking 442
            // t.setDaemon(true);
628 adamjking 443
            t.start();
444
 
445
        } else if (source == stopMessage) {
446
 
447
            Thread t = new Thread() {
448
                public void run() {
449
 
450
                    lcdMessage.cancelMessage();
451
                }
452
            };
453
 
874 adamjking 454
            // t.setDaemon(true);
628 adamjking 455
            t.start();
456
        }
457
    }
458
 
459
    public void update(Observable observable, Object object) {
460
 
461
        if (object == LCDMessage.LCD_WIDTH) {
462
            String text = lcdTextArea.getText();
463
            lcdTextArea.setText("");
464
            lcdTextArea.setColumns(lcdMessage.getLcdWidth());
465
            lcdTextArea.setText(text);
466
            lcdPanel.setVisible(false);
467
            lcdPanel.setVisible(true);
727 adamjking 468
            lcdWidthSpinner.setValue(lcdMessage.getLcdWidth());
628 adamjking 469
 
470
        } else if (object == LCDMessage.LCD_HEIGHT) {
471
            String text = lcdTextArea.getText();
472
            lcdTextArea.setText("");
473
            lcdTextArea.setRows(lcdMessage.getLcdHeight());
474
            lcdTextArea.setText(text);
475
            lcdPanel.setVisible(false);
476
            lcdPanel.setVisible(true);
727 adamjking 477
            lcdHeightSpinner.setValue(lcdMessage.getLcdHeight());
628 adamjking 478
 
479
        } else if (object == LCDMessage.MESSAGE_TEXT) {
480
            lcdTextArea.setText(lcdMessage.getMessageText());
481
 
482
        } else if (object == LCDMessage.MODE) {
483
            clearScreen
484
                    .setSelected(lcdMessage.getMode() == LCDMessage.CLEAR_SCREEN_MODE);
485
 
486
            currentPos
487
                    .setSelected(lcdMessage.getMode() == LCDMessage.CURRENT_POS_MODE);
488
 
489
            coOrds.setSelected(lcdMessage.getMode() == LCDMessage.COORDS_MODE);
490
 
491
        } else if (object == LCDMessage.POS_X) {
492
            posX.setValue(new Integer(lcdMessage.getPosX()));
493
 
494
        } else if (object == LCDMessage.POS_Y) {
495
            posY.setValue(new Integer(lcdMessage.getPosY()));
496
 
497
        } else if (object == LCDMessage.LOOP) {
498
            loop.setSelected(lcdMessage.isLoop());
499
 
500
        } else if (object == LCDMessage.DEVICE_ID) {
501
            deviceIDSpinner.setValue(new Integer(lcdMessage.getDeviceID()));
502
 
503
        }
504
 
505
        updateLCDControls();
506
    }
507
}