KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > ruby > rubyproject > IrbTopComponent


1 package org.netbeans.modules.ruby.rubyproject;
2
3 import java.awt.Color JavaDoc;
4 import java.awt.Font JavaDoc;
5 import java.awt.Insets JavaDoc;
6 import java.awt.Rectangle JavaDoc;
7 import java.awt.event.MouseAdapter JavaDoc;
8 import java.awt.event.MouseEvent JavaDoc;
9 import java.io.PipedInputStream JavaDoc;
10 import java.io.PrintStream JavaDoc;
11 import java.util.ArrayList JavaDoc;
12 import javax.swing.BorderFactory JavaDoc;
13 import javax.swing.JScrollPane JavaDoc;
14 import javax.swing.JTextPane JavaDoc;
15 import javax.swing.SwingUtilities JavaDoc;
16 import javax.swing.SwingUtilities JavaDoc;
17 import javax.swing.text.BadLocationException JavaDoc;
18 import org.jruby.Ruby;
19 import org.jruby.RubyInstanceConfig;
20 import org.jruby.internal.runtime.ValueAccessor;
21 import org.jruby.javasupport.JavaUtil;
22 import org.jruby.runtime.builtin.IRubyObject;
23 import java.io.Serializable JavaDoc;
24 import javax.swing.UIManager JavaDoc;
25 import javax.swing.text.Caret JavaDoc;
26 import org.jruby.demo.TextAreaReadline;
27 import org.netbeans.editor.Settings;
28 import org.netbeans.modules.ruby.rubyproject.api.RubyInstallation;
29 import org.openide.ErrorManager;
30 import org.openide.util.Exceptions;
31 import org.openide.util.NbBundle;
32 import org.openide.util.RequestProcessor;
33 import org.openide.util.Task;
34 import org.openide.util.TaskListener;
35 import org.openide.windows.TopComponent;
36 import org.openide.windows.WindowManager;
37 import org.openide.util.Utilities;
38 import org.netbeans.editor.SettingsNames;
39 import org.netbeans.editor.SettingsUtil;
40 import org.netbeans.editor.SettingsDefaults;
41 import org.netbeans.editor.BaseKit;
42
43 /**
44  * IRB window.
45  * This class is heavily based on IRBConsole in the JRuby distribution,
46  * but changed since IRBConsole extends from JFrame and we want to extend
47  * TopComponent (which is a JPanel).
48  *
49  * @todo Use the equivalent of "jirb -rirb/completion" to get autocompletion?
50  * (include "irb/completion"). See http://jira.codehaus.org/browse/JRUBY-389?page=all
51  * @todo It might be interesting to set the mime type of the embedded
52  * text pane to Ruby, and see if syntax highlighting works. Might
53  * need some tweaks, e.g. a derived mode for shell ruby.
54  * Also, if the TextAreaReadline messes with attributes in the StyledDocument,
55  * we're hosed. The NetBeans editor GuardedDocument implementation does not like that.
56  * @todo Use output2's APIs: AbstractOutputTab - it has a lot of good
57  * logic for keeping the pane scrolled to track output, locking the caret on the
58  * last line, etc.
59  */

60 final class IrbTopComponent extends TopComponent {
61     private boolean finished = true;
62     private JTextPane JavaDoc text;
63
64     private static IrbTopComponent instance;
65     /** path to the icon used by the component and its open action */
66     static final String JavaDoc ICON_PATH = "org/netbeans/modules/ruby/rubyproject/jruby.png"; // NOI18N
67

68     private static final String JavaDoc PREFERRED_ID = "IrbTopComponent"; // NOI18N
69

70     private IrbTopComponent() {
71         initComponents();
72         setName(NbBundle.getMessage(IrbTopComponent.class, "CTL_IrbTopComponent"));
73         setToolTipText(NbBundle.getMessage(IrbTopComponent.class, "HINT_IrbTopComponent"));
74         setIcon(Utilities.loadImage(ICON_PATH, true));
75     }
76
77     /** This method is called from within the constructor to
78      * initialize the form.
79      * WARNING: Do NOT modify this code. The content of this method is
80      * always regenerated by the Form Editor.
81      */

82     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
83
private void initComponents() {
84
85         setLayout(new java.awt.BorderLayout JavaDoc());
86     }// </editor-fold>//GEN-END:initComponents
87

88
89     // Variables declaration - do not modify//GEN-BEGIN:variables
90
// End of variables declaration//GEN-END:variables
91

92     /**
93      * Gets default instance. Do not use directly: reserved for *.settings files only,
94      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
95      * To obtain the singleton instance, use {@link findInstance}.
96      */

97     public static synchronized IrbTopComponent getDefault() {
98         if (instance == null) {
99             instance = new IrbTopComponent();
100         }
101         return instance;
102     }
103
104     /**
105      * Obtain the IrbTopComponent instance. Never call {@link #getDefault} directly!
106      */

107     public static synchronized IrbTopComponent findInstance() {
108         TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
109         if (win == null) {
110             ErrorManager.getDefault().log(ErrorManager.WARNING,
111                     "Cannot find MyWindow component. It will not be located properly in the window system.");
112             return getDefault();
113         }
114         if (win instanceof IrbTopComponent) {
115             return (IrbTopComponent)win;
116         }
117         ErrorManager.getDefault().log(ErrorManager.WARNING,
118                 "There seem to be multiple components with the '" + PREFERRED_ID +
119                 "' ID. That is a potential source of errors and unexpected behavior.");
120         return getDefault();
121     }
122
123     public int getPersistenceType() {
124         return TopComponent.PERSISTENCE_ALWAYS;
125     }
126
127     public void componentOpened() {
128         if (finished) {
129             // Start a new one
130
finished = false;
131             removeAll();
132             createTerminal();
133         }
134     }
135
136     public void componentClosed() {
137         // Leave the terminal session running
138
}
139     
140     @Override JavaDoc
141     public void componentActivated() {
142         // Make the caret visible. See comment under componentDeactivated.
143
if (text != null) {
144             Caret JavaDoc caret = text.getCaret();
145             if (caret != null) {
146                 caret.setVisible(true);
147             }
148         }
149     }
150
151     @Override JavaDoc
152     public void componentDeactivated() {
153         // I have to turn off the caret when the window loses focus. Text components
154
// normally do this by themselves, but the TextAreaReadline component seems
155
// to mess around with the editable property of the text pane, and
156
// the caret will not turn itself on/off for noneditable text areas.
157
if (text != null) {
158             Caret JavaDoc caret = text.getCaret();
159             if (caret != null) {
160                 caret.setVisible(false);
161             }
162         }
163     }
164     
165     /** replaces this in object stream */
166     public Object JavaDoc writeReplace() {
167         return new ResolvableHelper();
168     }
169
170     protected String JavaDoc preferredID() {
171         return PREFERRED_ID;
172     }
173
174     final static class ResolvableHelper implements Serializable JavaDoc {
175         private static final long serialVersionUID = 1L;
176         public Object JavaDoc readResolve() {
177             return IrbTopComponent.getDefault();
178         }
179     }
180
181     public void createTerminal() {
182         final PipedInputStream JavaDoc pipeIn = new PipedInputStream JavaDoc();
183
184         text = new JTextPane JavaDoc();
185
186         text.setMargin(new Insets JavaDoc(8,8,8,8));
187         text.setCaretColor(new Color JavaDoc(0xa4, 0x00, 0x00));
188         text.setBackground(new Color JavaDoc(0xf2, 0xf2, 0xf2));
189         text.setForeground(new Color JavaDoc(0xa4, 0x00, 0x00));
190         
191         // From core/output2/**/AbstractOutputPane
192
Integer JavaDoc i = (Integer JavaDoc) UIManager.get("customFontSize"); //NOI18N
193
int size;
194         if (i != null) {
195             size = i.intValue();
196         } else {
197             Font JavaDoc f = (Font JavaDoc) UIManager.get("controlFont"); // NOI18N
198
size = f != null ? f.getSize() : 11;
199         }
200         text.setFont(new Font JavaDoc ("Monospaced", Font.PLAIN, size)); //NOI18N
201
setBorder (BorderFactory.createEmptyBorder());
202         
203         // Try to initialize colors from NetBeans properties, see core/output2
204
Color JavaDoc c = UIManager.getColor("nb.output.selectionBackground"); // NOI18N
205
if (c != null) {
206             text.setSelectionColor(c);
207         }
208         
209         //Object value = Settings.getValue(BaseKit.class, SettingsNames.CARET_COLOR_INSERT_MODE);
210
//Color caretColor;
211
//if (value instanceof Color) {
212
// caretColor = (Color)value;
213
//} else {
214
// caretColor = SettingsDefaults.defaultCaretColorInsertMode;
215
//}
216
//text.setCaretColor(caretColor);
217
//text.setBackground(UIManager.getColor("text")); //NOI18N
218
//Color selectedFg = UIManager.getColor ("nb.output.foreground.selected"); //NOI18N
219
//if (selectedFg == null) {
220
// selectedFg = UIManager.getColor("textText") == null ? Color.BLACK : //NOI18N
221
// UIManager.getColor("textText"); //NOI18N
222
//}
223
//
224
//Color unselectedFg = UIManager.getColor ("nb.output.foreground"); //NOI18N
225
//if (unselectedFg == null) {
226
// unselectedFg = selectedFg;
227
//}
228
//text.setForeground(unselectedFg);
229
//text.setSelectedTextColor(selectedFg);
230
//
231
//Color selectedErr = UIManager.getColor ("nb.output.err.foreground.selected"); //NOI18N
232
//if (selectedErr == null) {
233
// selectedErr = new Color (164, 0, 0);
234
//}
235
//Color unselectedErr = UIManager.getColor ("nb.output.err.foreground"); //NOI18N
236
//if (unselectedErr == null) {
237
// unselectedErr = selectedErr;
238
//}
239

240         
241         JScrollPane JavaDoc pane = new JScrollPane JavaDoc();
242         pane.setViewportView(text);
243         pane.setBorder(BorderFactory.createLineBorder(Color.darkGray));
244         add(pane);
245         validate();
246
247         final TextAreaReadline tar = new TextAreaReadline(text, " " + // NOI18N
248
NbBundle.getMessage(IrbTopComponent.class, "IrbWelcome") + " \n\n"); // NOI18N
249

250         // Ensure that ClassPath can find libraries etc.
251
RubyInstallation.getInstance().setJRubyLoadPaths();
252
253         final RubyInstanceConfig config = new RubyInstanceConfig() {{
254             setInput(pipeIn);
255             setOutput(new PrintStream JavaDoc(tar));
256             setError(new PrintStream JavaDoc(tar));
257             setObjectSpaceEnabled(false);
258             }};
259         final Ruby runtime = Ruby.newInstance(config);
260
261         IRubyObject argumentArray = runtime.newArray(JavaUtil.convertJavaArrayToRuby(runtime, new String JavaDoc[0]));
262         runtime.defineGlobalConstant("ARGV", argumentArray); // NOI18N
263
runtime.getGlobalVariables().defineReadonly("$*", new ValueAccessor(argumentArray)); // NOI18N
264
runtime.getGlobalVariables().defineReadonly("$$", new ValueAccessor(runtime.newFixnum(System.identityHashCode(runtime)))); // NOI18N
265
runtime.getLoadService().init(new ArrayList JavaDoc());
266
267         tar.hookIntoRuntime(runtime);
268
269         RequestProcessor.Task task = RequestProcessor.getDefault().create(new Runnable JavaDoc() {
270         //RequestProcessor.getDefault().post(new Runnable() {
271
public void run() {
272                 runtime.evalScript("require 'irb'; require 'irb/completion'; IRB.start"); // NOI18N
273
}
274         });
275         task.addTaskListener(new TaskListener() {
276
277             public void taskFinished(Task task) {
278                 finished = true;
279                 //tar.writeMessage(" " + NbBundle.getMessage(IrbTopComponent.class, "IrbGoodbye") + " "); // NOI18N
280
text.setEditable(false);
281                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
282                     public void run() {
283                         IrbTopComponent.this.close();
284                         IrbTopComponent.this.removeAll();
285                         text = null;
286                     }
287                 });
288             }
289         });
290         task.schedule(10);
291         
292         // [Issue 91208] avoid of putting cursor in IRB console on line where is not a prompt
293
text.addMouseListener(new MouseAdapter JavaDoc() {
294            @Override JavaDoc
295            public void mouseClicked(MouseEvent JavaDoc ev) {
296                final int mouseX = ev.getX();
297                final int mouseY = ev.getY();
298                // Ensure that this is done after the textpane's own mouse listener
299
SwingUtilities.invokeLater(new Runnable JavaDoc() {
300                    public void run() {
301                        // Attempt to force the mouse click to appear on the last line of the text input
302
int pos = text.getDocument().getEndPosition().getOffset()-1;
303                        if (pos == -1) {
304                            return;
305                        }
306
307                        try {
308                            Rectangle JavaDoc r = text.modelToView(pos);
309
310                            if (mouseY >= r.y) {
311                                // The click was on the last line; try to set the X to the position where
312
// the user clicked since perhaps it was an attempt to edit the existing
313
// input string. Later I could perhaps cast the text document to a StyledDocument,
314
// then iterate through the document positions and locate the end of the
315
// input prompt (by comparing to the promptStyle in TextAreaReadline).
316
r.x = mouseX;
317                                pos = text.viewToModel(r.getLocation());
318                            }
319
320                            text.getCaret().setDot(pos);
321                        } catch (BadLocationException JavaDoc ble) {
322                            Exceptions.printStackTrace(ble);
323                        }
324                    }
325                });
326            }
327         });
328     }
329     
330     @Override JavaDoc
331     public void requestFocus() {
332         if (text != null) {
333             text.requestFocus();
334         }
335     }
336
337     @Override JavaDoc
338     public boolean requestFocusInWindow() {
339         if (text != null) {
340             return text.requestFocusInWindow();
341         }
342         
343         return false;
344     }
345 }
346
Popular Tags