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