并发任务更新复杂对象 JavaFX - swingworker 等效项?

2024-03-14

我想在后台运行一个任务,更新视图中的中间结果。我正在尝试实现 MVC JavaFX 应用程序。任务在模型中定义。 我想将部分结果发送给主要威胁,以便在视图中显示它们。 我使用 updateValue() 来执行此操作。另外,我在控制器中定义了对象属性和侦听器。

我的问题:每次在任务中执行 updateValue() 时,不会触发侦听器的方法changed()。为什么?我怎样才能强迫它这样做?

我还没有找到太多复杂的例子。

到目前为止我所拥有的:

模型.cpp

ComplexObject  _complexO;
public Task<ComplexObject> getModelTask() {
      return new Task<ComplexObject>() {
           @Override
           protected ComplexObject call() throws Exception {

            int    numberOfFiles = 0;
            boolean filesToRead = true;
            while (filesToRead){
                  // ....
              _complexO = new ComplexObject();
              try{
                   //..
                   if(f.exists()){
                       _complexO.initialize();
                       numberOfScans ++;

                     }
                    else{
                       _complexO.initializeToNull();
                     }

                  String stringNumber = Converter.toString(numberOfFiles);
                  updateMessage(stringNumber);                        
                  updateValue(_complexO );
              } catch(Exception ex){
                   ex.printStackTrace();
                   _complexO = null;
                   return _complexO;
              }
             filesToRead = areThereFilesToRead();
             }
             return _complexO;        
        }
   };
}

控制器.cpp

...

Task<  ComplexObject> task = _model.getModelTask();
_AJavaFXTextField.textProperty().bind(task.messageProperty());
_AJavaFXTextField.textProperty().addListener(new ChangeListener<String>() {

   @Override
   public void changed(ObservableValue observable, String oldValue, String newValue) {  
           System.out.println("Success with messageProperty!!" + newValue);
      }       
     });

SimpleObjectProperty<ComplexObject> complexObjectProperty = new SimpleObjectProperty<>();
complexObjectProperty.bind(task.valueProperty());
complexObjectProperty.addListener(new ChangeListener<ComplexObject>(){

   @Override
   public void changed(ObservableValue<? extends ComplexObject> observable, ComplexObject oldValue, ComplexObject newValue) {
      if(newValue.data == null ) {
        System.out.println("value is new!!! " + scansNumber);
      }
      else if(newValue.isValid()){
         System.out.println("I want to plot newValue data here");

       }
      }         
     });

   Thread th=  new Thread(task);
   System.out.println("call TASK");
   th.start();
}

我的问题/结论在这里:

  1. 如何强制我在任务 updateValue() 中执行的所有时间都真正执行侦听器 - 因此在我想要绘制数据的位置执行代码。

  2. 为什么 messageProperty 的触发绑定次数比 valueProperty 的触发次数多? - 应该是相同的次数。

  3. 为什么我发现侦听器代码在调试模式下比正常执行时被触发的次数更多?

  4. 任何关于这个主题的好资源的推荐(从复杂的角度来看)都会很棒。

  5. 我正在寻找 JavaFX 中的某些东西来替代 SwingWorker。

  6. 最后我真正想要的是:从任务中返回复杂对象的列表,理想情况下, updateValue() 会逐个发送对象(部分结果)

我已经关注:https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html

非常感谢您的任何贡献


Task仅保证值传递给updateValue或者稍后传递的值将被设置为value财产。这样做是为了通过限制侦听器收到通知的更改数量来提高应用程序线程的性能。

为什么更多次触发绑定messagePropertyvalueProperty? - 应该是相同的次数。

如上所述,根本无法保证更新的数量。

为什么我发现侦听器代码在调试模式下比正常执行时被触发的次数更多?

一般来说,调试会使你的程序更小。您的线程的更新频率越小Task,两次之间的更新次数越少Task类更新的属性越少,跳过的次数越多。 (更新可能每帧或每几帧执行一次。)如果您甚至在任务中使用断点/步进器,您可能会执行Task当应用程序线程以正常速度运行时速度非常慢。


它应该很容易实现publish自行使用List缓冲更新

public abstract class JavaFXWorker<S, T> extends Task<S> {

    private List<T> chunks = new ArrayList<>();
    private final Object lock = new Object();
    private boolean chunkUpdating = false;

    protected final void publish(T... results) {
        synchronized (lock) {
            chunks.addAll(Arrays.asList(results));
            if (!chunkUpdating) {
                chunkUpdating = true;
                Platform.runLater(() -> {
                    List<T> cs;
                    synchronized (lock) {
                        cs = chunks;
                        // create new list to not unnecessary lock worker thread
                        chunks = new ArrayList<>();
                        chunkUpdating = false;
                    }
                    try {
                        process(cs);
                    } catch (RuntimeException ex) {
                    }
                });
            }
        }
    }

    protected void process(List<T> chunks) {
    }

}

样品使用

