50 |
import java.awt.datatransfer.Transferable; |
import java.awt.datatransfer.Transferable; |
51 |
import java.awt.datatransfer.UnsupportedFlavorException; |
import java.awt.datatransfer.UnsupportedFlavorException; |
52 |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionEvent; |
53 |
|
import java.awt.event.ActionListener; |
54 |
import java.awt.event.InputMethodListener; |
import java.awt.event.InputMethodListener; |
55 |
import java.awt.event.KeyEvent; |
import java.awt.event.KeyEvent; |
56 |
import java.io.IOException; |
import java.io.IOException; |
69 |
import javax.swing.JViewport; |
import javax.swing.JViewport; |
70 |
import javax.swing.KeyStroke; |
import javax.swing.KeyStroke; |
71 |
import javax.swing.Scrollable; |
import javax.swing.Scrollable; |
72 |
|
import javax.swing.SwingConstants; |
73 |
|
import javax.swing.Timer; |
74 |
import javax.swing.TransferHandler; |
import javax.swing.TransferHandler; |
75 |
import javax.swing.UIManager; |
import javax.swing.UIManager; |
76 |
import javax.swing.event.CaretEvent; |
import javax.swing.event.CaretEvent; |
300 |
} |
} |
301 |
|
|
302 |
/** |
/** |
303 |
|
* The timer that lets the caret blink. |
304 |
|
*/ |
305 |
|
private class CaretBlinkTimer |
306 |
|
extends Timer |
307 |
|
implements ActionListener |
308 |
|
{ |
309 |
|
/** |
310 |
|
* Creates a new CaretBlinkTimer object with a default delay of 1 second. |
311 |
|
*/ |
312 |
|
public CaretBlinkTimer() |
313 |
|
{ |
314 |
|
super(1000, null); |
315 |
|
addActionListener(this); |
316 |
|
} |
317 |
|
|
318 |
|
/** |
319 |
|
* Lets the caret blink. |
320 |
|
*/ |
321 |
|
public void actionPerformed(ActionEvent ev) |
322 |
|
{ |
323 |
|
caret.setVisible(!caret.isVisible()); |
324 |
|
} |
325 |
|
|
326 |
|
/** |
327 |
|
* Updates the blink delay according to the current caret. |
328 |
|
*/ |
329 |
|
public void update() |
330 |
|
{ |
331 |
|
stop(); |
332 |
|
setDelay(caret.getBlinkRate()); |
333 |
|
if (editable) |
334 |
|
start(); |
335 |
|
else |
336 |
|
caret.setVisible(false); |
337 |
|
} |
338 |
|
} |
339 |
|
|
340 |
|
/** |
341 |
* According to <a |
* According to <a |
342 |
* href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this |
* href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this |
343 |
* report</a>, a pair of private classes wraps a {@link |
* report</a>, a pair of private classes wraps a {@link |
693 |
private Keymap keymap; |
private Keymap keymap; |
694 |
private char focusAccelerator = '\0'; |
private char focusAccelerator = '\0'; |
695 |
private NavigationFilter navigationFilter; |
private NavigationFilter navigationFilter; |
696 |
|
|
697 |
|
private CaretBlinkTimer caretBlinkTimer; |
698 |
|
|
699 |
/** |
/** |
700 |
* Get a Keymap from the global keymap table, by name. |
* Get a Keymap from the global keymap table, by name. |
701 |
* |
* |
952 |
creatingKeymap = true; |
creatingKeymap = true; |
953 |
} |
} |
954 |
|
|
955 |
|
caretBlinkTimer = new CaretBlinkTimer(); |
956 |
|
|
957 |
setFocusable(true); |
setFocusable(true); |
958 |
setEditable(true); |
setEditable(true); |
959 |
enableEvents(AWTEvent.KEY_EVENT_MASK); |
enableEvents(AWTEvent.KEY_EVENT_MASK); |
1131 |
|
|
1132 |
public Dimension getPreferredScrollableViewportSize() |
public Dimension getPreferredScrollableViewportSize() |
1133 |
{ |
{ |
1134 |
return null; |
return getPreferredSize(); |
1135 |
} |
} |
1136 |
|
|
1137 |
public int getScrollableUnitIncrement(Rectangle visible, int orientation, |
public int getScrollableUnitIncrement(Rectangle visible, int orientation, |
1138 |
int direction) |
int direction) |
1139 |
{ |
{ |
1140 |
return 0; |
// We return 1/10 of the visible area as documented in Sun's API docs. |
1141 |
|
if (orientation == SwingConstants.HORIZONTAL) |
1142 |
|
return visible.width / 10; |
1143 |
|
else if (orientation == SwingConstants.VERTICAL) |
1144 |
|
return visible.height / 10; |
1145 |
|
else |
1146 |
|
throw new IllegalArgumentException("orientation must be either " |
1147 |
|
+ "javax.swing.SwingConstants.VERTICAL " |
1148 |
|
+ "or " |
1149 |
|
+ "javax.swing.SwingConstants.HORIZONTAL" |
1150 |
|
); |
1151 |
} |
} |
1152 |
|
|
1153 |
public int getScrollableBlockIncrement(Rectangle visible, int orientation, |
public int getScrollableBlockIncrement(Rectangle visible, int orientation, |
1154 |
int direction) |
int direction) |
1155 |
{ |
{ |
1156 |
return 0; |
// We return the whole visible area as documented in Sun's API docs. |
1157 |
|
if (orientation == SwingConstants.HORIZONTAL) |
1158 |
|
return visible.width; |
1159 |
|
else if (orientation == SwingConstants.VERTICAL) |
1160 |
|
return visible.height; |
1161 |
|
else |
1162 |
|
throw new IllegalArgumentException("orientation must be either " |
1163 |
|
+ "javax.swing.SwingConstants.VERTICAL " |
1164 |
|
+ "or " |
1165 |
|
+ "javax.swing.SwingConstants.HORIZONTAL" |
1166 |
|
); |
1167 |
} |
} |
1168 |
|
|
1169 |
/** |
/** |
1186 |
if (editable == newValue) |
if (editable == newValue) |
1187 |
return; |
return; |
1188 |
|
|
1189 |
|
if (newValue == true) |
1190 |
|
caretBlinkTimer.start(); |
1191 |
|
else |
1192 |
|
{ |
1193 |
|
caretBlinkTimer.stop(); |
1194 |
|
caret.setVisible(false); |
1195 |
|
} |
1196 |
|
|
1197 |
boolean oldValue = editable; |
boolean oldValue = editable; |
1198 |
editable = newValue; |
editable = newValue; |
1199 |
firePropertyChange("editable", oldValue, newValue); |
firePropertyChange("editable", oldValue, newValue); |
1222 |
Caret oldCaret = caret; |
Caret oldCaret = caret; |
1223 |
caret = newCaret; |
caret = newCaret; |
1224 |
|
|
1225 |
|
caretBlinkTimer.update(); |
1226 |
|
|
1227 |
if (caret != null) |
if (caret != null) |
1228 |
caret.install(this); |
caret.install(this); |
1229 |
|
|