在JavaFX程序中嵌入Swing内容

转载自  在JavaFX程序中嵌入Swing内容

本教程描述如何在JavaFX应用程序中嵌入Swing组件。本文将讨论线程限制并提供一个可运行的应用程序来说明在JavaFX应用程序中嵌入带HTML内容的Swing按钮,以及Swing与JavaFX按钮间的协作性。

从JavaFX 2.0版本开始,就可以在Swing应用程序中嵌入JavaFX内容。为了增强JavaFX和Swing之间的协作性,JavaFX 8引入了一个新的类,提供了反向整合并使得开发者能够在JavaFX应用程序中嵌入Swing组件。

在运行本章代码之前,需要在计算机上安装JDK 8。

SwingNode类

JavaFX 8中引入了SwingNode类,其位于javafx.embed.swing包中。这个类使你可以在JavaFX应用程序中嵌入Swing内容。要指定SwingNode对象的内容,调用setContent方法,可以传入一个javax.swing.JComponent类的实例。你可以在JavaFX应用程序线程或者EDT中调用setContent方法。但是为了访问Swing内容,确保代码运行在EDT上,因为标准Swing线程限制。

例7-1的代码展示例使用SwingNode类的通常模式。

例7-1

 

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javax.swing.JButton;
import javax.swing.SwingUtilities;public class SwingFx extends Application {@Overridepublic void start (Stage stage) {final SwingNode swingNode = new SwingNode();createSwingContent(swingNode);StackPane pane = new StackPane();pane.getChildren().add(swingNode);stage.setTitle("Swing in JavaFX");stage.setScene(new Scene(pane, 250, 150));stage.show();}private void createSwingContent(final SwingNode swingNode) {SwingUtilities.invokeLater(() -> {swingNode.setContent(new JButton("Click me!"));});}}

运行代码后,输出如图7-1所示。

图7-1 在JavaFX程序中嵌入Swing的JButton

 

嵌入Swing内容并处理事件

在Swing教程中的ButtonHtmlDemo为3个按钮添加了字体、颜色和的其他格式,如例7-2和例7-3所示。按钮响应鼠标和键盘事件,如例7-5和例7-6所示。图7-2展示了在ButtonHtmlDemo中用Swing创建的三个按钮嵌入在一个JavaFX应用程序(SwingNodeSample)中的效果。你将创建SwingNodeSample应用程序以及确保所有事件被传递到适当的Swing按钮中并得到处理。

图7-2 ButtonHtmlDemo嵌入在JavaFX应用程序中

左按钮和右按钮有多行用HTML格式实现的文本,如例7-2所示。

例7-2

b1 = new JButton("<html><center><b><u>D</u>isable</b><br>"+ "<font color=#ffffdd>middle button</font>",leftButtonIcon);b3 = new JButton("<html><center><b><u>E</u>nable</b><br>"+ "<font color=#ffffdd>middle button</font>",rightButtonIcon);

中间按钮格式简单不需要HTML,所以只需要用一个字符串标签和一个图片来初始化,如例7-3所示。

例7-3

	b2 = new JButton("middle button", middleButtonIcon);

所有3个按钮都有工具提示和助记符字符,如例7-4所示。

7-4

b1.setToolTipText("Click this button to disable the middle button.");
b2.setToolTipText("This middle button does nothing when you click it.");
b3.setToolTipText("Click this button to enable the middle button.");b1.setMnemonic(KeyEvent.VK_D);
b2.setMnemonic(KeyEvent.VK_M);
b3.setMnemonic(KeyEvent.VK_E);

左按钮和右按钮分别用来禁用和启用中间按钮。为了使程序能够检测并响应用户对3个按钮的操作,如例7-5所示附加操作监听器并设置操作指令。

例7-5

b1.addActionListener(this);
b3.addActionListener(this);b1.setActionCommand("disable");
b3.setActionCommand("enable");

如例7-6所示实现actionPerformed方法。此方法当用户点击左按钮或右按钮时会被调用。

例7-6

public void actionPerformed(ActionEvent e) {if ("disable".equals(e.getActionCommand())) {    b2.setEnabled(false);b1.setEnabled(false);b3.setEnabled(true);} else {b2.setEnabled(true);b1.setEnabled(true);b3.setEnabled(false);}
}

查看ButtonHtmlDemo.java类的完整代码。

现在建立一个JavaFX工程并运行SwingNodeSample应用程序。

为了创建SwingNodeSample应用程序:

