KickJava   Java API By Example, From Geeks To Geeks.

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


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 gnu.jemacs.buffer.*;
6
7 import java.awt.event.FocusEvent JavaDoc;
8 import java.awt.event.KeyEvent JavaDoc;
9 import javax.swing.*;
10 import javax.swing.text.*;
11 import java.awt.*;
12 import java.util.Hashtable JavaDoc;
13
14 /** An Emacs window (EWindow) implemented using the Swing toolkits. */
15
16 public class SwingWindow extends EWindow
17 implements java.awt.event.FocusListener JavaDoc,
18   java.awt.event.KeyListener JavaDoc,
19   javax.swing.event.ChangeListener JavaDoc
20 {
21   /* Map JTextPane to SwingWindow. */
22   static Hashtable JavaDoc panemap = new Hashtable JavaDoc();
23
24   JTextPane jtextpane;
25   /** The panel that contains this window and the modeline. */
26   JPanel panel;
27   JScrollPane scrollPane;
28
29   public Modeline modeline;
30
31   public SwingWindow(Buffer buffer)
32   {
33     this(buffer, true);
34   }
35
36   /** Create new Window.
37    * @param buffer the Buffer containing the data.
38    * @param wantModeline true if we should create a mode line
39    */

40   public SwingWindow(Buffer buffer, boolean wantModeline)
41   {
42     super(null);
43     jtextpane = new JTextPane(((SwingBuffer) buffer).doc);
44     panemap.put(jtextpane, this);
45     if (wantModeline)
46       modeline = new Modeline(this, ((SwingBuffer) buffer).modelineDocument);
47     this.buffer = buffer;
48     jtextpane.addFocusListener(this);
49     jtextpane.addKeyListener(this);
50   }
51
52   /** Warp this (and optional modeline) inside a ScrollPane in a new JPanel. */
53   public JPanel wrap()
54   {
55     BorderLayout layout = new BorderLayout();
56     JPanel panel = new JPanel(layout);
57     scrollPane = new JScrollPane(jtextpane,
58                                  JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
59                                  JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
60     panel.add(scrollPane, BorderLayout.CENTER);
61     if (modeline != null)
62       panel.add(modeline, BorderLayout.SOUTH);
63     this.panel = panel;
64     return panel;
65   }
66
67   /** Get the JPanel containing this Window. */
68   public JPanel getPanel()
69   {
70     return panel;
71   }
72
73   public void focusGained(FocusEvent JavaDoc e)
74   {
75     setSelected();
76   }
77
78   public void focusLost(FocusEvent JavaDoc e)
79   {
80   }
81
82   public void requestFocus()
83   {
84     jtextpane.requestFocus();
85   }
86
87   public void setBuffer (Buffer buffer)
88   {
89     if (this.buffer == buffer)
90       return;
91
92     super.setBuffer(buffer);
93     jtextpane.setDocument(((SwingBuffer) buffer).doc);
94     if (modeline != null)
95       modeline.setDocument(((SwingBuffer) buffer).modelineDocument);
96     EWindow selected = getSelected();
97     if (selected == this)
98       {
99     unselect();
100     // Change buffer's pointMarker so it follows this EWindow's Caret.
101
Caret caret = jtextpane.getCaret();
102     caret.setDot(buffer.getDot());
103     select(caret);
104       }
105   }
106
107   public void unselect()
108   {
109     Caret caret = ((SwingBuffer) buffer).curPosition;
110     if (caret == null)
111       return;
112     int point = caret.getDot();
113     int index = ((SwingBuffer) buffer).content.buffer.createPos(point, true);
114     buffer.pointMarker.ipos = index;
115     ((SwingBuffer) buffer).curPosition = null;
116     jtextpane.getCaret().removeChangeListener(this);
117     // ?? selected = null;
118
}
119
120   public void setSelected()
121   {
122     super.setSelected();
123     select(jtextpane.getCaret());
124   }
125
126   public int getPoint()
127   {
128     return 1 + jtextpane.getCaret().getDot();
129   }
130
131   public void setDot(int offset)
132   {
133     jtextpane.getCaret().setDot(offset);
134   }
135
136   public EWindow split (Buffer buffer, int lines, boolean horizontal)
137   {
138     SwingWindow window = new SwingWindow(buffer);
139     EFrame frame = this.frame;
140     window.frame = frame;
141     linkSibling(window, horizontal);
142     window.modeline = new Modeline(window, ((SwingBuffer) buffer).modelineDocument);
143
144     JPanel panel = this.getPanel();
145     java.awt.Dimension JavaDoc oldSize = panel.getSize();
146     java.awt.Container JavaDoc oldParent = panel.getParent();
147     oldParent.remove(panel);
148     JSplitPane split
149       = new JSplitPane(horizontal ? JSplitPane.HORIZONTAL_SPLIT
150                        : JSplitPane.VERTICAL_SPLIT,
151                        panel, window.wrap());
152     split.setDividerSize(2);
153     // FIXME - use lines.
154
split.setDividerLocation((horizontal ? oldSize.width : oldSize.height) / 2);
155     oldParent.add(split);
156     oldParent.validate();
157     if (this == EWindow.getSelected())
158       this.requestFocus();
159     return window;
160   }
161
162   private void select(Caret caret)
163   {
164     // Change buffer's pointMarker so it follows this EWindow's Caret.
165
((SwingBuffer) buffer).curPosition = caret;
166     if (! buffer.pointMarker.isPoint())
167       ((SwingBuffer) buffer).content.buffer.releasePos(buffer.pointMarker.ipos);
168     buffer.pointMarker.sequence = null;
169     caret.addChangeListener(this);
170   }
171
172   public void stateChanged(javax.swing.event.ChangeEvent JavaDoc e)
173   {
174     Object JavaDoc source = e.getSource();
175     if (source instanceof Caret && buffer != null)
176       {
177     Caret caret = (Caret) source;
178     int mark = caret.getMark();
179     int dot = caret.getDot();
180     if (mark != dot)
181       {
182         buffer.markMarker.set(buffer, mark);
183       }
184       }
185   }
186
187   public static JTextPane getContainedWindow(Container cont, boolean last)
188   {
189     for (;;)
190       {
191         if (cont instanceof JTextPane)
192           return (JTextPane) cont;
193         if (cont instanceof JScrollPane)
194           cont = (Container) ((JScrollPane) cont).getViewport().getView();
195         else if (cont instanceof JFrame)
196           cont = ((JFrame) cont).getContentPane();
197         else if (cont instanceof JSplitPane)
198           {
199             JSplitPane split = (JSplitPane) cont;
200             cont = (Container)
201               (last ? split.getRightComponent() : split.getLeftComponent());
202           }
203         else
204           {
205             int count = cont.getComponentCount();
206             if (count == 0)
207               return null;
208             cont = (Container) cont.getComponent(last ? (count - 1) : 0);
209           }
210       }
211   }
212
213   /*
214   public SwingWindow getNextWindow(boolean forwards)
215   {
216     Container prev = this;
217     for (;;)
218       {
219         Container parent = prev.getParent();
220         if (parent == null)
221           return null;
222         if (parent instanceof JSplitPane)
223           {
224             JSplitPane split =(JSplitPane) parent;
225             if (prev == split.getLeftComponent())
226               {
227                 if (forwards)
228                   return getFirstWindow((Container) split.getRightComponent());
229               }
230             else // prev == split.getRightComponent():
231               {
232                 if (!forwards)
233                   return getLastWindow((Container) split.getLeftComponent());
234               }
235           }
236         prev = parent;
237       }
238   }
239   */

240
241   public static SwingWindow getWindow(java.awt.event.ActionEvent JavaDoc event)
242   {
243     // Maybe use TextAction.getTextComponent instead? FIXME.
244
Component component = (Component) event.getSource();
245     for (;;)
246       {
247         if (component instanceof JTextPane)
248           return (SwingWindow) panemap.get(component);
249         component = component.getParent();
250       }
251   }
252
253   protected void deleteNoValidate()
254   {
255     super.deleteNoValidate();
256     if (modeline != null)
257       panel.remove(modeline);
258     panel.remove(scrollPane);
259
260     // Mow remove the Panel from its parent.
261
Container oldParent = panel.getParent();
262     if (oldParent instanceof JSplitPane)
263       {
264         JSplitPane split = (JSplitPane) oldParent;
265         Component other;
266         if (panel == split.getLeftComponent())
267           other = split.getRightComponent();
268         else
269           other = split.getLeftComponent();
270         split.remove(jtextpane);
271         split.remove(other);
272         // In the JSplitPane's parent, replace the JSplitPane by just other
273
Container splitParent = split.getParent();
274         if (splitParent instanceof JSplitPane)
275           {
276             JSplitPane outerSplit = (JSplitPane) splitParent;
277             if (split == outerSplit.getLeftComponent())
278               outerSplit.setLeftComponent(other);
279             else
280               outerSplit.setRightComponent(other);
281           }
282         else
283           {
284             splitParent.remove(split);
285             splitParent.add(other);
286           }
287       }
288     else
289       oldParent.remove(panel);
290
291     panemap.remove(jtextpane);
292     jtextpane = null;
293     panel = null;
294     scrollPane = null;
295   }
296
297   public void activateRegion ()
298   {
299     System.err.println("(activateRegions)");
300     Caret caret = jtextpane.getCaret();
301     caret.setDot(buffer.markMarker.getOffset());
302     caret.moveDot(buffer.getDot());
303   }
304
305   public Dimension getPreferredScrollableViewportSize()
306   {
307     Dimension size = panel.getSize();
308     if (modeline != null)
309       size = new Dimension(size.width,
310                        size.height - modeline.getPreferredSize().height);
311     return size;
312   }
313
314   protected void getCharSize()
315   {
316     java.awt.Font JavaDoc defaultFont
317       = ((SwingBuffer) buffer).doc.getFont(SwingBuffer.defaultStyle);
318     java.awt.FontMetrics JavaDoc fm
319       = jtextpane.getGraphics().getFontMetrics(defaultFont);
320     charHeight = fm.getHeight();
321     charWidth = fm.charWidth('m');
322   }
323
324   public int getWidth ()
325   {
326     return jtextpane.getWidth();
327   }
328
329   public int getHeight ()
330   {
331     return jtextpane.getWidth();
332   }
333
334   public void keyTyped(KeyEvent JavaDoc e)
335   {
336     handle(e, toInt(e, 0));
337   }
338
339   public void keyPressed(KeyEvent JavaDoc e)
340   {
341     handle(e, toInt(e, EKeymap.PRESSED));
342   }
343
344   public void keyReleased(KeyEvent JavaDoc e)
345   {
346     handle(e, toInt(e, EKeymap.RELEASED));
347   }
348
349   protected void handle(KeyEvent JavaDoc e, int code)
350   {
351     Object JavaDoc action = lookupKey(code);
352
353     pushPrefix(code);
354     pendingLength--;
355
356     if (action == null || action instanceof IgnoreAction)
357       {
358     e.consume();
359     return;
360       }
361     handleCommand(action);
362     e.consume();
363   }
364
365   int toInt(KeyEvent JavaDoc e, int kind)
366   {
367     int code = e.getKeyCode();
368     if (code == 0)
369       code = e.getKeyChar();
370     else
371       code |= (e.getModifiers() | kind) << 16;
372     return code;
373   }
374
375 /**
376  *
377  */

378 void flushPending()
379 {
380   pendingLength = 0;
381 }
382
383 /**
384  * @see gnu.jemacs.buffer.EWindow#tooLong(int)
385  */

386 public Object JavaDoc tooLong(int pendingLength)
387 {
388   return new TooLongAction(pendingLength);
389 }
390
391 }
392
Popular Tags