JavaFX UI冻结问题 [英] JavaFX UI Freezing Issue

查看:353
本文介绍了JavaFX UI冻结问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图显示每个任务的进度和状态。每个任务由一行代表 TableView 。每个任务在每个线程中执行并行执行。请参阅 TableView 的图片。

I am trying to show the progress and the status of the each task. Each task represents by a row into TableView. Each task executs parallel in each Thread. Please refer image of TableView.

>

对于Progress TableColumn 我已经设置Cell Factory来渲染`ProgressBar'。

For "Progress" TableColumn I have set Cell Factory to render `ProgressBar".

  public static class ProgressBarTableCell<S, T> extends TableCell<S, T> {

        private final ProgressBar progressBar;
        private ObservableValue<T> ov;

        public ProgressBarTableCell() {
            this.progressBar = new ProgressBar();
            progressBar.setPrefHeight(23);
            setAlignment(Pos.CENTER);
        }

        @Override
        public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null) {
                setGraphic(null);
                setText(null);
            } else {
                if (item.toString().equalsIgnoreCase("Processing")) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {

                            if (getGraphic() == null) {
                                setGraphic(progressBar);
                                progressBar.setProgress(-1);
                            } else {
                                ProgressBar objpProgressBar = (ProgressBar) getGraphic();
                                objpProgressBar.setProgress(-1);
                            }
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                        }
                    });
                } else {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            if (getGraphic() == null) {
                                setGraphic(progressBar);
                                progressBar.setProgress(0);
                            } else {
                                ProgressBar objpProgressBar = (ProgressBar) getGraphic();
                                objpProgressBar.setProgress(0);
                            }
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                        }
                    });
                }
            }
        }
    } 

TableView 没有显示任务的更新状态和进度,所以我在后台定期运行一个线程,修改 TableView 当我调用 startUpdatingTableProgress()并在调用 stopUpdatingTableProgress()时停止。

The TableView was not showing updated status and progress of tasks, so I am running a thread periodically in background, which modifies TableView when I call startUpdatingTableProgress() and stops when I call stopUpdatingTableProgress().

 public void stopUpdatingTableProgress() {
    keepUpdating = false;
}

public void startUpdatingTableProgress() {
    keepUpdating = true;
    TableProgressBarUpdator tpu = new TableProgressBarUpdator(table);
    tpu.start();
}

class TableProgressBarUpdator implements Runnable {

    TableView table;

    public TableProgressBarUpdator(TableView fxtable) {
        table = fxtable;

    }

    public void start() {
        new Thread(this).start();
    }

    public void run() {

        while (keepUpdating) {
            try {
                updateProgressbar();
                Thread.sleep(1000);
            } catch (Exception e) {
                LogHandler.doErrorLogging("Error while updating tables cell", e);
            }
        }
        LogHandler.doDebugLogging("Table process repainting is completed.");
    }

    private void updateProgressbar() throws Exception {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ((TableColumn) table.getColumns().get(0)).setVisible(false);
                ((TableColumn) table.getColumns().get(0)).setVisible(true);
            }
        });


    }
}

JavaFX 应用程序的UI在连续时间后停止。是否有其他方法可以在后台线程中调用 updateProgressbar(),在特定时间间隔后自动触发并且不冻结我的 JavaFX 应用程序的UI?

But now My JavaFX app's UI freezes after consecutive times. Is there any alternative way to call updateProgressbar() in background thread that triggers automatically after specific time interval and do not freeze my JavaFX App's UI?

我不知道我是否正确地更新任务的状态,每个任务在单独的线程中运行。如果我想实现这个与 javafx.concurrent包的帮助,那么任何人都可以给我一些指导或流程?什么将进入任务,什么将进入服务类?我如何计划它更新进度条? FYI:一次只有5个主题可以并行执行。

I do not know whether I am on the right way to update status of tasks where each task runs in a separate thread. If I would like to implement this with the help of javafx.concurrent package then can anybody show me some guidance or flow? What will go into the Task and what will go into Service Class? How I can schedule it to update progress bar? FYI: At a time only 5 threads allowed to execute parallel.

已编辑 -

建议Andy Till先生更新我的代码,但仍然没有运气 -

according to suggestion of Mr. Andy Till I have updated my code but still no luck -

TableColumn tableColumn_Progress = new TableColumn("Progress");
        tableColumn_Progress.setCellValueFactory(new PropertyValueFactory<QueueData, Double>("progressBar"));
        tableColumn_Progress.setPrefWidth(100);

        Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>> attachmentCellFactory = //
                new Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>>() {
            @Override
            public TableCell call(final TableColumn param) {
                final ProgressBarTableCell cell = new ProgressBarTableCell() {
                    @Override
                    public void updateItem(Object item, boolean empty) {
                        super.updateItem(item, empty);
                    }
                };
                return cell;
            }
        };
        tableColumn_Progress.setCellFactory(attachmentCellFactory);

在QueueData类别中 -

In QueueData Class -

DoubleProperty progressBar = null;

public DoubleProperty progressBarProperty() {
        return progressBar;
    }

    public Double getprogressBar() {
        return progressBar.get();
    }

    public void setprogressBar(Double sType) {
        this.progressBar = new SimpleDoubleProperty(sType);
    }

并没有调用任何后台线程更新UI但没有运气。

And not calling any background thread to update UI but no luck.

推荐答案

你的'QueueData'类应该有方法来设置现有进度的double属性,看来你正在创建新的SimpleDoubleProperty每次在setprogressBar(Double sType)方法中设置进度状态。

Your 'QueueData' class should have methods to set double property of existing progress, it seems you are creating new SimpleDoubleProperty each and every time on setting progress status in setprogressBar(Double sType) method.

更新为 -

 public void setprogressBar(Double sType) {
        this.progressBar.set(sType);
    }

在开始时只需创建一个progressBar对象,然后更新现有的对象。

Just create object of progressBar once at start then update existing one.

这篇关于JavaFX UI冻结问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