Java tutorial
// License: GPL. For details, see LICENSE file. package org.openstreetmap.beboj.client.actions.mapmode.edit; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseUpEvent; import java.awt.Graphics2D; import java.awt.Point; import org.openstreetmap.beboj.client.Beboj; import org.openstreetmap.beboj.client.gui.CanvasGraphics2D; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.command.AddCommand; import org.openstreetmap.josm.command.ChangeCommand; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.gui.MapView; import org.openstreetmap.josm.gui.layer.MapViewPaintable; public class DrawWay extends ControllerState implements MapViewPaintable { private final static long DOUBLE_CLICK_LIMIT = 1000l; private Node startNode; private Node lastNode; private Way way; private long lastClickTime; private Point lastMousePos; public DrawWay(Node startNode) { super(); this.startNode = this.lastNode = startNode; way = new Way(); way.addNode(startNode); } public DrawWay(Way way, boolean editEnd) { this.way = way; this.startNode = this.lastNode = editEnd ? way.lastNode() : way.firstNode(); } @Override public ControllerState onMouseDown(MouseDownEvent evt, OsmPrimitive osm) { // TODO Auto-generated method stub // FIXME: drag return this; } @Override public ControllerState onMouseMove(MouseMoveEvent evt, OsmPrimitive osm) { lastMousePos = new Point(evt.getX(), evt.getY()); Beboj.canvasView.repaint(); return this; } @Override public ControllerState onMouseUp(MouseUpEvent evt, OsmPrimitive osm) { if (osm == null) { // create new node and insert it into way Node newNode = new Node(Main.map.mapView.getLatLon(evt.getX(), evt.getY())); Main.main.undoRedo.add(new AddCommand(newNode)); if (way.getNodesCount() == 1) { // haven't added way yet Main.main.undoRedo.add(new AddCommand(way)); getCurrentDataSet().setSelected(way); } Way newWay = new Way(way); newWay.addNode(newNode); Main.main.undoRedo.add(new ChangeCommand(way, newWay)); lastNode = newNode; Beboj.canvasView.repaint(); } if (osm instanceof Node) { if (System.currentTimeMillis() - lastClickTime < DOUBLE_CLICK_LIMIT) { if (way.getNodesCount() == 1 && numWayReferrer(way.getNode(0)) == 1 && osm.equals(startNode)) { // Actually the user double-clicked to make a new node, they didn't want to draw a way at all. return new SelectedPOINode((Node) osm); } else if (way.getNodesCount() == 1) { // It's not a poi, but they've double-clicked or clicked-twice the first node - do nothing return this; } else { // double-click at end of way // getCurrentDataSet().setSelected(way); return new SelectedWay(way); } } else if (osm.equals(lastNode)) { // clicked slowly on the end node - do nothing return this; } else { // hit a node, add it to this way and carry on Way newWay = new Way(way); newWay.addNode((Node) osm); Main.main.undoRedo.add(new ChangeCommand(way, newWay)); Beboj.canvasView.repaint(); } } lastClickTime = System.currentTimeMillis(); return this; } protected int numWayReferrer(Node n) { int i = 0; for (OsmPrimitive parent : n.getReferrers()) { if (parent instanceof Way) { ++i; } } if (way.getNodesCount() == 1) { // haven't added way to dataset, so it isn't reported as referrer if (way.getNode(0).equals(n)) { ++i; } } return i; } @Override public void enterState(ControllerState oldState) { lastClickTime = System.currentTimeMillis(); Main.map.mapView.addTemporaryLayer(this); // TODO Auto-generated method stub } @Override public void exitState(ControllerState newState) { Main.map.mapView.removeTemporaryLayer(this); // TODO Auto-generated method stub } @Override public String toString() { return "DrawWay"; } @Override public void paint(Graphics2D g, MapView mv, Bounds bbox) { Context2d c = ((CanvasGraphics2D) g).getContext2d(); // don't draw line if we don't know where to if (lastMousePos == null) return; // don't draw line if mouse is outside window if (!Main.map.mapView.view.getBounds().contains(lastMousePos)) return; Point p1 = mv.getPoint(lastNode); Point p2 = lastMousePos; c.setStrokeStyle("#ffff00"); c.beginPath(); c.moveTo(p1.x, p1.y); c.lineTo(p2.x, p2.y); c.stroke(); } }