diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java index b7bd765c637941a2965d97c3e204df5e4c2230a7..defe620ce876081d95e6852dc0e453bc1a830285 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java @@ -9,6 +9,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.stream.Collectors; +import tdt4140.gr1800.app.doc.DocumentStorageImpl; +import tdt4140.gr1800.app.doc.IDocumentImporter; +import tdt4140.gr1800.app.doc.IDocumentLoader; +import tdt4140.gr1800.app.doc.IDocumentPersistence; +import tdt4140.gr1800.app.doc.IDocumentStorage; import tdt4140.gr1800.app.gpx.GpxDocumentConverter; import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; @@ -67,40 +72,6 @@ public class App { return result; } - public void setGeoLocations(Collection<GeoLocations> geoLocations) { - this.geoLocations = new ArrayList<>(geoLocations); - fireGeoLocationsUpdated(null); - } - - public void addGeoLocations(GeoLocations geoLocations) { - if (hasGeoLocations(geoLocations.getName())) { - throw new IllegalArgumentException("Duplicate geo-locations name: " + geoLocations.getName()); - } - this.geoLocations.add(geoLocations); - fireGeoLocationsUpdated(geoLocations); - } - - public void removeGeoLocations(GeoLocations geoLocations) { - this.geoLocations.remove(geoLocations); - fireGeoLocationsUpdated(geoLocations); - } - - private Collection<IGeoLocationsListener> geoLocationsListeners = new ArrayList<>(); - - public void addGeoLocationsListener(IGeoLocationsListener listener) { - geoLocationsListeners.add(listener); - } - - public void removeGeoLocationsListener(IGeoLocationsListener listener) { - geoLocationsListeners.remove(listener); - } - - protected void fireGeoLocationsUpdated(GeoLocations geoLocations) { - for (IGeoLocationsListener listener : geoLocationsListeners) { - listener.geoLocationsUpdated(geoLocations); - } - } - // private IDocumentPersistence<Collection<GeoLocations>, File> documentPersistence = new IDocumentPersistence<Collection<GeoLocations>, File>() { @@ -125,7 +96,9 @@ public class App { @Override protected void setDocument(Collection<GeoLocations> document) { - setGeoLocations(document); + Collection<GeoLocations> oldDocument = getDocument(); + App.this.geoLocations = document; + fireDocumentChanged(oldDocument); } @Override diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java deleted file mode 100644 index 787f85d1d559a80439f2690f1ea04b5f782932ca..0000000000000000000000000000000000000000 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package tdt4140.gr1800.app.core; - -public interface IGeoLocationsListener { - - public void geoLocationsUpdated(GeoLocations geoLocations); -} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java similarity index 56% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java index b673c877d7fde81b765da55190e1a93347ccc816..6a104a6bd96db82210a2bbad3a8fd39625bd10ca 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java @@ -1,6 +1,8 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>, IDocumentPersistence<D, L> { @@ -13,17 +15,45 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>, @Override public void setDocumentLocation(L documentLocation) { + L oldDocumentLocation = this.documentLocation; this.documentLocation = documentLocation; + fireDocumentLocationChanged(oldDocumentLocation); } protected void setDocumentAndLocation(D document, L documentLocation) { setDocument(document); setDocumentLocation(documentLocation); } - + protected abstract D getDocument(); protected abstract void setDocument(D document); + // + + private Collection<IDocumentStorageListener<L>> documentListeners = new ArrayList<IDocumentStorageListener<L>>(); + + public void addDocumentStorageListener(IDocumentStorageListener<L> documentStorageListener) { + documentListeners.add(documentStorageListener); + } + + public void removeDocumentStorageListener(IDocumentStorageListener<L> documentStorageListener) { + documentListeners.remove(documentStorageListener); + } + + protected void fireDocumentLocationChanged(L oldDocumentLocation) { + for (IDocumentStorageListener<L> documentStorageListener : documentListeners) { + documentStorageListener.documentLocationChanged(documentLocation, oldDocumentLocation); + } + } + + protected void fireDocumentChanged(D oldDocument) { + for (IDocumentStorageListener<L> documentListener : documentListeners) { + if (documentListener instanceof IDocumentListener) { + ((IDocumentListener<D, L>) documentListener).documentChanged(getDocument(), oldDocument); + } + } + } + protected abstract D createDocument(); @Override diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java similarity index 80% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java index c37c4c56d4786538644974664c932a578ddac800..ba8b8ec2aa68702c1400a09032ab41c6f6140b23 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java @@ -1,4 +1,4 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; import java.io.IOException; diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentListener.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentListener.java new file mode 100644 index 0000000000000000000000000000000000000000..62b8ce211c1ca51449ef015efba9afabff903737 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentListener.java @@ -0,0 +1,5 @@ +package tdt4140.gr1800.app.doc; + +public interface IDocumentListener<D, L> extends IDocumentStorageListener<L>{ + public void documentChanged(D document, D oldDocument); +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java similarity index 76% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java index 928fd9b860ee6cfa3050917c5fb8037634bcb2af..ecb029b5d7668f17d9024a2599c94d70475689f8 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java @@ -1,4 +1,4 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; public interface IDocumentLoader<D, L> { public D loadDocument(L documentLocation) throws Exception; diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java similarity index 75% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java index 756f85d04ea4dd06618798eeab05c01f549fa913..9fbd23a7f7d04405e7b678fc7ab2ce448c46f9f8 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java @@ -1,4 +1,4 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; public interface IDocumentPersistence<D, L> extends IDocumentLoader<D, L>, IDocumentSaver<D, L> { } diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentSaver.java similarity index 78% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentSaver.java index 4d2ee0a3807554f6f4868f669ec3621007d82d24..b9a5d9264be304554845f6c5592c5aec9a79d741 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentSaver.java @@ -1,4 +1,4 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; public interface IDocumentSaver<D, L> { public void saveDocument(D document, L documentLocation) throws Exception; diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java similarity index 63% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java index 147bd16774ed90ac6e98643484c1392fd5e842bb..a037c42a38494ed0736c191f44a40f0e1dd03661 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java @@ -1,4 +1,4 @@ -package tdt4140.gr1800.app.core; +package tdt4140.gr1800.app.doc; import java.io.IOException; import java.util.Collection; @@ -7,6 +7,9 @@ public interface IDocumentStorage<L> { public L getDocumentLocation(); public void setDocumentLocation(L documentLocation); + public void addDocumentStorageListener(IDocumentStorageListener<L> documentStorageListener); + public void removeDocumentStorageListener(IDocumentStorageListener<L> documentStorageListener); + public void newDocument(); public void openDocument(L documentLocation) throws IOException; public void saveDocument() throws IOException; diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorageListener.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorageListener.java new file mode 100644 index 0000000000000000000000000000000000000000..1a21cdc63a83391fae9c7d1dd13abcce47e807d1 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorageListener.java @@ -0,0 +1,5 @@ +package tdt4140.gr1800.app.doc; + +public interface IDocumentStorageListener<L> { + public void documentLocationChanged(L documentLocation, L oldDocumentLocation); +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java index 55550bf54b9be9daba07ae3c71bb12ae3de6f396..7324eb5c112618c1ebbc5413155c696d727b8858 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java @@ -11,8 +11,8 @@ import io.jenetics.jpx.Track; import io.jenetics.jpx.TrackSegment; import io.jenetics.jpx.WayPoint; import tdt4140.gr1800.app.core.GeoLocations; -import tdt4140.gr1800.app.core.IDocumentLoader; import tdt4140.gr1800.app.core.LatLong; +import tdt4140.gr1800.app.doc.IDocumentLoader; public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>, File> { diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java index 28e971d9f84e2f2a13c9e5b73843603d80cdcd0f..b7dcb43a46239d18a34e3b1dce828ce2a803d0b0 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java @@ -4,7 +4,7 @@ import java.io.InputStream; import java.net.URL; import io.jenetics.jpx.GPX; -import tdt4140.gr1800.app.core.IDocumentLoader; +import tdt4140.gr1800.app.doc.IDocumentLoader; public class GpxDocumentLoader implements IDocumentLoader<GPX, URL> { diff --git a/tdt4140-gr1800/app.core/src/main/resources/tdt4140/gr1800/app/core/geoLocations.json b/tdt4140-gr1800/app.core/src/main/resources/tdt4140/gr1800/app/core/geoLocations.json index 25618224e011d14864f98f9bf4b26cce72be8960..bfda7a4524d5419067f9a0dba069740402aff30d 100644 --- a/tdt4140-gr1800/app.core/src/main/resources/tdt4140/gr1800/app/core/geoLocations.json +++ b/tdt4140-gr1800/app.core/src/main/resources/tdt4140/gr1800/app/core/geoLocations.json @@ -1,13 +1,13 @@ [ { - "id" : "1", + "name" : "1", "locations" : [ { "latitude" : "63", "longitude" : "10" }, [ "63.1", "10.1" ] ] }, { - "id" : "2", + "name" : "2", "path" : "true", "locations" : [ { "latitude" : "64", "longitude" : "11" }, diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java index 8add30329d13176bfa9a549f2d4defd5304112d8..60baab304af770ab0be1412a37b19e277ae35556 100644 --- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java @@ -8,6 +8,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import tdt4140.gr1800.app.doc.IDocumentStorage; + public class AppTest { private App app; diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx index e6ce49689300ce2b5c2b424e55bebbf697b36718..a006258ea21c91c5dedcb385650ec4abbee0ae9e 100644 --- a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx +++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx @@ -6,6 +6,10 @@ xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> +<metadata> + <bounds minlat="51.396017" minlon="4.498043" maxlat="51.430402" maxlon="4.556108"/> +</metadata> + <wpt lat="51.39709" lon="4.501519"> <name>START</name> </wpt> diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx index 279b657067b2ff6c9d7a6e326e94dad918644b5a..755f740e02199462cfa12b8a5243c73f49258786 100644 --- a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx +++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx @@ -6,6 +6,10 @@ xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> +<metadata> + <bounds minlat="51.396017" minlon="4.498043" maxlat="51.430402" maxlon="4.556108"/> +</metadata> + <wpt lat="51.39709" lon="4.501519"> <name>START</name> </wpt> diff --git a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java index 8575711352c784bd9b29449bb148e06a556dbf81..e7566ea1b6288baf620f609be92f57361fe51cfe 100644 --- a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java +++ b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java @@ -4,40 +4,26 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.stage.FileChooser; -import tdt4140.gr1800.app.core.IDocumentImporter; -import tdt4140.gr1800.app.core.IDocumentStorage; +import tdt4140.gr1800.app.doc.IDocumentImporter; +import tdt4140.gr1800.app.doc.IDocumentStorage; public class FileMenuController { - private IDocumentStorage<File> documentStorage; + IDocumentStorage<File> documentStorage; public void setDocumentStorage(IDocumentStorage<File> documentStorage) { this.documentStorage = documentStorage; } - - private Consumer<IDocumentStorage<File>> onDocumentChanged; - - public void setOnDocumentChanged(Consumer<IDocumentStorage<File>> onDocumentChanged) { - this.onDocumentChanged = onDocumentChanged; - } @FXML public void handleNewAction() { documentStorage.newDocument(); - fireDocumentChanged(); - } - - private void fireDocumentChanged() { - if (onDocumentChanged != null) { - onDocumentChanged.accept(documentStorage); - } } private List<File> recentFiles = new ArrayList<File>(); @@ -59,7 +45,7 @@ public class FileMenuController { private FileChooser fileChooser; - protected FileChooser getFileChooser() { + FileChooser getFileChooser() { if (fileChooser == null) { fileChooser = new FileChooser(); } @@ -80,13 +66,16 @@ public class FileMenuController { selection = fileChooser.showOpenDialog(null); } if (selection != null) { - try { - documentStorage.openDocument(selection); - updateRecentMenu(selection); - fireDocumentChanged(); - } catch (IOException e) { - // TODO - } + handleOpenAction(selection); + } + } + + void handleOpenAction(File selection) { + try { + documentStorage.openDocument(selection); + updateRecentMenu(selection); + } catch (IOException e) { + // TODO } } @@ -103,6 +92,10 @@ public class FileMenuController { public void handleSaveAsAction() { FileChooser fileChooser = getFileChooser(); File selection = fileChooser.showSaveDialog(null); + handleSaveAsAction(selection); + } + + void handleSaveAsAction(File selection) { File oldStorage = documentStorage.getDocumentLocation(); try { documentStorage.setDocumentLocation(selection); @@ -117,6 +110,10 @@ public class FileMenuController { public void handleSaveCopyAsAction() { FileChooser fileChooser = getFileChooser(); File selection = fileChooser.showSaveDialog(null); + handleSaveCopyAsAction(selection); + } + + void handleSaveCopyAsAction(File selection) { File oldStorage = documentStorage.getDocumentLocation(); try { documentStorage.setDocumentLocation(selection); @@ -135,6 +132,10 @@ public class FileMenuController { // String path = selection.getPath(); // int pos = path.lastIndexOf('.'); // String ext = (pos > 0 ? path.substring(pos + 1) : null); + handleImportAction(selection); + } + + void handleImportAction(File selection) { for (IDocumentImporter<File> importer : documentStorage.getDocumentImporters()) { try { importer.importDocument(selection); diff --git a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java index 20c656259f1cb4765d8656bcfba0925eb30fdfcd..060a5a45fd0561d8bf17cf8d5a90b1a10a97c8aa 100644 --- a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java +++ b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java @@ -1,5 +1,7 @@ package tdt4140.gr1800.app.ui; +import java.io.File; +import java.util.Collection; import java.util.Iterator; import fxmapcontrol.Location; @@ -7,27 +9,29 @@ import fxmapcontrol.MapBase; import fxmapcontrol.MapItemsControl; import fxmapcontrol.MapNode; import fxmapcontrol.MapTileLayer; +import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.control.ComboBox; import javafx.scene.control.Slider; import tdt4140.gr1800.app.core.App; import tdt4140.gr1800.app.core.GeoLocated; import tdt4140.gr1800.app.core.GeoLocations; -import tdt4140.gr1800.app.core.IGeoLocationsListener; import tdt4140.gr1800.app.core.LatLong; +import tdt4140.gr1800.app.doc.IDocumentListener; +import tdt4140.gr1800.app.doc.IDocumentStorage; -public class FxAppController implements IGeoLocationsListener { +public class FxAppController implements IDocumentListener<Collection<GeoLocations>, File> { @FXML - private FileMenuController fileMenuController; + FileMenuController fileMenuController; @FXML private ComboBox<String> geoLocationsSelector; @FXML - private MapBase mapView; + MapBase mapView; - private MapItemsControl<MapNode> markersParent; + MapItemsControl<MapNode> markersParent; @FXML private Slider zoomSlider; @@ -37,8 +41,9 @@ public class FxAppController implements IGeoLocationsListener { @FXML public void initialize() { app = new App(); - fileMenuController.setDocumentStorage(app.getDocumentStorage()); - fileMenuController.setOnDocumentChanged(documentStorage -> initMapMarkers()); + IDocumentStorage<File> documentStorage = app.getDocumentStorage(); + fileMenuController.setDocumentStorage(documentStorage); + documentStorage.addDocumentStorageListener(this); geoLocationsSelector.getSelectionModel().selectedItemProperty().addListener((stringProperty, oldValue, newValue) -> updateGeoLocations()); @@ -48,10 +53,24 @@ public class FxAppController implements IGeoLocationsListener { }); markersParent = new MapItemsControl<MapNode>(); mapView.getChildren().add(markersParent); - - app.addGeoLocationsListener(this); } + // + + @Override + public void documentLocationChanged(File documentLocation, File oldDocumentLocation) { + } + @Override + public void documentChanged(Collection<GeoLocations> document, Collection<GeoLocations> oldDocument) { + if (Platform.isFxApplicationThread()) { + initMapMarkers(); + } else { + Platform.runLater(() -> initMapMarkers()); + } + } + + // + private Object updateGeoLocations() { return null; } @@ -100,9 +119,4 @@ public class FxAppController implements IGeoLocationsListener { } return new LatLong(latSum / num, lonSum / num); } - - @Override - public void geoLocationsUpdated(GeoLocations geoLocations) { - initMapMarkers(); - } } diff --git a/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml b/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml index 9515c49930b7552d21d2adf531bdd4dd09a54afb..5de3493684996e64d7318ffeb16707366da68b04 100644 --- a/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml +++ b/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml @@ -7,14 +7,14 @@ <Menu xmlns:fx="http://javafx.com/fxml" text="File" fx:controller="tdt4140.gr1800.app.ui.FileMenuController"> <items> - <MenuItem text="New" onAction="#handleNewAction"/> - <MenuItem text="Open..." onAction="#handleOpenAction"/> + <MenuItem text="New" accelerator="Meta+N" onAction="#handleNewAction"/> + <MenuItem text="Open..." accelerator="Meta+O" onAction="#handleOpenAction"/> <Menu fx:id="recentMenu" text="Open Recent"/> <SeparatorMenuItem/> - <MenuItem text="Save" onAction="#handleSaveAction"/> - <MenuItem text="Save As..." onAction="#handleSaveAsAction"/> - <MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/> + <MenuItem text="Save" accelerator="Meta+S" onAction="#handleSaveAction"/> + <MenuItem text="Save As..." onAction="#handleSaveAsAction"/> + <MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/> <SeparatorMenuItem/> - <MenuItem text="Import..." onAction="#handleImportAction"/> + <MenuItem text="Import..." onAction="#handleImportAction"/> </items> </Menu> diff --git a/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java b/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java index 5bded2b5f54d04a93d671277315385eaaaf1a542..b31cb41137d1c57885ba42e7d64391ea1828eaee 100644 --- a/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java +++ b/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java @@ -1,16 +1,37 @@ package tdt4140.gr1800.app.ui; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.testfx.framework.junit.ApplicationTest; +import org.testfx.util.WaitForAsyncUtils; import fxmapcontrol.MapBase; +import fxmapcontrol.MapItemsControl; +import javafx.collections.ObservableList; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.ComboBox; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; +import javafx.stage.FileChooser; import javafx.stage.Stage; +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.doc.IDocumentStorageListener; public class FxAppTest extends ApplicationTest { @@ -21,20 +42,122 @@ public class FxAppTest extends ApplicationTest { } } + private FxAppController controller; + @Override public void start(Stage stage) throws Exception { - Parent root = FXMLLoader.load(getClass().getResource("FxApp.fxml")); - + FXMLLoader loader = new FXMLLoader(getClass().getResource("FxApp.fxml")); + Parent root = loader.load(); + this.controller = loader.getController(); Scene scene = new Scene(root); stage.setTitle("JavaFX and Maven"); stage.setScene(scene); stage.show(); } + + private File geoLocationsDotJson = null; + @Before + public void ensureGeoLocationsDotJson() { + openGeoLocationsDotJson(); + WaitForAsyncUtils.waitForFxEvents(); + } + + protected void openGeoLocationsDotJson() { + Assert.assertNotNull(this.controller); + InputStream inputStream = GeoLocations.class.getResourceAsStream("geoLocations.json"); + try { + geoLocationsDotJson = File.createTempFile("geoLocations", ".json"); + geoLocationsDotJson.deleteOnExit(); + Files.copy(inputStream, geoLocationsDotJson.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + Assert.fail(e.getMessage()); + } + try { + controller.fileMenuController.documentStorage.openDocument(geoLocationsDotJson); + } catch (IOException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void testMapExists() { + Node map = lookup("#mapView").query(); + Assert.assertTrue(map instanceof MapBase); + } + + private <T> T getItem(Iterable<?> items, Class<T> clazz, int num) { + for (Object child : items) { + if (clazz.isInstance(child)) { + num--; + if (num <= 0) { + return (T) child; + } + } + } + return null; + } + + private <T> Collection<T> getItems(Iterable<?> items, Class<T> clazz, int count) { + Collection<T> result = new ArrayList<T>(); + for (Object child : items) { + if (clazz.isInstance(child)) { + result.add((T) child); + count--; + if (count <= 0) { + return result; + } + } + } + return null; + } + @Test - public void testMapExists() { - Node map = lookup("#mapView").query(); - Assert.assertTrue(map instanceof MapBase); + public void testMapHasMarkers() { + Assert.assertNotNull(getItems(controller.markersParent.getItems(), MapMarker.class, 4)); + } + + @Test + public void testGeoLocationsSelector() { + Node combo = lookup("#geoLocationsSelector").query(); + Assert.assertTrue(combo instanceof ComboBox); + ObservableList<?> items = ((ComboBox<?>) combo).getItems(); + Assert.assertEquals(2, items.size()); + Assert.assertEquals("1 (2)", items.get(0)); + Assert.assertEquals("2 (2)", items.get(1)); + } + +// @Test + public void testOpenTestDocument() { + try { + InputStream inputStream = GeoLocations.class.getResourceAsStream("geoLocations.json"); + File tempFile = File.createTempFile("geoLocations", ".json"); + tempFile.deleteOnExit(); + Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + FileChooser fileChooser = controller.fileMenuController.getFileChooser(); + fileChooser.setInitialDirectory(tempFile.getParentFile()); +// fileChooser.setInitialFileName(tempFile.getName()); + KeyCodeCombination openKeys = new KeyCodeCombination(KeyCode.O, KeyCombination.META_DOWN); + push(openKeys); + sleep(1, TimeUnit.SECONDS); + String name = tempFile.getName().substring(0, 1); + for (int i = 0; i < name.length(); i++) { + push(KeyCode.getKeyCode(String.valueOf(name.charAt(i)).toUpperCase())); + } + final File[] documentLocations = new File[1]; + controller.fileMenuController.documentStorage.addDocumentStorageListener(new IDocumentStorageListener<File>() { + @Override + public void documentLocationChanged(File documentLocation, File oldDocumentLocation) { + documentLocations[0] = documentLocation; + } + }); + push(KeyCode.ENTER); + sleep(1, TimeUnit.SECONDS); + Assert.assertEquals(tempFile.getCanonicalPath(), String.valueOf(documentLocations[0])); + } catch (IOException e) { + System.out.println(e); + Assert.fail(e.getMessage()); + } } }