确保电脑已经安装JDK 8。然后在NetBeans IDE中建立一个JavaFX工程。

1. 在File菜单中,选择New Project

2. 在JavaFX应用程序分类中,选择JavaFX Application并点击Next

3. 将工程命名为SwingNodeSample并选择基于JDK 8的JavaFX平台。点击Finish

4. 在Projects窗口中,右键点击swingnodesample文件夹。选择New,然后选择Java class

5. 命名新的类为ButtonHtml并点击Finish

6. 复制ButtonHtml.java类的代码到这个工程里。

7. 打开磁盘中的swingnodesample文件夹并新建images文件夹。

8. 右键点击图片,选择图片另存为,下载left.gif, middle.gif和right.gif图片,并保存在images文件夹中。

9. 在SwingNodeSample类中,删除start方法里NetBeans自动生成的代码。

10. 相应的创建SwingNode对象和实现start方法,如例7-7所示。

例7-7

public void start(Stage stage) {final SwingNode swingNode = new SwingNode();createSwingContent(swingNode);StackPane pane = new StackPane();pane.getChildren().add(swingNode);Scene scene = new Scene(pane, 450, 100);stage.setScene(scene);stage.setTitle("ButtonHtmlDemo Embedded in JavaFX");stage.show();
}

11. 为了嵌入ButtonHtml类生成的三个按钮,将SwingNode对象的内容设置为ButtonHtml类的一个实例,如例7-8所示。

例7-8

private void createSwingContent(final SwingNode swingNode) {SwingUtilities.invokeLater(() -> {swingNode.setContent(new ButtonHtml());});
}

12. 按Ctrl(或Cmd)+Shift+I来修正引入声明。

可以点击SwingNodeSample.zip链接来下来SwingNodeSample应用程序的源代码。

运行SwingNodeSample工程并确认所有的按钮提供的交互方法都运行正常:

● 对于鼠标,越过按钮时可以看见工具提示。

● 点击左按钮和右按钮可以对应禁用和启用中间按钮。

● 按Alt+D和Alt+E可以对应禁用和启用中间按钮。

添加Swing和JavaFX组件之间的协作性。

你可以提供JavaFX按钮和Swing按钮之间的协作性。例如图7-3所示的EnableFXButton程序可以使用户点击Swing按钮来禁用或启用一个JavaFX按钮。相反的,图7-4所示的EnableButtons程序可以使用户点击一个JavaFX按钮来触发一个Swing按钮。

图7-3 启用JavaFX按钮样例

 

使用Swing按钮来操作一个JavaFX按钮

修改SwingNodeSample程序并将中间按钮改为javafx.scene.control.Button类的一个实例,来创建EnableFXButton应用程序。在修改后的应该程序中,Swing按钮(Disable FX button和Enable FX button)用来禁用和启用一个JavaFX按钮(FX Button)。图7-3展示了EnableFXButton程序。

按以下步骤来创建EnableFXButton应用程序:

1. 在File菜单中选择New Project

2. 在JavaFX应用程序分类中,选择JavaFX Application并点击Next

3. 将工程命名为EnableFXButton

4. 在Projects窗口中,右键点击enablefxbutton文件夹。选择New然后选择Java class

5. 将新的类命名为ButtonHtml并点击Finish

6. 复制ButtonHtml.java类的代码并粘贴到这个工程中。

7. 将包声明改为enablefxbutton。

8. 打开磁盘中的enablefxbutton文件夹并创建images文件夹。

9. 右键点击图片并选择图片另存为,下载down.gif和middle.gif图片并保存在images文件夹中。

10. 在EnableFXButton类中,声明一个Button对象,如例7-9所示。

例7-9

