我有一个带有MVC组件类的JavaFX项目。
处理View组件中的特定菜单项会导致FileChooser调用,并将其结果传递给Controller以供模型处理。
这个文件处理虽然可以持续几秒钟,所以我想在另一个线程上运行它,并在它运行时弹出一个进度对话框。
问题here显示了两个单独类的可能解决方案,我可以适应将进度状态从模型传递回View(管理进度对话框)(管理文件处理)通过控制器,但似乎是一个过于复杂的适应。
我很想知道其他人是否/如何在保持MVC分离的同时为此开发出清洁解决方案?
更新:
这就是我在这个阶段获得分离的方式:
查看:通过调用fileChooser并将所选文件传递给Controller来选择菜单。
Model:从Controller获取文件并在状态变量上调用firePropertyChange
Controller:从View获取文件,创建后台活动以调用Model活动,监视状态变量并在更改进程对话框时调用updateProgress。
public class eeView
implements Initializable {
@FXML
private void openHashdeep() {
...
file = fileChooser.showOpenDialog( primaryStage );
...
notifyReadHashdeepFile( file );
}
public void createProgressDialog(String title, String masthead, Worker<?> worker )
{
Dialogs.create()
.owner(primaryStage)
.title(title)
.masthead(masthead)
.showWorkerProgress(worker);
}
public class eeController
implements EEListener {
public void readHashdeepFile(File file) {
Service<Void> service = new Service<Void>()
{
@Override
protected Task<Void> createTask()
{
return new Task<Void>()
{
@Override
protected Void call()
throws InterruptedException
{
try {
System.out.println("readHashdeepFile " + file);
theModel.addPropertyChangeListener( new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
//System.out.println( "Change in " + propertyName + ", now " + (long) e.getNewValue() );
if ( "BytesToProcess".equals(propertyName) ) {
BytesToProcess = (long) e.getNewValue();
System.out.println( "Change in " + propertyName + ", now " + (long) e.getNewValue() );
}
else if ( "BytesProcessed".equals(propertyName) ) {
BytesProcessed = (long) e.getNewValue();
updateProgress( BytesProcessed, BytesToProcess );
}
}
});
theModel.readHashdeepFile( file );
}
catch( EEException ex ){
System.out.println(ex.getMessage());
theView.displayErrorMessage( ex.getMessage() );
}
// TODO theModel.removePropertyChangeListener(...);
return null;
}
};
}
};
theView.createProgressDialog("Progress Dialog", "Loading file", service );
service.start();
}
public class eeModel {
public void readHashdeepFile( File file )
throws EEException {
long BytesToProcess;
long BytesProcessed;
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
String[] word;
int lineno = 0;
List<Filedata> tempData = new ArrayList<Filedata>();
BytesToProcess = file.length();
mPcs.firePropertyChange( "BytesToProcess", 0, BytesToProcess );
BytesProcessed = 0;
while ((line = br.readLine()) != null) {
lineno++;
BytesProcessed += line.length();
mPcs.firePropertyChange( "BytesProcessed", 0, BytesProcessed );
...
}
br.close();
}
catch (FileNotFoundException e) {
...
}