KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > jemacs > swing > SwingBuffer


1 // Copyright (c) 2002 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.jemacs.swing;
5 import java.io.*;
6 import java.lang.reflect.InvocationTargetException JavaDoc;
7
8 import gnu.jemacs.buffer.*;
9 import gnu.mapping.*;
10 import gnu.lists.CharSeq;
11 import javax.swing.text.*;
12 import java.awt.Color JavaDoc;
13
14 /** An Emacs buffer implemented using the Swing toolkits. */
15
16 public class SwingBuffer extends Buffer
17 {
18   public DefaultStyledDocument doc;
19
20   public Caret curPosition = null;
21
22   public BufferContent content;
23   public StyledDocument modelineDocument;
24
25   public static javax.swing.text.StyleContext JavaDoc styles
26   = new javax.swing.text.StyleContext JavaDoc();
27   static public Style defaultStyle = styles.addStyle("default",null);
28   public Style inputStyle = defaultStyle;
29   public static Style redStyle = styles.addStyle("red", null);
30   static Style blueStyle = styles.addStyle("blue", null);
31   static
32   {
33     String JavaDoc version = System.getProperty("java.version");
34     if (version != null
35     && (version.startsWith("1.2") || version.startsWith("1.3")))
36       {
37     StyleConstants.setFontFamily(defaultStyle, "Lucida Sans TypeWriter");
38     StyleConstants.setFontSize(defaultStyle, 14);
39       }
40     StyleConstants.setForeground(redStyle, Color.red);
41     StyleConstants.setForeground(blueStyle, Color.blue);
42   }
43
44   public SwingBuffer(String JavaDoc name)
45   {
46     this(name, new BufferContent());
47   }
48
49   public SwingBuffer(String JavaDoc name, BufferContent content)
50   {
51     super(name);
52     doc = new DefaultStyledDocument(content, styles);
53     this.content = content;
54
55     pointMarker = new Marker(this, 0, true);
56     markMarker = new Marker();
57
58     modelineDocument
59       = new javax.swing.text.DefaultStyledDocument JavaDoc(new javax.swing.text.StringContent JavaDoc(), styles);
60     // Needed for proper bidi (bi-directional text) handling.
61
// Does cause extra overhead, so should perhaps not be default.
62
// Instead only set it if we insert Hebrew/Arabic text? FIXME.
63
doc.putProperty("i18n", Boolean.TRUE);
64     redrawModeline();
65   }
66
67   public void removeRegion (int start, int end)
68     throws javax.swing.text.BadLocationException JavaDoc
69   {
70     doc.remove(start, end - start);
71   }
72
73   public void removeAll ()
74   {
75     try
76       {
77     doc.remove(0, maxDot());
78       }
79     catch (javax.swing.text.BadLocationException JavaDoc ex)
80       {
81     throw new gnu.mapping.WrappedException(ex);
82       }
83   }
84
85   public void removeChar (int count)
86   {
87     remove(getDot(), count);
88   }
89
90   void remove (int point, int count)
91   {
92     try
93       {
94         if (count < 0)
95           {
96             count = - count;
97         if (point - count < minDot())
98           Signal.signal("Beginning of buffer");
99             point -= count;
100           }
101     else
102       {
103         if (point + count > maxDot())
104           Signal.signal("End of buffer");
105       }
106         doc.remove(point, count);
107
108     // Should not be needed, but seems to be. Otherwise, getDot()
109
// returns its *old* value, which is `count' characters too high.
110
// The problem seesm to be that Swing does not properly update
111
// a Windows's caret position when the underlying Document has text
112
// removed. Unfortunately, this fix probably won't do the right
113
// thing for *other windows* that reference the same buffer. FIXME.
114
// (Strangely, the correct thing seems to happen for insertions.)
115
setDot(point);
116       }
117     catch (javax.swing.text.BadLocationException JavaDoc ex)
118       {
119         throw new Error JavaDoc("bad location: "+ex);
120       }
121     //doc.remove(index, count);
122
}
123
124   public void removePos(int ipos, int count)
125   {
126     remove(nextIndex(ipos), count);
127   }
128
129   public void save(Writer out)
130     throws Exception JavaDoc
131   {
132     int length = getLength();
133     int todo = length;
134     Segment segment = new Segment();
135     int offset = 0;
136     while (offset < length)
137       {
138         int count = length;
139         if (count > 4096)
140           count = 4096;
141         doc.getText(offset, count, segment);
142         out.write(segment.array, segment.offset, segment.count);
143         offset += count;
144       }
145   }
146
147   public void insert (char ch, int count)
148   {
149     pointMarker.insert(ch, count, inputStyle);
150   }
151
152   public void insert (int index, String JavaDoc string, Object JavaDoc style)
153   {
154     if (style == null)
155       style = defaultStyle;
156     try
157       {
158         doc.insertString(index, string, (Style) style);
159       }
160     catch (javax.swing.text.BadLocationException JavaDoc ex)
161       {
162         throw new Error JavaDoc("bad location: "+ex);
163       }
164   }
165
166   public void insert (String JavaDoc string, Object JavaDoc style)
167   {
168     insert(getDot(), string ,style);
169   }
170
171   public void insert (String JavaDoc string, Object JavaDoc style, int ipos)
172   {
173     insert (nextIndex(ipos), string, style);
174   }
175
176   public void insertFile(Reader in)
177     throws Exception JavaDoc
178   {
179     char[] buffer = new char[2048];
180     int offset = getDot();
181     for (;;)
182       {
183         int count = in.read(buffer, 0, buffer.length);
184         if (count <= 0)
185           break;
186         doc.insertString(offset, new String JavaDoc(buffer, 0, count), null);
187         offset += count;
188       }
189   }
190
191   public void redrawModeline ()
192   {
193     try
194       {
195         modelineDocument.remove(0, modelineDocument.getLength());
196         
197         modelineDocument.insertString(0, "-----", redStyle);
198         modelineDocument.insertString(modelineDocument.getLength(),
199                                       "JEmacs: " + getName(),
200                                       blueStyle);
201         modelineDocument.insertString(modelineDocument.getLength(),
202                                       " ---",
203                                       redStyle);
204       }
205     catch (javax.swing.text.BadLocationException JavaDoc ex)
206       {
207         throw new Error JavaDoc("internal error in redraw-modeline- "+ex);
208       }
209   }
210
211   public long scan(char target, int start, int end,
212            int count, boolean allowQuit)
213   {
214     if (end == 0)
215       end = count > 0 ? content.length() - 1 : 0;
216     return content.scan(target, start, end, count, allowQuit);
217   }
218
219   public int lineStartOffset(int offset)
220   {
221     return (int) content.scan('\n', offset, minDot(), -1, true);
222   }
223
224   public int getDot()
225   {
226     if (pointMarker.sequence == null)
227       return curPosition.getDot();
228     else
229       return pointMarker.getOffset();
230   }
231
232   public void setDot(int i)
233   {
234     if (i > maxDot())
235       throw new Error JavaDoc("set dot to "+i+ " max:"+maxDot());
236     if (pointMarker.sequence == null)
237       curPosition.setDot(i);
238     else
239       pointMarker.set(this, i);
240   }
241
242   public int maxDot()
243   {
244     // Subtract 1 for the content's final "\n".
245
return content.length() - 1;
246   }
247
248   public int getLength()
249   {
250     return doc.getLength();
251   }
252
253   public CharSeq getStringContent ()
254   {
255     return content.buffer;
256   }
257
258   public int createPos(int index, boolean isAfter)
259   {
260     return content.buffer.createPos(index, isAfter);
261   }
262
263   public Object JavaDoc get (int index)
264   {
265     return content.buffer.get(index);
266   }
267
268   public int size ()
269   {
270     return content.buffer.size();
271   }
272
273   public int nextIndex(int ipos)
274   {
275     return content.buffer.nextIndex(ipos);
276   }
277
278   public long savePointMark ()
279   {
280     int pointPosition = content.buffer.createPos(getDot(), false);
281     int markPosition = 0; // FIXME
282
return ((long) markPosition) << 32 | ((long) pointPosition & 0xffffffffl);
283   }
284
285   public void restorePointMark (long pointMark)
286   {
287     int pointPosition = (int) pointMark;
288     int markPosition = (int) (pointMark >> 32);
289     setDot(content.buffer.nextIndex(pointPosition));
290     content.buffer.releasePos(pointPosition);
291     // Restore mark - FIXME
292
// content.releasePosition(markPosition);
293
}
294
295   public InPort openReader (int start, int count)
296   {
297     return new BufferReader(content.buffer, getName(), start, count);
298   }
299
300   /**
301    * @see gnu.jemacs.buffer.Buffer#invoke(java.lang.Runnable)
302    */

303   public void invoke(Runnable JavaDoc doRun)
304   {
305     try
306     {
307       javax.swing.SwingUtilities.invokeAndWait(doRun);
308     }
309     catch (Exception JavaDoc e)
310     {
311       throw new WrappedException(e);
312     }
313   }
314
315
316 }
317
Popular Tags