public class EnableFXButton extends Application {public static Button fxbutton;

11. 删除start方法中NetBeans IDE自动生成的代码,并按例7-10所示实现start方法。

例7-10

@Override
public void start(Stage stage) {final SwingNode swingNode = new SwingNode();createSwingContent(swingNode);BorderPane pane = new BorderPane();fxbutton = new Button("FX button");pane.setTop(swingNode);pane.setCenter(fxbutton);Scene scene = new Scene(pane, 300, 100);stage.setScene(scene);stage.setTitle("Enable JavaFX Button");stage.show();
}

12. 如例7-11所示添加SwingNode类的引入声明。

7-11

import javafx.embed.swing.SwingNode;

13. 实现createSwingContent方法来设置SwingNode对象的内容,如例7-12所示。

例7-12

private void createSwingContent(final SwingNode swingNode) {SwingUtilities.invokeLater(() -> {swingNode.setContent(new ButtonHtml());});
}

14. 按Ctrl(或Cmd)+Shift+I来添加swing.SwingUtilities类的引入声明。

15. 用例7-13中所示的代码替换fxbutton的初始化代码,为JavaFX按钮添加一个图片并设置一个工具提示和样式。

例7-13

Image fxButtonIcon = new Image(
getClass().getResourceAsStream("images/middle.gif"));fxbutton = new Button("FX button", new ImageView(fxButtonIcon));
fxbutton.setTooltip(new Tooltip("This middle button does nothing when you click it."));
fxbutton.setStyle("-fx-font: 22 arial; -fx-base: #cce6ff;");

16. 按Ctrl(或Cmd)+Shift+I来添加引入声明,如例7-14所示。

例7-14

import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.control.Tooltip;

17. 打开ButtonHtml类并删除中间按钮b2的所有相关代码。

18. 如例7-15所示为b1((Disable FX button)和b3(Enable FX button)按钮设置gif图片。

例7-15

ImageIcon buttonIcon = createImageIcon("images/down.gif");
b1 = new JButton("<html><center><b><u>D</u>isable</b><br>"+ "<font color=#ffffdd>FX button</font>", buttonIcon);
b3 = new JButton("<html><center><b><u>E</u>nable</b><br>"+ "<font color=#ffffdd>FX button</font>", buttonIcon);

19. 修改actionPerformed方法来实现禁用和启用fxbuttons,如例7-16所示。注意禁用和启用JavaFX按钮必须发生在JavaFX应用程序线程上。

例7-16

@Override
public void actionPerformed(ActionEvent e) {if ("disable".equals(e.getActionCommand())) {Platform.runLater(() -> {EnableFXButton.fxbutton.setDisable(true);});b1.setEnabled(false);b3.setEnabled(true);} else {Platform.runLater(() -> {EnableFXButton.fxbutton.setDisable(false);});b1.setEnabled(true);b3.setEnabled(false);}
}

20. 按Ctrl(或Cmd)+Shift+I来添加引入声明,如例7-17所示。

例7-17

import javafx.application.Platform;

21. 运行程序并点击Swing按钮来禁用或者启用JavaFX按钮,如图7-3所示。

使用JavaFX按钮来操作Swinig按钮

你可以继续修改EnableFXButton程序并实现JavaFX按钮的setOnAction方法,然后可以点击JavaFX按钮来激活Swing按钮。修改后的程序(EnableButtons)如图7-4所示。

图7-4 EnableButtons样例

 

创建EnableButtons应用程序:

1. 复制EnableFXButtons工程并命名为EnableButtons然后保存。

2. 将EnableButtons类重命名为EnableButtons,将enablefxbutton包重命名为enablebuttons。

3. 修正ButtonHtml和EnableButtons类的包声明。

4. 打开EnableButtons类,添加一个FlowPane类的实例pane,如例7-18所示。

例7-18

FlowPane pane = new FlowPane();

5. 使用gif图片来修改fxButtonIcon变量的初始化,如例7-19所示。

例7-19

Image fxButtonIcon = new Image(getClass().getResourceAsStream("images/left.gif"));

6. 如例7-20所示,改变fxbutton的文字,工具提示和字体,并设置disableProperty为true。

例7-20

fxbutton = new Button("Enable JButton", new ImageView(fxButtonIcon));
fxbutton.setTooltip(new Tooltip("Click this button to enable the Swing button."));
fxbutton.setStyle("-fx-font: 18 arial; -fx-base: #cce6ff;");
fxbutton.setDisable(true);

7. 如例7-21所示使用一个lambda表达式来实现setOnAction方法。注意必须在EDT线程上改变Swing对象。

7-21

fxbutton.setOnAction(ActionEvent e) {SwingUtilities.invokeLater(() -> {ButtonHtml.b1.setEnabled(true);});fxbutton.setDisable(true);}
});

注意:忽略启用b1代码左边的错误提示,你将在第11步修正错误。

8. 按Ctrl(或Cmd)+Shift+I来添加event.ActionEvent类的引入声明。

9. 在布局容器中添加swingNode和fxbutton对象,如例7-22所示。

例7-22

pane.getChildren().addAll(swingNode, fxbutton);

10. 将应用程序标题改为“Enable Buttons Sample”,如例7-23所示。

7-23

pane.getChildren().addAll(swingNode, fxbutton);

11. 打开ButtonHtml类,将b1按钮的修饰改为public static。注意EnableButtons类的错误提示已经消失。

