@Override
public boolean keyPressed(final Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
boolean consumed = false;
final TextArea textArea = (TextArea)getComponent();
Document document = textArea.getDocument();
Keyboard.Modifier commandModifier = Platform.getCommandModifier();
if (document != null) {
if (keyCode == Keyboard.KeyCode.ENTER
&& textArea.isEditable()) {
textArea.insertParagraph();
consumed = true;
} else if (keyCode == Keyboard.KeyCode.DELETE
&& textArea.isEditable()) {
textArea.delete(Direction.FORWARD);
consumed = true;
} else if (keyCode == Keyboard.KeyCode.BACKSPACE
&& textArea.isEditable()) {
textArea.delete(Direction.BACKWARD);
consumed = true;
} else if (keyCode == Keyboard.KeyCode.LEFT) {
int selectionStart = textArea.getSelectionStart();
int selectionLength = textArea.getSelectionLength();
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
// Add the previous character to the selection
if (selectionStart > 0) {
selectionStart--;
selectionLength++;
}
} else {
// Clear the selection and move the caret back by one
// character
if (selectionLength == 0
&& selectionStart > 0) {
selectionStart--;
}
selectionLength = 0;
}
textArea.setSelection(selectionStart, selectionLength);
scrollCharacterToVisible(selectionStart);
caretX = caret.x;
consumed = true;
} else if (keyCode == Keyboard.KeyCode.RIGHT) {
int selectionStart = textArea.getSelectionStart();
int selectionLength = textArea.getSelectionLength();
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
// Add the next character to the selection
if (selectionStart + selectionLength < document.getCharacterCount()) {
selectionLength++;
}
textArea.setSelection(selectionStart, selectionLength);
scrollCharacterToVisible(selectionStart + selectionLength);
} else {
// Clear the selection and move the caret forward by one
// character
if (selectionLength > 0) {
selectionStart += selectionLength - 1;
}
if (selectionStart < document.getCharacterCount() - 1) {
selectionStart++;
}
textArea.setSelection(selectionStart, 0);
scrollCharacterToVisible(selectionStart);
caretX = caret.x;
}
consumed = true;
} else if (keyCode == Keyboard.KeyCode.UP) {
int selectionStart = textArea.getSelectionStart();
int offset = getNextInsertionPoint(caretX, selectionStart, Direction.BACKWARD);
if (offset == -1) {
offset = 0;
}
int selectionLength;
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
int selectionEnd = selectionStart + textArea.getSelectionLength() - 1;
selectionLength = selectionEnd - offset + 1;
} else {
selectionLength = 0;
}
textArea.setSelection(offset, selectionLength);
scrollCharacterToVisible(offset);
consumed = true;
} else if (keyCode == Keyboard.KeyCode.DOWN) {
int selectionStart = textArea.getSelectionStart();
int selectionLength = textArea.getSelectionLength();
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
int from;
int x;
if (selectionLength == 0) {
// Get next insertion point from leading selection character
from = selectionStart;
x = caretX;
} else {
// Get next insertion point from right edge of trailing selection
// character
from = selectionStart + selectionLength - 1;
Bounds trailingSelectionBounds = getCharacterBounds(from);
x = trailingSelectionBounds.x + trailingSelectionBounds.width;
}
int offset = getNextInsertionPoint(x, from, Direction.FORWARD);
if (offset == -1) {
offset = documentView.getCharacterCount() - 1;
} else {
// If the next character is a paragraph terminator and is not the
// final terminator character, increment the selection
if (document.getCharacterAt(offset) == '\n'
&& offset < documentView.getCharacterCount() - 1) {
offset++;
}
}
textArea.setSelection(selectionStart, offset - selectionStart);
scrollCharacterToVisible(offset);
} else {
int from;
if (selectionLength == 0) {
// Get next insertion point from leading selection character
from = selectionStart;
} else {
// Get next insertion point from trailing selection character
from = selectionStart + selectionLength - 1;
}
int offset = getNextInsertionPoint(caretX, from, Direction.FORWARD);
if (offset == -1) {
offset = documentView.getCharacterCount() - 1;
}
textArea.setSelection(offset, 0);
scrollCharacterToVisible(offset);
}
consumed = true;
} else if (Keyboard.isPressed(commandModifier)) {
if (keyCode == Keyboard.KeyCode.A) {
textArea.setSelection(0, document.getCharacterCount());
consumed = true;
} else if (keyCode == Keyboard.KeyCode.X
&& textArea.isEditable()) {
textArea.cut();
consumed = true;
} else if (keyCode == Keyboard.KeyCode.C) {
textArea.copy();
consumed = true;
} else if (keyCode == Keyboard.KeyCode.V
&& textArea.isEditable()) {
textArea.paste();
consumed = true;
} else if (keyCode == Keyboard.KeyCode.Z
&& textArea.isEditable()) {
if (Keyboard.isPressed(Keyboard.Modifier.SHIFT)) {
textArea.undo();
} else {
textArea.redo();
}
consumed = true;
}
} else {