同时运行javafx和swing应用程序

同时运行javafx和swing应用程序,java,swing,javafx,webcam,webcam-capture,Java,Swing,Javafx,Webcam,Webcam Capture,我正在使用java中的网络摄像头捕获API访问我的网络摄像头。网络摄像头捕获API是基于Swing构建的,我知道,但是我想将网络摄像头Swing类与JavaFX类结合起来。JavaFX类在屏幕上显示一个矩形。我的目标是:运行在屏幕上显示矩形的JavaFX类。在某个时候(如鼠标单击),我想启动网络摄像头。网络摄像头设置为查看屏幕,然后应该对矩形的图像执行某些操作 JavaFX类: public class JavaFXDisplay extends Application { @Over

我正在使用java中的网络摄像头捕获API访问我的网络摄像头。网络摄像头捕获API是基于Swing构建的,我知道,但是我想将网络摄像头Swing类与JavaFX类结合起来。JavaFX类在屏幕上显示一个矩形。我的目标是:运行在屏幕上显示矩形的JavaFX类。在某个时候(如鼠标单击),我想启动网络摄像头。网络摄像头设置为查看屏幕,然后应该对矩形的图像执行某些操作

JavaFX类:

public class JavaFXDisplay extends Application {

    @Override
    public void start(Stage primaryStage) {
        WebcamCapture wc = new WebcamCapture();

        StackPane root = new StackPane();

        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(500);
        rectangle.setHeight(500);

        Scene scene = new Scene(root, 1000, 1000);
        root.getChildren().addAll(rectangle);

        primaryStage.setScene(scene);
        primaryStage.show();

        scene.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                wc.doSomething();
            }
        });
   }

   public static void main(String[] args) {
       launch(args);
   }
}

但是,我的JavaFX类没有启动/显示。我的代码有什么问题?

我不熟悉您正在使用的web cam API(因此我不知道这是否是唯一的错误),但您确实需要在AWT事件调度线程上创建Swing内容。目前,您正在FX应用程序线程上创建它

您可以使用以下习惯用法:

public class JavaFXDisplay extends Application {

    private WebcamCapture wc ;

