1 /* 2 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.jemmy.fx.control; 26 27 import javafx.scene.control.Menu; 28 import javafx.scene.control.MenuBar; 29 import javafx.scene.control.MenuItem; 30 import org.jemmy.action.FutureAction; 31 import org.jemmy.control.As; 32 import org.jemmy.control.ControlInterfaces; 33 import org.jemmy.control.ControlType; 34 import org.jemmy.env.Environment; 35 import org.jemmy.fx.NodeWrap; 36 import org.jemmy.input.StringMenuOwner; 37 import org.jemmy.interfaces.Collapsible; 38 import org.jemmy.interfaces.Focus; 39 import org.jemmy.interfaces.Parent; 40 41 import java.util.List; 42 43 /** 44 * Menu is supported in two different form.<br/> 45 * One is by using <code>MenuOwner</code> control interface. There you could 46 * perform basic menu pushing or selecting. Select operation returns a wrap, 47 * which you could pass into a constructor of a dock or use directly.<br/> 48 * The other approach is to use MenuItemDock which allows advanced lookup and 49 * more input operations.<br/> 50 * Please consult <a href="../../samples/menu">samples</a> for more info. 51 * 52 * @param <CONTROL> 53 * @author shura 54 * @see MenuItemWrap 55 * @see StringMenuOwner 56 * @see MenuBarDock 57 */ 58 @ControlType({MenuBar.class}) 59 @ControlInterfaces(value = {Parent.class, StringMenuOwner.class, Collapsible.class}, 60 encapsulates = {MenuItem.class, MenuItem.class}, name = {"asMenuParent", "asMenuOwner"}) 61 public class MenuBarWrap<CONTROL extends MenuBar> extends NodeWrap<CONTROL> { 62 63 private StringMenuOwnerImpl menuOwner = null; 64 private Parent<MenuItem> parent = null; 65 private Focus focus = ThemeDriverFactory.getThemeFactory().menuBarFocuser(this); 66 67 /** 68 * @param env 69 * @param nd 70 */ 71 @SuppressWarnings("unchecked") 72 public MenuBarWrap(Environment env, CONTROL nd) { 73 super(env, nd); 74 } 75 76 /** 77 * Turns into a parent which you could use to look for menu items within. <br/> 78 * Notice that the lookup is performed through the whole hierarchy. You only 79 * need to specify criteria for a single menu item no matter how deep in the 80 * hierarchy it resides. <br/> 81 * Notice also that menus are sometimes dynamic - that is, 82 * sub-items are only loaded when a parent is expanded. If a node is not loaded, 83 * this lookup would not find it. You need to find a parent node in question, 84 * expand it, and use it as a root for further search. 85 * 86 * @return 87 * @see MenuWrap#asMenuParent() 88 */ 89 @As(MenuItem.class) 90 public Parent<MenuItem> asMenuParent() { 91 if (parent == null) { 92 parent = new MenuItemParent(this) { 93 94 @Override 95 protected List getControls() { 96 return new FutureAction<>(getEnvironment(),()-> getControl().getMenus()).get(); 97 } 98 }; 99 } 100 return parent; 101 } 102 103 /** 104 * Allows to perform simple push and selection operations on the menu. 105 * 106 * @return 107 */ 108 @As(MenuItem.class) 109 public StringMenuOwner<MenuItem> asMenuOwner() { 110 if (menuOwner == null) { 111 menuOwner = new StringMenuOwnerImpl(this, (Parent <Menu>)this.as(Parent.class, Menu.class)); 112 } 113 return menuOwner; 114 } 115 116 private Collapsible collapsible = null; 117 118 /** 119 * Collapses ass the sub-menus. 120 * 121 * @return 122 */ 123 @As 124 public Collapsible asCollapsible() { 125 if (collapsible == null) { 126 collapsible = () -> new FutureAction<>(getEnvironment(),() -> getControl().getMenus().stream().forEach(m -> m.hide())); 127 } 128 return collapsible; 129 } 130 131 @Override 132 public Focus focuser() { 133 return focus; 134 } 135 136 @Override 137 public boolean isFocused() { 138 return true; // stab: currently no way to detemine pseudo-focused state 139 } 140 }