2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax
.swing
.plaf
.basic
;
41 import java
.awt
.Container
;
42 import java
.awt
.Dimension
;
43 import java
.awt
.Graphics
;
44 import java
.awt
.Insets
;
45 import java
.awt
.Point
;
46 import java
.awt
.Rectangle
;
47 import java
.awt
.Shape
;
48 import java
.awt
.event
.FocusEvent
;
49 import java
.awt
.event
.FocusListener
;
50 import java
.beans
.PropertyChangeEvent
;
51 import java
.beans
.PropertyChangeListener
;
53 import javax
.swing
.Action
;
54 import javax
.swing
.ActionMap
;
55 import javax
.swing
.InputMap
;
56 import javax
.swing
.JComponent
;
57 import javax
.swing
.SwingUtilities
;
58 import javax
.swing
.UIDefaults
;
59 import javax
.swing
.UIManager
;
60 import javax
.swing
.plaf
.TextUI
;
61 import javax
.swing
.plaf
.UIResource
;
62 import javax
.swing
.text
.BadLocationException
;
63 import javax
.swing
.text
.Caret
;
64 import javax
.swing
.text
.DefaultCaret
;
65 import javax
.swing
.text
.DefaultEditorKit
;
66 import javax
.swing
.text
.DefaultHighlighter
;
67 import javax
.swing
.text
.Document
;
68 import javax
.swing
.text
.EditorKit
;
69 import javax
.swing
.text
.Element
;
70 import javax
.swing
.text
.Highlighter
;
71 import javax
.swing
.text
.JTextComponent
;
72 import javax
.swing
.text
.Keymap
;
73 import javax
.swing
.text
.PlainView
;
74 import javax
.swing
.text
.Position
;
75 import javax
.swing
.text
.View
;
76 import javax
.swing
.text
.ViewFactory
;
79 public abstract class BasicTextUI
extends TextUI
80 implements ViewFactory
82 public static class BasicCaret
extends DefaultCaret
90 public static class BasicHighlighter
extends DefaultHighlighter
93 public BasicHighlighter()
98 private class RootView
extends View
109 public ViewFactory
getViewFactory()
111 // FIXME: Handle EditorKit somehow.
112 return BasicTextUI
.this;
115 public void setView(View v
)
118 view
.setParent(null);
126 public Container
getContainer()
128 return textComponent
;
131 public float getPreferredSpan(int axis
)
134 return view
.getPreferredSpan(axis
);
136 return Integer
.MAX_VALUE
;
139 public void paint(Graphics g
, Shape s
)
145 public Shape
modelToView(int position
, Shape a
, Position
.Bias bias
)
146 throws BadLocationException
151 return ((PlainView
) view
).modelToView(position
, a
, bias
).getBounds();
155 class UpdateHandler
implements PropertyChangeListener
157 public void propertyChange(PropertyChangeEvent event
)
159 if (event
.getPropertyName().equals("document"))
167 static EditorKit kit
= new DefaultEditorKit();
169 RootView rootView
= new RootView();
170 JTextComponent textComponent
;
171 UpdateHandler updateHandler
= new UpdateHandler();
177 protected Caret
createCaret()
179 return new BasicCaret();
182 protected Highlighter
createHighlighter()
184 return new BasicHighlighter();
187 protected final JTextComponent
getComponent()
189 return textComponent
;
192 public void installUI(final JComponent c
)
197 textComponent
= (JTextComponent
) c
;
199 Document doc
= textComponent
.getDocument();
202 doc
= getEditorKit(textComponent
).createDefaultDocument();
203 textComponent
.setDocument(doc
);
206 textComponent
.addPropertyChangeListener(updateHandler
);
211 installKeyboardActions();
214 protected void installDefaults()
216 Caret caret
= textComponent
.getCaret();
219 caret
= createCaret();
220 textComponent
.setCaret(caret
);
223 Highlighter highlighter
= textComponent
.getHighlighter();
224 if (highlighter
== null)
225 textComponent
.setHighlighter(createHighlighter());
227 String prefix
= getPropertyPrefix();
228 UIDefaults defaults
= UIManager
.getLookAndFeelDefaults();
229 textComponent
.setBackground(defaults
.getColor(prefix
+ ".background"));
230 textComponent
.setForeground(defaults
.getColor(prefix
+ ".foreground"));
231 textComponent
.setMargin(defaults
.getInsets(prefix
+ ".margin"));
232 textComponent
.setBorder(defaults
.getBorder(prefix
+ ".border"));
233 textComponent
.setFont(defaults
.getFont(prefix
+ ".font"));
235 caret
.setBlinkRate(defaults
.getInt(prefix
+ ".caretBlinkRate"));
238 private FocusListener focuslistener
= new FocusListener() {
239 public void focusGained(FocusEvent e
)
241 textComponent
.repaint();
243 public void focusLost(FocusEvent e
)
245 textComponent
.repaint();
249 protected void installListeners()
251 textComponent
.addFocusListener(focuslistener
);
254 protected String
getKeymapName()
256 return "BasicTextUI";
259 protected Keymap
createKeymap()
261 String prefix
= getPropertyPrefix();
262 UIDefaults defaults
= UIManager
.getLookAndFeelDefaults();
263 JTextComponent
.KeyBinding
[] bindings
=
264 (JTextComponent
.KeyBinding
[]) defaults
.get(prefix
+ ".keyBindings");
265 Keymap km
= JTextComponent
.addKeymap(getKeymapName(),
266 JTextComponent
.getKeymap(JTextComponent
.DEFAULT_KEYMAP
));
267 JTextComponent
.loadKeymap(km
, bindings
, textComponent
.getActions());
271 protected void installKeyboardActions()
273 // load any bindings for the older Keymap interface
274 Keymap km
= JTextComponent
.getKeymap(getKeymapName());
277 textComponent
.setKeymap(km
);
279 // load any bindings for the newer InputMap / ActionMap interface
280 SwingUtilities
.replaceUIInputMap(textComponent
,
281 JComponent
.WHEN_FOCUSED
,
282 getInputMap(JComponent
.WHEN_FOCUSED
));
283 SwingUtilities
.replaceUIActionMap(textComponent
, getActionMap());
286 InputMap
getInputMap(int condition
)
288 String prefix
= getPropertyPrefix();
289 UIDefaults defaults
= UIManager
.getLookAndFeelDefaults();
292 case JComponent
.WHEN_IN_FOCUSED_WINDOW
:
293 // FIXME: is this the right string? nobody seems to use it.
294 return (InputMap
) defaults
.get(prefix
+ ".windowInputMap");
295 case JComponent
.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
:
296 return (InputMap
) defaults
.get(prefix
+ ".ancestorInputMap");
298 case JComponent
.WHEN_FOCUSED
:
299 return (InputMap
) defaults
.get(prefix
+ ".focusInputMap");
303 ActionMap
getActionMap()
305 String prefix
= getPropertyPrefix();
306 UIDefaults defaults
= UIManager
.getLookAndFeelDefaults();
307 ActionMap am
= (ActionMap
) defaults
.get(prefix
+ ".actionMap");
310 am
= createActionMap();
311 defaults
.put(prefix
+ ".actionMap", am
);
316 ActionMap
createActionMap()
318 Action
[] actions
= textComponent
.getActions();
319 ActionMap am
= new ActionMap();
320 for (int i
= 0; i
< actions
.length
; ++i
)
322 String name
= (String
) actions
[i
].getValue(Action
.NAME
);
324 am
.put(name
, actions
[i
]);
329 public void uninstallUI(final JComponent component
)
331 super.uninstallUI(component
);
332 rootView
.setView(null);
334 textComponent
.removePropertyChangeListener(updateHandler
);
337 uninstallListeners();
338 uninstallKeyboardActions();
340 textComponent
= null;
343 protected void uninstallDefaults()
348 protected void uninstallListeners()
350 textComponent
.removeFocusListener(focuslistener
);
353 protected void uninstallKeyboardActions()
358 protected abstract String
getPropertyPrefix();
360 public Dimension
getPreferredSize(JComponent c
)
362 View v
= getRootView(textComponent
);
364 float w
= v
.getPreferredSpan(View
.X_AXIS
);
365 float h
= v
.getPreferredSpan(View
.Y_AXIS
);
367 return new Dimension((int) w
, (int) h
);
370 public final void paint(Graphics g
, JComponent c
)
375 protected void paintSafely(Graphics g
)
377 Caret caret
= textComponent
.getCaret();
378 Highlighter highlighter
= textComponent
.getHighlighter();
380 if (textComponent
.isOpaque())
383 if (highlighter
!= null
384 && textComponent
.getSelectionStart() != textComponent
.getSelectionEnd())
385 highlighter
.paint(g
);
387 rootView
.paint(g
, getVisibleEditorRect());
389 if (caret
!= null && textComponent
.hasFocus())
393 protected void paintBackground(Graphics g
)
395 g
.setColor(textComponent
.getBackground());
396 g
.fillRect(0, 0, textComponent
.getWidth(), textComponent
.getHeight());
399 public void damageRange(JTextComponent t
, int p0
, int p1
)
401 damageRange(t
, p0
, p1
, null, null);
404 public void damageRange(JTextComponent t
, int p0
, int p1
,
405 Position
.Bias firstBias
, Position
.Bias secondBias
)
409 public EditorKit
getEditorKit(JTextComponent t
)
414 public int getNextVisualPositionFrom(JTextComponent t
, int pos
,
415 Position
.Bias b
, int direction
,
416 Position
.Bias
[] biasRet
)
417 throws BadLocationException
422 public View
getRootView(JTextComponent t
)
427 public Rectangle
modelToView(JTextComponent t
, int pos
)
428 throws BadLocationException
430 return modelToView(t
, pos
, Position
.Bias
.Forward
);
433 public Rectangle
modelToView(JTextComponent t
, int pos
, Position
.Bias bias
)
434 throws BadLocationException
436 return rootView
.modelToView(pos
, getVisibleEditorRect(), bias
).getBounds();
439 public int viewToModel(JTextComponent t
, Point pt
)
441 return viewToModel(t
, pt
, null);
444 public int viewToModel(JTextComponent t
, Point pt
, Position
.Bias
[] biasReturn
)
449 public View
create(Element elem
)
451 // Subclasses have to implement this to get this functionality.
455 public View
create(Element elem
, int p0
, int p1
)
457 // Subclasses have to implement this to get this functionality.
461 protected Rectangle
getVisibleEditorRect()
463 int width
= textComponent
.getWidth();
464 int height
= textComponent
.getHeight();
466 if (width
<= 0 || height
<= 0)
469 Insets insets
= textComponent
.getInsets();
470 return new Rectangle(insets
.left
, insets
.top
,
471 width
- insets
.left
+ insets
.right
,
472 height
- insets
.top
+ insets
.bottom
);
475 protected final void setView(View view
)
477 rootView
.setView(view
);
478 view
.setParent(rootView
);
481 protected void modelChanged()
483 if (textComponent
== null || rootView
== null)
485 ViewFactory factory
= rootView
.getViewFactory();
488 Document doc
= textComponent
.getDocument();
491 Element elem
= doc
.getDefaultRootElement();
494 setView(factory
.create(elem
));