/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.scene.control.behavior;
import com.sun.javafx.scene.NodeHelper;
import com.sun.javafx.scene.traversal.Direction;
import javafx.event.EventTarget;
import javafx.scene.Node;
import com.sun.javafx.scene.control.inputmap.InputMap;
import com.sun.javafx.scene.control.inputmap.KeyBinding;
import javafx.scene.input.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import static com.sun.javafx.scene.control.inputmap.InputMap.*;
import static javafx.scene.input.KeyCode.DOWN;
import static javafx.scene.input.KeyCode.LEFT;
import static javafx.scene.input.KeyCode.RIGHT;
import static javafx.scene.input.KeyCode.TAB;
import static javafx.scene.input.KeyCode.UP;
public class FocusTraversalInputMap<N extends Node> {
private static final List<InputMap.Mapping<?>> mappings = new ArrayList<>();
static {
mappings.add(new KeyMapping(UP, e -> traverseUp(e)));
mappings.add(new KeyMapping(DOWN, e -> traverseDown(e)));
mappings.add(new KeyMapping(LEFT, e -> traverseLeft(e)));
mappings.add(new KeyMapping(RIGHT, e -> traverseRight(e)));
mappings.add(new KeyMapping(TAB, e -> traverseNext(e)));
mappings.add(new KeyMapping(new KeyBinding(TAB).shift(), e -> traversePrevious(e)));
mappings.add(new KeyMapping(new KeyBinding(UP).shift().alt().ctrl(), e -> traverseUp(e)));
mappings.add(new KeyMapping(new KeyBinding(DOWN).shift().alt().ctrl(), e -> traverseDown(e)));
mappings.add(new KeyMapping(new KeyBinding(LEFT).shift().alt().ctrl(), e -> traverseLeft(e)));
mappings.add(new KeyMapping(new KeyBinding(RIGHT).shift().alt().ctrl(), e -> traverseRight(e)));
mappings.add(new KeyMapping(new KeyBinding(TAB).shift().alt().ctrl(), e -> traverseNext(e)));
mappings.add(new KeyMapping(new KeyBinding(TAB).alt().ctrl(), e -> traversePrevious(e)));
}
private FocusTraversalInputMap() {
// no-op, just forcing use of static method
}
public static InputMap.Mapping<?>[] getFocusTraversalMappings() {
return mappings.toArray(new InputMap.Mapping[mappings.size()]);
}
public static <N extends Node> InputMap<N> createInputMap(N node) {
InputMap<N> inputMap = new InputMap<>(node);
inputMap.getMappings().addAll(getFocusTraversalMappings());
return inputMap;
}
/***************************************************************************
* Focus Traversal methods *
**************************************************************************/
Called by any of the BehaviorBase traverse methods to actually effect a
traversal of the focus. The default behavior of this method is to simply
traverse on the given node, passing the given direction. A
subclass may override this method.
Params: - node – The node to traverse on
- dir – The direction to traverse
/**
* Called by any of the BehaviorBase traverse methods to actually effect a
* traversal of the focus. The default behavior of this method is to simply
* traverse on the given node, passing the given direction. A
* subclass may override this method.
*
* @param node The node to traverse on
* @param dir The direction to traverse
*/
public static void traverse(final Node node, final Direction dir) {
if (node == null) {
throw new IllegalArgumentException("Attempting to traverse on a null Node. " +
"Most probably a KeyEvent has been fired with a null target specified.");
}
NodeHelper.traverse(node, dir);
}
Calls the focus traversal engine and indicates that traversal should
go the next focusTraversable Node above the current one.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the next focusTraversable Node above the current one.
*/
public static final void traverseUp(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.UP);
}
Calls the focus traversal engine and indicates that traversal should
go the next focusTraversable Node below the current one.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the next focusTraversable Node below the current one.
*/
public static final void traverseDown(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.DOWN);
}
Calls the focus traversal engine and indicates that traversal should
go the next focusTraversable Node left of the current one.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the next focusTraversable Node left of the current one.
*/
public static final void traverseLeft(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.LEFT);
}
Calls the focus traversal engine and indicates that traversal should
go the next focusTraversable Node right of the current one.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the next focusTraversable Node right of the current one.
*/
public static final void traverseRight(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.RIGHT);
}
Calls the focus traversal engine and indicates that traversal should
go the next focusTraversable Node in the focus traversal cycle.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the next focusTraversable Node in the focus traversal cycle.
*/
public static final void traverseNext(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.NEXT);
}
Calls the focus traversal engine and indicates that traversal should
go the previous focusTraversable Node in the focus traversal cycle.
/**
* Calls the focus traversal engine and indicates that traversal should
* go the previous focusTraversable Node in the focus traversal cycle.
*/
public static final void traversePrevious(KeyEvent e) {
traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.PREVIOUS);
}
private static Node getNode(KeyEvent e) {
EventTarget target = e.getTarget();
if (target instanceof Node) {
return (Node) target;
}
return null;
}
}