添加上下文菜单ContextMenu

当你无法分配任何UI空间给一个需要的功能时,你可以使用上下文菜单ContextMenu。上下文菜单ContextMenu是一个弹出窗口,会由一次鼠标点击事件触发显示出来。一个上下文菜单可以包含一个或者多个菜单项。

在Menu Sample应用程序中,为植物的图片设置一个上下文菜单ContextMenu,使得用户可以复制图像。

当用户右击ImageView对象,上下文菜单的show()方法就会被调用使其显示。

为上下文菜单的Copy菜单项定义的setOnAction()方法创建了一个ClipBoard并添加图像作为其内容

使用ContextMenu类来创建上下文菜单

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
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.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;public class MenuSample extends Application {final PageData[] pages = new PageData[]{new PageData("标题一","描述一","名称一"),new PageData("标题二","描述二","名称二"),new PageData("标题三","描述三","名称三"),new PageData("标题","描述","名称")};final String[] viewOptions = new String[]{"标题","二项式","图片","描述"};final Entry<String, Effect>[] effects = new Entry[]{//Entry类型数组对象的初始化new SimpleEntry<>("褐色特效", new SepiaTone()),//创建一个深褐色特效 用SimpleEntry类型对象保存,key是String 而value 是特效对象new SimpleEntry<>("发光特效", new Glow()),//创建一个发光特效,用SimpleEntry类型对象保存,key是String 而value 是特效对象new SimpleEntry<>("阴影特效", new DropShadow())//创建一个阴影特效,用SimpleEntry类型对象保存,key是String 而value 是特效对象};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);}@Overridepublic void start(Stage stage) {stage.setTitle("Menu例子");Image image = new Image("https://www.dllg56.com/qt/img/logo-sing.png");stage.getIcons().add(image);Scene scene = new Scene(new VBox(), 400, 350);//创建一个场景对象,并将场景上挂载一个垂直盒子Vbox布局对象final VBox vbox = new VBox();//创建一个垂直布局对象vbox.setAlignment(Pos.CENTER);//设置vbox对象对齐方式vbox.setSpacing(10);//设置vbox对象布局的元素之间的空间距离vbox.setPadding(new Insets(0, 10, 0, 10));//设置Vbox对象内边距vbox.getChildren().addAll(name, binName, pic, description);//vbox布局器中要添加的被布局元素对象(用vbox对象布局相关Node类型Label标签型对象和ImageView类型对象)shuffle();//清晰复原程序MenuBar menuBar = new MenuBar();//创建一个MenuBar类型对象// --- Menu FileMenu menuFile = new Menu("Menu选择图片");// --- Menu EditMenu menuEdit = new Menu("Menu图片编辑");// --- Menu ViewMenu menuView = new Menu("Menu菜单三");//将上文创建的三个Menu对象添加(镶嵌)到MenuBar对象上去menuBar.getMenus().addAll(menuFile, menuEdit, menuView);//Menu类型对象都是要镶嵌在MenuBar对象上的        final ContextMenu cm = new ContextMenu();//创建内置上下文菜单MenuItem cmItem1 = new MenuItem("复制图片");//创建菜单选项MenuItem类型对象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());}});Menu menuEffect = new Menu("图片特效");//创建一个菜单(后续作为子菜单)final ToggleGroup groupEffect = new ToggleGroup();//创建一个互斥切换组对象for (Entry<String, Effect> effect : effects) {//遍历保存了图形特效的List<SimpleEntry>类型对象RadioMenuItem itemEffect = new RadioMenuItem(effect.getKey());//创建一个RadioMenuItem类型菜单选项对象itemEffect.setUserData(effect.getValue());//将从SimpleEntry类型对象中获取的vlaue值(Effect类型图像特效对象)作为用户选择数据项内容设置给RadioMenuItem类型对象的用户选择数据内容itemEffect.setToggleGroup(groupEffect);//将RadioMenuItem类型对象添加到一个互斥组对象中去menuEffect.getItems().add(itemEffect);//将RadioMenuItem类型对象作为选下挂载到前文定义的 图片特效子菜单中}
//No Effects菜单final MenuItem noEffects = new MenuItem("无特效");//创建一个普通菜单选项MenuItem类型对象noEffects.setDisable(true);// 初始化无特效菜单选项是被禁用的noEffects.setOnAction((ActionEvent t) -> {//给上文定义的菜单选项对象添加交互事件处理回调函数pic.setEffect(null);//将ImageView类型对象pic的特效设置为nullgroupEffect.getSelectedToggle().setSelected(false);//将互斥组ToggleGroup类型对象groupEffect的被选中项的对象对应的选中状态设置为false未选状态noEffects.setDisable(true);//引用无特效选项});//处理菜单项的选中事件groupEffect.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {//ToggleGroup类型对象的互斥选项,选项选中改变交互事件处理回调函数的编写public void changed(ObservableValue<? extends Toggle> ov,Toggle old_toggle, Toggle new_toggle) {if (groupEffect.getSelectedToggle() != null) {Effect effect =(Effect) groupEffect.getSelectedToggle().getUserData();//获取切换组对象ToggleGroup 中选中的互斥选项对象对应的用户选中数据内容,本例中将选中数据内容转换成Effect类型图像特效对象pic.setEffect(effect);//给ImageView类型对象pic添加图形效果}}});//ToggleGroup类型对象的互斥选项,选项选中改变交互事件处理回调函数的编写groupEffect.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> ov, Toggle old_toggle,Toggle new_toggle) -> {if (groupEffect.getSelectedToggle() != null) {//获取切换组对象ToggleGroup类型groupEffect对象 中选中的互斥选项对象对应的用户选中数据内容,本例中将选中数据内容转换成Effect类型图像特效对象Effect effect =(Effect) groupEffect.getSelectedToggle().getUserData();pic.setEffect(effect);//给ImageView类型对象pic添加图形效果对象effectnoEffects.setDisable(false);//启用无特效选项}else {noEffects.setDisable(true);//禁用无特效选项}});//向Edit菜单添加菜单项menuEdit.getItems().addAll(menuEffect, noEffects);//向图像编辑主菜单添加挂载对应的子菜单和菜单选项((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox);//scene对象的根节点元素上添加上文定义的menuBar对象和vbox对象,从场景对象scene对象上获取Vbox类型布局对象,并将前文定义的MenuBar类型对象添加到Vbox布局对象上去stage.setScene(scene);//舞台上添加场景stage.show();//舞台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);//label添加文字binName.setText("(" + pages[i].binNames + ")");//label添加文字description.setText(pages[i].description);//label对象添加文字currentIndex = i;}private class PageData {//自定义的类似于pojo类型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("archimedes.jpg"));//创建并加载一个图片对象}}
}

使用Context Menu

你可以尝试复制那个图像然后粘贴到一个图像编辑器中。

为了进一步改进,你可以添加更多的菜单项到上下文菜单中并指定不同的动作。你可以使用CustomMenuItem来创建自定义的菜单。通过这个CustomMenuItem类,你可以将任何Node类型组件作为菜单项添加到一个菜单中,比如Button或者Slider等组件类型对象。

javaFX学习之剪贴板Clipboard类型对象及剪贴板内容ClipboardContent对象 和 ContextMenu内嵌式上下文菜单的使用相关推荐

  1. Udesk即时通讯网页插件发送咨询对象(一、使用内嵌代码)

    作者:张振琦 最近接到了一个客户工单,咨询是否可以在即时通讯的聊天窗口里发送商品信息.Udesk即时通讯网页插件是提供了这个功能的,叫做咨询对象.我也整理了一下,网页插件实现发送咨询对象可分为三种方式 ...

  2. 类型列表Python 学习手册 第二部分 类型与运算 第4章 介绍Python对象类型

    这几周一直在查找类型列表之类的问题,上午正好有机会和大家讨论一下. 第二分部 类型与算运   第四章 绍介Python象对类型   形成: 象对 --> 表达式 --> 语句 --> ...

  3. 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用

    学习 EF Code First+MVC 时遇到了在请求JsonResult时出现 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用 的异常,原因 ...

  4. [读书笔记]C#学习笔记三: C#类型详解..

    前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...

  5. JavaFX学习之道:JavaFX之TableView

     TableView表     TableColumn列  构建一个表主要有TableView,TableColumn,ObservableList,Bean.  加入列table.getColumn ...

  6. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  7. [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)...

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Go圣经-学习笔记之复合类型(二)

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇 Go圣经-学习笔记之复合类型 下一篇 Go圣经-学习笔记之复合数据结构(三) map介绍和简单使用 map是一种无序的 ...

  9. 231个web前端的javascript特效分享(仅供本人学习,非教程类型)

    2019独角兽企业重金招聘Python工程师标准>>> 1.文本框焦点问题 onBlur:当失去输入焦点后产生该事件 onFocus:当输入获得焦点后,产生该文件 Onchange: ...

最新文章

  1. 企业运维监控平台架构设计与实现
  2. 求幂,我居然又没做出来
  3. [转]android 获取 imei号码
  4. [转]Android 导入v7包常见错误,以及项目引用v7包错误解决
  5. 计算两个String 类型的时间相关几个月
  6. 以软件开发周期来说明不同的测试的使用情况
  7. gridview為什麼分頁後,GridView1_RowDataBound就運行不了
  8. 互联网+正在颠覆行车记录仪市场
  9. 【小5聊】重装系统之台式电脑BIOSTAR映泰主板,启动U盘PE系统以及重装后无法启动情况
  10. 智能网联汽车仿真测试软件,智能网联汽车测试评价及检测认证
  11. html横向导航条代码动态伪类,伪类导航栏.html
  12. 保利威视播放器函数接口汇总
  13. 近期java面试总结
  14. 联想计算机无线网络设置密码,联想(Lenovo)无线路由器怎么设置
  15. Python爬取虎牙主播图片
  16. 创建 Time Machine 时间机器的备份至 openmediavault 5(OMV 5) NAS 的 SMB/CIFS 共享文件夹
  17. 钱塘湖春行 白居易 唐代
  18. softmax分类器 matlab,softmax原理及Matlab实现
  19. 在线GC日志分析工具——GCeasy
  20. 痞子衡嵌入式:大话双核i.MXRT1170之单独在线调试从核工程的方法(IAR篇)

热门文章

  1. 清华计算机科学与技术研究生复试,有效包括 2018年清华计算机科学与技术系考研复试科目复试通知复试分数...
  2. 1052. 设计密码
  3. Linux各种文件系统(ext3,ReiserFS,jfs,xfs)的性能
  4. android串口通信-rs232
  5. flex froggy 青蛙跳荷叶的小游戏答案
  6. 为什么64位计算机CPU架构叫amd64
  7. could not determine kind of name for C.memcpy
  8. gridlayout java_Java GridLayout
  9. ubuntu防火墙ufw使用教程
  10. 解答WPF中ComboBox SelectedItem Binding不上的Bug