001: package net.sourceforge.squirrel_sql.plugins.syntax;
002:
003: import javax.swing.*;
004: import java.awt.*;
005: import java.awt.event.ActionEvent;
006: import java.awt.event.KeyEvent;
007: import java.awt.event.FocusListener;
008: import java.awt.event.FocusEvent;
009:
010: /**
011: * Manages the ctrl left/right and ctrl shift left/right keys.
012: */
013: public class KeyManager {
014: public static final char[] STOP_AT = new char[] { '.', '(', ')',
015: '\'', '\n', ',', '=', '<', '>' };
016:
017: private JEditorPane _textPane;
018:
019: public KeyManager(JEditorPane textPane) {
020: _textPane = textPane;
021:
022: // One may ask why we don't register the key strokes permanently.
023: // When we did so with two internal frames open, the key stroke event
024: // sometimes went to the wrong frame. This doesn't happen if we procede
025: // like we do.
026: // The question is, why?
027:
028: _textPane.addFocusListener(new FocusListener() {
029: public void focusGained(FocusEvent e) {
030: registerKeyStrokes();
031: }
032:
033: public void focusLost(FocusEvent e) {
034: unregisterKeyStrokes();
035: }
036: });
037:
038: }
039:
040: private void unregisterKeyStrokes() {
041: KeyStroke keyStroke;
042:
043: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
044: Event.CTRL_MASK);
045: _textPane.getKeymap().removeKeyStrokeBinding(keyStroke);
046:
047: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
048: Event.CTRL_MASK | Event.SHIFT_MASK);
049: _textPane.getKeymap().removeKeyStrokeBinding(keyStroke);
050:
051: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
052: Event.CTRL_MASK);
053: _textPane.getKeymap().removeKeyStrokeBinding(keyStroke);
054:
055: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
056: Event.CTRL_MASK | Event.SHIFT_MASK);
057: _textPane.getKeymap().removeKeyStrokeBinding(keyStroke);
058:
059: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
060: Event.CTRL_MASK);
061: _textPane.getKeymap().removeKeyStrokeBinding(keyStroke);
062: }
063:
064: private void registerKeyStrokes() {
065: KeyStroke keyStroke;
066: Action act;
067:
068: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
069: Event.CTRL_MASK);
070: act = new AbstractAction() {
071: public void actionPerformed(ActionEvent e) {
072: onRightCtrl();
073: }
074: };
075: _textPane.getKeymap().addActionForKeyStroke(keyStroke, act);
076:
077: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
078: Event.CTRL_MASK | Event.SHIFT_MASK);
079: act = new AbstractAction() {
080: public void actionPerformed(ActionEvent e) {
081: onRightCtrlShift();
082: }
083: };
084: _textPane.getKeymap().addActionForKeyStroke(keyStroke, act);
085:
086: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
087: Event.CTRL_MASK);
088: act = new AbstractAction() {
089: public void actionPerformed(ActionEvent e) {
090: onLeftCtrl();
091: }
092: };
093: _textPane.getKeymap().addActionForKeyStroke(keyStroke, act);
094:
095: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
096: Event.CTRL_MASK | Event.SHIFT_MASK);
097: act = new AbstractAction() {
098: public void actionPerformed(ActionEvent e) {
099: onLeftCtrlShift();
100: }
101: };
102: _textPane.getKeymap().addActionForKeyStroke(keyStroke, act);
103:
104: keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
105: Event.CTRL_MASK);
106: act = new AbstractAction() {
107: public void actionPerformed(ActionEvent e) {
108: onCtrlBackSpace();
109: }
110:
111: };
112: _textPane.getKeymap().addActionForKeyStroke(keyStroke, act);
113: }
114:
115: private void onCtrlBackSpace() {
116: moveCtrlLeft(true);
117: _textPane.replaceSelection("");
118: }
119:
120: private void onLeftCtrlShift() {
121: moveCtrlLeft(true);
122: }
123:
124: private void onLeftCtrl() {
125: moveCtrlLeft(false);
126: }
127:
128: private void moveCtrlLeft(boolean select) {
129: String text = _textPane.getText();
130: int pos = _textPane.getCaretPosition() - 1;
131:
132: if (pos < 0) {
133: return;
134: }
135:
136: for (; pos > 0; --pos) {
137: if (isToStopAt(text.charAt(pos - 1), text.charAt(pos))) {
138: break;
139: }
140: }
141:
142: if (select) {
143: _textPane.moveCaretPosition(pos);
144: } else {
145: _textPane.setCaretPosition(pos);
146: }
147: }
148:
149: private void onRightCtrlShift() {
150: moveCtrlRight(true);
151: }
152:
153: private void onRightCtrl() {
154: moveCtrlRight(false);
155: }
156:
157: private void moveCtrlRight(boolean select) {
158: String text = _textPane.getText();
159: int pos = _textPane.getCaretPosition() + 1;
160:
161: if (pos > text.length()) {
162: return;
163: }
164:
165: for (; pos < text.length(); ++pos) {
166: if (isToStopAt(text.charAt(pos), text.charAt(pos - 1))) {
167: break;
168: }
169: }
170:
171: if (select) {
172: _textPane.moveCaretPosition(pos);
173: } else {
174: _textPane.setCaretPosition(pos);
175: }
176: }
177:
178: private boolean isToStopAt(char toCheck, char former) {
179: if (isInStopAtArray(former) || isInStopAtArray(toCheck)) {
180: return true;
181: } else if (false == Character.isWhitespace(former)
182: && Character.isWhitespace(toCheck)
183: || Character.isWhitespace(former)
184: && false == Character.isWhitespace(toCheck))
185: // else if(Character.isWhitespace(former) && false == Character.isWhitespace(toCheck))
186: {
187: return true;
188: }
189:
190: return false;
191: }
192:
193: private boolean isInStopAtArray(char toCheck) {
194: for (int i = 0; i < STOP_AT.length; i++) {
195: if (toCheck == STOP_AT[i]) {
196: return true;
197: }
198: }
199:
200: return false;
201: }
202:
203: }
|