28 import javafx.css.PseudoClass;
29 import javafx.beans.property.ObjectProperty;
30 import javafx.beans.property.ObjectPropertyBase;
31 import javafx.collections.FXCollections;
32 import javafx.collections.ObservableList;
33 import javafx.event.ActionEvent;
34 import javafx.event.Event;
35 import javafx.event.EventType;
36 import javafx.geometry.Side;
37 import javafx.scene.AccessibleAction;
38 import javafx.scene.AccessibleRole;
39 import javafx.scene.Node;
40 import javafx.scene.control.skin.MenuButtonSkin;
41 import javafx.beans.property.ReadOnlyBooleanProperty;
42 import javafx.beans.property.ReadOnlyBooleanWrapper;
43
44 /**
45 * MenuButton is a button which, when clicked or pressed, will show a
46 * {@link ContextMenu}. A MenuButton shares a very similar API to the {@link Menu}
47 * control, insofar that you set the items that should be shown in the
48 * {@link #items} ObservableList, and there is a {@link #text} property to specify the
49 * label shown within the MenuButton.
50 * <p>
51 * As mentioned, like the Menu API itself, you'll find an {@link #items} ObservableList
52 * within which you can provide anything that extends from {@link MenuItem}.
53 * There are several useful subclasses of {@link MenuItem} including
54 * {@link RadioMenuItem}, {@link CheckMenuItem}, {@link Menu},
55 * {@link SeparatorMenuItem} and {@link CustomMenuItem}.
56 * <p>
57 * A MenuButton can be set to show its menu on any side of the button. This is
58 * specified using the {@link #popupSideProperty() popupSide} property. By default
59 * the menu appears below the button. However, regardless of the popupSide specified,
60 * if there is not enough room, the {@link ContextMenu} will be
61 * smartly repositioned, most probably to be on the opposite side of the
62 * MenuButton.
63 *
64 * <p>Example:</p>
65 * <pre>
66 * MenuButton m = new MenuButton("Eats");
67 * m.getItems().addAll(new MenuItem("Burger"), new MenuItem("Hot Dog"));
68 * </pre>
69 *
70 * <p>
71 * MnemonicParsing is enabled by default for MenuButton.
213 }
214 };
215 private void setShowing(boolean value) {
216 // these events will not fire if the showing property is bound
217 Event.fireEvent(this, value ? new Event(ON_SHOWING) :
218 new Event(ON_HIDING));
219 showing.set(value);
220 Event.fireEvent(this, value ? new Event(ON_SHOWN) :
221 new Event(ON_HIDDEN));
222 }
223 public final boolean isShowing() { return showing.get(); }
224 public final ReadOnlyBooleanProperty showingProperty() { return showing.getReadOnlyProperty(); }
225
226
227
228 /**
229 * Indicates on which side the {@link ContextMenu} should open in
230 * relation to the MenuButton. Menu items are generally laid
231 * out vertically in either case.
232 * For example, if the menu button were in a vertical toolbar on the left
233 * edge of the application, you might change {@link #popupSide} to {@code Side.RIGHT} so that
234 * the popup will appear to the right of the MenuButton.
235 *
236 * @defaultValue {@code Side.BOTTOM}
237 */
238 // TODO expose via CSS
239 private ObjectProperty<Side> popupSide;
240
241 public final void setPopupSide(Side value) {
242 popupSideProperty().set(value);
243 }
244
245 public final Side getPopupSide() {
246 return popupSide == null ? Side.BOTTOM : popupSide.get();
247 }
248
249 public final ObjectProperty<Side> popupSideProperty() {
250 if (popupSide == null) {
251 popupSide = new ObjectPropertyBase<Side>(Side.BOTTOM) {
252 @Override protected void invalidated() {
253 final Side side = get();
254 final boolean active = (side == Side.TOP) || (side == Side.BOTTOM);
|
28 import javafx.css.PseudoClass;
29 import javafx.beans.property.ObjectProperty;
30 import javafx.beans.property.ObjectPropertyBase;
31 import javafx.collections.FXCollections;
32 import javafx.collections.ObservableList;
33 import javafx.event.ActionEvent;
34 import javafx.event.Event;
35 import javafx.event.EventType;
36 import javafx.geometry.Side;
37 import javafx.scene.AccessibleAction;
38 import javafx.scene.AccessibleRole;
39 import javafx.scene.Node;
40 import javafx.scene.control.skin.MenuButtonSkin;
41 import javafx.beans.property.ReadOnlyBooleanProperty;
42 import javafx.beans.property.ReadOnlyBooleanWrapper;
43
44 /**
45 * MenuButton is a button which, when clicked or pressed, will show a
46 * {@link ContextMenu}. A MenuButton shares a very similar API to the {@link Menu}
47 * control, insofar that you set the items that should be shown in the
48 * {@link #getItems() items} ObservableList, and there is a {@link #textProperty() text} property to specify the
49 * label shown within the MenuButton.
50 * <p>
51 * As mentioned, like the Menu API itself, you'll find an {@link #getItems() items} ObservableList
52 * within which you can provide anything that extends from {@link MenuItem}.
53 * There are several useful subclasses of {@link MenuItem} including
54 * {@link RadioMenuItem}, {@link CheckMenuItem}, {@link Menu},
55 * {@link SeparatorMenuItem} and {@link CustomMenuItem}.
56 * <p>
57 * A MenuButton can be set to show its menu on any side of the button. This is
58 * specified using the {@link #popupSideProperty() popupSide} property. By default
59 * the menu appears below the button. However, regardless of the popupSide specified,
60 * if there is not enough room, the {@link ContextMenu} will be
61 * smartly repositioned, most probably to be on the opposite side of the
62 * MenuButton.
63 *
64 * <p>Example:</p>
65 * <pre>
66 * MenuButton m = new MenuButton("Eats");
67 * m.getItems().addAll(new MenuItem("Burger"), new MenuItem("Hot Dog"));
68 * </pre>
69 *
70 * <p>
71 * MnemonicParsing is enabled by default for MenuButton.
213 }
214 };
215 private void setShowing(boolean value) {
216 // these events will not fire if the showing property is bound
217 Event.fireEvent(this, value ? new Event(ON_SHOWING) :
218 new Event(ON_HIDING));
219 showing.set(value);
220 Event.fireEvent(this, value ? new Event(ON_SHOWN) :
221 new Event(ON_HIDDEN));
222 }
223 public final boolean isShowing() { return showing.get(); }
224 public final ReadOnlyBooleanProperty showingProperty() { return showing.getReadOnlyProperty(); }
225
226
227
228 /**
229 * Indicates on which side the {@link ContextMenu} should open in
230 * relation to the MenuButton. Menu items are generally laid
231 * out vertically in either case.
232 * For example, if the menu button were in a vertical toolbar on the left
233 * edge of the application, you might change {@link #popupSideProperty() popupSide}
234 * to {@code Side.RIGHT} so that the popup will appear to the right of the MenuButton.
235 *
236 * @defaultValue {@code Side.BOTTOM}
237 */
238 // TODO expose via CSS
239 private ObjectProperty<Side> popupSide;
240
241 public final void setPopupSide(Side value) {
242 popupSideProperty().set(value);
243 }
244
245 public final Side getPopupSide() {
246 return popupSide == null ? Side.BOTTOM : popupSide.get();
247 }
248
249 public final ObjectProperty<Side> popupSideProperty() {
250 if (popupSide == null) {
251 popupSide = new ObjectPropertyBase<Side>(Side.BOTTOM) {
252 @Override protected void invalidated() {
253 final Side side = get();
254 final boolean active = (side == Side.TOP) || (side == Side.BOTTOM);
|