在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
總結
以上是生活随笔為你收集整理的在JavaFX程序中嵌入Swing内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 建立qq群的方法
- 下一篇: 在Swing和Swt中使用JavaFX