View Javadoc
1   /*
2    * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   *
23   */
24  
25  package sun.jvm.hotspot.ui;
26  
27  import java.io.*;
28  import java.awt.*;
29  import java.awt.event.*;
30  import javax.swing.*;
31  import javax.swing.event.*;
32  import javax.swing.text.*;
33  
34  import sun.jvm.hotspot.CommandProcessor;
35  import sun.jvm.hotspot.debugger.*;
36  import sun.jvm.hotspot.utilities.*;
37  
38  /** A JPanel subclass containing a scrollable text area displaying the
39      debugger's console, if it has one. This should not be created for
40      a debugger which does not have a console. */
41  
42  public class CommandProcessorPanel extends JPanel {
43      private CommandProcessor commands;
44      private JTextArea editor;
45      private boolean updating;
46      private int     mark;
47      private String  curText;  // handles multi-line input via '\'
48  
49      // Don't run the "main" method of this class unless this flag is set to true first
50      private static final boolean DEBUGGING = false;
51  
52      ByteArrayOutputStream baos = new ByteArrayOutputStream(10240);
53  
54  
55      public CommandProcessorPanel(CommandProcessor cp) {
56  
57          commands = cp;
58  
59          setLayout(new BorderLayout());
60  
61          editor = new JTextArea();
62          editor.setDocument(new EditableAtEndDocument());
63          editor.setFont(GraphicsUtilities.lookupFont("Courier"));
64          JScrollPane scroller = new JScrollPane();
65          scroller.getViewport().add(editor);
66          add(scroller, BorderLayout.CENTER);
67  
68          // Set up out
69          PrintStream o = new PrintStream(baos, true);
70          cp.setOutput(o);
71          cp.setErr(o);
72  
73          editor.getDocument().addDocumentListener(new DocumentListener() {
74                  public void changedUpdate(DocumentEvent e) {
75                  }
76  
77                  public void insertUpdate(DocumentEvent e) {
78                      if (updating) return;
79                      beginUpdate();
80                      editor.setCaretPosition(editor.getDocument().getLength());
81                      if (insertContains(e, '\n')) {
82                          String cmd = getMarkedText();
83                          // Handle multi-line input
84                          if ((cmd.length() == 0) || (cmd.charAt(cmd.length() - 1) != '\\')) {
85                              // Trim "\\n" combinations
86                              final String ln = trimContinuations(cmd);
87                              SwingUtilities.invokeLater(new Runnable() {
88                                      public void run() {
89                                          beginUpdate();
90                                          try {
91                                              commands.executeCommand(ln, true);
92                                              commands.printPrompt();
93                                              Document d = editor.getDocument();
94                                              try {
95                                                  d.insertString(d.getLength(), baos.toString(), null);
96                                              }
97                                              catch (BadLocationException ble) {
98                                                  ble.printStackTrace();
99                                              }
100                                             baos.reset();
101                                             editor.setCaretPosition(editor.getDocument().getLength());
102                                             setMark();
103                                         } finally {
104                                             endUpdate();
105                                         }
106                                     }
107                                 });
108                         }
109                     } else {
110                         endUpdate();
111                     }
112                 }
113 
114                 public void removeUpdate(DocumentEvent e) {
115                 }
116             });
117 
118         // This is a bit of a hack but is probably better than relying on
119         // the JEditorPane to update the caret's position precisely the
120         // size of the insertion
121         editor.addCaretListener(new CaretListener() {
122                 public void caretUpdate(CaretEvent e) {
123                     int len = editor.getDocument().getLength();
124                     if (e.getDot() > len) {
125                         editor.setCaretPosition(len);
126                     }
127                 }
128             });
129 
130         Box hbox = Box.createHorizontalBox();
131         hbox.add(Box.createGlue());
132         JButton button = new JButton("Clear Saved Text");
133         button.addActionListener(new ActionListener() {
134                 public void actionPerformed(ActionEvent e) {
135                     clear();
136                 }
137             });
138         hbox.add(button);
139         hbox.add(Box.createGlue());
140         add(hbox, BorderLayout.SOUTH);
141 
142         clear();
143     }
144 
145     public void requestFocus() {
146         editor.requestFocus();
147     }
148 
149     public void clear() {
150         EditableAtEndDocument d = (EditableAtEndDocument) editor.getDocument();
151         d.clear();
152         commands.executeCommand("", false);
153         setMark();
154         editor.requestFocus();
155     }
156 
157     public void setMark() {
158         ((EditableAtEndDocument) editor.getDocument()).setMark();
159     }
160 
161     public String getMarkedText() {
162         try {
163             String s = ((EditableAtEndDocument) editor.getDocument()).getMarkedText();
164             int i = s.length();
165             while ((i > 0) && (s.charAt(i - 1) == '\n')) {
166                 i--;
167             }
168             return s.substring(0, i);
169         }
170         catch (BadLocationException e) {
171             e.printStackTrace();
172             return null;
173         }
174     }
175 
176     //--------------------------------------------------------------------------------
177     // Internals only below this point
178     //
179 
180     private void beginUpdate() {
181         updating = true;
182     }
183 
184     private void endUpdate() {
185         updating = false;
186     }
187 
188     private boolean insertContains(DocumentEvent e, char c) {
189         String s = null;
190         try {
191             s = editor.getText(e.getOffset(), e.getLength());
192             for (int i = 0; i < e.getLength(); i++) {
193                 if (s.charAt(i) == c) {
194                     return true;
195                 }
196             }
197         }
198         catch (BadLocationException ex) {
199             ex.printStackTrace();
200         }
201         return false;
202     }
203 
204     private String trimContinuations(String text) {
205         int i;
206         while ((i = text.indexOf("\\\n")) >= 0) {
207             text = text.substring(0, i) + text.substring(i+2, text.length());
208         }
209         return text;
210     }
211 
212     public static void main(String[] args) {
213         JFrame frame = new JFrame();
214         frame.getContentPane().setLayout(new BorderLayout());
215         CommandProcessorPanel panel = new CommandProcessorPanel(null);
216         frame.getContentPane().add(panel, BorderLayout.CENTER);
217         frame.addWindowListener(new WindowAdapter() {
218                 public void windowClosing(WindowEvent e) {
219                     System.exit(0);
220                 }
221             });
222         frame.setSize(500, 500);
223         frame.setVisible(true);
224         panel.requestFocus();
225     }
226 }