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

More slides and simpleexample project.

parent 664f2bc4
No related branches found
No related tags found
No related merge requests found
Pipeline #46474 passed
Showing
with 843 additions and 0 deletions
# Resources used by the web server code
\ No newline at end of file
package simpleex.ui;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
public class DraggableNodeController {
public DraggableNodeController() {
}
public DraggableNodeController(final NodeDraggedHandler nodeDraggedHandler) {
setNodeDraggedHandler(nodeDraggedHandler);
}
private NodeDraggedHandler nodeDraggedHandler;
public void setNodeDraggedHandler(final NodeDraggedHandler nodeDraggedHandler) {
this.nodeDraggedHandler = nodeDraggedHandler;
}
private boolean immediate = false;
public void setImmediate(final boolean immediate) {
this.immediate = immediate;
}
private Node currentNode = null;
private Point2D startPoint = null;
private Point2D startTranslate = null;
private final EventHandler<MouseEvent> mousePressedHandler = this::mousePressed;
private final EventHandler<MouseEvent> mouseDraggedHandler = this::mouseDragged;
private final EventHandler<MouseEvent> mouseReleasedHandler = this::mouseReleased;
public void attach(final Node node) {
node.setOnMousePressed(mousePressedHandler);
node.setOnMouseDragged(mouseDraggedHandler);
node.setOnMouseReleased(mouseReleasedHandler);
}
public void detach(final Node node) {
node.setOnMousePressed(null);
node.setOnMouseDragged(null);
node.setOnMouseReleased(null);
}
private void mousePressed(final MouseEvent mouseEvent) {
if (currentNode == null && mouseEvent.getSource() instanceof Node) {
currentNode = (Node) mouseEvent.getSource();
startPoint = new Point2D(mouseEvent.getSceneX(), mouseEvent.getSceneY());
startTranslate = new Point2D(currentNode.getTranslateX(), currentNode.getTranslateY());
mouseEvent.consume();
}
}
private void mouseDragged(final MouseEvent mouseEvent) {
if (currentNode != null && currentNode == mouseEvent.getSource()) {
final double dx = mouseEvent.getSceneX() - startPoint.getX();
final double dy = mouseEvent.getSceneY() - startPoint.getY();
updateNode(dx, dy);
}
}
protected void updateNode(final double dx, final double dy) {
if (immediate && nodeDraggedHandler != null) {
nodeDraggedHandler.nodeDragged(currentNode, dx, dy);
startPoint = startPoint.add(dx, dy);
} else {
currentNode.setTranslateX(startTranslate.getX() + dx);
currentNode.setTranslateY(startTranslate.getY() + dy);
}
}
private void mouseReleased(final MouseEvent mouseEvent) {
if (currentNode != null && currentNode == mouseEvent.getSource()) {
final double dx = mouseEvent.getSceneX() - startPoint.getX();
final double dy = mouseEvent.getSceneY() - startPoint.getY();
if (! immediate) {
currentNode.setTranslateX(startTranslate.getX());
currentNode.setTranslateY(startTranslate.getY());
}
final Node node = currentNode;
currentNode = null;
if (nodeDraggedHandler != null) {
nodeDraggedHandler.nodeDragged(node, dx, dy);
}
}
}
public interface NodeDraggedHandler {
public void nodeDragged(Node currentNode2, double dx, double dy);
}
}
package simpleex.ui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import simpleex.core.LatLongs;
public class FxApp extends Application {
@Override
public void start(final Stage stage) throws Exception {
final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("FxApp.fxml"));
final Parent root = fxmlLoader.load();
final FxAppController controller = fxmlLoader.getController();
controller.setLatLongs(new LatLongs(63.1, 11.2, 63.2, 11.0));
final Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(final String[] args) {
// only needed on ios
System.setProperty("os.target", "ios");
System.setProperty("os.name", "iOS");
System.setProperty("glass.platform", "ios");
System.setProperty("targetos.name", "iOS");
launch(args);
}
}
package simpleex.ui;
import java.io.File;
import fxmapcontrol.Location;
import fxmapcontrol.MapBase;
import fxmapcontrol.MapItemsControl;
import fxmapcontrol.MapNode;
import fxmapcontrol.MapProjection;
import fxutil.doc.FileMenuController;
import fxutil.doc.IDocumentListener;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.control.ListView;
import javafx.scene.control.Slider;
import simpleex.core.LatLong;
import simpleex.core.LatLongs;
public class FxAppController extends FileMenuController implements IDocumentListener<LatLongs, File> {
private final LatLongsStorage latLongsStorage;
public FxAppController() {
latLongsStorage = new LatLongsStorage();
latLongsStorage.addDocumentStorageListener(this);
}
public LatLongs getLatLongs() {
return latLongsStorage.getDocument();
}
// to make it testable
public void setLatLongs(final LatLongs latLongs) {
latLongsStorage.setDocument(latLongs);
updateLocationViewList(0);
}
// @FXML
// private FileMenuController fileMenuController;
@FXML
private ListView<LatLong> locationListView;
@FXML
private MapBase mapView;
private MapItemsControl<MapNode> markersParent;
private MapMarker marker = null;
private DraggableNodeController draggableMapController = null;
private DraggableNodeController draggableMarkerController = null;
@FXML
private Slider zoomSlider;
@FXML
private void initialize() {
// fileMenuController.
setDocumentStorage(latLongsStorage);
// map stuff
// mapView.getChildren().add(MapTileLayer.getOpenStreetMapLayer());
zoomSlider.valueProperty().addListener((prop, oldValue, newValue) -> mapView.setZoomLevel(zoomSlider.getValue()));
zoomSlider.setValue(8);
markersParent = new MapItemsControl<MapNode>();
mapView.getChildren().add(markersParent);
draggableMapController = new DraggableNodeController(this::handleMapDragged);
draggableMapController.setImmediate(true);
draggableMapController.attach(mapView);
draggableMarkerController = new DraggableNodeController(this::handleMarkerDragged);
// the location list
locationListView.getSelectionModel().selectedIndexProperty().addListener((prop, oldValue, newValue) -> updateMapMarker(true));
}
private void handleMapDragged(final Node node, final double dx, final double dy) {
final MapProjection projection = mapView.getProjection();
final Point2D point = projection.locationToViewportPoint(mapView.getCenter());
final Location newCenter = projection.viewportPointToLocation(point.add(-dx, -dy));
mapView.setCenter(newCenter);
}
private void handleMarkerDragged(final Node node, final double dx, final double dy) {
final MapProjection projection = mapView.getProjection();
final Point2D point = projection.locationToViewportPoint(marker.getLocation());
final Location newLocation = projection.viewportPointToLocation(point.add(dx, dy));
getLatLongs().setLatLong(locationListView.getSelectionModel().getSelectedIndex(), location2LatLong(newLocation));
updateLocationViewListSelection(false);
}
private LatLong location2LatLong(final Location newLocation) {
return new LatLong(newLocation.getLatitude(), newLocation.getLongitude());
}
private void updateMapMarker(final boolean centerOnMarker) {
final int num = locationListView.getSelectionModel().getSelectedIndex();
if (num < 0 || num >= getLatLongs().getLatLongCount()) {
markersParent.getItems().clear();
if (draggableMarkerController != null) {
draggableMarkerController.detach(marker);
}
marker = null;
} else {
final LatLong latLong = getLatLongs().getLatLong(num);
if (marker == null) {
marker = new MapMarker(latLong);
markersParent.getItems().add(marker);
if (draggableMarkerController != null) {
draggableMarkerController.attach(marker);
}
} else {
marker.setLocation(latLong);
}
if (centerOnMarker) {
mapView.setCenter(marker.getLocation());
}
}
}
@FXML
private void handleAddLocation() {
final Location center = mapView.getCenter();
final int pos = getLatLongs().addLatLong(location2LatLong(center));
updateLocationViewList(pos);
}
private void updateLocationViewListSelection(final Boolean updateMapMarker) {
final int selectedIndex = locationListView.getSelectionModel().getSelectedIndex();
updateLocationViewListItem(selectedIndex);
if (updateMapMarker != null) {
updateMapMarker(updateMapMarker);
}
}
private void updateLocationViewListItem(final int index) {
locationListView.getItems().set(index, getLatLongs().getLatLong(index));
}
private void updateLocationViewList(int selectedIndex) {
final LatLong[] latLongs = new LatLong[getLatLongs().getLatLongCount()];
for (int i = 0; i < latLongs.length; i++) {
latLongs[i] = getLatLongs().getLatLong(i);
}
final int oldSelectionIndex = locationListView.getSelectionModel().getSelectedIndex();
locationListView.setItems(FXCollections.observableArrayList(latLongs));
if (selectedIndex < 0 || selectedIndex >= latLongs.length) {
selectedIndex = oldSelectionIndex;
}
if (selectedIndex >= 0 && selectedIndex < getLatLongs().getLatLongCount()) {
locationListView.getSelectionModel().select(selectedIndex);
}
}
// IDocumentListener
@Override
public void documentLocationChanged(final File documentLocation, final File oldDocumentLocation) {
}
@Override
public void documentChanged(final LatLongs document, final LatLongs oldDocument) {
updateLocationViewList(0);
}
}
package simpleex.ui;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;
import fxutil.doc.AbstractDocumentStorageImpl;
import fxutil.doc.IDocumentImporter;
import fxutil.doc.IDocumentLoader;
import fxutil.doc.IDocumentPersistence;
import fxutil.doc.IDocumentStorage;
import simpleex.core.LatLongs;
public class LatLongsApp {
private LatLongs latLongs = null;
private final IDocumentPersistence<LatLongs, File> documentPersistence = new IDocumentPersistence<LatLongs, File>() {
@Override
public LatLongs loadDocument(final InputStream inputStream) throws Exception {
// TODO
return null;
}
@Override
public void saveDocument(final LatLongs document, final File documentLocation) throws Exception {
try (OutputStream output = new FileOutputStream(documentLocation)) {
// TODO
}
}
};
private final AbstractDocumentStorageImpl<LatLongs, File> documentStorage = new AbstractDocumentStorageImpl<LatLongs, File>() {
@Override
protected LatLongs getDocument() {
return latLongs;
}
@Override
protected void setDocument(final LatLongs document) {
final LatLongs oldDocument = getDocument();
LatLongsApp.this.latLongs = document;
fireDocumentChanged(oldDocument);
}
@Override
protected LatLongs createDocument() {
return new LatLongs();
}
@Override
protected InputStream toInputStream(final File storage) throws IOException {
return new FileInputStream(storage);
}
@Override
public LatLongs loadDocument(final InputStream inputStream) throws Exception {
return documentPersistence.loadDocument(inputStream);
}
@Override
public void saveDocument(final LatLongs document, final File documentLocation) throws Exception {
documentPersistence.saveDocument(document, documentLocation);
}
@Override
public Collection<IDocumentImporter> getDocumentImporters() {
return documentLoaders.stream().map(loader -> new IDocumentImporter() {
@Override
public void importDocument(final InputStream inputStream) throws IOException {
try {
setDocumentAndLocation(loader.loadDocument(inputStream), null);
} catch (final Exception e) {
throw new IOException(e);
}
}
}).collect(Collectors.toList());
}
};
public IDocumentStorage<File> getDocumentStorage() {
return documentStorage;
}
private final Collection<IDocumentLoader<LatLongs>> documentLoaders = Arrays.asList();
public Iterable<IDocumentLoader<LatLongs>> getDocumentLoaders() {
return documentLoaders;
}
}
package simpleex.ui;
import java.io.File;
import com.fasterxml.jackson.databind.module.SimpleModule;
import fxutil.doc.IDocumentStorage;
import fxutil.doc.SimpleJsonFileStorageImpl;
import simpleex.core.LatLong;
import simpleex.core.LatLongs;
import simpleex.json.LatLongDeserializer;
import simpleex.json.LatLongSerializer;
import simpleex.json.LatLongsDeserializer;
import simpleex.json.LatLongsSerializer;
public class LatLongsStorage extends SimpleJsonFileStorageImpl<LatLongs> implements IDocumentStorage<File> {
public LatLongsStorage() {
super(LatLongs.class);
}
@Override
protected void configureJacksonModule(final SimpleModule module) {
module.addSerializer(LatLong.class, new LatLongSerializer());
module.addSerializer(LatLongs.class, new LatLongsSerializer());
module.addDeserializer(LatLong.class, new LatLongDeserializer());
module.addDeserializer(LatLongs.class, new LatLongsDeserializer());
}
}
package simpleex.ui;
import fxmapcontrol.Location;
import fxmapcontrol.MapItem;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import simpleex.core.LatLong;
public class MapMarker extends MapItem<LatLong> {
public MapMarker(final LatLong latLong) {
setLocation(latLong);
final Circle circle = new Circle();
circle.setRadius(5);
circle.setFill(Color.BLUE);
getChildren().add(circle);
}
public void setLocation(final LatLong latLong) {
setLocation(new Location(latLong.latitude, latLong.longitude));
}
}
# The UI source code, a minimal JavaFX/FXML UI
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<Menu xmlns:fx="http://javafx.com/fxml" text="File" fx:controller="fxutil.doc.FileMenuController">
<items>
<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" accelerator="Meta+S" onAction="#handleSaveAction"/>
<MenuItem text="Save As..." onAction="#handleSaveAsAction"/>
<MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/>
<SeparatorMenuItem/>
<Menu fx:id="importMenu" text="Import">
<MenuItem text="File..." onAction="#handleFileImportAction"/>
<MenuItem text="URL..." onAction="#handleURLImportAction"/>
</Menu>
</items>
</Menu>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Slider?>
<?import fxmapcontrol.MapBase?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<?import fxmapcontrol.MapTileLayer?>
<?import fxmapcontrol.TileSource?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<BorderPane xmlns:fx="http://javafx.com/fxml"
fx:controller="simpleex.ui.FxAppController"
prefHeight="750" prefWidth="1000">
<top>
<VBox>
<MenuBar >
<menus>
<fx:include fx:id="fileMenu" source="FileMenu.fxml"/>
</menus>
</MenuBar>
</VBox>
</top>
<left>
<VBox fillWidth="true">
<ListView fx:id="locationListView"/>
<Button text="Add location" onAction="#handleAddLocation"/>
</VBox>
</left>
<center>
<VBox>
<MapBase fx:id="mapView">
<MapTileLayer name="OpenStreetMap" minZoomLevel="0" maxZoomLevel="17">
<tileSource>
<TileSource urlFormat="http://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"/>
<!--
<TileSource urlFormat="https://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
<TileSource urlFormat="http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo2&amp;zoom={z}&amp;x={x}&amp;y={y}"/>
<TileSource urlFormat="http://mt1.google.com/vt/lyrs=m@129&amp;hl=en&amp;s=Galileo&amp;z={z}&amp;x={x}&amp;y={y}"/>
-->
</tileSource>
</MapTileLayer>
</MapBase>
<Slider fx:id="zoomSlider" min="1" max="20" value="9"/>
</VBox>
</center>
</BorderPane>
package simpleex.core;
import org.junit.Assert;
import org.junit.Test;
public class LatLongTest {
@Test
public void testToString() {
final LatLong latLong = new LatLong(63.0, 10.0);
Assert.assertEquals(Double.toString(63) + "," + Double.toString(10), latLong.toString());
}
@Test
public void testValueOf() {
testLatLong(LatLong.valueOf("63.0, 10.0"), 63.0, 10.0);
testLatLong(LatLong.valueOf("63.0, 10.0", ","), 63.0, 10.0);
testLatLong(LatLong.valueOf("63.0; 10.0", ";"), 63.0, 10.0);
}
private void testLatLong(final LatLong latLong, final double lat, final double lon) {
Assert.assertEquals(lat, latLong.latitude, 0.0);
Assert.assertEquals(lon, latLong.longitude, 0.0);
}
@Test
public void testEquals() {
Assert.assertTrue(new LatLong(63.0, 10.0).equals(new LatLong(63.0, 10.0)));
Assert.assertFalse(new LatLong(10.0, 63.0).equals(new LatLong(63.0, 10.0)));
Assert.assertFalse(new LatLong(10.0, 63.0).equals(null));
}
}
package simpleex.core;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import simpleex.core.LatLongs;
public class LatLongsTest {
private LatLongs latLongs;
@Before
public void setup() {
latLongs = new LatLongs();
}
@Test
public void testEmptyConstructor() {
Assert.assertEquals(0, latLongs.getLatLongCount());
}
}
package simpleex.json;
import java.io.IOException;
import org.junit.Assert;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public abstract class AbstractJsonTest {
private ObjectMapper objectMapper;
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public void setup() {
objectMapper = createObjectMapper();
}
protected abstract ObjectMapper createObjectMapper();
protected <T> SimpleModule createSimpleModule(final Class<T> clazz, final JsonSerializer<T> serializer, final JsonDeserializer<T> deserializer) {
return new SimpleModule()
.addSerializer(clazz, serializer)
.addDeserializer(clazz, deserializer);
}
protected <T> ObjectMapper createObjectMapper(final Class<T> clazz, final JsonSerializer<T> serializer, final JsonDeserializer<T> deserializer) {
return new ObjectMapper().registerModule(createSimpleModule(clazz, serializer, deserializer));
}
protected void assertEqualsIgnoreWhitespace(final String expected, final String actual) throws Exception {
Assert.assertEquals(expected, actual.replaceAll("\\s+", ""));
}
protected void assertWriteValue(final String expected, final Object value) throws Exception {
assertEqualsIgnoreWhitespace(expected, getObjectMapper().writeValueAsString(value));
}
protected <T> T readValue(final String s, final Class<T> clazz) throws IOException, JsonParseException, JsonMappingException {
return getObjectMapper().readValue(s, clazz);
}
}
package simpleex.json;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
import simpleex.core.LatLong;
import simpleex.json.LatLongDeserializer;
import simpleex.json.LatLongSerializer;
public class LatLongJsonTest extends AbstractJsonTest {
@Before
@Override
public void setup() {
super.setup();
}
@Override
protected ObjectMapper createObjectMapper() {
return createObjectMapper(LatLong.class, new LatLongSerializer(), new LatLongDeserializer());
}
@Test
public void testLatLongSerialization() throws Exception {
assertWriteValue("{\"latitude\":63.1,\"longitude\":12.3}", new LatLong(63.1, 12.3));
}
@Test
public void testLatLongDeserialization() throws Exception {
Assert.assertEquals(new LatLong(63.1, 12.3), readValue("[ 63.1, 12.3 ]", LatLong.class));
}
}
package simpleex.ui;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.testfx.framework.junit.ApplicationTest;
import fxmapcontrol.Location;
import fxmapcontrol.MapBase;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import simpleex.core.LatLong;
import simpleex.core.LatLongs;
public class FxAppTest extends ApplicationTest {
@BeforeClass
public static void headless() {
if (Boolean.valueOf(System.getProperty("gitlab-ci", "false"))) {
System.setProperty("prism.verbose", "true"); // optional
System.setProperty("java.awt.headless", "true");
System.setProperty("testfx.robot", "glass");
System.setProperty("testfx.headless", "true");
System.setProperty("glass.platform", "Monocle");
System.setProperty("monocle.platform", "Headless");
System.setProperty("prism.order", "sw");
System.setProperty("prism.text", "t2k");
System.setProperty("testfx.setup.timeout", "2500");
}
}
private FxAppController controller;
private LatLongs latLongs;
@Override
public void start(final Stage stage) throws Exception {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("FxApp.fxml"));
final Parent root = loader.load();
this.controller = loader.getController();
setUpLatLongs();
final Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
private List<LatLong> latLongList;
private void setUpLatLongs() {
// test data
latLongList = new ArrayList<>(List.of(new LatLong(63.1, 11.2), new LatLong(63.2, 11.0)));
// "mocked" (faked) LatLongs object with very specific and limited behavior
latLongs = mock(LatLongs.class);
// get nth LatLong object
when(latLongs.getLatLong(anyInt())).then(invocation -> latLongList.get(invocation.getArgument(0)));
// get the number of LatLong objects
when(latLongs.getLatLongCount()).then(invocation -> latLongList.size());
// iterator for LatLong objects
when(latLongs.iterator()).then(invocation -> latLongList.iterator());
controller.setLatLongs(latLongs);
}
@Test
public void testController() {
Assert.assertTrue(this.controller instanceof FxAppController);
}
@Test
public void testLocationListView() {
final ListView<?> locationListView = lookup("#locationListView").query();
// list contains equals elements in same order
Assert.assertEquals(latLongList, locationListView.getItems());
// first list element is auto-selected
Assert.assertEquals(0, locationListView.getSelectionModel().getSelectedIndex());
}
@Test
public void testMapView() {
final MapBase mapView = lookup("#mapView").query();
// center of map view is approx. the first LatLong object
final Location center = mapView.getCenter();
final double epsilon = 0.000001; // round-off error
Assert.assertEquals(latLongList.get(0).latitude, center.getLatitude(), epsilon);
Assert.assertEquals(latLongList.get(0).longitude, center.getLongitude(), epsilon);
}
@Test
public void testAddLocation() {
// needs map center
final Location center = ((MapBase) lookup("#mapView").query()).getCenter();
// add behavior for add
final LatLong latLong = new LatLong(center.getLatitude(), center.getLongitude());
when(latLongs.addLatLong(latLong)).thenReturn(2); // add center
// make test less sensitive to exact button text
final Button addLocButton = lookup(node -> node instanceof Button && ((Button) node).getText().toLowerCase().startsWith("add loc")).query();
clickOn(addLocButton);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<Menu xmlns:fx="http://javafx.com/fxml" text="File" fx:controller="fxutil.doc.FileMenuController">
<items>
<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" accelerator="Meta+S" onAction="#handleSaveAction"/>
<MenuItem text="Save As..." onAction="#handleSaveAsAction"/>
<MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/>
<SeparatorMenuItem/>
<Menu fx:id="importMenu" text="Import">
<MenuItem text="File..." onAction="#handleFileImportAction"/>
<MenuItem text="URL..." onAction="#handleURLImportAction"/>
</Menu>
</items>
</Menu>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Slider?>
<?import fxmapcontrol.MapBase?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<?import fxmapcontrol.MapTileLayer?>
<?import fxmapcontrol.TileSource?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<BorderPane xmlns:fx="http://javafx.com/fxml"
fx:controller="simpleex.ui.FxAppController"
prefHeight="750" prefWidth="1000">
<top>
<VBox>
<MenuBar >
<menus>
<fx:include fx:id="fileMenu" source="FileMenu.fxml"/>
</menus>
</MenuBar>
</VBox>
</top>
<left>
<VBox fillWidth="true">
<ListView fx:id="locationListView"/>
<Button text="Add location" onAction="#handleAddLocation"/>
</VBox>
</left>
<center>
<VBox>
<MapBase fx:id="mapView">
<MapTileLayer name="OpenStreetMap" minZoomLevel="0" maxZoomLevel="17">
<tileSource>
<TileSource urlFormat="http://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"/>
<!--
<TileSource urlFormat="https://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
<TileSource urlFormat="http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo2&amp;zoom={z}&amp;x={x}&amp;y={y}"/>
<TileSource urlFormat="http://mt1.google.com/vt/lyrs=m@129&amp;hl=en&amp;s=Galileo&amp;z={z}&amp;x={x}&amp;y={y}"/>
-->
</tileSource>
</MapTileLayer>
</MapBase>
<Slider fx:id="zoomSlider" min="1" max="20" value="9"/>
</VBox>
</center>
</BorderPane>
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