All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.javafx.scene.control.behavior.BehaviorBase Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010, 2013, 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 javafx.css.PseudoClass;
import javafx.event.EventHandler;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.control.Control;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import com.sun.javafx.scene.traversal.Direction;

import static javafx.scene.input.KeyCode.*;

/**
 * A convenient base class from which all our built-in behaviors extend. The
 * main functionality in BehaviorBase revolves around infrastructure for
 * resolving key events into function calls. The differences between platforms
 * can be subtle, and we attempt to build sufficient infrastructure into
 * BehaviorBase to minimize the amount of code and the complexity of code
 * necessary to support multiple platforms sufficiently well.
 * 

* BehaviorBase also implements the hooks for focus traversal. This * implementation is sufficient for most subclasses of BehaviorBase. The * following action names are registered in the keyMap for handling focus * traversal. Subclasses which need to invoke focus traversal using non-standard * key strokes should map key strokes to these action names: *

    *
  • TraverseUp
  • *
  • TraverseDown
  • *
  • TraverseLeft
  • *
  • TraverseRight
  • *
  • TraverseNext
  • *
  • TraversePrevious
  • *
*

* Note that by convention, action names are camel case with the first letter * uppercase, matching class naming conventions. */ public class BehaviorBase { /** * The default key bindings for focus traversal. For many behavior * implementations, you may be able to use this directly. The built in names * for these traversal actions are: *

    *
  • TraverseUp
  • *
  • TraverseDown
  • *
  • TraverseLeft
  • *
  • TraverseRight
  • *
  • TraverseNext
  • *
  • TraversePrevious
  • *
*/ protected static final List TRAVERSAL_BINDINGS = new ArrayList(); static { TRAVERSAL_BINDINGS.add(new KeyBinding(UP, "TraverseUp")); TRAVERSAL_BINDINGS.add(new KeyBinding(DOWN, "TraverseDown")); TRAVERSAL_BINDINGS.add(new KeyBinding(LEFT, "TraverseLeft")); TRAVERSAL_BINDINGS.add(new KeyBinding(RIGHT, "TraverseRight")); TRAVERSAL_BINDINGS.add(new KeyBinding(TAB, "TraverseNext")); TRAVERSAL_BINDINGS.add(new KeyBinding(TAB, "TraversePrevious").shift()); TRAVERSAL_BINDINGS.add(new KeyBinding(UP, "TraverseUp").shift().alt().ctrl()); TRAVERSAL_BINDINGS.add(new KeyBinding(DOWN, "TraverseDown").shift().alt().ctrl()); TRAVERSAL_BINDINGS.add(new KeyBinding(LEFT, "TraverseLeft").shift().alt().ctrl()); TRAVERSAL_BINDINGS.add(new KeyBinding(RIGHT, "TraverseRight").shift().alt().ctrl()); TRAVERSAL_BINDINGS.add(new KeyBinding(TAB, "TraverseNext").shift().alt().ctrl()); TRAVERSAL_BINDINGS.add(new KeyBinding(TAB, "TraversePrevious").alt().ctrl()); } protected static final List EMPTY_BINDINGS = new ArrayList(); /** * The Control with which this Behavior is used. This must be specified in * the constructor and must not be null. */ private C control; /** * The key bindings for this Behavior. */ private List keyBindings = createKeyBindings(); /** * Create a new BehaviorBase for the given control. The Control must not * be null. * @param control */ public BehaviorBase(C control) { this.control = control; control.addEventHandler(KeyEvent.ANY, keyEventListener); } private final EventHandler keyEventListener = new EventHandler() { @Override public void handle(KeyEvent e) { if (!e.isConsumed()) { callActionForEvent(e); } } }; /** * Called during initialization to compute the set of key bindings which * should be applied for this behavior. This method should NOT mutate the * List after having returned it. * * @return a non-null list of key bindings. */ protected List createKeyBindings() { return EMPTY_BINDINGS; } /*************************************************************************** * Implementation of the Behavior interface * **************************************************************************/ public final C getControl() { return control; } protected /*final*/ String matchActionForEvent(KeyEvent e) { KeyBinding match = null; int specificity = 0; // keyBindings may be null... int maxBindings = keyBindings.size(); for (int i = 0; i < maxBindings; i++) { KeyBinding binding = keyBindings.get(i); int s = binding.getSpecificity(control, e); if (s > specificity) { specificity = s; match = binding; } } String action = null; if (match != null) { action = match.getAction(); if (e.getCode() == LEFT || e.getCode() == RIGHT) { if (control.getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) { if (match.getAction().equals("TraverseLeft")) { action = "TraverseRight"; } else { if (match.getAction().equals("TraverseRight")) { action = "TraverseLeft"; } } } } } return action; } protected /*final*/ void callActionForEvent(KeyEvent e) { String action = matchActionForEvent(e); if (action != null) { callAction(action); e.consume(); } } /** * Called to invoke the action associated with the given name. *

* When a KeyEvent is handled, it is first passed through * callActionForEvent which resolves which "action" should be executed * based on the key event. This action is indicated by name. This name is * then passed to this function which is responsible for invoking the right * function based on the name. *

*/ protected void callAction(String name) { if ("TraverseUp".equals(name)) traverseUp(); else if ("TraverseDown".equals(name)) traverseDown(); else if ("TraverseLeft".equals(name)) traverseLeft(); else if ("TraverseRight".equals(name)) traverseRight(); else if ("TraverseNext".equals(name)) traverseNext(); else if ("TraversePrevious".equals(name)) traversePrevious(); } /*************************************************************************** * Focus Traversal methods * **************************************************************************/ public void traverse(Node node, Direction dir) { node.impl_traverse(dir); } /** * Calls the focus traversal engine and indicates that traversal should * go the next focusTraversable Node above the current one. */ public void traverseUp() { traverse(control, 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. */ public void traverseDown() { traverse(control, 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. */ public void traverseLeft() { traverse(control, 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. */ public void traverseRight() { traverse(control, 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. */ public void traverseNext() { traverse(control, 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. */ public void traversePrevious() { traverse(control, com.sun.javafx.scene.traversal.Direction.PREVIOUS); } /*************************************************************************** * Mouse handlers * * TODO I'm not sure why only mouse events are here. What about drag and * * drop events for instance? What about touch events? What about the * * other mouse events? It does seem like these need to be here, because * * for example mouse interaction logic might differ from platform to * * platform, and the Behavior is supposed to implement all the user * * interaction logic (not just key handling). So it seems like * * BehaviorBase should have methods for handling all forms of input events,* * and not just these four mouse events. * **************************************************************************/ /** * Invoked by a Skin when the body of the control has been pressed by * the mouse. Subclasses should be sure to call super unless they intend * to disable any built-in support. * * @param e */ public void mousePressed(MouseEvent e) { } /** * Invoked by a Skin when the body of the control has been dragged by * the mouse. Subclasses should be sure to call super unless they intend * to disable any built-in support (for example, for tooltips). * * @param e */ public void mouseDragged(MouseEvent e) { } /** * Invoked by a Skin when the body of the control has been released by * the mouse. Subclasses should be sure to call super unless they intend * to disable any built-in support (for example, for tooltips). * * @param e */ public void mouseReleased(MouseEvent e) { } /** * Invoked by a Skin when the body of the control has been entered by * the mouse. Subclasses should be sure to call super unless they intend * to disable any built-in support. * * @param e */ public void mouseEntered(MouseEvent e) { } /** * Invoked by a Skin when the body of the control has been exited by * the mouse. Subclasses should be sure to call super unless they intend * to disable any built-in support. * * @param e */ public void mouseExited(MouseEvent e) { } /** * @see Node#pseudoClassStateChanged() */ public final void pseudoClassStateChanged(PseudoClass pseudoClass, boolean active) { Control ctl = getControl(); if (ctl != null) { ctl.pseudoClassStateChanged(pseudoClass, active); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy