【发布时间】:2015-07-20 00:44:01
【问题描述】:
我制作了一个小型 MVC 程序,将文件从 A 复制到 B。为了更好地指示进度,我使用 ProgressBar 和 Observer Pattern 来刷新它。
模型(复制器和 Observable):
[...]
Files.copy(file.toPath(), Paths.get(destinationPath.toString() + "/" + file.getName()),
StandardCopyOption.REPLACE_EXISTING);
copyingFile = file.getName();
progress++;
setChanged();
notifyObservers("progress");
[...]
还有视图(ProgressBar + Observer):
[...]
progressBar = new ProgressBar();
[...]
@Override
public void update(Observable observable, Object arg) {
if (observable != null && observable instanceof MainModel) {
if (arg instanceof String && "progress".equals(arg)) {
Platform.runLater(() -> {
progressBar.setProgress(model.getProgress());
copyingFile.setText(model.getCopyingFile());
percent.setText(df.format(progressBar.getProgress()* 100) + "%");
});
}
[...]
这很好用。 ProgressBar 不断更新,但如果我复制 100 多个文件(大约 2MB),它就不再工作了。
似乎notifyObservers("progress") 经常触发并卡住,或者线程太忙于复制文件,应该更新ProgressBar 的JavaFX 线程没有时间做它的工作。
整个问题让我想到了代码,我怀疑这种使用观察者模式快速更新ProgressBar 的方法似乎不是一个好方法。
更新ProgressBar 的正确方法是什么?绑定属性?
补充问题: 我正在使用观察者模式来更新视图中的所有数据。因为模型需要更新很多不同的东西,而且它并不总是需要更新整个数据,所以我使用这种更新方式:
@Override
public void update(Observable observable, Object arg) {
if (observable != null && observable instanceof MainModel) {
if (arg instanceof String && "progress".equals(arg)) {
Platform.runLater(() -> {
progressBar.setProgress(model.getProgress());
copyingFile.setText(model.getCopyingFile());
percent.setText(df.format(progressBar.getProgress() * 100) + "%");
if (progressBar.getProgress() > 0.5) {
percent.setTextFill(Color.WHITE);
}
});
} else if (arg instanceof String && "finished".equals(arg)) {
Platform.runLater(() -> {
progressBar.setProgress(1);
copyingFile.setText("Fertig!");
percent.setText("100%");
finishButton.setDisable(false);
});
} else if (arg instanceof String && "events".equals(arg)) {
eventChoiceBox.setDisable(false);
List<String> events = new LinkedList<>();
events.addAll(model.getEvents());
Collections.sort(events);
events.add(0, "Neue Veranstaltung...");
eventChoiceBox.setItems(FXCollections.observableArrayList(events));
eventChoiceBox.getSelectionModel().select(model.getEvent());
} else {
userNames.setItems(FXCollections.observableArrayList(model.getUsers()));
filesList.setItems(FXCollections.observableArrayList(model.getFilesAsString()));
userNames.getSelectionModel().select(model.getUser());
}
}
我对整个if-else 事物和关键字(进度、完成、事件)的这种方式持怀疑态度。
好吧,它在大多数情况下都有效并使用这种方式,但这甚至是一种好方法吗?
非常感谢!
【问题讨论】:
-
你能比“它不再工作”更具体吗?当您复制 100 个或更多文件时,您看到了什么行为?
标签: java javafx progress-bar observer-pattern