55 |
import javax.swing.ActionMap; |
import javax.swing.ActionMap; |
56 |
import javax.swing.InputMap; |
import javax.swing.InputMap; |
57 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
58 |
|
import javax.swing.LookAndFeel; |
59 |
import javax.swing.SwingUtilities; |
import javax.swing.SwingUtilities; |
60 |
import javax.swing.UIDefaults; |
import javax.swing.UIDefaults; |
61 |
import javax.swing.UIManager; |
import javax.swing.UIManager; |
75 |
import javax.swing.text.Highlighter; |
import javax.swing.text.Highlighter; |
76 |
import javax.swing.text.JTextComponent; |
import javax.swing.text.JTextComponent; |
77 |
import javax.swing.text.Keymap; |
import javax.swing.text.Keymap; |
|
import javax.swing.text.PlainView; |
|
78 |
import javax.swing.text.Position; |
import javax.swing.text.Position; |
79 |
import javax.swing.text.View; |
import javax.swing.text.View; |
80 |
import javax.swing.text.ViewFactory; |
import javax.swing.text.ViewFactory; |
93 |
/** |
/** |
94 |
* A {@link DefaultCaret} that implements {@link UIResource}. |
* A {@link DefaultCaret} that implements {@link UIResource}. |
95 |
*/ |
*/ |
96 |
public static class BasicCaret extends DefaultCaret |
public static class BasicCaret extends DefaultCaret implements UIResource |
|
implements UIResource |
|
97 |
{ |
{ |
98 |
public BasicCaret() |
public BasicCaret() |
99 |
{ |
{ |
100 |
|
// Nothing to do here. |
101 |
} |
} |
102 |
} |
} |
103 |
|
|
109 |
{ |
{ |
110 |
public BasicHighlighter() |
public BasicHighlighter() |
111 |
{ |
{ |
112 |
|
// Nothing to do here. |
113 |
} |
} |
114 |
} |
} |
115 |
|
|
254 |
* |
* |
255 |
* This is delegated to the real root view. |
* This is delegated to the real root view. |
256 |
* |
* |
257 |
* @param pos the position of the character in the model |
* @param position the position of the character in the model |
258 |
* @param a the area that is occupied by the view |
* @param a the area that is occupied by the view |
259 |
* @param bias either {@link Position.Bias.Forward} or |
* @param bias either {@link Position.Bias#Forward} or |
260 |
* {@link Position.Bias.Backward} depending on the preferred |
* {@link Position.Bias#Backward} depending on the preferred |
261 |
* direction bias. If <code>null</code> this defaults to |
* direction bias. If <code>null</code> this defaults to |
262 |
* <code>Position.Bias.Forward</code> |
* <code>Position.Bias.Forward</code> |
263 |
* |
* |
334 |
/** |
/** |
335 |
* Receives notifications when properties of the text component change. |
* Receives notifications when properties of the text component change. |
336 |
*/ |
*/ |
337 |
class UpdateHandler implements PropertyChangeListener |
class PropertyChangeHandler implements PropertyChangeListener |
338 |
{ |
{ |
339 |
/** |
/** |
340 |
* Notifies when a property of the text component changes. |
* Notifies when a property of the text component changes. |
348 |
// Document changed. |
// Document changed. |
349 |
modelChanged(); |
modelChanged(); |
350 |
} |
} |
351 |
else if (event.getPropertyName().equals("editable")) |
|
352 |
{ |
BasicTextUI.this.propertyChange(event); |
|
if (textComponent.isEditable()) |
|
|
textComponent.setBackground(background); |
|
|
else |
|
|
textComponent.setBackground(inactiveBackground); |
|
|
} |
|
353 |
} |
} |
354 |
} |
} |
355 |
|
|
368 |
*/ |
*/ |
369 |
public void changedUpdate(DocumentEvent ev) |
public void changedUpdate(DocumentEvent ev) |
370 |
{ |
{ |
371 |
Dimension size = textComponent.getSize(); |
rootView.changedUpdate(ev, getVisibleEditorRect(), |
|
rootView.changedUpdate(ev, new Rectangle(0, 0, size.width, size.height), |
|
372 |
rootView.getViewFactory()); |
rootView.getViewFactory()); |
373 |
} |
} |
374 |
|
|
375 |
/** |
/** |
376 |
* Notification about a document insert event. |
* Notification about a document insert event. |
377 |
* |
* |
379 |
*/ |
*/ |
380 |
public void insertUpdate(DocumentEvent ev) |
public void insertUpdate(DocumentEvent ev) |
381 |
{ |
{ |
382 |
Dimension size = textComponent.getSize(); |
rootView.insertUpdate(ev, getVisibleEditorRect(), |
|
rootView.insertUpdate(ev, new Rectangle(0, 0, size.width, size.height), |
|
383 |
rootView.getViewFactory()); |
rootView.getViewFactory()); |
|
int caretPos = textComponent.getCaretPosition(); |
|
|
if (caretPos >= ev.getOffset()) |
|
|
textComponent.setCaretPosition(caretPos + ev.getLength()); |
|
384 |
} |
} |
385 |
|
|
386 |
/** |
/** |
390 |
*/ |
*/ |
391 |
public void removeUpdate(DocumentEvent ev) |
public void removeUpdate(DocumentEvent ev) |
392 |
{ |
{ |
393 |
Dimension size = textComponent.getSize(); |
rootView.removeUpdate(ev, getVisibleEditorRect(), |
|
rootView.removeUpdate(ev, new Rectangle(0, 0, size.width, size.height), |
|
394 |
rootView.getViewFactory()); |
rootView.getViewFactory()); |
|
int caretPos = textComponent.getCaretPosition(); |
|
|
if (caretPos >= ev.getOffset()) |
|
|
textComponent.setCaretPosition(ev.getOffset()); |
|
395 |
} |
} |
396 |
} |
} |
397 |
|
|
414 |
/** |
/** |
415 |
* Receives notification when the model changes. |
* Receives notification when the model changes. |
416 |
*/ |
*/ |
417 |
UpdateHandler updateHandler = new UpdateHandler(); |
PropertyChangeHandler updateHandler = new PropertyChangeHandler(); |
418 |
|
|
419 |
/** The DocumentEvent handler. */ |
/** The DocumentEvent handler. */ |
420 |
DocumentHandler documentHandler = new DocumentHandler(); |
DocumentHandler documentHandler = new DocumentHandler(); |
436 |
*/ |
*/ |
437 |
public BasicTextUI() |
public BasicTextUI() |
438 |
{ |
{ |
439 |
|
// Nothing to do here. |
440 |
} |
} |
441 |
|
|
442 |
/** |
/** |
514 |
textComponent.setHighlighter(createHighlighter()); |
textComponent.setHighlighter(createHighlighter()); |
515 |
|
|
516 |
String prefix = getPropertyPrefix(); |
String prefix = getPropertyPrefix(); |
517 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
LookAndFeel.installColorsAndFont(textComponent, prefix + ".background", |
518 |
textComponent.setMargin(defaults.getInsets(prefix + ".margin")); |
prefix + ".foreground", prefix + ".font"); |
519 |
textComponent.setBorder(defaults.getBorder(prefix + ".border")); |
LookAndFeel.installBorder(textComponent, prefix + ".border"); |
520 |
textComponent.setFont(defaults.getFont(prefix + ".font")); |
textComponent.setMargin(UIManager.getInsets(prefix + ".margin")); |
521 |
|
|
522 |
caret.setBlinkRate(defaults.getInt(prefix + ".caretBlinkRate")); |
caret.setBlinkRate(UIManager.getInt(prefix + ".caretBlinkRate")); |
523 |
|
|
524 |
// Fetch the colors for enabled/disabled text components. |
// Fetch the colors for enabled/disabled text components. |
525 |
background = defaults.getColor(prefix + ".background"); |
inactiveBackground = UIManager.getColor(prefix + ".inactiveBackground"); |
|
inactiveBackground = defaults.getColor(prefix + ".inactiveBackground"); |
|
|
textComponent.setForeground(defaults.getColor(prefix + ".foreground")); |
|
526 |
textComponent.setDisabledTextColor |
textComponent.setDisabledTextColor |
527 |
(defaults.getColor(prefix + ".inactiveForeground")); |
(UIManager.getColor(prefix + ".inactiveForeground")); |
528 |
|
textComponent.setSelectedTextColor(UIManager.getColor(prefix + ".selectionForeground")); |
529 |
} |
} |
530 |
|
|
531 |
/** |
/** |
811 |
{ |
{ |
812 |
// This method does nothing. All the background filling is done by the |
// This method does nothing. All the background filling is done by the |
813 |
// ComponentUI update method. However, the method is called by paint |
// ComponentUI update method. However, the method is called by paint |
814 |
// to provide a way for subclasses to draw something different (e.g. background |
// to provide a way for subclasses to draw something different (e.g. |
815 |
// images etc) on the background. |
// background images etc) on the background. |
816 |
} |
} |
817 |
|
|
818 |
/** |
/** |
899 |
/** |
/** |
900 |
* Maps a position in the document into the coordinate space of the View. |
* Maps a position in the document into the coordinate space of the View. |
901 |
* The output rectangle usually reflects the font height but has a width |
* The output rectangle usually reflects the font height but has a width |
902 |
* of zero. A bias of {@link Position.Bias.Forward} is used in this method. |
* of zero. A bias of {@link Position.Bias#Forward} is used in this method. |
903 |
* |
* |
904 |
|
* @param t the text component |
905 |
* @param pos the position of the character in the model |
* @param pos the position of the character in the model |
|
* @param a the area that is occupied by the view |
|
906 |
* |
* |
907 |
* @return a rectangle that gives the location of the document position |
* @return a rectangle that gives the location of the document position |
908 |
* inside the view coordinate space |
* inside the view coordinate space |
922 |
* The output rectangle usually reflects the font height but has a width |
* The output rectangle usually reflects the font height but has a width |
923 |
* of zero. |
* of zero. |
924 |
* |
* |
925 |
|
* @param t the text component |
926 |
* @param pos the position of the character in the model |
* @param pos the position of the character in the model |
927 |
* @param a the area that is occupied by the view |
* @param bias either {@link Position.Bias#Forward} or |
928 |
* @param bias either {@link Position.Bias.Forward} or |
* {@link Position.Bias#Backward} depending on the preferred |
|
* {@link Position.Bias.Backward} depending on the preferred |
|
929 |
* direction bias. If <code>null</code> this defaults to |
* direction bias. If <code>null</code> this defaults to |
930 |
* <code>Position.Bias.Forward</code> |
* <code>Position.Bias.Forward</code> |
931 |
* |
* |
971 |
*/ |
*/ |
972 |
public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn) |
public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn) |
973 |
{ |
{ |
974 |
return 0; // FIXME: Implement me. |
return rootView.viewToModel(pt.x, pt.y, getVisibleEditorRect(), biasReturn); |
975 |
} |
} |
976 |
|
|
977 |
/** |
/** |
1017 |
int height = textComponent.getHeight(); |
int height = textComponent.getHeight(); |
1018 |
|
|
1019 |
if (width <= 0 || height <= 0) |
if (width <= 0 || height <= 0) |
1020 |
return null; |
return new Rectangle(0, 0, 0, 0); |
1021 |
|
|
1022 |
Insets insets = textComponent.getInsets(); |
Insets insets = textComponent.getInsets(); |
1023 |
return new Rectangle(insets.left, insets.top, |
return new Rectangle(insets.left, insets.top, |
1034 |
{ |
{ |
1035 |
rootView.setView(view); |
rootView.setView(view); |
1036 |
view.setParent(rootView); |
view.setParent(rootView); |
1037 |
|
textComponent.revalidate(); |
1038 |
|
textComponent.repaint(); |
1039 |
} |
} |
1040 |
|
|
1041 |
/** |
/** |
1059 |
View view = factory.create(elem); |
View view = factory.create(elem); |
1060 |
setView(view); |
setView(view); |
1061 |
} |
} |
1062 |
|
|
1063 |
|
/** |
1064 |
|
* Receives notification whenever one of the text component's bound |
1065 |
|
* properties changes. This default implementation does nothing. |
1066 |
|
* It is a hook that enables subclasses to react to property changes |
1067 |
|
* on the text component. |
1068 |
|
* |
1069 |
|
* @param ev the property change event |
1070 |
|
*/ |
1071 |
|
protected void propertyChange(PropertyChangeEvent ev) |
1072 |
|
{ |
1073 |
|
// The default implementation does nothing. |
1074 |
|
} |
1075 |
} |
} |