12. 删除b3按钮相关的所有代码,删除设置b1行为指令的代码行。

13. 使用lambda表达式来修改actionPerformed方法,如例7-24所示。

例7-24

@Override
public void actionPerformed(ActionEvent e) {Platform.runLater(() -> {EnableButtons.fxbutton.setDisable(false);});b1.setEnabled(false);
}

结论

在本章中你学会了如何在JavaFX应用程序中嵌入已存在的Swing组件,并提供Swing和JavaFX对象之间的协作性。在JavaFX程序中嵌入Swing内容可以使开发者移植使用了复杂第三方Swing组件但没有源代码的Swing应用程序,或者包含只进行维护的遗留模块的应用程序。

应用程序资源

源代码

● SwingNodeSample.java

● ButtonHtml.java

● EnableButtons.java

● EnableFXButton.java

NetBeans工程

● EnableButtons.zip

● EnableFXButton.zip

● SwingNodeSample.zip

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你胆敢不加break试试?

我们经常在实际开发中会用到一些转换类&#xff0c;比如在金融界中&#xff0c;我们需要将1转换为“壹”&#xff0c;2转换成“贰”。还有类似这样的需求&#xff0c;食堂在一周内每天的菜单都是不一样的&#xff0c;周一为鱼香肉丝鸡腿&#xff0c;周二为爆炒土豆丝鲅鱼&#…

三大特性之继承性

一、继承性的好处&#xff1a; ① 减少了代码的冗余&#xff0c;提高了代码的复用性 ② 便于功能的扩展 ③ 为之后多态性的使用&#xff0c;提供了前提 二、继承性的格式&#xff1a; class A extends B{} A:子类、派生类、subclass B:父类、超类、基类、superclass 2.1体现&…

ssl2346-联络员【图论,最小生成树】

题目 一个图&#xff0c;给几条固定的边&#xff0c;求最小生成树 输入 第一行n&#xff0c;m表示n个点&#xff0c;有m条边&#xff0c;每行四个非负整数&#xff0c;p,u,v,w 当p1时&#xff0c;表示这个边为固定边&#xff08;必须要&#xff09;&#xff1b;当p2时&#…

JQuery 动画效果

掌握要点 显示隐藏show() hide() 改变width、height、opacity 淡入淡出fadeIn() fadeOut() 改变opacity 滑入滑出slideDown() slideUp() 改变height&#xff08;对于img同时改变height和width&#xff09; 隐藏的显示/显示的隐藏 toggle() 参考网站&#xff1a;http://www.jq2…

微软作为金牌会员加入Cloud Foundry基金会

在最近召开的Cloud Foundry峰会上&#xff0c;微软宣布他们已经加入了Cloud Foundry基金&#xff0c;成为金牌会员。除此之外&#xff0c;微软正在加大对开源云平台的支持力度&#xff0c;他们提供的服务包括Azure数据库&#xff08;PostgreSQL和MySQL&#xff09;的后端集成以…

你胆敢在case后面不加break试试?

我们经常在实际开发中会用到一些转换类&#xff0c;比如在金融界中&#xff0c;我们需要将1转换为“壹”&#xff0c;2转换成“贰”。还有类似这样的需求&#xff0c;食堂在一周内每天的菜单都是不一样的&#xff0c;周一为鱼香肉丝鸡腿&#xff0c;周二为爆炒土豆丝鲅鱼&#…

在Swing和Swt中使用JavaFX

转载自 在Swing和Swt中使用JavaFX 本人从08年12月份&#xff0c;JavaFX发布第一个版本开始关注它的发展。 算算到现在&#xff0c;也差不多是第五个年头了。期间经历了一些动荡&#xff0c;但JavaFX还是坚持着发展了下来&#xff0c;也经历了很多改变(这也是Java技术的特点&a…

三大特性之封装性

体现一 Java中通过将属性声明为私有的(private)&#xff0c;再提供公共的&#xff08;public&#xff09;方法:getXxx()和setXxx()实现对该属性的操作&#xff0c;以实现下述目的&#xff1a; 隐藏一个类中不需要对外提供的实现细节&#xff1b; 使用者只能通过事先定制…

JQuery 表单校验

表单校验的作用 为什么要进行表单验证&#xff1a;保证数据符合要求 为什么要进行JavaScript或者jQuery表单验证&#xff1a; 1.降低服务器端负担 2.还可以进行服务器验证&#xff08;JSP&#xff09; 正则表达式 为什么使用正则表达式&#xff1a; 简洁的代码 严谨的验证文…