    @Override
    public void init() throws Exception {
        super.init();
        FutureTask<WebcamCapture> launchWebcam = new FutureTask<>(WebcamCapture::new) ;
        SwingUtilities.invokeLater(launchWebcam);

        // block until webcam is started:
        wc = launchWebcam.get();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        StackPane root = new StackPane();

        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(500);
        rectangle.setHeight(500);

        Scene scene = new Scene(root, 1000, 1000);
        root.getChildren().addAll(rectangle);

        primaryStage.setScene(scene);
        primaryStage.show();

        scene.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                wc.doSomething();
            }
        });
   }

   public static void main(String[] args) {
       launch(args);
   }
}
public类JavaFXDisplay扩展了应用程序{
私人网络摄像机;
@凌驾
public void init()引发异常{
super.init();
FutureTask launchWebcam=新建FutureTask(WebcamCapture::新建);
SwingUtilities.invokeLater(启动网络摄像头);
//阻止,直到网络摄像头启动:
wc=启动WebCam.get();
}
@凌驾
public void start(Stage primaryStage)引发异常{
StackPane root=新的StackPane();
矩形=新矩形();
矩形。设置宽度(500);
矩形。设置高度(500);
场景=新场景(根,1000,1000);
root.getChildren().addAll(矩形);
初级阶段。场景(场景);
primaryStage.show();
scene.addEventFilter(按下MouseEvent.MOUSE_,新建EventHandler()){
@凌驾
公共无效句柄(MouseEvent MouseEvent){
wc.doSomething();
}
});
}
公共静态void main(字符串[]args){
发射(args);
}
}
作为参考,这里有一个仅限于JavaFX的网络摄像头查看器。我在运行OS X Sierra(10.12.2)的MacBookPro上测试了这一点,并在2011年的27英寸Thunderbolt显示屏上安装了摄像头

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FXWebCamViewer extends Application {

    private BlockingQueue<Image> imageQueue = new ArrayBlockingQueue<>(5);

    private Executor exec = Executors.newCachedThreadPool(runnable -> {
        Thread t = new Thread(runnable);
        t.setDaemon(true);
        return t ;
    });

    private Webcam webcam;

    @Override
    public void init() {
        webcam = Webcam.getWebcams().get(0);
        Dimension viewSize = WebcamResolution.QVGA.getSize();
        webcam.setViewSize(viewSize);
        webcam.open();
    }

    @Override
    public void start(Stage primaryStage) {
        ImageView imageView = new ImageView();

        StackPane root = new StackPane(imageView);
        imageView.fitWidthProperty().bind(root.widthProperty());
        imageView.fitHeightProperty().bind(root.heightProperty());
        imageView.setPreserveRatio(true);

        AnimationTimer updateImage = new AnimationTimer() {
            @Override
            public void handle(long timestamp) {
                Image image = imageQueue.poll();
                if (image != null) {
                    imageView.setImage(image);
                }
            }
        };
        updateImage.start();

        exec.execute(this::generateImages);

        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void generateImages() {
        while (! Thread.interrupted()) {
            try {
                if (webcam.isOpen() && webcam.isImageNew()) {
                    BufferedImage bimg = webcam.getImage();
                    if (bimg != null) {
                        imageQueue.put(SwingFXUtils.toFXImage(bimg, null));
                    }
                } else {
                    Thread.sleep(250);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入java.awt.Dimension;
导入java.awt.image.buffereImage;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.Executor;
导入java.util.concurrent.Executors;
导入com.github.sarxos.webcam.webcam;
导入com.github.sarxos.webcam.webcam分辨率;
导入javafx.animation.AnimationTimer;
导入javafx.application.application;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.scene;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类FXWebCamViewer扩展了应用程序{
private BlockingQueue imageQueue=new ArrayBlockingQueue(5);
private Executor exec=Executors.newCachedThreadPool(可运行->{
螺纹t=新螺纹(可运行);
t、 setDaemon(true);
返回t;
});
私人网络摄像机;
@凌驾
公共void init(){
webcam=webcam.getWebcams().get(0);
维度viewSize=WebcamResolution.QVGA.getSize();
webcam.setViewSize(viewSize);
webcam.open();
}
@凌驾
公共无效开始(阶段primaryStage){
ImageView ImageView=新的ImageView();
StackPane根=新的StackPane(imageView);
imageView.fitWidthProperty().bind(root.widthProperty());
imageView.fitHeightProperty().bind(root.heightProperty());
imageView.setPreserveRatio(真);
AnimationTimer updateImage=新建AnimationTimer(){
@凌驾
公共无效句柄(长时间戳){
Image=imageQueue.poll();
如果(图像!=null){
设置图像(图像);
}
}
};
updateImage.start();
exec.execute(this::generateImages);
场景=新场景(root,600600);
初级阶段。场景(场景);
primaryStage.show();
}
私有void generateAges(){
而(!Thread.interrupted()){
试一试{
if(webcam.isOpen()&&webcam.isImageNew()){
BuffereImage bimg=webcam.getImage();
如果(bimg!=null){
imageQueue.put(SwingFXUtils.toFXImage(bimg,null));
}
}否则{
睡眠(250);
}
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

我不熟悉您正在使用的网络摄像头捕获API;但是,如果您混合使用Swing和JavaFX,则需要正确管理线程。Swing UI只能在AWT事件调度线程上操作;JavaFX UI只能在JavaFX应用程序线程上操作。例如,有关混合使用这两个线程的信息,请参阅。(如果组件是轻量级的,您可以使用
SwingNode
,将网络摄像头直接嵌入JavaFX。)你可能是对的,在JavaFX中实现Swing部分可能是最好的解决方案,但是我对JavaFX和网络摄像头捕获API还不够熟悉。因此,如果你将所有内容移动到正确的线程,它会工作吗?不是所有内容都已经在正确的线程中了吗?至少我认为是。不:你正在FX上完成所有Swing工作应用程序线程。遗憾的是,我的问题仍然存在。请澄清一下,带有网络摄像头捕获API的Swing类来自库创建者的示例,并且可以工作(链接:),但让我怀疑的是作者的JavaFX示例(链接:)也不起作用。也许有人能帮我检查一下它是否起作用吗?也许它与我的机器有关。@DanielleWoods请参阅更新。对于版本0,它对我起作用。
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FXWebCamViewer extends Application {

    private BlockingQueue<Image> imageQueue = new ArrayBlockingQueue<>(5);

    private Executor exec = Executors.newCachedThreadPool(runnable -> {
        Thread t = new Thread(runnable);
        t.setDaemon(true);
        return t ;
    });

    private Webcam webcam;

    @Override
    public void init() {
        webcam = Webcam.getWebcams().get(0);
        Dimension viewSize = WebcamResolution.QVGA.getSize();
        webcam.setViewSize(viewSize);
        webcam.open();
    }

    @Override
    public void start(Stage primaryStage) {
        ImageView imageView = new ImageView();

        StackPane root = new StackPane(imageView);
        imageView.fitWidthProperty().bind(root.widthProperty());
        imageView.fitHeightProperty().bind(root.heightProperty());
        imageView.setPreserveRatio(true);

        AnimationTimer updateImage = new AnimationTimer() {
            @Override
            public void handle(long timestamp) {
                Image image = imageQueue.poll();
                if (image != null) {
                    imageView.setImage(image);
                }
            }
        };
        updateImage.start();

        exec.execute(this::generateImages);

        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void generateImages() {
        while (! Thread.interrupted()) {
            try {
                if (webcam.isOpen() && webcam.isImageNew()) {
                    BufferedImage bimg = webcam.getImage();
                    if (bimg != null) {
                        imageQueue.put(SwingFXUtils.toFXImage(bimg, null));
                    }
                } else {
                    Thread.sleep(250);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}