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