Java FX swt_在Swing和Swt中使用JavaFX | 學步園

本人從08年12月份,JavaFX發布第一個版本開始關注它的發展。

算算到現在,也差不多是第五個年頭了。期間經歷了一些動蕩,但JavaFX還是堅持著發展了下來,也經歷了很多改變(這也是Java技術的特點,不會像微軟對技術的拋棄和更新換代很頻繁),由以前順應富互聯網技術發展的單純的JavaFX腳本語言,到現在已經變為完全用於取代Swing的技術。

雖然是為了取代Swing,但任何的技術為了不造成很大的影響,都必須有一個逐步換代的過程。如果單純的從JDK中剔除Swing而增加JavaFX的話,將會造成世界數不清的程序無法運行,影響不可估量(就像JDK中有很多以前不合理的舊的類庫,就算有新的可替代的方案,也不能將以前的完全刪除,所以JDK其實越來越臃腫)。這裡,我們將會介紹一下如何在Swing中使用JavaFX。

首先我們要明白,不管是Swing還是JavaFX,GUI的構建必須要各自的EDT(事件分發線程)中進行,這也是在其他線程中操作UI會出現error的原因。

而在JavaFX中,新增加了JFXPanel。這個組件是JavaFX和Swing進行混合編程的橋樑。

下面我們來看看JFXPanel的繼承關係。

1365993527_3133.jpg

大家可以看到,JFXPanel是繼承於JComponent的。而JavaFX的UI控制項都是繼承於javafx.scene.control.Control。所以很明顯,它其實是一個Swing組件,而非JavaFX的組件。

下面我們來看看JPanel的繼承關係。

1365993732_9653.png

繼承關係基本相同,也就是說,凡是在使用JPanel的地方,我們都可以用JFXPanel來替代。JFXPanel中有一個setScene方法,可以設置其中顯示的JavaFX內容。

根據文檔介紹,setScene方法可以在Swing和JavaFX的EDT中使用。也可以說,setScene才是將JavaFX和Swing結合起來的關鍵。

不過由於JavaFX的GUI的構建也需要在JavaFX的事件分發線程中進行。所以我們還需要用到另外一個類Platform。

Platform.runLater(new Runnable())中間執行的是JavaFX的事件分發線程。我們可以在Runnable中進行JavaFX的UI的創建。

下面我們來看一個簡單的示例-----在Swing中嵌入一個JavaFX的網頁瀏覽器。

import java.awt.BorderLayout;

import java.awt.Toolkit;

import javafx.application.Platform;

import javafx.embed.swing.JFXPanel;

import javafx.event.ActionEvent;

import javafx.event.EventHandler;

import javafx.scene.Group;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.control.TextField;

import javafx.scene.layout.HBox;

import javafx.scene.layout.VBox;

import javafx.scene.web.WebEngine;

import javafx.scene.web.WebView;

import javax.swing.JFrame;

public class MainClass {

private static final int WIDTH = 800;

private static final int HEIGHT = 600;

private static final String url = "http://blog.csdn.net/ml3947";

private static final String urlStart = "http://";

/**

* @param args

*/

public static void main(String[] args) {

JFrame frame = new JFrame("JavaFX in Swing");

final JFXPanel webBrowser = new JFXPanel();

frame.setLayout(new BorderLayout());

frame.add(webBrowser, BorderLayout.CENTER);

Platform.runLater(new Runnable() {

@Override

public void run() {

Group root = new Group();

Scene scene = new Scene(root, WIDTH, HEIGHT);

webBrowser.setScene(scene);

Double widthDouble = new Integer(WIDTH).doubleValue();

Double heightDouble = new Integer(HEIGHT).doubleValue();

VBox box = new VBox(10);

HBox urlBox = new HBox(10);

final TextField urlTextField = new TextField();

urlTextField.setText(url);

Button go = new Button("go");

urlTextField.setPrefWidth(WIDTH - 70);

urlBox.getChildren().addAll(urlTextField, go);

WebView view = new WebView();

view.setMinSize(widthDouble, heightDouble);

view.setPrefSize(widthDouble, heightDouble);

final WebEngine eng = view.getEngine();

eng.load(url);

root.getChildren().add(view);

box.getChildren().add(urlBox);

box.getChildren().add(view);

root.getChildren().add(box);

go.setOnAction(new EventHandler() {

@Override

public void handle(ActionEvent event) {

if (!urlTextField.getText().startsWith(urlStart)) {

eng.load(urlStart + urlTextField.getText());

} else {

eng.load(urlTextField.getText());

}

}

});

}

});

int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;

int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setSize(WIDTH, HEIGHT);

frame.setLocation((screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2);

frame.setVisible(true);

}

}

這是一個很簡單的例子。

我們創建了JFrame和JFXPanel,然後在Platform.runLater中進行Scene的創建,並設置到JFXPanel中。

我們創建了一個Textfield用來輸入網址,創建了一個JavaFX Button來跳轉到網址。判斷網址是不是http://開頭並做簡單的處理。

下面看看運行效果:

1365994383_1458.png

如圖所示。

另外,在Swt中使用的話是JFXCanvas,由於實現機制的問題,我們並不需要像在Swing中使用Platform類。而JFXCanvas也是org.eclipse.swt.widgets.Canvas的直接子類,我們可以直接使用。

示例如下:

public class JFXInSwt {

private static Scene createScene() {

Group group = new Group();

Scene scene = new Scene(group);

Button button = new Button("JFX Button");

group.getChildren().add(button);

return scene;

}

public static void main(String[] args) {

Display display = new Display();

Shell shell = new Shell(display);

shell.setLayout(new FillLayout());

FXCanvas canvas = new FXCanvas(shell, SWT.NONE);

Scene scene = createScene();

canvas.setScene(scene);

shell.open();

while (!shell.isDisposed()) {

if (!display.readAndDispatch()) display.sleep();

}

display.dispose();

}

}

---------------------------------------------------------------------------------------

很不幸,由於Sourceforge的項目首頁貌似被屏蔽了,就算我綁定了自己的一個一級域名...也是有時可以訪問有時不能訪問,所以示例不準備放在上面了。過一段時間買個空間自己建個站。

---------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值