SWT - настройка моего ProgressMonitorDialog
У меня есть рабочий ProgressMonitorDialog, но я хочу убедиться, что я его правильно настраиваю.
Сначала код:
Способ создания диалога
public void startProgressBar() {
try {
new ProgressMonitorDialog(getShell()).run(true, true,
new ProgressBarThread());
}
catch (InvocationTargetException e) {
MessageDialog.openError(getShell(), "Error", e.getMessage());
}
catch (InterruptedException e) {
MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage());
}
}
Файл класса
class ProgressBarThread implements IRunnableWithProgress {
private static final int TOTAL_TIME = 1000;
public ProgressBarThread() {
}
public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException {
monitor.beginTask("Creating PDF File(s): Please wait.....", IProgressMonitor.UNKNOWN);
for (int total = 0; total < TOTAL_TIME ; total++) {
Thread.sleep(total);
monitor.worked(total);
if (total == TOTAL_TIME / 2) monitor.subTask("Please be patient... Operation should finish soon.");
}
monitor.done();
}
}
Метод, который вызывает ProgressBar и запускает операцию создания PDF-файла.
private void startSavePdfOperation() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
startProgressBar();
}
});
saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session);
saveOp.addOperationListener(new MyOperationListener(this) {
public void endOperationImpl() {
java.io.File zipFile = null;
try {
AplotSaveResultsParser.SaveResult saveResults = saveOp.getSaveResults();
if (saveResults != null) {
ETC..... ETC......
Вопросы:
Поскольку ProgressMonitorDialog является графическим интерфейсом, его необходимо выполнить в Display.getDefault(). AsyncExec?
Если ProgressMonitorDialog выполняется в отдельном потоке, как он узнает, что закрывается, когда операция завершается?
Есть ли связь между индикатором выполнения и операцией?
Я прав в предположении, что цикл for в классе ProgressBarThread является в основном таймером, который держит монитор открытым?
Есть ли способ увеличить скорость индикатора ProgressMonitorDialog, также вы можете удалить кнопку отмены?
Это то, что я думаю, что происходит в настоящее время.
Я запускаю индикатор выполнения непосредственно перед запуском прослушивателя операций PDF. См. StartSavePdfOperation () выше.
Индикатор выполнения работает как неизвестный, но использует цикл for, чтобы держать диалоговое окно индикатора выполнения открытым, пока операция выполняется в потоке в фоновом режиме.
Смотрите класс ProgressBarThread вышеКогда операция PDF завершается, класс операций слушателя закрывает диалоговое окно основного графического интерфейса.
public void endOperation() { try { endOperationImpl(); } finally { Display.getDefault().asyncExec(new Runnable() { public void run() { w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); w.recursiveSetEnabled(getShell(), true); w.getShell().setEnabled(!getShell().getEnabled()); w.close(); } }); }
}
Я не уверен, что происходит с монитором ProgressBarThread?
Это возможно?
Когда начинается операция PDF, ProgressMonitorDialog открывается и запускает индикатор. Хорошо с сохранением этого неизвестным.
Когда операция PDF завершается, монитор закрывается, затем базовый диалог
Я просто хочу открыть диалоговое окно индикатора выполнения, которое сообщит пользователю, что его запрос работает в фоновом режиме.
Как указано выше, код работает, но я боюсь, что закрытие базового графического интерфейса пользователя может привести к тому, что уничтожение моего Progress Thread и Monitor не является хорошей практикой.
1 ответ
Прежде всего, в вашем ProgressBarThread#run()
ты должен использовать monitor.worked(1)
, Вам не нужно устанавливать общее количество выполненных работ, но увеличивайте его на количество выполненных работ, начиная с последнего вызова.
Q1. Да, это должно быть выполнено в потоке отображения Q2. Обычно работа, которую необходимо выполнить, фактически выполняется в исполняемом модуле, который передается в диалоговое окно монитора прогресса, чтобы вы могли точно сообщить о достигнутом прогрессе. Таким образом, ваша операция (если это синхронный вызов) должна быть вызвана изнутри ProgressBarThread#run()
так что вы вызываете monitor.worked(1) только после завершения обработки одного файла.
Q3. Какую операцию вы выполняете, возможно, она уже поддерживает отображение индикатора выполнения, и вам просто нужно вызвать правильный API. Это IUndoableOperation
?
Q4. Как я уже говорил, такой подход проблематичен, потому что вы никогда не сможете точно сообщить о ходе работы и закрыть диалог только после завершения операции. Но если это единственный выбор, который у вас есть, то вы можете просто сохранить monitor
ссылка где-то, чтобы он был доступен для другого потока. однажды monitor.done()
называется твой ProgressBarThread#run()
должен вернуться, диалог закроется.
Q5. Вы можете удалить кнопку отмены, передав правильный параметр ProgressMonitorDialog#run(..)
:
new ProgressMonitorDialog(getShell()).run(true, false, new ProgressBarThread());
На остальные вопросы я могу лучше ответить, если знаю, какую операцию (какой API) вы используете.