Skip to content
Snippets Groups Projects
Commit 4e8e8e36 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Adds File menu and corresponding controller.

parent 453aacfb
No related branches found
No related tags found
No related merge requests found
package tdt4140.gr1800.app.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
......@@ -17,7 +21,7 @@ public class App {
private Collection<GeoLocations> geoLocations;
public Iterable<String> getGeoLocationNames() {
Collection<String> names = new ArrayList<String>(geoLocations.size());
Collection<String> names = new ArrayList<String>(geoLocations != null ? geoLocations.size() : 0);
if (geoLocations != null) {
for (GeoLocations geoLocations : geoLocations) {
names.add(geoLocations.getName());
......@@ -25,7 +29,7 @@ public class App {
}
return names;
}
public boolean hasGeoLocations(String name) {
if (geoLocations != null) {
for (GeoLocations geoLocations : geoLocations) {
......@@ -47,4 +51,46 @@ public class App {
}
return null;
}
//
private DocumentStorageImpl<Collection<GeoLocations>, File> documentStorage = new DocumentStorageImpl<Collection<GeoLocations>, File>() {
@Override
protected Collection<GeoLocations> getDocument() {
return geoLocations;
}
@Override
protected void setDocument(Collection<GeoLocations> document) {
geoLocations = document;
}
@Override
protected Collection<GeoLocations> createDocument() {
return new ArrayList<GeoLocations>();
}
@Override
protected Collection<GeoLocations> loadDocument(File file) throws IOException {
try {
return geoLocationsLoader.loadLocations(new FileInputStream(file));
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
protected void storeDocument(Collection<GeoLocations> document, File file) throws IOException {
try {
geoLocationsLoader.saveLocations(document, new FileOutputStream(file));
} catch (Exception e) {
throw new IOException(e);
}
}
};
public IDocumentStorage<File> getDocumentStorage() {
return documentStorage;
}
}
package tdt4140.gr1800.app.core;
import java.io.IOException;
public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L> {
private L documentLocation;
@Override
public L getDocumentLocation() {
return documentLocation;
}
@Override
public void setDocumentLocation(L documentLocation) {
this.documentLocation = documentLocation;
}
protected abstract D getDocument();
protected abstract void setDocument(D document);
protected abstract D createDocument();
protected abstract D loadDocument(L storage) throws IOException;
protected abstract void storeDocument(D document, L storage) throws IOException;
@Override
public void newDocument() {
setDocument(createDocument());
}
@Override
public void openDocument(L storage) throws IOException {
setDocument(loadDocument(storage));
}
@Override
public void saveDocument() throws IOException {
storeDocument(getDocument(), getDocumentLocation());
}
public void saveDocumentAs(L documentLocation) throws IOException {
setDocumentLocation(documentLocation);
saveDocument();
}
public void saveCopyAs(L documentLocation) throws IOException {
storeDocument(getDocument(), documentLocation);
}
}
package tdt4140.gr1800.app.core;
import java.io.IOException;
public interface IDocumentStorage<L> {
public L getDocumentLocation();
public void setDocumentLocation(L documentLocation);
public void newDocument();
public void openDocument(L documentLocation) throws IOException;
public void saveDocument() throws IOException;
}
package tdt4140.gr1800.app.ui;
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.IDocumentStorage;
public class FileMenuController {
private 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>();
@FXML
private Menu recentMenu;
protected void updateRecentMenu(File file) {
recentFiles.remove(file);
recentFiles.add(0, file);
recentMenu.getItems().clear();
for (File recentFile : recentFiles) {
MenuItem menuItem = new MenuItem();
menuItem.setText(recentFile.toString());
menuItem.setOnAction(event -> handleOpenAction(event));
recentMenu.getItems().add(menuItem);
}
}
private FileChooser fileChooser;
protected FileChooser getFileChooser() {
if (fileChooser == null) {
fileChooser = new FileChooser();
}
return fileChooser;
}
@FXML
public void handleOpenAction(ActionEvent event) {
File selection = null;
if (event.getSource() instanceof MenuItem) {
File file = new File(((MenuItem) event.getSource()).getText());
if (file.exists()) {
selection = file;
}
}
if (selection == null) {
FileChooser fileChooser = getFileChooser();
selection = fileChooser.showOpenDialog(null);
}
if (selection != null) {
try {
documentStorage.openDocument(selection);
updateRecentMenu(selection);
fireDocumentChanged();
} catch (IOException e) {
// TODO
}
}
}
@FXML
public void handleSaveAction() {
try {
documentStorage.saveDocument();
} catch (IOException e) {
// TODO
}
}
@FXML
public void handleSaveAsAction() {
FileChooser fileChooser = getFileChooser();
File selection = fileChooser.showSaveDialog(null);
File oldStorage = documentStorage.getDocumentLocation();
try {
documentStorage.setDocumentLocation(selection);
documentStorage.saveDocument();
} catch (IOException e) {
// TODO
documentStorage.setDocumentLocation(oldStorage);
}
}
@FXML
public void handleSaveCopyAsAction() {
FileChooser fileChooser = getFileChooser();
File selection = fileChooser.showSaveDialog(null);
File oldStorage = documentStorage.getDocumentLocation();
try {
documentStorage.setDocumentLocation(selection);
documentStorage.saveDocument();
} catch (IOException e) {
// TODO
} finally {
documentStorage.setDocumentLocation(oldStorage);
}
}
}
package tdt4140.gr1800.app.ui;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.MapComponentInitializedListener;
import com.lynden.gmapsfx.javascript.event.UIEventType;
import com.lynden.gmapsfx.javascript.object.GoogleMap;
import com.lynden.gmapsfx.javascript.object.MVCArray;
import com.lynden.gmapsfx.javascript.object.MapOptions;
import com.lynden.gmapsfx.javascript.object.MapShape;
import com.lynden.gmapsfx.javascript.object.MapTypeIdEnum;
import com.lynden.gmapsfx.javascript.object.Marker;
import com.lynden.gmapsfx.javascript.object.MarkerOptions;
import com.lynden.gmapsfx.shapes.Polyline;
import com.lynden.gmapsfx.shapes.PolylineOptions;
import java.util.Iterator;
import fxmapcontrol.MapBase;
import fxmapcontrol.MapItemsControl;
import fxmapcontrol.MapNode;
import fxmapcontrol.MapTileLayer;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import tdt4140.gr1800.app.core.App;
import tdt4140.gr1800.app.core.GeoLocations;
import tdt4140.gr1800.app.core.LatLong;
public class FxAppController implements MapComponentInitializedListener {
public class FxAppController {
@FXML
private TextField geolocationsFileText;
private FileMenuController fileMenuController;
@FXML
private ComboBox<String> geoLocationsSelector;
@FXML
private GoogleMapView mapView;
private GoogleMap map;
private MapBase mapView;
private MapItemsControl<MapNode> markersParent;
@FXML
private Slider zoomSlider;
......@@ -51,133 +33,62 @@ public class FxAppController implements MapComponentInitializedListener {
@FXML
public void initialize() {
mapView.addMapInializedListener(this);
app = new App();
fileMenuController.setDocumentStorage(app.getDocumentStorage());
fileMenuController.setOnDocumentChanged(documentStorage -> initMapMarkers());
geoLocationsSelector.getSelectionModel().selectedItemProperty().addListener((stringProperty, oldValue, newValue) -> updateGeoLocations());
zoomSlider.valueProperty().addListener((doubleProperty, oldValue, newValue) -> map.setZoom((int) zoomSlider.getValue()));
mapView.getChildren().add(MapTileLayer.getOpenStreetMapLayer());
mapView.zoomLevelProperty().bind(zoomSlider.valueProperty());
markersParent = new MapItemsControl<MapNode>();
mapView.getChildren().add(markersParent);
}
private Object updateGeoLocations() {
return null;
}
private Map<GeoLocations, MapShape> shapes = new HashMap<GeoLocations, MapShape>();
private Map<GeoLocations, Collection<Marker>> markers = new HashMap<GeoLocations, Collection<Marker>>();
private void initMapMarkers() {
map.clearMarkers();
markersParent.getItems().clear();
for (String geoLocationName : app.getGeoLocationNames()) {
GeoLocations geoLocations = app.getGeoLocations(geoLocationName);
if (geoLocations.isPath()) {
Collection<com.lynden.gmapsfx.javascript.object.LatLong> latLongs = new ArrayList<com.lynden.gmapsfx.javascript.object.LatLong>();
for (LatLong latLong : geoLocations) {
double lat = latLong.latitude, lon = latLong.longitude;
latLongs.add(new com.lynden.gmapsfx.javascript.object.LatLong(lat, lon));
}
MVCArray mvc = new MVCArray(latLongs.toArray(new com.lynden.gmapsfx.javascript.object.LatLong[latLongs.size()]));
PolylineOptions options = new PolylineOptions()
.path(mvc)
.strokeColor("red")
.strokeWeight(2);
Polyline polyline = new Polyline(options);
map.addMapShape(polyline);
this.shapes.put(geoLocations, polyline);
} else {
Collection<Marker> markers = new ArrayList<Marker>();
for (LatLong latLong : geoLocations) {
double lat = latLong.latitude, lon = latLong.longitude;
MarkerOptions options = new MarkerOptions().label(geoLocationName)
.position(new com.lynden.gmapsfx.javascript.object.LatLong(lat, lon));
Marker marker = new Marker(options);
map.addMarker(marker);
markers.add(marker);
MapMarker lastMarker = null;
for (LatLong latLong : geoLocations) {
MapMarker mapMarker = new MapMarker(latLong);
markersParent.getItems().add(mapMarker);
if (geoLocations.isPath() && lastMarker != null) {
MapPathLine pathLine = new MapPathLine(lastMarker, mapMarker);
markersParent.getItems().add(pathLine);
}
this.markers.put(geoLocations, markers);
lastMarker = mapMarker;
}
geoLocationsSelector.getItems().add(geoLocationName);
}
map.setCenter(getCenter(null));
map.addMouseEventHandler(UIEventType.click, (event) -> {
com.lynden.gmapsfx.javascript.object.LatLong latLong = event.getLatLong();
System.out.println("Latitude: " + latLong.getLatitude());
System.out.println("Longitude: " + latLong.getLongitude());
});
LatLong center = getCenter(null);
System.out.println("Map markers initialized");
}
private com.lynden.gmapsfx.javascript.object.LatLong getCenter(GeoLocations geoLocations) {
private LatLong getCenter(GeoLocations geoLocations) {
double latSum = 0.0, lonSum = 0.0;
int num = 0;
Iterator<String> names = null;
if (geoLocations == null) {
for (String geoLocationName : app.getGeoLocationNames()) {
geoLocations = app.getGeoLocations(geoLocationName);
for (LatLong latLong : geoLocations) {
double lat = latLong.latitude, lon = latLong.longitude;
latSum += lat;
lonSum += lon;
num++;
}
names = app.getGeoLocationNames().iterator();
}
while (geoLocations != null || (names != null && names.hasNext())) {
if (names != null) {
geoLocations = app.getGeoLocations(names.next());
}
} else {
for (LatLong latLong : geoLocations) {
double lat = latLong.latitude, lon = latLong.longitude;
latSum += lat;
lonSum += lon;
num++;
}
}
return new com.lynden.gmapsfx.javascript.object.LatLong(latSum / num, lonSum / num);
}
@Override
public void mapInitialized() {
// Set the initial properties of the map.
MapOptions mapOptions = new MapOptions();
mapOptions
.mapType(MapTypeIdEnum.ROADMAP)
.center(new com.lynden.gmapsfx.javascript.object.LatLong(63.0, 10.0))
.overviewMapControl(false)
.panControl(false)
.rotateControl(false)
.scaleControl(false)
.streetViewControl(false)
.zoomControl(false)
.zoom(zoomSlider.getValue());
map = mapView.createMap(mapOptions);
System.out.println("Map initialized: " + map);
if (app.getGeoLocationNames().iterator().hasNext()) {
initMapMarkers();
}
}
@FXML
public void loadGeolocationsFile() {
try {
URI fileUri = new URI(geolocationsFileText.getText());
app.loadGeoLocations(fileUri);
System.out.println("GeoLocations initialized: " + app.getGeoLocationNames());
if (map != null) {
initMapMarkers();
if (names != null) {
geoLocations = null;
}
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Exception when loading from " + geolocationsFileText.getText() + ": " + e.getMessage());
alert.setContentText(e.getMessage());
alert.show();
}
}
@FXML
public void handleBrowseGeolocationsFile() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Select geo-locations file");
File file = fileChooser.showOpenDialog(mapView.getScene().getWindow());
if (file == null) {
file = new File(".");
}
geolocationsFileText.setText(file.toURI().toString());
geolocationsFileText.getOnAction().handle(null);
return new LatLong(latSum / num, lonSum / num);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<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"/>
<Menu fx:id="recentMenu" text="Open Recent"/>
<MenuItem text="Save" onAction="#handleSaveAction"/>
<MenuItem text="Save As..." onAction="#handleSaveAsAction"/>
<MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/>
</items>
</Menu>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment