KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > terminalemulator > Screen


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is Terminal Emulator.
16  * The Initial Developer of the Original Software is Sun Microsystems, Inc..
17  * Portions created by Sun Microsystems, Inc. are Copyright (C) 2001.
18  * All Rights Reserved.
19  *
20  * Contributor(s): Ivan Soleimanipour.
21  */

22
23 /*
24  * "Screen.java"
25  * Screen.java 1.9 01/07/26
26  */

27
28 package org.netbeans.lib.terminalemulator;
29
30 import java.awt.*;
31 import java.awt.event.*;
32
33 import javax.swing.*;
34 // import javax.swing.FocusManager; // override java.awt.FocusManager if present
35
import javax.accessibility.*;
36 import javax.swing.text.AttributeSet JavaDoc;
37 import javax.swing.text.SimpleAttributeSet JavaDoc;
38 import javax.swing.text.MutableAttributeSet JavaDoc;
39 import javax.swing.text.StyleConstants JavaDoc;
40
41 // We can _almost_ inherit from awt.Canvas, except that then we lose various
42
// very handy abilities:
43
// - Tool tips end up not working right since the AWT Canvas won't cooperate
44
// with our containing JRootPane.
45
// - We loose the ability to use DebugGraphics.
46
// - JComponent does double-buffering for us, so we need not reimplement it.
47
// (there's still an issue of whose double buffering is quicker).
48

49
50 class Screen extends JComponent implements Accessible {
51     private Term term; // back pointer
52

53     private static final boolean debug = false;
54
55     public Screen(Term term, int dx, int dy) {
56     this.term = term;
57     Dimension dim = new Dimension(dx, dy);
58     setSize(dim);
59     setPreferredSize(dim);
60     // setOpaque(true); // see comment in Term.repaint()
61

62     setGrabTab(true);
63
64     if (debug) {
65         // Just turning our double buffering isn't enough, need to
66
// turn it off everywhere.
67
RepaintManager repaintManager = RepaintManager.currentManager(this);
68         repaintManager.setDoubleBufferingEnabled(false);
69
70         setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION |
71                     DebugGraphics.BUFFERED_OPTION |
72                     DebugGraphics.LOG_OPTION);
73     }
74     }
75
76     // debugging hooks:
77

78     /* TMP
79     public void setSize(int width, int height) {
80         super.setSize(width, height);
81     }
82     public void setSize(Dimension dim) {
83         super.setSize(dim);
84     }
85     */

86
87     // When under NB we sometime get resizes when validate() happens
88
// while Term !isShowing() so the sizes are <= 0.
89
// The result is a 1-column output.
90
// In the following we discard "bad" resizes as a workaround.
91

92     public void setBounds(int x, int y, int width, int height) {
93     if (width <= 0 || height <= 0)
94         return;
95     super.setBounds(x, y, width, height);
96     }
97     
98     public void setBounds(Rectangle r) {
99     super.setBounds(r);
100     }
101
102     /**
103      * Allow Tab's to come through to us.
104      * This is deprecated under 1.4 but works runtime-wise.
105      * Once we shipt to building under 1.4 should do things as the comment
106      * below suggests.
107     */

108     public boolean OLD_isManagingFocus() {
109     return true;
110     }
111
112     /* LATER
113
114     This code to be used when we want Term to only see Tab but not CtrlTab.
115     This is easily accomplished by overriding isManagingFocus (in Screen).
116     But that function is deprecated and when we switch to 1.4 as a base
117     we'll have to use the below methodology. There are a lot of new 1.4
118     classes involved so I haven't bothered writing it introspectively.
119
120     Also the below way isn't the best. It assumes that all java
121     implementations will follow the Swing guides for focus traversal keys
122     and that no container of us will modify the set. A better way would be to
123     use a read-modify-write approach where we "subtract" out the keystrokes
124     we want to see. Note though that the Set returned by
125     getFocusTraversalKeys is immutable and you'll need to achieve the
126     subtraction through copying instead of deleting.
127     */

128
129     private java.util.Set JavaDoc original_fwd_keys = null;
130     private java.util.Set JavaDoc original_bwd_keys = null;
131
132
133     private void setGrabTab(boolean grabTab) {
134
135     if (original_fwd_keys == null) {
136         original_fwd_keys = new java.util.HashSet JavaDoc();
137         original_fwd_keys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
138                                    InputEvent.CTRL_MASK));
139         original_bwd_keys = new java.util.HashSet JavaDoc();
140         original_bwd_keys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
141                                    InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
142     }
143
144     if (grabTab) {
145         // install our simplified version allowing Ctrl-TAB to traverse
146
setFocusTraversalKeys(
147         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, original_fwd_keys);
148         setFocusTraversalKeys(
149         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, original_bwd_keys);
150
151     } else {
152         // revert to default
153
setFocusTraversalKeys(
154         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
155         setFocusTraversalKeys(
156         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
157     }
158     }
159
160     public void paint(Graphics g) {
161
162     // No need to double buffer as our caller, the repaint manager,
163
// already does so.
164

165     if (debug) {
166         // HACK, normally, by the time we get the Graphics
167
// the components getComponentGraphics() should've retrieved
168
// a DebugGraphics for us, _but_ it only does that if we have
169
// a 'ui' which we don't, so I have to do this myself.
170
g = new DebugGraphics(g, this);
171     }
172
173     // Let the term do the actual work of rendering
174
term.do_paint(g);
175     }
176
177     public Dimension getMaximumSize() {
178     return new Dimension(1000, 1000);
179     }
180
181     //..........................................................................
182
// Accessibility stuff is all here
183
//..........................................................................
184

185     private AccessibleContext accessible_context;
186
187     private AccessibleScreenText accessible_screen_text;
188
189     public AccessibleContext getAccessibleContext() {
190     if (accessible_context == null) {
191          accessible_context = new AccessibleScreen();
192     }
193     return accessible_context;
194     }
195
196     protected class AccessibleScreenText implements AccessibleText {
197     AccessibleScreenText() {
198     }
199
200     public int getCaretPosition() {
201         return term.CoordToPosition(term.getCursorCoord());
202     }
203
204     // cache for getCharacterAttribute
205
private int last_attr;
206     private MutableAttributeSet JavaDoc last_as;
207
208     public AttributeSet JavaDoc getCharacterAttribute(int index) {
209         Coord c = term.PositionToCoord(index);
210         if (c == null)
211         return null;
212         BCoord b = c.toBCoord(term.firsta);
213         int attr = 0;
214         try {
215         Line l = term.buf.lineAt(b.row);
216         int [] attrs = l.attrArray();
217         attr = attrs[b.col];
218         } catch (Exception JavaDoc x) {
219         ;
220         }
221
222         if (attr == last_attr)
223         return last_as;
224
225         MutableAttributeSet JavaDoc as = new SimpleAttributeSet JavaDoc();
226
227         if ((attr & Attr.UNDERSCORE) == Attr.UNDERSCORE)
228         as.addAttribute(StyleConstants.Underline, Boolean.TRUE);
229         if ((attr & Attr.BRIGHT) == Attr.BRIGHT)
230         as.addAttribute(StyleConstants.Bold, Boolean.TRUE);
231
232         boolean reverse = ((attr & Attr.REVERSE) == Attr.REVERSE);
233
234         Color color;
235         if ((color = term.foregroundColor(reverse, attr)) != Color.black)
236         as.addAttribute(StyleConstants.Foreground, color);
237
238         if ((color = term.backgroundColor(reverse, attr)) != null)
239         as.addAttribute(StyleConstants.Background, color);
240
241         last_attr = attr;
242         last_as = as;
243
244         return as;
245     }
246
247     public Rectangle getCharacterBounds(int index) {
248         return term.getCharacterBounds(term.PositionToCoord(index));
249     }
250
251     public int getCharCount() {
252         return term.getCharCount();
253     }
254
255     public int getSelectionStart() {
256         Extent x = term.getSelectionExtent();
257         if (x == null)
258         return getCaretPosition();
259         return term.CoordToPosition(x.begin);
260     }
261
262     public int getSelectionEnd() {
263         Extent x = term.getSelectionExtent();
264         if (x == null)
265         return getCaretPosition();
266         return term.CoordToPosition(x.end);
267     }
268
269     public String JavaDoc getSelectedText() {
270         return term.getSelectedText();
271     }
272
273
274     private String JavaDoc getHelper(int part, BCoord b) {
275         if (b == null)
276         return null;
277
278         Line l = term.buf.lineAt(b.row);
279
280         switch (part) {
281         case CHARACTER:
282             return new String JavaDoc(l.charArray(), b.col, 1);
283         case WORD:
284             BExtent bword = term.buf.find_word(term.word_delineator, b);
285             Extent word = bword.toExtent(term.firsta);
286             return term.textWithin(word.begin, word.end);
287         case SENTENCE:
288             return new String JavaDoc(l.charArray());
289         }
290         return null;
291     }
292
293     public String JavaDoc getAfterIndex(int part, int index) {
294         Coord c = term.PositionToCoord(index);
295         if (c == null)
296         return null;
297         BCoord b = c.toBCoord(term.firsta);
298         b = term.buf.advance(b);
299         return getHelper(part, b);
300     }
301
302     public String JavaDoc getAtIndex(int part, int index) {
303         Coord c = term.PositionToCoord(index);
304         if (c == null)
305         return null;
306         BCoord b = c.toBCoord(term.firsta);
307         return getHelper(part, b);
308     }
309
310     public String JavaDoc getBeforeIndex(int part, int index) {
311         Coord c = term.PositionToCoord(index);
312         if (c == null)
313         return null;
314         BCoord b = c.toBCoord(term.firsta);
315         b = term.buf.backup(b);
316         return getHelper(part, b);
317     }
318
319     public int getIndexAtPoint(Point p) {
320         BCoord v = term.toViewCoord(p);
321         BCoord b = term.toBufCoords(v);
322         return term.CoordToPosition(new Coord(b, term.firsta));
323     }
324     }
325
326
327     protected class AccessibleScreen extends AccessibleJComponent {
328     public String JavaDoc getAccessibleDescription() {
329         return "Terminal emulator";
330     }
331     public AccessibleRole getAccessibleRole() {
332         return AccessibleRole.TEXT;
333     }
334     public AccessibleText getAccessibleText() {
335         if (accessible_screen_text == null)
336         accessible_screen_text = new AccessibleScreenText();
337         return accessible_screen_text;
338     }
339     }
340
341     private int oldPos;
342
343     void possiblyUpdateCaretText() {
344     /*
345      * Called from Term.putc_work().
346      *
347      * This is very crude. It works on the assumption that Term is just
348      * getting regular characters and on each one we modify the text and
349      * the cursor advances so we fire both simultaneously.
350      */

351
352     // don't bother with this stuff if no-one cares
353
if (accessible_screen_text == null)
354         return;
355
356     int pos = term.CoordToPosition(term.getCursorCoord());
357
358     accessible_context.firePropertyChange(
359         AccessibleContext.ACCESSIBLE_TEXT_PROPERTY,
360         null, new Integer JavaDoc(pos));
361     // sending null, pos is how JTextComponent does it.
362

363     accessible_context.firePropertyChange(
364         AccessibleContext.ACCESSIBLE_CARET_PROPERTY,
365         new Integer JavaDoc(pos), new Integer JavaDoc(oldPos));
366
367     oldPos = pos;
368     }
369 }
370
Popular Tags