5.8 使用案例

本章的案例主要介绍如何把Swing和JavaFX集成起来使用。在目前的Java桌面应用中,除了使用SWT之外,绝大部分是利用Swing来开发的。在使用JavaFX开发新的桌面应用时,免不了要与遗留的Swing应用进行整合。在一个已有的Swing程序中嵌入JavaFX组件是一件比较容易的事情。JavaFX提供了javafx.embed.swing.JFXPanel类,可以显示JavaFX中的场景。JFXPanel类继承自JComponent类,因此可以在Swing程序中使用,同时可以通过setScene方法来设置JavaFX中表示场景的Scene类的对象。

在集成Swing和JavaFX时,要注意界面更新线程的使用。Swing中的界面更新操作都需要在事件分发线程中进行,而JavaFX中的界面更新操作需要在JavaFX应用线程中进行。这两个线程是不一样的。需要使用SwingUtilities类的invokeLater方法和Platform类的runLater方法来在正确的线程中执行界面更新操作。

本案例开发的是一个简单的MP3播放器,实现根据MP3文件的URL来进行播放的功能。由于JavaFX提供了良好的对音频文件播放的支持,因此音乐播放这部分工作由JavaFX来实现,剩下的界面显示由Swing来实现。代码清单5-24给出了案例的完整实现。方法initAndShowUI用来创建整个Swing界面,对该方法的调用需要封装在SwingUtilities类的invokeLater方法的调用中。方法initPanel用来创建JFXPanel类的对象中包含的界面组件,对该方法的调用需要封装在Platform类的runLater方法的调用中。

代码清单5-24 集成JavaFX和Swing的MP3播放器


public class JavafxPlayer{

public static void main(String[]args){

SwingUtilities.invokeLater(new Runnable(){

public void run(){

initAndShowUI();

}

});

}

private static void initAndShowUI(){

JFrame frame=new JFrame("Music Player");

final JFXPanel fxPanel=new JFXPanel();

frame.add(fxPanel, BorderLayout.NORTH);

final JLabel label=new JLabel();

frame.add(label, BorderLayout.CENTER);

frame.setSize(400,200);

frame.setVisible(true);

Platform.runLater(new Runnable(){

public void run(){

initPanel(fxPanel, label);

}

});

}

private static void initPanel(JFXPanel fxPanel, final JLabel label){

HBox box=new HBox(10);

Button play=new Button("Play");

play.setMinWidth(100);

Media media=new Media("http://localhost/test.mp3");

final MediaPlayer player=new MediaPlayer(media);

play.setOnAction(new EventHandler<ActionEvent>(){

public void handle(ActionEvent t){

player.play();

SwingUtilities.invokeLater(new Runnable(){

public void run(){

label.setText(player.getMedia().getSource());

}

});

}

});

box.getChildren().addAll(play);

fxPanel.setScene(new Scene(box,400,50));

}

}