如何将JavaFx用于GUI和将PApplet用于输出(在不同的窗口中)

时间:2018-12-25 15:25:17

标签: javafx processing

我正在开发一个使用 JavaFX 作为GUI来控制在不同窗口中运行的 PApplet 的应用。

我设法使这两个东西都可以显示并正常工作,但是当我尝试在PApplet类中加载文件时,我收到一条警告,提示"The sketch path is not set"和类似这样的错误:{ {1}}

我猜我可能没有正确初始化PApplet。

这是我的javafx.Application类

"java.lang.RuntimeException: Files must be loaded inside setup() or after it has been called."

这是我的PApplet课程

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("application.fxml"));
            Scene scene = new Scene(root,400,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setTitle("Clusters");
            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        PApplet.main("application.Controller");
        launch(args);
    }
}

这是我将importImages()方法链接到FXXML文件的方式

public class Controller extends PApplet {

    private ArrayList<File> files;
    private ArrayList<PImage> images;

    public Controller() {
    }

    public void settings() {
        size(640, 360);
    }

    public void setup() {
        background(0);     
        images = new ArrayList<PImage>();
        files = new ArrayList<File>();
    }

    public void draw() {
    }

    public void importImages() {
        // Open File Chooser
        FileChooser dialog = new FileChooser();
        dialog.setTitle("Import Images");
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("Image files (*.jpg, *.png, *.tiff)", "*.jpg", "*.png", "*.tiff");
        dialog.getExtensionFilters().add(extFilter);
        List<File> imported_files = dialog.showOpenMultipleDialog(new Stage());
        System.out.println(imported_files); 

        for (File f: imported_files) {
            images.add(loadImage(f.getAbsolutePath()));
            System.out.println(f.getName() + " loaded");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我的猜测是,需要从Processing的主线程调用loadImage()之类的Processing函数,而需要从JavaFX Application Thread调用dialog.showOpenMultipleDialog()之类的JavaFX函数。

在JavaFX Application Thread上进行工作非常简单。阅读Concurrency in JavaFXJavaFX working with threads and GUI(或仅在Google上搜索“ JavaFX thread”之类的内容,以获取大量结果)。但基本上,您可以调用Platform.runLater()函数在JavaFX Application Thread上进行工作。

采用另一种方法并在处理线程上进行工作会稍微复杂一些。您可以阅读有关并发here的更多信息。

要检验这一理论,我会做一些简单的事情:

public class Controller extends PApplet {
  boolean loadImages = false;
  // other variables you need to communicate between threads

  public void draw() {
    if(loadImages){
      // call loadImages()
      loadImages = false;
    }
  }

  // call this from JavaFX
  public void importImages() {
    // set other variables you need here
    loadImages = true;
  }
}

如果可行,您可以做一些更奇妙的事情,例如维护事件队列。