modules/controls/src/main/java/com/sun/javafx/scene/control/behavior/MenuButtonBehaviorBase.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

*** 1,7 **** /* ! * Copyright (c) 2010, 2014, 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 --- 1,7 ---- /* ! * Copyright (c) 2010, 2015, 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
*** 23,126 **** * questions. */ package com.sun.javafx.scene.control.behavior; - import static javafx.scene.input.KeyCode.UP; - 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.CANCEL; - import static javafx.scene.input.KeyCode.ESCAPE; - import static javafx.scene.input.KeyEvent.KEY_PRESSED; - - import java.util.ArrayList; - import java.util.List; - - import javafx.geometry.NodeOrientation; import javafx.geometry.Side; import javafx.scene.control.MenuButton; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; /** * The base behavior for a MenuButton. */ public abstract class MenuButtonBehaviorBase<C extends MenuButton> extends ButtonBehavior<C> { ! /*************************************************************************** ! * * ! * Constructors * ! * * ! **************************************************************************/ ! ! public MenuButtonBehaviorBase(final C menuButton, List<KeyBinding> bindings) { ! super(menuButton, bindings); ! } /*************************************************************************** * * ! * Key event handling * * * **************************************************************************/ ! /** ! * Opens the popup menu. ! */ ! protected static final String OPEN_ACTION = "Open"; ! /** ! * Closes the popup menu. ! */ ! protected static final String CLOSE_ACTION = "Close"; /** * The base key bindings for a MenuButton. These basically just define the * bindings to close an open menu. Subclasses will tell you what can be done * to open it. */ ! protected static final List<KeyBinding> BASE_MENU_BUTTON_BINDINGS = new ArrayList<KeyBinding>(); ! static { ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(UP, "TraverseUp")); ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(DOWN, "TraverseDown")); ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(LEFT, "TraverseLeft")); ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(RIGHT, "TraverseRight")); ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(ESCAPE, KEY_PRESSED, CLOSE_ACTION)); ! BASE_MENU_BUTTON_BINDINGS.add(new KeyBinding(CANCEL, KEY_PRESSED, CLOSE_ACTION)); ! } ! /** ! * Invokes the given named action. ! * ! * @param name the name of the action to invoke ! */ ! @Override protected void callAction(String name) { ! MenuButton button = getControl(); ! Side popupSide = button.getPopupSide(); ! ! if (CLOSE_ACTION.equals(name)) { ! button.hide(); ! } else if (OPEN_ACTION.equals(name)) { ! if (button.isShowing()) { ! button.hide(); ! } else { ! button.show(); } ! } else if (!button.isShowing() && ! ("TraverseUp".equals(name) && popupSide == Side.TOP) || ! ("TraverseDown".equals(name) && (popupSide == Side.BOTTOM || popupSide == Side.TOP)) || ! ("TraverseLeft".equals(name) && (popupSide == Side.RIGHT || popupSide == Side.LEFT)) || ! ("TraverseRight".equals(name) && (popupSide == Side.RIGHT || popupSide == Side.LEFT))) { // Show the menu when arrow key matches the popupSide // direction -- but also allow RIGHT key for LEFT position and // DOWN key for TOP position. To be symmetrical, we also allow for // the LEFT key to work when in the RIGHT position. This is needed // because the skin only paints right- and down-facing arrows in // these cases. button.show(); } else { ! super.callAction(name); } } /*************************************************************************** * * --- 23,114 ---- * questions. */ package com.sun.javafx.scene.control.behavior; import javafx.geometry.Side; import javafx.scene.control.MenuButton; + import com.sun.javafx.scene.control.inputmap.InputMap; + import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; + import static com.sun.javafx.scene.control.inputmap.InputMap.KeyMapping; + import static javafx.scene.input.KeyCode.*; + /** * The base behavior for a MenuButton. */ public abstract class MenuButtonBehaviorBase<C extends MenuButton> extends ButtonBehavior<C> { ! private final InputMap<C> buttonInputMap; /*************************************************************************** * * ! * Constructors * * * **************************************************************************/ ! public MenuButtonBehaviorBase(final C menuButton) { ! super(menuButton); ! // pull down the parent input map, no need to add focus traversal ! // mappings - added in ButtonBehavior. ! buttonInputMap = super.getInputMap(); ! ! // We want to remove the maping for MOUSE_RELEASED, as the event is ! // handled by the skin instead, which calls the mouseReleased method below. ! removeMapping(MouseEvent.MOUSE_RELEASED); /** * The base key bindings for a MenuButton. These basically just define the * bindings to close an open menu. Subclasses will tell you what can be done * to open it. */ ! addDefaultMapping(new KeyMapping(ESCAPE, e -> getNode().hide())); ! addDefaultMapping(new KeyMapping(CANCEL, e -> getNode().hide())); ! // we create a child input map, as we want to override some of the ! // focus traversal behaviors (and child maps take precedence over parent maps) ! InputMap<C> customFocusInputMap = new InputMap<>(menuButton); ! addDefaultMapping(customFocusInputMap, new KeyMapping(UP, this::overrideTraversalInput)); ! addDefaultMapping(customFocusInputMap, new KeyMapping(DOWN, this::overrideTraversalInput)); ! addDefaultMapping(customFocusInputMap, new KeyMapping(LEFT, this::overrideTraversalInput)); ! addDefaultMapping(customFocusInputMap, new KeyMapping(RIGHT, this::overrideTraversalInput)); ! addDefaultChildMap(buttonInputMap, customFocusInputMap); } ! ! ! /*************************************************************************** ! * * ! * Key event handling * ! * * ! **************************************************************************/ ! ! private void overrideTraversalInput(KeyEvent event) { ! final MenuButton button = getNode(); ! final Side popupSide = button.getPopupSide(); ! if (!button.isShowing() && ! (event.getCode() == UP && popupSide == Side.TOP) || ! (event.getCode() == DOWN && (popupSide == Side.BOTTOM || popupSide == Side.TOP)) || ! (event.getCode() == LEFT && (popupSide == Side.RIGHT || popupSide == Side.LEFT)) || ! (event.getCode() == RIGHT && (popupSide == Side.RIGHT || popupSide == Side.LEFT))) { // Show the menu when arrow key matches the popupSide // direction -- but also allow RIGHT key for LEFT position and // DOWN key for TOP position. To be symmetrical, we also allow for // the LEFT key to work when in the RIGHT position. This is needed // because the skin only paints right- and down-facing arrows in // these cases. button.show(); + } + } + + protected void openAction() { + if (getNode().isShowing()) { + getNode().hide(); } else { ! getNode().show(); } } /*************************************************************************** * *
*** 134,144 **** * * @param e the mouse press event * @param behaveLikeButton if true, this should act just like a button */ public void mousePressed(MouseEvent e, boolean behaveLikeButton) { ! final C control = getControl(); /* * Behaving like a button is easy - we just call super. But, we cannot * call super if all we want to do is show the popup. The reason for * this is that super also handles all the arm/disarm/fire logic, and --- 122,132 ---- * * @param e the mouse press event * @param behaveLikeButton if true, this should act just like a button */ public void mousePressed(MouseEvent e, boolean behaveLikeButton) { ! final C control = getNode(); /* * Behaving like a button is easy - we just call super. But, we cannot * call super if all we want to do is show the popup. The reason for * this is that super also handles all the arm/disarm/fire logic, and
*** 163,190 **** } } } } - @Override public void mouseReleased(MouseEvent e) { - // Overriding to not call fire() on mouseReleased. - // The event is handled by the skin instead, which calls - // the method below. - } - /** * Handles mouse release events. This will be called by the skin. * * @param e the mouse press event * @param behaveLikeButton if true, this should act just like a button */ public void mouseReleased(MouseEvent e, boolean behaveLikeButton) { if (behaveLikeButton) { super.mouseReleased(e); } else { ! if (getControl().isShowing() && !getControl().contains(e.getX(), e.getY())) { ! getControl().hide(); } ! getControl().disarm(); } } } --- 151,172 ---- } } } } /** * Handles mouse release events. This will be called by the skin. * * @param e the mouse press event * @param behaveLikeButton if true, this should act just like a button */ public void mouseReleased(MouseEvent e, boolean behaveLikeButton) { if (behaveLikeButton) { super.mouseReleased(e); } else { ! if (getNode().isShowing() && !getNode().contains(e.getX(), e.getY())) { ! getNode().hide(); } ! getNode().disarm(); } } }