/[svn]/jsampler/trunk/src/org/jsampler/view/std/JSLSConsolePane.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/JSLSConsolePane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1786 - (show annotations) (download)
Wed Oct 8 22:38:15 2008 UTC (15 years, 6 months ago) by iliev
File size: 29817 byte(s)
* Implemented option to launch the backend if it is not yet started
  (choose Edit/Preferences, then click the `Backend' tab)
* LSCP scripts can now be run by passing them to jsampler
  as command-line arguments
* The scripts in the `scripts' directory now pass the command-line
  arguments to the respective jsampler distribution
* ant: the default target is now build-fantasia
* bugfix: backend address was always set to 127.0.0.1 when adding
  backend to the backend list

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.std;
24
25 import java.awt.Color;
26 import java.awt.Dimension;
27 import java.awt.Point;
28 import java.awt.Window;
29
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.event.InputEvent;
35 import java.awt.event.KeyEvent;
36 import java.awt.event.MouseAdapter;
37 import java.awt.event.MouseEvent;
38 import java.awt.event.WindowAdapter;
39 import java.awt.event.WindowEvent;
40
41 import java.io.BufferedReader;
42 import java.io.File;
43 import java.io.FileOutputStream;
44 import java.io.FileReader;
45 import java.io.StringReader;
46
47 import java.util.logging.Level;
48
49 import javax.swing.AbstractAction;
50 import javax.swing.Action;
51 import javax.swing.BorderFactory;
52 import javax.swing.Box;
53 import javax.swing.BoxLayout;
54 import javax.swing.JComponent;
55 import javax.swing.JLabel;
56 import javax.swing.JList;
57 import javax.swing.JPanel;
58 import javax.swing.JScrollPane;
59 import javax.swing.JTextField;
60 import javax.swing.JTextPane;
61 import javax.swing.JWindow;
62 import javax.swing.KeyStroke;
63 import javax.swing.ListSelectionModel;
64 import javax.swing.SwingUtilities;
65 import javax.swing.TransferHandler;
66
67 import javax.swing.event.DocumentEvent;
68 import javax.swing.event.DocumentListener;
69
70 import javax.swing.text.Style;
71 import javax.swing.text.StyleConstants;
72 import javax.swing.text.StyleContext;
73 import javax.swing.text.StyledDocument;
74
75 import org.jsampler.CC;
76 import org.jsampler.DefaultLSConsoleModel;
77 import org.jsampler.HF;
78 import org.jsampler.OrchestraInstrument;
79 import org.jsampler.JSPrefs;
80 import org.jsampler.LSConsoleModel;
81 import org.jsampler.LscpUtils;
82
83 import org.jsampler.event.LSConsoleEvent;
84 import org.jsampler.event.LSConsoleListener;
85
86 import static javax.swing.KeyStroke.*;
87 import static org.jsampler.view.std.JSLSConsolePane.*;
88 import static org.jsampler.view.std.StdPrefs.*;
89
90
91 /**
92 *
93 * @author Grigor Iliev
94 */
95 public class JSLSConsolePane extends JPanel {
96 private enum AutocompleteMode { AUTOCOMPLETE, HISTORY_SEARCH, CMD_LIST_SEARCH }
97 private AutocompleteMode autocompleteMode = AutocompleteMode.AUTOCOMPLETE;
98
99 private Window owner;
100
101 private final LSConsoleTextPane console = new LSConsoleTextPane();
102
103 private final JPanel inputPane = new JPanel();
104 private final JLabel lInput = new JLabel();
105 private final JTextField tfSearch = new JTextField();
106 private final CmdLineTextField tfInput = new CmdLineTextField();
107
108 private AutoCompleteWindow autoCompleteWindow;
109
110 private final LSConsoleModel model = new DefaultLSConsoleModel();
111
112 private final StringBuffer consoleText = new StringBuffer();
113
114 private boolean processingSearch = false;
115
116 protected JPanel mainPane = new JPanel();
117
118
119 /**
120 * Creates a new instance of <code>JSLSConsolePane</code>.
121 */
122 public
123 JSLSConsolePane(Window owner) {
124 setOwner(owner);
125 setLayout(new java.awt.BorderLayout());
126
127 int i = preferences().getIntProperty(LS_CONSOLE_HISTSIZE);
128 model.setCommandHistorySize(i);
129
130 loadConsoleHistory();
131
132 mainPane.setOpaque(false);
133 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
134
135 i = preferences().getIntProperty(LS_CONSOLE_BACKGROUND_COLOR);
136 setBackgroundColor(new Color(i));
137
138 i = preferences().getIntProperty(LS_CONSOLE_TEXT_COLOR);
139 setTextColor(new Color(i));
140
141 mainPane.add(new JScrollPane(console));
142
143 inputPane.setLayout(new BoxLayout(inputPane, BoxLayout.X_AXIS));
144 inputPane.setBorder(tfInput.getBorder());
145 tfInput.setBorder(BorderFactory.createEmptyBorder());
146 tfSearch.setBorder(BorderFactory.createEmptyBorder());
147
148 lInput.setOpaque(false);
149 lInput.setVisible(false);
150 inputPane.add(lInput);
151
152 Dimension d = new Dimension(Short.MAX_VALUE, tfSearch.getPreferredSize().height);
153 tfSearch.setMaximumSize(d);
154
155 tfSearch.setVisible(false);
156 tfSearch.setFocusTraversalKeysEnabled(false);
157 inputPane.add(tfSearch);
158
159 d = new Dimension(Short.MAX_VALUE, tfInput.getPreferredSize().height);
160 tfInput.setMaximumSize(d);
161
162 tfInput.setFocusTraversalKeysEnabled(false);
163 inputPane.add(tfInput);
164
165 mainPane.add(inputPane);
166
167 add(mainPane);
168
169 tfInput.addActionListener(getHandler());
170 tfInput.getDocument().addDocumentListener(getHandler());
171 getModel().addLSConsoleListener(getHandler());
172
173 tfSearch.addActionListener(new Actions(Actions.APPLY_SEARCH));
174
175 installKeyboardListeners();
176 }
177
178 private JSPrefs
179 preferences() { return CC.getViewConfig().preferences(); }
180
181 private void
182 installKeyboardListeners() {
183 KeyStroke k = getKeyStroke(KeyEvent.VK_TAB, 0);
184 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.AUTOCOMPLETE);
185 tfInput.getActionMap().put(Actions.AUTOCOMPLETE, new Actions(Actions.AUTOCOMPLETE));
186
187 k = getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK);
188 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.HISTORY_SEARCH);
189 tfInput.getActionMap().put (
190 Actions.HISTORY_SEARCH, new Actions(Actions.HISTORY_SEARCH)
191 );
192
193 k = getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK);
194 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.CMD_LIST_SEARCH);
195 tfInput.getActionMap().put (
196 Actions.CMD_LIST_SEARCH, new Actions(Actions.CMD_LIST_SEARCH)
197 );
198
199 k = getKeyStroke(KeyEvent.VK_UP, 0);
200 tfInput.getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_UP);
201 tfInput.getActionMap().put(Actions.MOVE_UP, new Actions(Actions.MOVE_UP));
202
203 k = getKeyStroke(KeyEvent.VK_DOWN, 0);
204 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_DOWN);
205 tfInput.getActionMap().put(Actions.MOVE_DOWN, new Actions(Actions.MOVE_DOWN));
206
207 k = getKeyStroke(KeyEvent.VK_HOME, 0);
208 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_HOME);
209 tfInput.getActionMap().put(Actions.MOVE_HOME, new Actions(Actions.MOVE_HOME));
210
211 k = getKeyStroke(KeyEvent.VK_END, 0);
212 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_END);
213 tfInput.getActionMap().put(Actions.MOVE_END, new Actions(Actions.MOVE_END));
214
215 k = getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_MASK);
216 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.CLEAR_CONSOLE);
217 tfInput.getActionMap().put (
218 Actions.CLEAR_CONSOLE, new Actions(Actions.CLEAR_CONSOLE)
219 );
220
221 k = getKeyStroke(KeyEvent.VK_ESCAPE, 0);
222 tfInput.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
223 k, Actions.CANCEL_SELECTION
224 );
225 tfInput.getActionMap().put (
226 Actions.CANCEL_SELECTION, new Actions(Actions.CANCEL_SELECTION)
227 );
228
229 k = getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK);
230 tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.QUIT_SESSION);
231 tfInput.getActionMap().put(Actions.QUIT_SESSION, new Actions(Actions.QUIT_SESSION));
232
233
234 k = getKeyStroke(KeyEvent.VK_UP, 0);
235 tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_UP);
236 tfSearch.getActionMap().put(Actions.MOVE_UP, new Actions(Actions.MOVE_UP));
237
238 k = getKeyStroke(KeyEvent.VK_DOWN, 0);
239 tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_DOWN);
240 tfSearch.getActionMap().put(Actions.MOVE_DOWN, new Actions(Actions.MOVE_DOWN));
241
242 k = getKeyStroke(KeyEvent.VK_HOME, 0);
243 tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_HOME);
244 tfSearch.getActionMap().put(Actions.MOVE_HOME, new Actions(Actions.MOVE_HOME));
245
246 k = getKeyStroke(KeyEvent.VK_END, 0);
247 tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_END);
248 tfSearch.getActionMap().put(Actions.MOVE_END, new Actions(Actions.MOVE_END));
249
250 k = getKeyStroke(KeyEvent.VK_ESCAPE, 0);
251 tfSearch.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
252 k, Actions.CANCEL_SEARCH
253 );
254 tfSearch.getActionMap().put (
255 Actions.CANCEL_SEARCH, new Actions(Actions.CANCEL_SEARCH)
256 );
257 }
258
259 public void
260 disconnect() { if(model != null) ((DefaultLSConsoleModel)model).disconnect(); }
261
262 private void
263 loadConsoleHistory() {
264 String s = CC.getJSamplerHome();
265 if(s == null) return;
266
267 File f = new File(s + File.separator + "console_history");
268 if(!f.isFile()) return;
269
270 try {
271 BufferedReader br = new BufferedReader(new FileReader(f));
272 s = br.readLine();
273 while(s != null) {
274 getModel().addToCommandHistory(s);
275 s = br.readLine();
276 }
277 br.close();
278 } catch(Exception x) {
279 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
280 }
281 }
282
283 protected JTextPane
284 getLSConsoleTextPane() { return console; }
285
286 /**
287 * Saves the console history into the <code>console_history</code>
288 * file, located in the JSampler's home directory.
289 */
290 public void
291 saveConsoleHistory() {
292 if(CC.getJSamplerHome() == null) return;
293
294 try {
295 String s = CC.getJSamplerHome() + File.separator + "console_history";
296 FileOutputStream fos = new FileOutputStream(s, false);
297
298 for(String line : getModel().getCommandHistory()) {
299 fos.write(line.getBytes("US-ASCII"));
300 fos.write('\n');
301 }
302
303 fos.close();
304 } catch(Exception x) {
305 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
306 }
307 }
308
309 /**
310 * Delete the <code>console_history</code> file, located in the
311 * JSampler's home directory.
312 */
313 public static void
314 clearConsoleHistory() {
315 String s = CC.getJSamplerHome();
316 if(s == null) return;
317
318 File f = new File(s + File.separator + "console_history");
319 if(f.isFile()) f.delete();
320 }
321
322 /**
323 * Gets the LS Console data model.
324 * @return The LS Console data model.
325 */
326 public LSConsoleModel
327 getModel() { return model; }
328
329 /**
330 * Sets the text color of the LS Console.
331 * @param c The text color of the LS Console.
332 */
333 public void
334 setTextColor(Color c) {
335 console.setTextColor(c);
336
337 lInput.setForeground(c);
338 tfInput.setForeground(c);
339 tfSearch.setForeground(c);
340
341 autoCompleteWindow.setTextColor(c);
342 }
343
344 /**
345 * Gets the text color of the LS Console.
346 * @return The text color of the LS Console.
347 */
348 public Color
349 getTextColor() { return console.getTextColor(); }
350
351 /**
352 * Sets the background color of the LS Console.
353 * @param c The background color of the LS Console.
354 */
355 public void
356 setBackgroundColor(Color c) {
357 console.setBackground(c);
358
359 lInput.setBackground(c);
360 inputPane.setBackground(c);
361 tfInput.setBackground(c);
362 tfSearch.setBackground(c);
363
364 autoCompleteWindow.setBackgroundColor(c);
365 }
366
367 /**
368 * Gets the background color of the LS Console.
369 * @return The background color of the LS Console.
370 */
371 public Color
372 getBackgroundColor() { return console.getBackground(); }
373
374 /**
375 * Sets the notification messages' color.
376 * @param c The notification messages' color.
377 */
378 public void
379 setNotifyColor(Color c) { console.setNotifyColor(c); }
380
381 /**
382 * Sets the warning messages' color.
383 * @param c The warning messages' color.
384 */
385 public void
386 setWarningColor(Color c) { console.setWarningColor(c); }
387
388 /**
389 * Sets the error messages' color.
390 * @param c The error messages' color.
391 */
392 public void
393 setErrorColor(Color c) { console.setErrorColor(c); }
394
395 public class CmdLineTextField extends JTextField {
396 CmdLineTextField() {
397 setTransferHandler(new TransferHandler("instrumentLoad"));
398 }
399
400 public String
401 getInstrumentLoad() { return getSelectedText(); }
402
403 public void setInstrumentLoad(String instr) {
404 if(instr == null) return;
405
406 if(!OrchestraInstrument.isDnDString(instr)) {
407 replaceSelection(instr);
408 return;
409 }
410
411 String[] args = instr.split("\n");
412 if(args.length < 6) return;
413
414 String s = "LOAD INSTRUMENT NON_MODAL '" + args[4] + "' " + args[5] + " ";
415 getModel().setCommandLineText(s);
416 requestFocus();
417 }
418 }
419
420 public void
421 setOwner(Window owner) {
422 if(autoCompleteWindow != null && autoCompleteWindow.isVisible())
423 autoCompleteWindow.setVisible(false);
424
425 autoCompleteWindow = new AutoCompleteWindow(owner);
426
427 if(getOwner() != null) getOwner().removeWindowListener(getHandler());
428 owner.addWindowListener(getHandler());
429
430 this.owner = owner;
431 }
432
433 public Window
434 getOwner() { return owner; }
435
436 /** Hides the autocomplete window. */
437 public void
438 hideAutoCompleteWindow() { autoCompleteWindow.setVisible(false); }
439
440 protected void
441 quitSession() {
442 getModel().clearSessionHistory();
443 console.setText("");
444 }
445
446
447 private final SearchHandler searchHandler = new SearchHandler();
448
449 private SearchHandler
450 getSearchHandler() { return searchHandler; }
451
452 private class SearchHandler implements DocumentListener {
453 // DocumentListener
454 public void
455 insertUpdate(DocumentEvent e) { processSearch(); }
456
457 public void
458 removeUpdate(DocumentEvent e) { processSearch(); }
459
460 public void
461 changedUpdate(DocumentEvent e) { processSearch(); }
462 }
463
464
465 private final Handler eventHandler = new Handler();
466
467 private Handler
468 getHandler() { return eventHandler; }
469
470 private class Handler extends WindowAdapter
471 implements ActionListener, DocumentListener, LSConsoleListener {
472
473 // ActionListener
474 public void
475 actionPerformed(ActionEvent e) {
476 if(autoCompleteWindow.isVisible()) autoCompleteWindow.applySelection();
477 else getModel().execCommand();
478 }
479
480 // DocumentListener
481 public void
482 insertUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
483
484 public void
485 removeUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
486
487 public void
488 changedUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
489
490 // WindowListener
491 public void
492 windowActivated(WindowEvent e) {
493 if(autocompleteMode == AutocompleteMode.AUTOCOMPLETE) {
494 tfInput.requestFocusInWindow();
495 } else tfSearch.requestFocusInWindow();
496 }
497
498 public void
499 windowDeactivated(WindowEvent e) { autoCompleteWindow.setVisible(false); }
500
501 public void
502 windowIconified(WindowEvent e) { autoCompleteWindow.setVisible(false); }
503
504 // LSConsoleListener
505
506 /** Invoked when the text in the command line is changed. */
507 public void
508 commandLineTextChanged(LSConsoleEvent e) {
509 commandChanged(e.getPreviousCommandLineText());
510 }
511
512 /** Invoked when the command in the command line has been executed. */
513 public void
514 commandExecuted(LSConsoleEvent e) {
515 console.addCommand(getModel().getLastExecutedCommand());
516 }
517
518 /** Invoked when response is received from LinuxSampler. */
519 public void
520 responseReceived(LSConsoleEvent e) {
521 console.addCommandResponse(e.getResponse());
522 }
523 }
524
525 private void
526 commandChanged(String oldCmdLine) {
527 if(!tfInput.getText().equals(getModel().getCommandLineText()))
528 tfInput.setText(getModel().getCommandLineText());
529
530 if(LscpUtils.spellCheck(tfInput.getText())) {
531 tfInput.setForeground(console.getTextColor());
532 } else {
533 tfInput.setForeground(console.getErrorColor());
534 if(autoCompleteWindow.isVisible()) autoCompleteWindow.setVisible(false);
535 }
536
537 if(autoCompleteWindow.isVisible()) processAutoComplete(oldCmdLine);
538 }
539
540 private boolean
541 isProcessingSearch() { return processingSearch; }
542
543 private void
544 setProcessingSearch(boolean b) { processingSearch = b; }
545
546 /** Invoked when the tab key is pressed. */
547 private void
548 processAutoComplete() {
549 processAutoComplete(null);
550 }
551
552 private void
553 processAutoComplete(String oldCmdLine) {
554 String cmdLine = getModel().getCommandLineText();
555 switch(autocompleteMode) {
556 case AUTOCOMPLETE:
557
558 break;
559 case HISTORY_SEARCH:
560 case CMD_LIST_SEARCH:
561 if(autoCompleteWindow.isVisible()) return;
562 }
563
564 autocompleteMode = AutocompleteMode.AUTOCOMPLETE;
565
566 final String[] cmdS;
567
568 try {
569 cmdS = LscpUtils.getCompletionPossibilities(cmdLine);
570 } catch(IllegalStateException e) {
571 autoCompleteWindow.setVisible(false);
572 java.awt.Toolkit.getDefaultToolkit().beep();
573 return;
574 }
575
576 if(cmdS.length == 0) {
577 autoCompleteWindow.setVisible(false);
578 return;
579 }
580 if(cmdS.length == 1) {
581 if(oldCmdLine != null && oldCmdLine.startsWith(cmdLine)) return;
582
583 // To prevent IllegalStateException exception.
584 SwingUtilities.invokeLater(new Runnable() {
585 public void
586 run() { tfInput.setText(cmdS[0]); }
587 });
588
589 return;
590 }
591
592 autoCompleteWindow.setCommandList(cmdS);
593 autoCompleteWindow.setVisible(true);
594 }
595
596 private void
597 startHistorySearch() {
598 autocompleteMode = AutocompleteMode.HISTORY_SEARCH;
599 lInput.setText("History Search: ");
600
601 startSearch();
602 }
603
604 private void
605 startCmdListSearch() {
606 autocompleteMode = AutocompleteMode.CMD_LIST_SEARCH;
607 lInput.setText("Command List Search: ");
608
609 startSearch();
610 }
611
612 private void
613 startSearch() {
614 if(!isProcessingSearch())
615 tfSearch.getDocument().addDocumentListener(getSearchHandler());
616
617 setProcessingSearch(true);
618
619 lInput.setVisible(true);
620 tfInput.setVisible(false);
621 tfSearch.setText(getModel().getCommandLineText());
622 tfSearch.setVisible(true);
623 tfSearch.requestFocusInWindow();
624
625 revalidate();
626 repaint();
627
628 processSearch();
629 }
630
631 private void
632 processSearch() {
633 String[] cmdS = null;
634
635 switch(autocompleteMode) {
636 case HISTORY_SEARCH:
637 cmdS = getModel().searchCommandHistory(tfSearch.getText());
638 break;
639 case CMD_LIST_SEARCH:
640 cmdS = getModel().searchCommandList(tfSearch.getText());
641 break;
642 }
643
644 autoCompleteWindow.setCommandList(cmdS);
645 autoCompleteWindow.setVisible(cmdS.length > 0);
646 }
647
648 private void
649 stopSearch(boolean cancelSearch) {
650 setProcessingSearch(false);
651
652 tfSearch.getDocument().removeDocumentListener(getSearchHandler());
653
654 lInput.setVisible(false);
655 lInput.setText("");
656 tfSearch.setVisible(false);
657 tfInput.setVisible(true);
658 tfInput.requestFocusInWindow();
659
660 revalidate();
661 repaint();
662
663 if(cancelSearch) {
664 autoCompleteWindow.setVisible(false);
665 return;
666 }
667
668 if(autoCompleteWindow.isVisible()) autoCompleteWindow.applySelection();
669 else getModel().setCommandLineText(tfSearch.getText());
670 }
671
672
673 protected class Actions extends AbstractAction {
674 public static final String AUTOCOMPLETE = "autocomplete";
675 public static final String HISTORY_SEARCH = "historySearch";
676 public static final String CMD_LIST_SEARCH = "cmdListSearch";
677 public static final String CANCEL_SEARCH = "cancelSearch";
678 public static final String APPLY_SEARCH = "applySearch";
679 public static final String MOVE_UP = "moveUp";
680 public static final String MOVE_DOWN = "moveDown";
681 public static final String MOVE_HOME = "moveHome";
682 public static final String MOVE_END = "moveEnd";
683 public static final String CANCEL_SELECTION = "cancelSelection";
684 public static final String CLEAR_CONSOLE = "clearConsole";
685 public static final String CLEAR_SESSION_HISTORY = "clearSessionHistory";
686 public static final String CLEAR_COMMAND_HISTORY = "clearCommandHistory";
687 public static final String QUIT_SESSION = "quitSession";
688
689 public
690 Actions(String name) { super(name); }
691
692 public void
693 actionPerformed(ActionEvent e) {
694 String key = getValue(Action.NAME).toString();
695
696 if(key == AUTOCOMPLETE) {
697 processAutoComplete();
698 } else if(key == HISTORY_SEARCH) {
699 startHistorySearch();
700 } else if(key == CMD_LIST_SEARCH) {
701 startCmdListSearch();
702 } else if(key == CANCEL_SEARCH) {
703 stopSearch(true);
704 } else if(key == APPLY_SEARCH) {
705 stopSearch(false);
706 } else if(key == MOVE_UP) {
707 if(autoCompleteWindow.isVisible()) {
708 autoCompleteWindow.selectPreviousItem();
709 return;
710 }
711
712 getModel().browseCommandHistoryUp();
713 } else if(key == MOVE_DOWN) {
714 if(autoCompleteWindow.isVisible()) {
715 autoCompleteWindow.selectNextItem();
716 return;
717 }
718
719 getModel().browseCommandHistoryDown();
720 } else if(key == MOVE_HOME) {
721 if(autoCompleteWindow.isVisible()) {
722 autoCompleteWindow.selectFirstItem();
723 return;
724 }
725
726 JTextField tf = tfInput.isVisible() ? tfInput : tfSearch;
727 tf.setCaretPosition(0);
728 } else if(key == MOVE_END) {
729 if(autoCompleteWindow.isVisible()) {
730 autoCompleteWindow.selectLastItem();
731 return;
732 }
733
734 JTextField tf = tfInput.isVisible() ? tfInput : tfSearch;
735 tf.setCaretPosition(tf.getText().length());
736 } else if(key == CANCEL_SELECTION) {
737 autoCompleteWindow.setVisible(false);
738 } else if(key == CLEAR_CONSOLE) {
739 console.setText("");
740 } else if(key == CLEAR_SESSION_HISTORY) {
741 getModel().clearSessionHistory();
742 } else if(key == CLEAR_COMMAND_HISTORY) {
743 getModel().clearCommandHistory();
744 } else if(key == QUIT_SESSION) {
745 quitSession();
746 }
747 }
748 }
749
750 private class AutoCompleteWindow extends JWindow {
751 private int MAX_HEIGHT = 140;
752
753 private JList list = new JList();
754 private JScrollPane scrollPane;
755
756 AutoCompleteWindow(Window owner) {
757 super(owner);
758
759 owner.addComponentListener(getHandler());
760
761 list.addMouseListener(new MouseAdapter() {
762 public void
763 mouseClicked(MouseEvent e) {
764 if(list.getSelectedIndex() != -1) applySelection();
765 }
766 });
767
768 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
769
770 scrollPane = new JScrollPane(list);
771 //sp.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
772 scrollPane.setPreferredSize (
773 new Dimension(scrollPane.getPreferredSize().width, MAX_HEIGHT)
774 );
775 add(scrollPane);
776
777 int i = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
778 getRootPane().getInputMap(i).put (
779 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
780 "applySelection"
781 );
782
783 getRootPane().getActionMap().put ("applySelection", new AbstractAction() {
784 public void
785 actionPerformed(ActionEvent e) { applySelection(); }
786 });
787
788 }
789
790 public void
791 setCommandList(String[] cmdS) {
792 list.setListData(cmdS);
793 if(cmdS.length > 0) list.setSelectedIndex(0);
794
795 int h = list.getPreferredSize().height + 6;
796 if(h > MAX_HEIGHT) h = MAX_HEIGHT;
797 if(h == scrollPane.getSize().height) return;
798
799 scrollPane.setPreferredSize (
800 new Dimension(scrollPane.getPreferredSize().width, h)
801 );
802
803 scrollPane.setMaximumSize (
804 new Dimension(scrollPane.getPreferredSize().width, h)
805 );
806
807 setVisible(false);
808 setSize(getSize().width, h);
809 setVisible(true);
810 }
811
812 public void
813 setVisible(boolean b) {
814 if(b) updateLocation0();
815 super.setVisible(b);
816 }
817
818 public void
819 selectNextItem() {
820 int size = list.getModel().getSize();
821 if(size == 0) return;
822
823 int i = list.getSelectedIndex();
824 if(i == -1 || i == size - 1) list.setSelectedIndex(0);
825 else list.setSelectedIndex(i + 1);
826
827 list.ensureIndexIsVisible(list.getSelectedIndex());
828 }
829
830 public void
831 selectPreviousItem() {
832 int size = list.getModel().getSize();
833 if(size == 0) return;
834
835 int i = list.getSelectedIndex();
836 if(i == -1 || i == 0) list.setSelectedIndex(size - 1);
837 else list.setSelectedIndex(i - 1);
838
839 list.ensureIndexIsVisible(list.getSelectedIndex());
840 }
841
842 public void
843 selectFirstItem() {
844 int size = list.getModel().getSize();
845 if(size == 0) return;
846
847 list.setSelectedIndex(0);
848
849 list.ensureIndexIsVisible(list.getSelectedIndex());
850 }
851
852 public void
853 selectLastItem() {
854 int size = list.getModel().getSize();
855 if(size == 0) return;
856
857 list.setSelectedIndex(size - 1);
858
859 list.ensureIndexIsVisible(list.getSelectedIndex());
860 }
861
862 /**
863 * Sets the text color of the autocompletion list.
864 * @param c The text color of autocompletion list.
865 */
866 public void
867 setTextColor(Color c) {
868 //Object o = list.getCellRenderer();
869 //if(o instanceof JComponent) ((JComponent)o).setForeground(c);
870 list.setForeground(c);
871 }
872
873 /**
874 * Sets the background color of the autocompletion list.
875 * @param c The background color of the autocompletion list.
876 */
877 public void
878 setBackgroundColor(Color c) { list.setBackground(c); }
879
880 private void
881 updateLocation() {
882 if(!isVisible()) return;
883 updateLocation0();
884 }
885
886 private void
887 updateLocation0() {
888 Dimension d;
889 d = new Dimension(inputPane.getSize().width - 6, getSize().height);
890 setPreferredSize(d);
891
892 Point p = inputPane.getLocationOnScreen();
893 pack();
894 setLocation(p.x + 3, p.y - getSize().height);
895 }
896
897 private void
898 applySelection() {
899 Object o = list.getSelectedValue();
900 if(o != null) tfInput.setText(o.toString());
901 setVisible(false);
902 }
903
904 private final Handler eventHandler = new Handler();
905
906 private Handler
907 getHandler() { return eventHandler; }
908
909 private class Handler extends ComponentAdapter {
910
911 // ComponentListener
912 public void
913 componentMoved(ComponentEvent e) { updateLocation(); }
914
915 public void
916 componentResized(ComponentEvent e) { updateLocation(); }
917 }
918 }
919 }
920
921 class LSConsoleTextPane extends JTextPane {
922 private final String STYLE_ROOT = "root";
923 private final String STYLE_REGULAR = "regular";
924 private final String STYLE_BOLD = "bold";
925 private final String STYLE_NOTIFY_0 = "notificationMessage0";
926 private final String STYLE_NOTIFY = "notificationMessage";
927 private final String STYLE_WARN_0 = "warningMessage0";
928 private final String STYLE_WARN = "warningMessage";
929 private final String STYLE_ERROR_0 = "errorMessage0";
930 private final String STYLE_ERROR = "errorMessage";
931
932 private Color cmdColor;
933 private Color notifyColor;
934 private Color warnColor;
935 private Color errorColor;
936
937 LSConsoleTextPane() {
938 int i = preferences().getIntProperty(LS_CONSOLE_TEXT_COLOR);
939 cmdColor = new Color(i);
940
941 i = preferences().getIntProperty(LS_CONSOLE_NOTIFY_COLOR);
942 notifyColor = new Color(i);
943
944 i = preferences().getIntProperty(LS_CONSOLE_ERROR_COLOR);
945 errorColor = new Color(i);
946
947 i = preferences().getIntProperty(LS_CONSOLE_WARNING_COLOR);
948 warnColor = new Color(i);
949
950 Style def;
951 def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
952 StyledDocument doc = getStyledDocument();
953 Style root = doc.addStyle(STYLE_ROOT, def);
954 Style regular = doc.addStyle(STYLE_REGULAR, root);
955
956 Style style = doc.addStyle(STYLE_BOLD, regular);
957 StyleConstants.setBold(style, true);
958
959 style = doc.addStyle(STYLE_NOTIFY_0, regular);
960 StyleConstants.setForeground(style, notifyColor);
961 doc.addStyle(STYLE_NOTIFY, style);
962
963 style = doc.addStyle(STYLE_WARN_0, regular);
964 StyleConstants.setForeground(style, warnColor);
965 doc.addStyle(STYLE_WARN, style);
966
967 style = doc.addStyle(STYLE_ERROR_0, regular);
968 StyleConstants.setForeground(style, errorColor);
969 doc.addStyle(STYLE_ERROR, style);
970
971 setEditable(false);
972 setBorder(BorderFactory.createEmptyBorder());
973
974 }
975
976 private JSPrefs
977 preferences() { return CC.getViewConfig().preferences(); }
978
979 /**
980 * Sets the text color.
981 * @param c The text color.
982 */
983 public void
984 setTextColor(Color c) {
985 cmdColor = c;
986
987 StyledDocument doc = getStyledDocument();
988 Style root = doc.getStyle(STYLE_ROOT);
989 StyleConstants.setForeground(root, cmdColor);
990 }
991
992 /**
993 * Gets the text color of the LS Console.
994 * @return The text color of the LS Console.
995 */
996 public Color
997 getTextColor() { return cmdColor; }
998
999 /**
1000 * Sets the notification messages' color.
1001 * @param c The notification messages' color.
1002 */
1003 public void
1004 setNotifyColor(Color c) {
1005 notifyColor = c;
1006
1007 Style notify = getStyledDocument().getStyle(STYLE_NOTIFY_0);
1008 StyleConstants.setForeground(notify, notifyColor);
1009 }
1010
1011 /**
1012 * Gets the notification messages' color.
1013 * @return The notification messages' color.
1014 */
1015 public Color
1016 getNotifyColor() { return notifyColor; }
1017
1018 /**
1019 * Gets the warning messages' color.
1020 * @return The warning messages' color.
1021 */
1022 public Color
1023 getWarningColor() { return warnColor; }
1024
1025 /**
1026 * Sets the warning messages' color.
1027 * @param c The warning messages' color.
1028 */
1029 public void
1030 setWarningColor(Color c) {
1031 warnColor = c;
1032
1033 Style warn = getStyledDocument().getStyle(STYLE_WARN_0);
1034 StyleConstants.setForeground(warn, warnColor);
1035 }
1036
1037 /**
1038 * Gets the error messages' color.
1039 * @return The error messages' color.
1040 */
1041 public Color
1042 getErrorColor() { return errorColor; }
1043
1044 /**
1045 * Sets the error messages' color.
1046 * @param c The error messages' color.
1047 */
1048 public void
1049 setErrorColor(Color c) {
1050 errorColor = c;
1051
1052 Style error = getStyledDocument().getStyle(STYLE_ERROR_0);
1053 StyleConstants.setForeground(error, errorColor);
1054 }
1055
1056 /**
1057 * Adds the specified command to this text pane.
1058 * @param cmd The command to be added.
1059 */
1060 public void
1061 addCommand(String cmd) {
1062 StyledDocument doc = getStyledDocument();
1063 try {
1064 String s = "lscp> ";
1065 doc.insertString(doc.getLength(), s, doc.getStyle(STYLE_BOLD));
1066 s = cmd + "\n";
1067 doc.insertString(doc.getLength(), s, doc.getStyle(STYLE_REGULAR));
1068 } catch(Exception x) {
1069 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
1070 }
1071 }
1072
1073 /**
1074 * Adds the specified command response to this text pane.
1075 * @param cmd The command response to be added.
1076 */
1077 public void
1078 addCommandResponse(String cmdResponse) {
1079 StyledDocument doc = getStyledDocument();
1080 try {
1081 String s = cmdResponse + "\n";
1082 Style style = doc.getStyle(STYLE_REGULAR);
1083 if(s.startsWith("ERR:")) style = doc.getStyle(STYLE_ERROR);
1084 else if(s.startsWith("WRN:")) style = doc.getStyle(STYLE_WARN);
1085 else if(s.startsWith("NOTIFY:")) style = doc.getStyle(STYLE_NOTIFY);
1086 doc.insertString(doc.getLength(), s, style);
1087 } catch(Exception x) {
1088 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
1089 }
1090 }
1091 }

  ViewVC Help
Powered by ViewVC