JavaFX初探(菜单)
2015-02-12 11:49
162 查看
JavaFX初探(菜单)
本节我们介绍如何创建菜单、菜单栏、增加菜单项、为菜单分类,创建子菜单、设置菜单上下文。你可以使用下面的类来创建菜单。MenuBar
MenuItem
Menu
CheckMenuItem
RadioMenuItem
CustomMenuItem
SeparatorMenuItem
ContextMenu
下图是一个典型的菜单的使用:
在应用中构建菜单
一个菜单就是一系列可操作的项目,可以根据用户的需要来表现。当一个菜单可见的时候,用户可以在某一时刻选中其中一个,在用户选中某一项时,这个菜单变成隐藏模式。通过使用菜单,我们可以节省用户界面的空间,因为有一些功能某些时间并不是总要现实出来的。菜单在菜单栏中被分组,你需要使用下面的菜单项类,当你构建一个菜单的时候。
MenuItem 创建可选项
Menu 创建子菜单
RadioButtonItem 创建一个单选项
CheckMenuItem 这个菜单项可以在选择被无选择之间转换。
为了给菜单分类,可以使用SeparatorMenuItem 类。
菜单通常在窗口的顶部,并且这些菜单是隐藏的,我们可以通过鼠标点击上下文来打开菜单。
创建菜单栏
尽管菜单栏可以放在用户界面的任何地方,但是一般情况我们放到窗口的顶部。并且菜单栏可已自动的改变自己的大小。默认情况下,每一个菜单栏中的菜单像一个按钮一样呈现出来。想想一个这样的一个应用,他显示植物的名称,图片,以及简单的描述信息。我们创建3个菜单项,:File,Edit,View.并给这三项添加菜单项。代码如下所示:
import java.util.AbstractMap.SimpleEntry; import java.util.Map.Entry; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.effect.DropShadow; import javafx.scene.effect.Effect; import javafx.scene.effect.Glow; import javafx.scene.effect.SepiaTone; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class MenuSample extends Application { final PageData[] pages = new PageData[] { new PageData("Apple", "The apple is the pomaceous fruit of the apple tree, species Malus " + "domestica in the rose family (Rosaceae). It is one of the most " + "widely cultivated tree fruits, and the most widely known of " + "the many members of genus Malus that are used by humans. " + "The tree originated in Western Asia, where its wild ancestor, " + "the Alma, is still found today.", "Malus domestica"), new PageData("Hawthorn", "The hawthorn is a large genus of shrubs and trees in the rose " + "family, Rosaceae, native to temperate regions of the Northern " + "Hemisphere in Europe, Asia and North America. " + "The name hawthorn was " + "originally applied to the species native to northern Europe, " + "especially the Common Hawthorn C. monogyna, and the unmodified " + "name is often so used in Britain and Ireland.", "Crataegus monogyna"), new PageData("Ivy", "The ivy is a flowering plant in the grape family (Vitaceae) native to" + " eastern Asia in Japan, Korea, and northern and eastern China. " + "It is a deciduous woody vine growing to 30 m tall or more given " + "suitable support, attaching itself by means of numerous small " + "branched tendrils tipped with sticky disks.", "Parthenocissus tricuspidata"), new PageData("Quince", "The quince is the sole member of the genus Cydonia and is native to " + "warm-temperate southwest Asia in the Caucasus region. The " + "immature fruit is green with dense grey-white pubescence, most " + "of which rubs off before maturity in late autumn when the fruit " + "changes color to yellow with hard, strongly perfumed flesh.", "Cydonia oblonga") }; final String[] viewOptions = new String[] { "Title", "Binomial name", "Picture", "Description" }; final Entry<String, Effect>[] effects = new Entry[] { new SimpleEntry<>("Sepia Tone", new SepiaTone()), new SimpleEntry<>("Glow", new Glow()), new SimpleEntry<>("Shadow", new DropShadow()) }; final ImageView pic = new ImageView(); final Label name = new Label(); final Label binName = new Label(); final Label description = new Label(); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { stage.setTitle("Menu Sample"); Scene scene = new Scene(new VBox(), 400, 350); MenuBar menuBar = new MenuBar(); // --- Menu File Menu menuFile = new Menu("File"); // --- Menu Edit Menu menuEdit = new Menu("Edit"); // --- Menu View Menu menuView = new Menu("View"); menuBar.getMenus().addAll(menuFile, menuEdit, menuView); ((VBox) scene.getRoot()).getChildren().addAll(menuBar); stage.setScene(scene); stage.show(); } private class PageData { public String name; public String description; public String binNames; public Image image; public PageData(String name, String description, String binNames) { this.name = name; this.description = description; this.binNames = binNames; image = new Image(getClass().getResourceAsStream(name + ".jpg")); } } }
和其他的UI控件不同,Menu类和其他的扩展MenuItem的类都不是扩展自Node类。所以他们不能直接添加到场景中,需要先添加到MenuBar中然后在添加到场景中。运行如下图所示:
你可以使用键盘的方向键来浏览菜单,然而当你选中一个菜单的时候,什么都没有发生,那是因为我们还没有指定行为。
添加菜单项
为文件菜单添加功能。Shuffle 加载植物的参考信息
Clear 删除参考信息并清空场景
Separator 分离菜单项
Exit 退出应用
使用MenuItem创建了一个Shuffle菜单,并添加了一个图片组件。我们可以为MenuItem指定文本和图片。我们可以通过setAction方法来指定该菜单被点击时候的事件,这个Button是一样的。代码如下:
import java.util.AbstractMap.SimpleEntry; import java.util.Map.Entry; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.effect.DropShadow; import javafx.scene.effect.Effect; import javafx.scene.effect.Glow; import javafx.scene.effect.SepiaTone; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.TextAlignment; import javafx.stage.Stage; public class MenuSample extends Application { final PageData[] pages = new PageData[] { new PageData("Apple", "The apple is the pomaceous fruit of the apple tree, species Malus " +"domestica in the rose family (Rosaceae). It is one of the most " +"widely cultivated tree fruits, and the most widely known of " +"the many members of genus Malus that are used by humans. " +"The tree originated in Western Asia, where its wild ancestor, " +"the Alma, is still found today.", "Malus domestica"), new PageData("Hawthorn", "The hawthorn is a large genus of shrubs and trees in the rose " + "family, Rosaceae, native to temperate regions of the Northern " + "Hemisphere in Europe, Asia and North America. " + "The name hawthorn was " + "originally applied to the species native to northern Europe, " + "especially the Common Hawthorn C. monogyna, and the unmodified " + "name is often so used in Britain and Ireland.", "Crataegus monogyna"), new PageData("Ivy", "The ivy is a flowering plant in the grape family (Vitaceae) native" +" to eastern Asia in Japan, Korea, and northern and eastern China." +" It is a deciduous woody vine growing to 30 m tall or more given " +"suitable support, attaching itself by means of numerous small " +"branched tendrils tipped with sticky disks.", "Parthenocissus tricuspidata"), new PageData("Quince", "The quince is the sole member of the genus Cydonia and is native" +" to warm-temperate southwest Asia in the Caucasus region. The " +"immature fruit is green with dense grey-white pubescence, most " +"of which rubs off before maturity in late autumn when the fruit " +"changes color to yellow with hard, strongly perfumed flesh.", "Cydonia oblonga") }; final String[] viewOptions = new String[] { "Title", "Binomial name", "Picture", "Description" }; final Entry<String, Effect>[] effects = new Entry[] { new SimpleEntry<>("Sepia Tone", new SepiaTone()), new SimpleEntry<>("Glow", new Glow()), new SimpleEntry<>("Shadow", new DropShadow()) }; final ImageView pic = new ImageView(); final Label name = new Label(); final Label binName = new Label(); final Label description = new Label(); private int currentIndex = -1; public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { stage.setTitle("Menu Sample"); Scene scene = new Scene(new VBox(), 400, 350); scene.setFill(Color.OLDLACE); name.setFont(new Font("Verdana Bold", 22)); binName.setFont(new Font("Arial Italic", 10)); pic.setFitHeight(150); pic.setPreserveRatio(true); description.setWrapText(true); description.setTextAlignment(TextAlignment.JUSTIFY); shuffle(); MenuBar menuBar = new MenuBar(); final VBox vbox = new VBox(); vbox.setAlignment(Pos.CENTER); vbox.setSpacing(10); vbox.setPadding(new Insets(0, 10, 0, 10)); vbox.getChildren().addAll(name, binName, pic, description); // --- Menu File Menu menuFile = new Menu("File"); MenuItem add = new MenuItem("Shuffle", new ImageView(new Image("menusample/new.png"))); add.setOnAction((ActionEvent t) -> { shuffle(); vbox.setVisible(true); }); menuFile.getItems().addAll(add); // --- Menu Edit Menu menuEdit = new Menu("Edit"); // --- Menu View Menu menuView = new Menu("View"); menuBar.getMenus().addAll(menuFile, menuEdit, menuView); ((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox); stage.setScene(scene); stage.show(); } private void shuffle() { int i = currentIndex; while (i == currentIndex) { i = (int) (Math.random() * pages.length); } pic.setImage(pages[i].image); name.setText(pages[i].name); binName.setText("(" + pages[i].binNames + ")"); description.setText(pages[i].description); currentIndex = i; } private class PageData { public String name; public String description; public String binNames; public Image image; public PageData(String name, String description, String binNames) { this.name = name; this.description = description; this.binNames = binNames; image = new Image(getClass().getResourceAsStream(name + ".jpg")); } } }
当用户选择Shuffle菜单的时候,会就调用我们指定的setOnAction方法,显示出植物的名字、图片和简单描述。
Clear菜单用来抹除场景中的内容。我们可以使用下面的方法:
MenuItem clear = new MenuItem("Clear"); clear.setAccelerator(KeyCombination.keyCombination("Ctrl+X")); clear.setOnAction((ActionEvent t) -> { vbox.setVisible(false); });
Exit菜单实现如下:
MenuItem exit = new MenuItem("Exit"); exit.setOnAction((ActionEvent t) -> { System.exit(0); });
我们使用getItems方法来添加这些菜单项,如下:
menuFile.getItems().addAll(add, clear, new SeparatorMenuItem(), exit);
编译运行应用,如下图所示:
View菜单可以来用指定,显示植物的部分信息,
// --- Creating four check menu items within the start method CheckMenuItem titleView = createMenuItem ("Title", name); CheckMenuItem binNameView = createMenuItem ("Binomial name", binName); CheckMenuItem picView = createMenuItem ("Picture", pic); CheckMenuItem descriptionView = createMenuItem ("Description", description); menuView.getItems().addAll(titleView, binNameView, picView, descriptionView); ... // The createMenuItem method private static CheckMenuItem createMenuItem (String title, final Node node){ CheckMenuItem cmi = new CheckMenuItem(title); cmi.setSelected(true); cmi.selectedProperty().addListener( (ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> { node.setVisible(new_val); }); return cmi; }
CheckMenuItem 是MenuItem类的扩展,他可以选中和非选中,如果被选中了,会显示出一个标记。编译运行如下图所示:
创建子菜单
Edit菜单中定义了两个菜单项:图片效果和无效果。图片效果菜单项有子菜单项。使用RadioMenuItem 来创建子菜单,代码如下:
//Picture Effect menu Menu menuEffect = new Menu("Picture Effect"); final ToggleGroup groupEffect = new ToggleGroup(); for (Entry<String, Effect> effect : effects) { RadioMenuItem itemEffect = new RadioMenuItem(effect.getKey()); itemEffect.setUserData(effect.getValue()); itemEffect.setToggleGroup(groupEffect); menuEffect.getItems().add(itemEffect); } //No Effects menu final MenuItem noEffects = new MenuItem("No Effects"); noEffects.setOnAction((ActionEvent t) -> { pic.setEffect(null); groupEffect.getSelectedToggle().setSelected(false); }); //Processing menu item selection groupEffect.selectedToggleProperty().addListener(new ChangeListener<Toggle>() { public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) { if (groupEffect.getSelectedToggle() != null) { Effect effect = (Effect) groupEffect.getSelectedToggle().getUserData(); pic.setEffect(effect); } } }); groupEffect.selectedToggleProperty().addListener( (ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) -> { if (groupEffect.getSelectedToggle() != null) { Effect effect = (Effect) groupEffect.getSelectedToggle().getUserData(); pic.setEffect(effect); } }); //Adding items to the Edit menu menuEdit.getItems().addAll(menuEffect, noEffects);
如下所示:
我们可以使用setDisable来禁用某一个菜单。
Menu menuEffect = new Menu("Picture Effect"); final ToggleGroup groupEffect = new ToggleGroup(); for (Entry<String, Effect> effect : effects) { RadioMenuItem itemEffect = new RadioMenuItem(effect.getKey()); itemEffect.setUserData(effect.getValue()); itemEffect.setToggleGroup(groupEffect); menuEffect.getItems().add(itemEffect); } final MenuItem noEffects = new MenuItem("No Effects"); noEffects.setDisable(true); noEffects.setOnAction((ActionEvent t) -> { pic.setEffect(null); groupEffect.getSelectedToggle().setSelected(false); noEffects.setDisable(true); }); groupEffect.selectedToggleProperty().addListener( (ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) -> { if (groupEffect.getSelectedToggle() != null) { Effect effect = (Effect) groupEffect.getSelectedToggle().getUserData(); pic.setEffect(effect); noEffects.setDisable(false); } else { noEffects.setDisable(true); } }); menuEdit.getItems().addAll(menuEffect, noEffects);
添加上下文菜单
如果你的界面中没有为菜单的控件,那么你可以使用上下文菜单。当点击鼠标的时候,弹出上下文菜单。final ContextMenu cm = new ContextMenu(); MenuItem cmItem1 = new MenuItem("Copy Image"); cmItem1.setOnAction((ActionEvent e) -> { Clipboard clipboard = Clipboard.getSystemClipboard(); ClipboardContent content = new ClipboardContent(); content.putImage(pic.getImage()); clipboard.setContent(content); }); cm.getItems().add(cmItem1); pic.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> { if (e.getButton() == MouseButton.SECONDARY) cm.show(pic, e.getScreenX(), e.getScreenY()); });
相关文章推荐
- JavaFx初探
- javafX初探(按钮)
- javaFX初探(灯光)
- javafX初探(滚动条)
- JavaFX初探(时间选择器)
- javaFx 学习--之组件篇1(边框与布局管理1菜单)
- javafX初探(选择框)
- JavaFx初探
- 优秀的菜单控件DevExpress Bar使用初探
- WPF初探--弹出菜单
- javaFX初探(材料)
- JavaFX初探与MediaPlayer(2)
- javaFx菜单简单应用示例--1多级菜单
- android侧滑菜单实现方法初探
- WPF初探--弹出菜单
- javaFX初探(选择)
- JavaFX 2 初探----Eclipse下运行Ensemble程序
- javafX初探(文本域)
- JavaFX实现鱼眼菜单 v0.1
- javaFX初探(使用画布 API)