)类 新建javafx程序时_DOC-13-07 在JavaFX程序中嵌入Swing内容

这篇教程讲解了如何在JavaFX应用中嵌入Swing组件,通过SwingNode类实现。从JavaFX 8开始,可以将Swing内容嵌入到JavaFX应用中。文中提供了一个示例展示如何在JavaFX中使用Swing JButton,并讨论了线程限制。此外,还介绍了如何处理事件,以及在JavaFX和Swing组件间建立协作。
摘要由CSDN通过智能技术生成

DOC-13-07 在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

Java

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 {

@Override

public 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!"));

});

}

}

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

importjavafx.application.Application;

importjavafx.embed.swing.SwingNode;

importjavafx.scene.Scene;

importjavafx.scene.layout.StackPane;

importjavafx.stage.Stage;

importjavax.swing.JButton;

importjavax.swing.SwingUtilities;

publicclassSwingFxextendsApplication{

@Override

publicvoidstart(Stagestage){

finalSwingNodeswingNode=newSwingNode();

createSwingContent(swingNode);

StackPanepane=newStackPane();

pane.getChildren().add(swingNode);

stage.setTitle("Swing in JavaFX");

stage.setScene(newScene(pane,250,150));

stage.show();

}

privatevoidcreateSwingContent(finalSwingNodeswingNode){

SwingUtilities.invokeLater(()->{

swingNode.setContent(newJButton("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-2ButtonHtmlDemo嵌入在JavaFX应用程序中

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

例7-2

Java

b1 = new JButton("

Disable
"

+ "middle button",

leftButtonIcon);

b3 = new JButton("

Enable
"

+ "middle button",

rightButtonIcon);

1

2

3

4

5

6

7

b1=newJButton("

Disable
"

+"middle button",

leftButtonIcon);

b3=newJButton("

Enable
"

+"middle button",

rightButtonIcon);

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

例7-3

Java

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

1

b2=newJButton("middle button",middleButtonIcon);

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

例7-4

Java

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);

1

2

3

4

5

6

7

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

Java

b1.addActionListener(this);

b3.addActionListener(this);

b1.setActionCommand("disable");

b3.setActionCommand("enable");

1

2

3

4

5

b1.addActionListener(this);

b3.addActionListener(this);

b1.setActionCommand("disable");

b3.setActionCommand("enable");

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

例7-6

Java

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);

}

}

1

2

3

4

5

6

7

8

9

10

11

publicvoidactionPerformed(ActionEvente){

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

Java

@Override

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();

}

1

2

3

4

5

6

7

8

9

10

11

12

@Override

publicvoidstart(Stagestage){

finalSwingNodeswingNode=newSwingNode();

createSwingContent(swingNode);

StackPanepane=newStackPane();

pane.getChildren().add(swingNode);

Scenescene=newScene(pane,450,100);

stage.setScene(scene);

stage.setTitle("ButtonHtmlDemo Embedded in JavaFX");

stage.show();

}

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

例7-8

Java

private void createSwingContent(final SwingNode swingNode) {

SwingUtilities.invokeLater(() -> {

swingNode.setContent(new ButtonHtml());

});

}

1

2

3

4

5

privatevoidcreateSwingContent(finalSwingNodeswingNode){

SwingUtilities.invokeLater(()->{

swingNode.setContent(newButtonHtml());

});

}

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

Java

public class EnableFXButton extends Application {

public static Button fxbutton;

1

2

publicclassEnableFXButtonextendsApplication{

publicstaticButtonfxbutton;

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

例7-10

Java

@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();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Override

publicvoidstart(Stagestage){

finalSwingNodeswingNode=newSwingNode();

createSwingContent(swingNode);

BorderPanepane=newBorderPane();

fxbutton=newButton("FX button");

pane.setTop(swingNode);

pane.setCenter(fxbutton);

Scenescene=newScene(pane,300,100);

stage.setScene(scene);

stage.setTitle("Enable JavaFX Button");

stage.show();

}

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

例7-11

Java

import javafx.embed.swing.SwingNode;

1

importjavafx.embed.swing.SwingNode;

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

例7-12

Java

private void createSwingContent(final SwingNode swingNode) {

SwingUtilities.invokeLater(() -> {

swingNode.setContent(new ButtonHtml());

});

}

1

2

3

4

5

privatevoidcreateSwingContent(finalSwingNodeswingNode){

SwingUtilities.invokeLater(()->{

swingNode.setContent(newButtonHtml());

});

}

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

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

例7-13

Java

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;");

1

2

3

4

5

6

7

ImagefxButtonIcon=newImage(

getClass().getResourceAsStream("images/middle.gif"));

fxbutton=newButton("FX button",newImageView(fxButtonIcon));

fxbutton.setTooltip(

newTooltip("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

Java

import javafx.scene.image.Image;

import javafx.scene.image.ImageView;

import javafx.scene.control.Tooltip;

1

2

3

importjavafx.scene.image.Image;

importjavafx.scene.image.ImageView;

importjavafx.scene.control.Tooltip;

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

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

例7-15

Java

ImageIcon buttonIcon = createImageIcon("images/down.gif");

b1 = new JButton("

Disable
"

+ "FX button",

buttonIcon);

b3 = new JButton("

Enable
"

+ "FX button",

buttonIcon);

1

2

3

4

5

6

7

ImageIconbuttonIcon=createImageIcon("images/down.gif");

b1=newJButton("

Disable
"

+"FX button",

buttonIcon);

b3=newJButton("

Enable
"

+"FX button",

buttonIcon);

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

例7-16

Java

@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);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@Override

publicvoidactionPerformed(ActionEvente){

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

Java

import javafx.application.Platform;

1

importjavafx.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

Java

FlowPane pane = new FlowPane();

1

FlowPanepane=newFlowPane();

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

例7-19

Java

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

1

ImagefxButtonIcon=newImage(getClass().getResourceAsStream("images/left.gif"));

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

例7-20

Java

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);

1

2

3

4

5

fxbutton=newButton("Enable JButton",newImageView(fxButtonIcon));

fxbutton.setTooltip(

newTooltip("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

Java

fxbutton.setOnAction(ActionEvent e) {

SwingUtilities.invokeLater(() -> {

ButtonHtml.b1.setEnabled(true);

});

fxbutton.setDisable(true);

}

});

1

2

3

4

5

6

7

fxbutton.setOnAction(ActionEvente){

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

Java

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

1

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

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

例7-23

Java

stage.setTitle("Enable Buttons Sample");

1

stage.setTitle("Enable Buttons Sample");

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

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

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

例7-24

Java

@Override

public void actionPerformed(ActionEvent e) {

Platform.runLater(() -> {

EnableButtons.fxbutton.setDisable(false);

});

b1.setEnabled(false);

}

1

2

3

4

5

6

7

@Override

publicvoidactionPerformed(ActionEvente){

Platform.runLater(()->{

EnableButtons.fxbutton.setDisable(false);

});

b1.setEnabled(false);

}

结论

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

应用程序资源

源代码

NetBeans工程

打赏一下

支付宝

微信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值