当前位置: 首页 > 知识库问答 >
问题:

如何将JFXPanel添加到现有的swing应用程序中

西门梓
2023-03-14

我很难知道如何将我的JFXPanel(它是一个mp3播放器)集成到一个现有的Swing应用程序中,该应用程序是一个JFrame,其中添加了几个不同的JPanel。我对JavaFX是一个完全的noob,它与Swing非常不同。

我能够得到下面的代码来运行和做我想做的事情。它将播放mp3文件从一个目录,我有他们包含在。这是某人编写的示例中的代码。我的问题是,这段代码创建了JFrame,有main方法和所有的东西都在这段代码中。我已经制作了一个swing应用程序,我只想添加一个JFXPanel,该应用程序具有如下所示的功能。JavaFX中有许多新方法我很困惑,不知道如何使用或在我的Swing应用程序中放在哪里。例如invokeLater、runLater和InitandShowGUI。我知道这可能是一个烦人的问题,很难从这样一个noob中回答。我有一个项目,这是在明晚午夜,我真的想得到这个应用程序的一部分实现。我们没有在课堂上学过JavaFX,我不知道它对我来说这么棘手。

package application;  

import java.io.*;  
import java.util.*;  

import javafx.application.Platform;  
import javafx.beans.value.*;  
import javafx.embed.swing.JFXPanel;  
import javafx.event.*;  
import javafx.geometry.Pos;  
import javafx.scene.Scene;  
import javafx.scene.control.*;  
import javafx.scene.layout.*;  
import javafx.scene.media.*;  
import javafx.util.Duration;  

import javax.swing.*;  

/** Example of playing all mp3 audio files in a given directory  
 * using a JavaFX MediaView launched from Swing  
 */  
public class JavaFXVideoPlayerLaunchedFromSwing {  
  private static void initAndShowGUI() {  
    // This method is invoked on Swing thread  
    JFrame frame = new JFrame("FX");  
    final JFXPanel fxPanel = new JFXPanel();  
    frame.add(fxPanel);  
    frame.setBounds(200, 100, 800, 250);  
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);  
    frame.setVisible(true);  

    Platform.runLater(new Runnable() {  
      @Override public void run() {  
        initFX(fxPanel);          
      }  
    });  
  }  

  private static void initFX(JFXPanel fxPanel) {  
    // This method is invoked on JavaFX thread  
    Scene scene = new SceneGenerator().createScene();  
    fxPanel.setScene(scene);  
  }  

  public static void main(String[] args) {  
    SwingUtilities.invokeLater(new Runnable() {  
      @Override public void run() {  
        initAndShowGUI();  
      }  
    });  
  }  
}  

class SceneGenerator {      
  final Label currentlyPlaying = new Label();  
  final ProgressBar progress = new ProgressBar();  
  private ChangeListener<Duration> progressChangeListener;  

  public Scene createScene() {  
    final StackPane layout = new StackPane();  

    // determine the source directory for the playlist  
    final File dir = new File("C:/Users/Mark/Copy/Mp3Directory");  
    if (!dir.exists() || !dir.isDirectory()) {  
      System.out.println("Cannot find video source directory: " + dir);  
      Platform.exit();  
      return null;  
    }  

    // create some media players.  
    final List<MediaPlayer> players = new ArrayList<MediaPlayer>();  
    for (String file : dir.list(new FilenameFilter() {  
      @Override public boolean accept(File dir, String name) {  
        return name.endsWith(".mp3");  
      }  
    })) players.add(createPlayer("file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20")));  
    if (players.isEmpty()) {  
      System.out.println("No audio found in " + dir);  
      Platform.exit();  
      return null;  
    }      

    // create a view to show the mediaplayers.  
    final MediaView mediaView = new MediaView(players.get(0));  
    final Button skip = new Button("Skip");  
    final Button play = new Button("Pause");  

    // play each audio file in turn.  
    for (int i = 0; i < players.size(); i++) {  
      final MediaPlayer player     = players.get(i);  
      final MediaPlayer nextPlayer = players.get((i + 1) % players.size());  
      player.setOnEndOfMedia(new Runnable() {  
        @Override public void run() {  
          player.currentTimeProperty().removeListener(progressChangeListener);  
          mediaView.setMediaPlayer(nextPlayer);  
          nextPlayer.play();  
        }  
      });  
    }  

