Skip to content

Commit de4db6f

Browse files
committed
Refactor io metadata to new class, add tests for io metadata updating and for utils classes.
1 parent 5b3f687 commit de4db6f

File tree

5 files changed

+195
-44
lines changed

5 files changed

+195
-44
lines changed

src/main/java/boundingboxeditor/controller/Controller.java

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,10 @@ public class Controller {
118118
private final ChangeListener<Boolean> imageNavigationKeyPressedListener = createImageNavigationKeyPressedListener();
119119
private final BooleanProperty navigatePreviousKeyPressed = new SimpleBooleanProperty(false);
120120
private final BooleanProperty navigateNextKeyPressed = new SimpleBooleanProperty(false);
121+
private final IoMetaData ioMetaData = new IoMetaData();
121122
String lastLoadedImageUrl;
122123
private final ChangeListener<Number> selectedFileIndexListener = createSelectedFileIndexListener();
123124
Thread directoryWatcher;
124-
private File currentImageLoadingDirectory;
125-
private File currentAnnotationSavingDirectory;
126-
private File currentAnnotationLoadingDirectory;
127125

128126
/**
129127
* Creates a new controller object that is responsible for handling the application logic and
@@ -146,12 +144,17 @@ public Controller(final Stage mainStage) {
146144
setUpModelListeners();
147145
}
148146

147+
IoMetaData getIoMetaData() {
148+
return ioMetaData;
149+
}
150+
149151
/**
150152
* Handles the event of the user requesting to open a new image folder.
151153
*/
152154
public void onRegisterOpenImageFolderAction() {
153155
final File imageFolder = MainView.displayDirectoryChooserAndGetChoice(IMAGE_FOLDER_CHOOSER_TITLE, stage,
154-
currentImageLoadingDirectory);
156+
ioMetaData
157+
.getDefaultImageLoadingDirectory());
155158

156159
if(imageFolder != null) {
157160
initiateImageFolderLoading(imageFolder);
@@ -166,12 +169,12 @@ public void onRegisterOpenImageFolderAction() {
166169
public void initiateImageFolderLoading(File imageFolder) {
167170
updateModelFromView();
168171
loadImageFiles(imageFolder);
169-
currentImageLoadingDirectory = imageFolder;
172+
ioMetaData.setDefaultImageLoadingDirectory(imageFolder);
170173
}
171174

172175
public void initiateCurrentFolderReloading() {
173176
updateModelFromView();
174-
forceLoadImageFiles(currentImageLoadingDirectory);
177+
forceLoadImageFiles(ioMetaData.getDefaultImageLoadingDirectory());
175178
}
176179

177180
/**
@@ -216,7 +219,6 @@ public void onRegisterSaveAnnotationsAction(ImageAnnotationSaveStrategy.Type sav
216219

217220
if(destination != null) {
218221
new AnnotationSaverService(destination, saveFormat).startAndShowProgressDialog();
219-
setCurrentAnnotationSavingDirectory(destination);
220222
}
221223
}
222224

@@ -228,7 +230,6 @@ public void onRegisterImportAnnotationsAction(ImageAnnotationLoadStrategy.Type l
228230

229231
if(source != null) {
230232
initiateAnnotationImport(source, loadFormat);
231-
setCurrentAnnotationLoadingDirectory(source);
232233
}
233234
}
234235

@@ -601,28 +602,25 @@ private void initiateAnnotationSavingWithFormatChoiceAndRunOnSaveSuccess(Runnabl
601602
if(destination != null) {
602603
// Save annotations.
603604
AnnotationSaverService annotationSaverService = new AnnotationSaverService(destination, choice);
604-
annotationSaverService.runOnSuccess(() -> {
605-
setCurrentAnnotationSavingDirectory(destination);
606-
runnable.run();
607-
});
605+
annotationSaverService.runOnSuccess(runnable);
608606
annotationSaverService.startAndShowProgressDialog();
609607
}
610608
});
611609
}
612610

613611
private void setCurrentAnnotationSavingDirectory(File destination) {
614612
if(destination.isDirectory()) {
615-
currentAnnotationSavingDirectory = destination;
613+
ioMetaData.setDefaultAnnotationSavingDirectory(destination);
616614
} else if(destination.isFile() && destination.getParentFile().isDirectory()) {
617-
currentAnnotationSavingDirectory = destination.getParentFile();
615+
ioMetaData.setDefaultAnnotationSavingDirectory(destination.getParentFile());
618616
}
619617
}
620618

621619
private void setCurrentAnnotationLoadingDirectory(File source) {
622620
if(source.isDirectory()) {
623-
currentAnnotationLoadingDirectory = source;
621+
ioMetaData.setDefaultAnnotationLoadingDirectory(source);
624622
} else if(source.isFile() && source.getParentFile().isDirectory()) {
625-
currentAnnotationLoadingDirectory = source.getParentFile();
623+
ioMetaData.setDefaultAnnotationLoadingDirectory(source.getParentFile());
626624
}
627625
}
628626

@@ -642,10 +640,7 @@ private void initiateAnnotationSavingWithFormatChoiceAndRunInAnyCase(Runnable ru
642640
if(destination != null) {
643641
// Save annotations.
644642
AnnotationSaverService annotationSaverService = new AnnotationSaverService(destination, choice);
645-
annotationSaverService.runOnSuccess(() -> {
646-
setCurrentAnnotationSavingDirectory(destination);
647-
runnable.run();
648-
});
643+
annotationSaverService.runOnSuccess(runnable);
649644
annotationSaverService.startAndShowProgressDialog();
650645
} else {
651646
runnable.run();
@@ -658,7 +653,7 @@ private File getAnnotationSavingDestination(ImageAnnotationSaveStrategy.Type sav
658653

659654
if(saveFormat.equals(ImageAnnotationSaveStrategy.Type.JSON)) {
660655
destination = MainView.displayFileChooserAndGetChoice(SAVE_IMAGE_ANNOTATIONS_FILE_CHOOSER_TITLE, stage,
661-
currentAnnotationSavingDirectory,
656+
ioMetaData.getDefaultAnnotationSavingDirectory(),
662657
DEFAULT_JSON_EXPORT_FILENAME,
663658
new FileChooser.ExtensionFilter("JSON files",
664659
"*.json",
@@ -667,7 +662,7 @@ private File getAnnotationSavingDestination(ImageAnnotationSaveStrategy.Type sav
667662
} else {
668663
destination =
669664
MainView.displayDirectoryChooserAndGetChoice(SAVE_IMAGE_ANNOTATIONS_DIRECTORY_CHOOSER_TITLE, stage,
670-
currentAnnotationSavingDirectory);
665+
ioMetaData.getDefaultAnnotationSavingDirectory());
671666
}
672667

673668
return destination;
@@ -678,14 +673,14 @@ private File getAnnotationLoadingSource(ImageAnnotationLoadStrategy.Type loadFor
678673

679674
if(loadFormat.equals(ImageAnnotationLoadStrategy.Type.JSON)) {
680675
source = MainView.displayFileChooserAndGetChoice(LOAD_IMAGE_ANNOTATIONS_FILE_CHOOSER_TITLE, stage,
681-
currentAnnotationLoadingDirectory,
676+
ioMetaData.getDefaultAnnotationLoadingDirectory(),
682677
DEFAULT_JSON_EXPORT_FILENAME,
683678
new FileChooser.ExtensionFilter("JSON files", "*.json",
684679
"*.JSON"),
685680
MainView.FileChooserType.OPEN);
686681
} else {
687682
source = MainView.displayDirectoryChooserAndGetChoice(LOAD_IMAGE_ANNOTATIONS_DIRECTORY_CHOOSER_TITLE, stage,
688-
currentAnnotationLoadingDirectory);
683+
ioMetaData.getDefaultAnnotationLoadingDirectory());
689684
}
690685

691686
return source;
@@ -956,7 +951,7 @@ private void loadPreferences() {
956951
File imageLoadingDirectoryPreference = new File(imageLoadingDirectoryPathPreference);
957952

958953
if(imageLoadingDirectoryPreference.exists() && imageLoadingDirectoryPreference.isDirectory()) {
959-
currentImageLoadingDirectory = imageLoadingDirectoryPreference;
954+
ioMetaData.setDefaultImageLoadingDirectory(imageLoadingDirectoryPreference);
960955
}
961956
}
962957

@@ -967,7 +962,7 @@ private void loadPreferences() {
967962
File annotationLoadingDirectoryPreference = new File(annotationLoadingDirectoryPathPreference);
968963

969964
if(annotationLoadingDirectoryPreference.exists() && annotationLoadingDirectoryPreference.isDirectory()) {
970-
currentAnnotationLoadingDirectory = annotationLoadingDirectoryPreference;
965+
ioMetaData.setDefaultAnnotationLoadingDirectory(annotationLoadingDirectoryPreference);
971966
}
972967
}
973968

@@ -978,7 +973,7 @@ private void loadPreferences() {
978973
File annotationSavingDirectoryPreference = new File(annotationSavingDirectoryPathPreference);
979974

980975
if(annotationSavingDirectoryPreference.exists() && annotationSavingDirectoryPreference.isDirectory()) {
981-
currentAnnotationSavingDirectory = annotationSavingDirectoryPreference;
976+
ioMetaData.setDefaultAnnotationSavingDirectory(annotationSavingDirectoryPreference);
982977
}
983978
}
984979
}
@@ -988,18 +983,19 @@ private void savePreferences() {
988983

989984
preferences.putBoolean(IS_WINDOW_MAXIMIZED_PREFERENCE_NAME, stage.isMaximized());
990985

991-
if(currentImageLoadingDirectory != null) {
992-
preferences.put(CURRENT_IMAGE_LOADING_DIRECTORY_PREFERENCE_NAME, currentImageLoadingDirectory.toString());
986+
if(ioMetaData.getDefaultImageLoadingDirectory() != null) {
987+
preferences.put(CURRENT_IMAGE_LOADING_DIRECTORY_PREFERENCE_NAME,
988+
ioMetaData.getDefaultImageLoadingDirectory().toString());
993989
}
994990

995-
if(currentAnnotationLoadingDirectory != null) {
991+
if(ioMetaData.getDefaultAnnotationLoadingDirectory() != null) {
996992
preferences.put(CURRENT_ANNOTATION_LOADING_DIRECTORY_PREFERENCE_NAME,
997-
currentAnnotationLoadingDirectory.toString());
993+
ioMetaData.getDefaultAnnotationLoadingDirectory().toString());
998994
}
999995

1000-
if(currentAnnotationSavingDirectory != null) {
996+
if(ioMetaData.getDefaultAnnotationSavingDirectory() != null) {
1001997
preferences.put(CURRENT_ANNOTATION_SAVING_DIRECTORY_PREFERENCE_NAME,
1002-
currentAnnotationSavingDirectory.toString());
998+
ioMetaData.getDefaultAnnotationSavingDirectory().toString());
1003999
}
10041000
}
10051001

@@ -1140,6 +1136,8 @@ private void defaultOnSucceededHandler() {
11401136
} else {
11411137
model.setSaved(true);
11421138
}
1139+
1140+
setCurrentAnnotationSavingDirectory(destination);
11431141
}
11441142

11451143
private void defaultOnFailedHandler() {
@@ -1214,7 +1212,10 @@ private void defaultOnSuccessHandler() {
12141212
} else if(loadResult.getNrSuccessfullyProcessedItems() == 0) {
12151213
MainView.displayErrorAlert(ANNOTATION_IMPORT_ERROR_TITLE,
12161214
ANNOTATION_IMPORT_ERROR_NO_VALID_FILES_CONTENT);
1215+
return;
12171216
}
1217+
1218+
setCurrentAnnotationLoadingDirectory(source);
12181219
}
12191220

12201221
private void defaultOnFailedHandler() {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package boundingboxeditor.model.io;
2+
3+
import java.io.File;
4+
5+
/**
6+
* Metadata related to IO operations.
7+
*/
8+
public class IoMetaData {
9+
private File defaultImageLoadingDirectory = null;
10+
private File defaultAnnotationSavingDirectory = null;
11+
private File defaultAnnotationLoadingDirectory = null;
12+
13+
/**
14+
* Get the currently set default directory for image loading.
15+
* @return the directory
16+
*/
17+
public File getDefaultImageLoadingDirectory() {
18+
return defaultImageLoadingDirectory;
19+
}
20+
21+
/**
22+
* Set the current default directory for image loading.
23+
* @param defaultImageLoadingDirectory the directory
24+
*/
25+
public void setDefaultImageLoadingDirectory(File defaultImageLoadingDirectory) {
26+
this.defaultImageLoadingDirectory = defaultImageLoadingDirectory;
27+
}
28+
29+
/**
30+
* Get the currently set default directory for annotation saving.
31+
* @return the directory
32+
*/
33+
public File getDefaultAnnotationSavingDirectory() {
34+
return defaultAnnotationSavingDirectory;
35+
}
36+
37+
/**
38+
* Set the current default directory for annotation saving.
39+
* @param defaultAnnotationSavingDirectory the directory
40+
*/
41+
public void setDefaultAnnotationSavingDirectory(File defaultAnnotationSavingDirectory) {
42+
this.defaultAnnotationSavingDirectory = defaultAnnotationSavingDirectory;
43+
}
44+
45+
/**
46+
* Get the currently set default directory for annotation loading.
47+
* @return the directory
48+
*/
49+
public File getDefaultAnnotationLoadingDirectory() {
50+
return defaultAnnotationLoadingDirectory;
51+
}
52+
53+
/**
54+
* Set the current default directory for annotation loading.
55+
* @param defaultAnnotationLoadingDirectory the directory
56+
*/
57+
public void setDefaultAnnotationLoadingDirectory(File defaultAnnotationLoadingDirectory) {
58+
this.defaultAnnotationLoadingDirectory = defaultAnnotationLoadingDirectory;
59+
}
60+
}

src/test/java/boundingboxeditor/BoundingBoxEditorTestBase.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,18 @@ protected void timeOutAssertTopModalStageClosed(FxRobot robot, String stageTitle
335335
" sec.");
336336
}
337337

338-
protected void assertNoTopModalStage(FxRobot robot) {
339-
verifyThat(robot.listWindows()
340-
.stream()
341-
.filter(window -> window instanceof Stage)
342-
.map(window -> (Stage) window)
343-
.anyMatch(stage -> stage.getModality() == Modality.APPLICATION_MODAL), Matchers.is(false));
338+
protected void timeOutAssertNoTopModelStage(FxRobot robot) {
339+
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
340+
() -> !isTopModalStagePresent(robot)),
341+
"Could find top modal stage within " + TIMEOUT_DURATION_IN_SEC + " sec.");
342+
}
343+
344+
private boolean isTopModalStagePresent(FxRobot robot) {
345+
return robot.listWindows()
346+
.stream()
347+
.filter(window -> window instanceof Stage)
348+
.map(window -> (Stage) window)
349+
.anyMatch(stage -> stage.getModality() == Modality.APPLICATION_MODAL);
344350
}
345351

346352
private Scene createSceneFromParent(final Parent parent) {

0 commit comments

Comments
 (0)