I need to have a control which will wordwrap, add scrollbars, etc - but ignore the enter key and jump to the next control using tab/shift tab. I can\'t seem to get this right.
I think I found a solution which will allow me to have this work as designed.
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
this.setWrapText(true);
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
private class TabAndEnterHandler implements EventHandler<KeyEvent> {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.ENTER) {
event.consume();
if(event.getCode() == KeyCode.TAB){
selectNextNode(!event.isShiftDown());
}
}
}
private void selectNextNode(boolean forward){
List<Node> nodes = getAllNodes(myTextArea.getScene().getRoot());
int index = nodes.indexOf(myTextArea);
if(forward){
if(index < nodes.size() - 1) {
nodes.get(index + 1).requestFocus();
}else {
nodes.get(0).requestFocus();
}
}else {
if(index == 0) {
nodes.get(nodes.size() - 1).requestFocus();
}else {
nodes.get(index - 1).requestFocus();
}
}
}
private ArrayList<Node> getAllNodes(Parent root) {
ArrayList<Node> nodes = new ArrayList<Node>();
addAllDescendents(root, nodes);
return nodes;
}
private void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
if(node.isFocusTraversable()){
nodes.add(node);
}
if (node instanceof Parent)
addAllDescendents((Parent)node, nodes);
}
}
}
}
If you see anything wrong with this approach I would appreciate it, but it seems to work for my purposes.