    // allow the user to skip a track.  
    skip.setOnAction(new EventHandler<ActionEvent>() {  
      @Override public void handle(ActionEvent actionEvent) {  
        final MediaPlayer curPlayer = mediaView.getMediaPlayer();  
        MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());  
        mediaView.setMediaPlayer(nextPlayer);  
        curPlayer.currentTimeProperty().removeListener(progressChangeListener);  
        curPlayer.stop();  
        nextPlayer.play();  
      }  
    });  

    // allow the user to play or pause a track.  
    play.setOnAction(new EventHandler<ActionEvent>() {  
      @Override public void handle(ActionEvent actionEvent) {  
        if ("Pause".equals(play.getText())) {  
          mediaView.getMediaPlayer().pause();  
          play.setText("Play");  
        } else {  
          mediaView.getMediaPlayer().play();  
          play.setText("Pause");  
        }  
      }  
    });  

    // display the name of the currently playing track.  
    mediaView.mediaPlayerProperty().addListener(new ChangeListener<MediaPlayer>() {  
      @Override public void changed(ObservableValue<? extends MediaPlayer> observableValue, MediaPlayer oldPlayer, MediaPlayer newPlayer) {  
        setCurrentlyPlaying(newPlayer);  
      }  
    });  

    // start playing the first track.  
    mediaView.setMediaPlayer(players.get(0));  
    mediaView.getMediaPlayer().play();  
    setCurrentlyPlaying(mediaView.getMediaPlayer());  

    // silly invisible button used as a template to get the actual preferred size of the Pause button.  
    Button invisiblePause = new Button("Pause");  
    invisiblePause.setVisible(false);  
    play.prefHeightProperty().bind(invisiblePause.heightProperty());  
    play.prefWidthProperty().bind(invisiblePause.widthProperty());  

    // layout the scene.  
    layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;");  
    layout.getChildren().addAll(  
      invisiblePause,  
      VBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children(  
        currentlyPlaying,  
        mediaView,  
        HBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children(skip, play, progress).build()  
      ).build()  
    );  
    progress.setMaxWidth(Double.MAX_VALUE);  
    HBox.setHgrow(progress, Priority.ALWAYS);  
    return new Scene(layout, 800, 600);  
  }  

  /** sets the currently playing label to the label of the new media player and updates the progress monitor. */  
  private void setCurrentlyPlaying(final MediaPlayer newPlayer) {  
    progress.setProgress(0);  
    progressChangeListener = new ChangeListener<Duration>() {  
      @Override public void changed(ObservableValue<? extends Duration> observableValue, Duration oldValue, Duration newValue) {  
        progress.setProgress(1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis());  
      }  
    };  
    newPlayer.currentTimeProperty().addListener(progressChangeListener);  

    String source = newPlayer.getMedia().getSource();  
    source = source.substring(0, source.length() - ".mp4".length());  
    source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " ");  
    currentlyPlaying.setText("Now Playing: " + source);  
  }  

  /** @return a MediaPlayer for the given source which will report any errors it encounters */  
  private MediaPlayer createPlayer(String aMediaSrc) {  
    System.out.println("Creating player for: " + aMediaSrc);  
    final MediaPlayer player = new MediaPlayer(new Media(aMediaSrc));  
    player.setOnError(new Runnable() {  
      @Override public void run() {  
        System.out.println("Media error occurred: " + player.getError());  
      }  
    });  
    return player;  
  }  
}  

共有1个答案

戚宏浚
2023-03-14

JFXPanel扩展javax.Swing.jcomponent,因此将JFXPanel添加到JFrame中,就像添加其他Swing组件一样:JFrame.getContentPane().add(myJFXPanel)

SSCCE:

package stack;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.effect.Reflection;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class FXInSwing extends JFrame{

    JFXPanel panel;
    Scene scene;
    StackPane stack;
    Text hello;

    boolean wait = true;

    public FXInSwing(){
        panel = new JFXPanel();
        Platform.runLater(new Runnable(){
            @Override
            public void run() {
                stack = new StackPane();
                scene = new Scene(stack,300,300);
                hello = new Text("Hello");

                scene.setFill(Color.BLACK);
                hello.setFill(Color.WHEAT);
                hello.setEffect(new Reflection());

                panel.setScene(scene);
                stack.getChildren().add(hello);

                wait = false;
            }
        });
        this.getContentPane().add(panel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(300, 300);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new FXInSwing();
            }
        });
    }
}  

请记住,当您使用JFXPanel时,您应该在Swing事件调度线程上初始化它,但是SetScene()应该在JavaFX应用程序线程上完成。否则,您将得到一个异常。

 类似资料:
  • 我试图创建一个模式对话框,要求用户输入。我的程序使用Swing构建gui,但由于我想用css设计组件,所以我使用JFXPanels而不是常规的JPanel。当我将JFXPanel添加到JFrame时,一切正常,但如果我尝试将JFXPanel添加到JDialog,JDialog不会显示任何内容。 我正在使用JDK 11。 我错过了什么? 这是我的代码:

  • 问题内容: 我一直在开发React应用程序,现在我需要Redux来处理它的某些方面。 阅读了一堆教程之后,我相当着迷于如何使“更智能”的组件“笨拙”以及如何将功能移入我的动作和化简器中。 因此,例如,应用程序的一个方面更多是待办事项列表样式。 我的课程之一是这样开始的: 因此,如您所见,这是非常繁重的逻辑。我已经开始通过在索引文件中添加来添加Redux ,并制作了一个基本的reducers文件,该

  • 问题内容: 我想我在这里遇到了一些classpath忧郁症。我一直在关注这些例子。我看了教程。但是似乎没有什么对我有用。 假设我在以下URI中具有JPEG: 假设我有一个带有的Swing应用,并且我想将此JPEG添加到JPanel中(位置/布局无关紧要)。 那么如何做到这一点? 我没有收到任何错误或异常,只是没有看到JPEG负载。我要使用的代码是这样的: 请告知…我从今天中午开始及其午夜一直在处理

  • 我想在我的应用程序中添加带有,但一旦我将插件添加到我的应用程序中。yaml,我的应用程序不再运行。下面是错误 失败:生成失败,出现异常。 > 错误:任务执行失败:app:transformDexArchiveWithExternalLibsDexMergerForDebug'。 通用域名格式。Android建设者德兴。DexArchiveMergerException:合并dex存档时出错:/Us

  • 我有一个现有的Spring应用程序,它是一个web应用程序,我正在尝试向它添加一个REST API。 我不知道如何连接所有东西,使其工作 我在网上添加了一个条目。xml。最初,servlet类指向我创建的DispatcherServlet,但我将其指向org。springframework。网状物servlet。我在网上找到的基于DispatcherServlet的东西。 网状物xml rest-

  • 我希望将ASP.NET Web API添加到在Visual Studio2012中开发的ASP.NET MVC4 Web应用程序项目中。我必须执行哪些步骤才能向项目中添加一个正常工作的Web API?我知道我需要一个从ApiController派生出来的控制器,但这就是我所知道的全部。 null