@Override
public void start(Stage primaryStage) {

    ListView<Integer> lv = new ListView<>();

    Button btn = new Button("Run");
    btn.setOnAction((ActionEvent event) -> {
        JavaFXWorker<Void, Integer> worker = new JavaFXWorker<Void, Integer>() {

            @Override
            protected Void call() throws Exception {
                final int maxCount = 100;

                Random random = new Random();

                int breakIndex = random.nextInt(maxCount-1)+1;

                for (int i = 0; i < breakIndex; i++) {
                    publish(i);
                }
                // some break simulating a part long part of the task with no updates
                Thread.sleep(3000);
                for (int i = breakIndex; i <= maxCount; i++) {
                    publish(i);
                }

                return null;
            }

            @Override
            protected void process(List<Integer> chunks) {
                lv.getItems().addAll(chunks);
            }

        };
        new Thread(worker).start();
    });


    Scene scene = new Scene(new VBox(btn, lv));

    primaryStage.setScene(scene);
    primaryStage.show();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并发任务更新复杂对象 JavaFX - swingworker 等效项? 的相关文章

  • JavaFX 的 Swing 计时器替代方案以及线程管理差异

    使用 JavaFX 的 Swing 计时器是否安全 或者 Swing 有特殊的替代方案吗 JavaFX 和 Swing 的线程管理有什么区别 事实上我很想知道相当于摇摆计时器 SwingUtilities invokeLater and i
  • JavaFX 使用动画最小化和最大化未装饰的舞台

    我在这个问题中使用已接受的答案 JavaFX 最小化未修饰的阶段 https stackoverflow com questions 26972683 javafx minimizing undecorated stage正确最小化我的应用
  • JAVA FXCollections LoadException 类不是有效类型

    我正在尝试在此帮助下实现带有一些数据的 TableViewTutorial https docs oracle com javafx 2 fxml get started fxml tutorial intermediate htm CIA
  • Python中的键盘可中断阻塞队列

    It seems import Queue Queue Queue get timeout 10 键盘可中断 ctrl c 而 import Queue Queue Queue get 不是 我总是可以创建一个循环 import Queue
  • 在Java中,如何在单线程程序中抛出ConcurrentModificationException? [复制]

    这个问题在这里已经有答案了 我正在读这篇文章 Java常见并发问题 https stackoverflow com questions 461896 what is the most frequent concurrency problem
  • 向 Windows 任务栏缩略图添加按钮 JavaFX?

    这个问题已经闲置一年多了 我的问题仍然没有解决方案 我编辑此内容是为了澄清我的问题并引起人们对它的新关注 如果您使用 Windows 您可能知道将程序图标悬停在任务栏上时显示的小预览图像 缩略图 某些程序 例如 Spotify Git 扩展
  • 完全替换 ASP.Net 的会话

    ASP Net 会话对于传统的 WebForms 应用程序来说似乎很完美 但它们所做的一些事情对于现代 AJAX 和 MVC 应用程序来说是一个严重的问题 具体来说 访问 ASP Net 提供程序只有 3 种方法 锁定读和写 默认 会话被锁
  • JavaFX - 如何检测 Windows 注销/关闭请求?

    我有一个应用程序必须在退出时处理一些方法 但是 当用户在没有先关闭我的应用程序的情况下关闭 Windows 时 Windows 会终止该应用程序并且不会运行关闭方法 如何检测用户何时请求关闭或注销 Windows 我需要运行的方法需要几毫秒
  • 尝试让 GUI 使用 arrayList 在牌组中打印随机卡

    所以我目前正在用java开发一个卡牌战争游戏 我试图让 GUI 屏幕使用 arrayList 从一组卡片图像中打印 2 张随机卡片 必须使用它进行分配 卡片图像文件名为 1 png 2 png 52 png 并存储在 image card
  • Dispatcher.BeginInvoke() 未异步运行

    这是我想做的事情的简化版本 onClick abutton a aNewMethod 将异步运行以保持 UI 响应 就是这样 我读过一些答案 这是我能想到的 private async void button Click object se
  • Java - SwingWorker - 我们可以从其他 SwingWorker 调用一个 SwingWorker 而不是 EDT

    我有一个SwingWorker如下 public class MainWorker extends SwingWorker Void MyObject 我调用了上面的Swing Worker来自东部夏令时间 MainWorker mainW
  • 如何在JavaFX中获得一个小的ProgressBar

    我正在尝试获得一个类似 iTunes 的进度条 该进度条非常小 高度约为 5 像素 但我似乎无法低于 19 或 20 像素 我尝试在周围的窗格上设置 fx max height 但没有效果 请注意 这个值确实会改变高度 我只是不能让它小于大
  • 如何使 AnchorPane 大小响应最大化的屏幕视图

    我不知道什么是灰色地带以及如何扩展我的Anchorpane到整个屏幕Image https i stack imgur com m5HqA png 不是未最大化的视图是这样的image2 https i stack imgur com 14
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事
  • JavaFx ComboBox 绑定混乱

    我有一个 I18N 实现 它通过属性绑定 JavaFX UI 元素 例如 def translateLabel l Label key String args Any Unit l textProperty bind createStrin
  • 访问 java jigsaw 模块中的资源文件[重复]

    这个问题在这里已经有答案了 我正在尝试从项目中的类访问 Eclipse 项目中的文件 我需要将该项目声明为 jigsaw 模块才能从其他项目访问它 但是通过这样做 我无法再访问项目中的 example png 等文件 这是我的项目结构 pr
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 在 VSCode 的集成终端中运行任务?

    当我过去运行任务 tasks json 时 它们在 VSCode 的集成终端内运行 但是 在重置我的开发计算机并重新安装所有内容后 我的任务现在在新的 cmd 窗口中运行 当任务因错误而失败时 就会出现问题 在这种情况下 cmd 窗口刚刚关
  • JavaFX 中的内部框架

    我找到了这个内部框架的例子 http docs oracle com javase tutorial uiswing components internalframe html http docs oracle com javase tut
  • JavaFX 如何在不改变线宽的情况下缩放路径的坐标?

    我目前正在制作具有缩放和平移功能的阶梯折线图 由于我需要处理的数据量非常大 因此每次调用layoutPlotChildren 时 我无法重新创建步骤线的整个路径 所以我的想法是创建一次路径元素 然后在缩放和平移事件时对其进行转换 到目前为止

随机推荐