ssl2348-连接格点【图论,最小生成树,并查集】

题目 有一个M行N列的点阵&#xff0c;相邻两点可以相连。一条纵向的连线花费一个单位&#xff0c;一条横向的连线花费两个单位。某些点之间已经有连线了&#xff0c;试问至少还需要花费多少个单位才能使所有的点全部连通。 输入 第一行输入两个正整数m和n。 以下若干行每行…

活动: 北京Xamarin分享会第4期(2017年7月8日)

BXUG(Beijing Xamarin User Group)将举行第4期线下活动&#xff0c;本期内容预告&#xff1a; 案例演讲: "Xamarin原生跨平台开发的风险与收益"分享者: 神秘分享嘉宾Mike&#xff0c;来自国内一线互联网教育公司的研发经理&#xff0c;.NET新时代CTO联盟发起者。方案…

内存模型是怎么解决缓存一致性的

转载自 内存模型是怎么解决缓存一致性的 在再有人问你Java内存模型是什么&#xff0c;就把这篇文章发给他这篇文章中&#xff0c;我们介绍过关于Java内存模型的来龙去脉。 我们在文章中提到过&#xff0c;由于CPU和主存的处理速度上存在一定差别&#xff0c;为了匹配这种差距…

这是什么操作?java中的变量竟然可以先使用后声明?

相信大家在看到标题之后&#xff0c;是疑惑的点进来看内容的。 在看到标题之后&#xff0c;大家肯定会怀疑&#xff0c;我赵某人用java写了好几年的代码了&#xff0c;还真就没见过java中的变量能先用在声明&#xff0c;今天就是进来看看你在没有声明变量的前提下是怎么用的&a…

重写(override / overwrite)

方法的重写(override / overwrite) 1.重写&#xff1a;子类继承父类以后&#xff0c;可以对父类中同名同参数的方法&#xff0c;进行覆盖操作 2.应用&#xff1a;重写以后&#xff0c;当创建子类对象以后&#xff0c;通过子类对象调用子父类中的同名同参数的方法时&#xff0c;…

ssl1613-最短路径问题【图论,最短路径(还不明显?)】

题目 一个图&#xff0c;求两个点的最短路径 输入 第一行为一个整数n。 n行&#xff0c;两个整数x和y&#xff0c;一个点的坐标 一个整数m&#xff0c;表示图中线的个数。 m行&#xff0c;一条线&#xff0c;i,j&#xff0c;表示第i个点和第j个点之间有线。 最后一行&am…

jQuery 表格实现

<script type"text/javascript">$(function(){/******实现全选的操作****/$("#chks").click(function(){//获得当前框的勾选状态var flag $("#chks").prop("checked");$("input[namechk]").prop(checked,flag);})/*…

来吧学学.Net Core之项目文件简介及配置文件与IOC的使用

序言 在当前编程语言蓬勃发展与竞争的时期,对于我们.net从业者来说,.Net Core是风头正紧,势不可挡的.芸芸口水之中,不学习使用Core,你的圈内处境或许会渐渐的被边缘化.所以我们还是抽出一点点时间学学.net core吧. 那VS Code 可以编写,也可以调试Core本人也尝试啦下,但是感觉…

真正的问题应该在我身上……

渐渐地&#xff0c;学生已进入学习状态。在未测试之前&#xff0c;一直以为大家都学的很好&#xff0c;从课堂上的互动氛围就可以看得出来&#xff0c;一问问题&#xff0c;你一言他一语的……在测试之后&#xff0c;真是让我大跌眼镜&#xff0c;平时感觉表现很好的学生们&…

搞定计算机网络面试,看这篇就够了

转载自 搞定计算机网络面试&#xff0c;看这篇就够了 文章目录结构&#xff1a; 一 OSI与TCP/IP各层的结构与功能&#xff0c;都有哪些协议 运输层主要使用以下两种协议&#xff1a; UDP的主要特点&#xff1a; TCP的主要特点&#xff1a; 域名系统&#xff08;Domain Nam…

来吧学学.Net Core之登录认证与跨域资源使用

序言 学习core登录认证与跨域资源共享是越不过的砍,所以我在学习中同样也遇到啦这两个问题,今天我们就用示例来演示下使用下这2个技术点吧. 本篇主要内容如下: 1、展示一个登录认证的简单示例 2、跨域资源访问 3、跨域获取登录认证的用户信息 .Net Core使用身份认证(Auth…