1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
---
title: MenuBar
order: 26
layout: page
---
[[components.menubar]]
= MenuBar
ifdef::web[]
[.sampler]
image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/interaction/menu-bar"]
endif::web[]
The [classname]#MenuBar# component allows creating horizontal drop-down menus, much like the main menu in desktop applications.
[[figure.components.menubar]]
.Menu Bar
image::img/menubar-example1.png[width=40%, scaledwidth=60%]
The menu items open as the user navigates them by hovering or clicking with the mouse.
Menus can have separators to divide items into sub-sections.
Menu items can have an icon and styling.
They can also be checkable, so that the user can click on them to toggle between checked and unchecked.
[[components.menubar.creation]]
== Creating a Menu
The actual menu bar component is first created as follows:
[source, java]
----
MenuBar barmenu = new MenuBar();
main.addComponent(barmenu);
----
You insert the top-level menu items to the [classname]#MenuBar# object with the
[methodname]#addItem()# method. It takes a string label, an icon resource, and a
command as its parameters. The icon and command are not required and can be
[parameter]#null#. The [methodname]#addItem()# method returns a
[classname]#MenuBar.MenuItem# object, which you can use to add sub-menu items.
The [classname]#MenuItem# has an identical [methodname]#addItem()# method.
For example (the command is explained later):
[source, java]
----
// A top-level menu item that opens a submenu
MenuItem drinks = barmenu.addItem("Beverages", null, null);
// Submenu item with a sub-submenu
MenuItem hots = drinks.addItem("Hot", null, null);
hots.addItem("Tea",
new ThemeResource("icons/tea-16px.png"), mycommand);
hots.addItem("Coffee",
new ThemeResource("icons/coffee-16px.png"), mycommand);
// Another submenu item with a sub-submenu
MenuItem colds = drinks.addItem("Cold", null, null);
colds.addItem("Milk", null, mycommand);
colds.addItem("Weissbier", null, mycommand);
// Another top-level item
MenuItem snacks = barmenu.addItem("Snacks", null, null);
snacks.addItem("Weisswurst", null, mycommand);
snacks.addItem("Bratwurst", null, mycommand);
snacks.addItem("Currywurst", null, mycommand);
// Yet another top-level item
MenuItem servs = barmenu.addItem("Services", null, null);
servs.addItem("Car Service", null, mycommand);
----
[[components.menubar.commands]]
== Handling Menu Selection
Menu selection is handled by executing a __command__ when the user selects an
item from the menu. A command is a call-back class that implements the
[classname]#MenuBar.Command# interface.
[source, java]
----
// A feedback component
final Label selection = new Label("-");
main.addComponent(selection);
// Define a common menu command for all the menu items.
MenuBar.Command mycommand = new MenuBar.Command() {
public void menuSelected(MenuItem selectedItem) {
selection.setValue("Ordered a " +
selectedItem.getText() +
" from menu.");
}
};
----
ifdef::web[]
[[components.menubar.menuitem]]
== Menu Items
Menu items have properties such as a caption, icon, enabled, visible, and
description (tooltip). The meaning of these is the same as for components.
Submenus are created by adding sub-items to an item with [methodname]#addItem()#
or [methodname]#addItemBefore()#.
The __command__ property is a [classname]#MenuBar.Command# that is called when
the particular menu item is selected. The [methodname]#menuSelected()# callback
gets the clicked menu item as its parameter.
Menus can have __separators__, which are defined before or after an item with
[methodname]#addSeparatorBefore()# or [methodname]#addSeparator()# on the item,
respectively.
[source, java]
----
MenuItem drinks = barmenu.addItem("Beverages", null, null);
...
// A sub-menu item after a separator
drinks.addSeparator();
drinks.addItem("Quit Drinking", null, null);
----
Enabling __checkable__ on an menu item with [methodname]#setCheckable()# allows
the user to switch between checked and unchecked state by clicking on the item.
You can set the checked state with [methodname]#setChecked()#. Note that if such
an item has a command, the checked state is not flipped automatically, but you
need to do it explicitly.
Menu items have various other properties as well, see the API documentation for
more details.
endif::web[]
[[components.menubar.css]]
== CSS Style Rules
[source, css]
----
.v-menubar { }
.v-menubar-submenu { }
.v-menubar-menuitem { }
.v-menubar-menuitem-caption { }
.v-menubar-menuitem-selected { }
.v-menubar-submenu-indicator { }
----
The menu bar has the overall style name [literal]#++.v-menubar++#. Each menu
item has [literal]#++.v-menubar-menuitem++# style normally and additionally
[literal]#++.v-menubar-selected++# when the item is selected, that is, when the
mouse pointer hovers over it. The item caption is inside a
[literal]#++v-menubar-menuitem-caption++#. In the top-level menu bar, the items
are directly under the component element.
Submenus are floating [literal]#++v-menubar-submenu++# elements outside the menu
bar element. Therefore, you should not try to match on the component element for
the submenu popups. In submenus, any further submenu levels are indicated with a
[literal]#++v-menubar-submenu-indicator++#.
ifdef::web[]
[[components.menubar.css.menuitems]]
=== Styling Menu Items
You can set the CSS style name for the menu items with
[methodname]#setStyleName()#, just like for components. The style name will be
prepended with [literal]#++v-menubar-menuitem-++#. As [classname]#MenuBar# does
not indicate the previous selection in any way, you can do that by highlighting
the previously selected item. However, beware that the [literal]#++selected++#
style for menu items, that is, [literal]#++v-menubar-menuitem-selected++#, is
reserved for mouse-hover indication.
[source, java]
----
MenuBar barmenu = new MenuBar();
barmenu.addStyleName("mybarmenu");
layout.addComponent(barmenu);
// A feedback component
final Label selection = new Label("-");
layout.addComponent(selection);
// Define a common menu command for all the menu items
MenuBar.Command mycommand = new MenuBar.Command() {
MenuItem previous = null;
public void menuSelected(MenuItem selectedItem) {
selection.setValue("Ordered a " +
selectedItem.getText() +
" from menu.");
if (previous != null)
previous.setStyleName(null);
selectedItem.setStyleName("highlight");
previous = selectedItem;
}
};
// Put some items in the menu
barmenu.addItem("Beverages", null, mycommand);
barmenu.addItem("Snacks", null, mycommand);
barmenu.addItem("Services", null, mycommand);
----
You could then style the highlighting in CSS as follows:
[source, css]
----
.mybarmenu .v-menubar-menuitem-highlight {
background: #000040; /* Dark blue */
}
----
endif::web[]
|