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.MenuButton; 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.control.Property; 35 import org.jemmy.env.Environment; 36 import org.jemmy.input.StringMenuOwner; 37 import org.jemmy.interfaces.Collapsible; 38 import org.jemmy.interfaces.Expandable; 39 import org.jemmy.interfaces.Parent; 40 import org.jemmy.timing.State; 41 42 import java.util.List; 43 44 /** 45 * Menu button is supported in the very same way as menu bar. 46 * Please consult <a href="../../samples/menu">samples</a> for more info. 47 * 48 * @param <CONTROL> 49 * @author shura 50 * @see MenuBarWrap 51 * @see MenuButtonDock 52 */ 53 @ControlType({MenuButton.class}) 54 @ControlInterfaces(value = {Parent.class, StringMenuOwner.class, Expandable.class, Collapsible.class}, 55 encapsulates = {MenuItem.class, MenuItem.class}, name = {"asMenuParent", "asMenuOwner"}) 56 public class MenuButtonWrap<CONTROL extends MenuButton> extends TextControlWrap<CONTROL> { 57 58 private StringMenuOwnerImpl menuOwner = null; 59 private Parent<MenuItem> parent = null; 60 61 /** 62 * @param env 63 * @param nd 64 */ 65 @SuppressWarnings("unchecked") 66 public MenuButtonWrap(Environment env, CONTROL nd) { 67 super(env, nd); 68 } 69 70 @Property("isShowing") 71 public boolean isShowing() { 72 return new FutureAction<>(getEnvironment(), () -> getControl().isShowing()).get(); 73 } 74 75 /** 76 * @return 77 * @see MenuBarWrap#asMenuParent() 78 */ 79 @As(MenuItem.class) 80 public Parent<MenuItem> asMenuParent() { 81 if (parent == null) { 82 parent = new MenuItemParent(this) { 83 84 @Override 85 protected List getControls() { 86 return new FutureAction<>(getEnvironment(), () -> getControl().getItems()).get(); 87 } 88 }; 89 } 90 return parent; 91 } 92 93 /** 94 * @return 95 * @see MenuBarWrap#asMenuOwner() 96 */ 97 @As(MenuItem.class) 98 public StringMenuOwner<MenuItem> asMenuOwner() { 99 if (menuOwner == null) { 100 menuOwner = new StringMenuOwnerImpl(this, (Parent <Menu>)this.as(Parent.class, Menu.class)) { 101 102 @Override 103 protected void prepare() { 104 if (!isShowing()) { 105 mouse().click(); 106 getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(true, 107 showingState); 108 } 109 } 110 }; 111 } 112 return menuOwner; 113 } 114 115 private Expandable expandable = null; 116 private State<Boolean> showingState = this::isShowing; 117 118 /** 119 * Clicks on the button if the menu is not visible. 120 * 121 * @return 122 */ 123 @As 124 public Expandable asExpandable() { 125 if (expandable == null) { 126 expandable = () -> { 127 if (!isShowing()) 128 invokeExpandOrCollapseAction(); 129 waitState(showingState, true); 130 }; 131 } 132 return expandable; 133 } 134 135 private Collapsible collapsible = null; 136 137 /** 138 * Clicks on the button if the menu is visible. 139 * 140 * @return 141 */ 142 @As 143 public Collapsible asCollapsible() { 144 if (collapsible == null) { 145 collapsible = () -> { 146 if (isShowing()) 147 invokeExpandOrCollapseAction(); 148 waitState(showingState, false); 149 }; 150 151 } 152 return collapsible; 153 } 154 155 protected void invokeExpandOrCollapseAction() { 156 mouse().click(); 157 } 158 }