Index: /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/GraphViewPlugin.java
===================================================================
--- /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/GraphViewPlugin.java	(revision 26480)
+++ /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/GraphViewPlugin.java	(revision 26481)
@@ -119,4 +119,5 @@
                     graphViewLayer.setWayGraph(graph);
                     graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
+                    graphViewLayer.setArrowheadPlacement(preferences.getArrowheadPlacement());
                     graphViewLayer.setNodePositioner(new DefaultNodePositioner());
 
@@ -269,4 +270,5 @@
             if (graphViewLayer != null) {
                 graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
+                graphViewLayer.setArrowheadPlacement(preferences.getArrowheadPlacement());
             }
         }
Index: /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewPreferenceEditor.java
===================================================================
--- /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewPreferenceEditor.java	(revision 26480)
+++ /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewPreferenceEditor.java	(revision 26481)
@@ -3,10 +3,16 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.GridLayout;
+import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.geom.Line2D;
 import java.io.File;
 import java.util.Collection;
@@ -25,9 +31,13 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.JSlider;
 import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
 import org.openstreetmap.josm.plugins.graphview.plugin.dialogs.AccessParameterDialog.BookmarkAction;
+import org.openstreetmap.josm.plugins.graphview.plugin.layer.GraphViewLayer;
 import org.openstreetmap.josm.plugins.graphview.plugin.preferences.GraphViewPreferenceDefaults;
 import org.openstreetmap.josm.plugins.graphview.plugin.preferences.GraphViewPreferences;
@@ -56,5 +66,9 @@
     private JButton nodeColorButton;
     private JPanel nodeColorField;
-    
+    private JButton arrowheadFillColorButton;
+    private JPanel arrowheadFillColorField;
+    private JSlider arrowheadPlacementSlider;
+    private JPanel arrowPreviewPanel;
+
     public void addGui(PreferenceTabbedPane gui) {
 
@@ -182,22 +196,22 @@
         return vehiclePanel;
     }
-    
+
     private JPanel createVisualizationPanel() {
-    	
+
     	JPanel visualizationPanel = new JPanel();
     	visualizationPanel.setBorder(BorderFactory.createTitledBorder(tr("Visualization")));
     	visualizationPanel.setLayout(new BoxLayout(visualizationPanel, BoxLayout.Y_AXIS));
-    	
+
     	separateDirectionsCheckBox = new JCheckBox(tr("Draw directions separately"));
     	separateDirectionsCheckBox.setSelected(GraphViewPreferences.getInstance().getSeparateDirections());
     	visualizationPanel.add(separateDirectionsCheckBox);
-    	
+
     	{ // create color chooser panel
-    		
+
     		JPanel colorPanel = new JPanel();
-    		colorPanel.setLayout(new GridLayout(2, 2));
-    		
+    		colorPanel.setLayout(new GridLayout(3, 2));
+
     		Color nodeColor = GraphViewPreferences.getInstance().getNodeColor();
-    		
+
     		nodeColorButton = new JButton(tr("Node color"));
     		nodeColorButton.addActionListener(chooseNodeColorActionListener);
@@ -206,7 +220,7 @@
     		nodeColorField.setBackground(nodeColor);
     		colorPanel.add(nodeColorField);
-    		
+
     		Color segmentColor = GraphViewPreferences.getInstance().getSegmentColor();
-    		
+
     		segmentColorButton = new JButton(tr("Arrow color"));
     		segmentColorButton.addActionListener(chooseSegmentColorActionListener);
@@ -215,9 +229,32 @@
     		segmentColorField.setBackground(segmentColor);
     		colorPanel.add(segmentColorField);
-    		
+
+    		Color arrowheadFillColor = GraphViewPreferences.getInstance().getArrowheadFillColor();
+
+    		arrowheadFillColorButton = new JButton(tr("Arrowhead fill color"));
+    		arrowheadFillColorButton.addActionListener(chooseArrowheadFillColorActionListener);
+    		colorPanel.add(arrowheadFillColorButton);
+    		arrowheadFillColorField = new JPanel();
+    		arrowheadFillColorField.setBackground(arrowheadFillColor);
+    		colorPanel.add(arrowheadFillColorField);
+
     		visualizationPanel.add(colorPanel);
-    		
+
     	}
-    	
+
+    	arrowheadPlacementSlider = new JSlider(0, 100);
+    	arrowheadPlacementSlider.setToolTipText(tr("Arrowhead placement"));
+    	arrowheadPlacementSlider.setMajorTickSpacing(10);
+    	arrowheadPlacementSlider.setPaintTicks(true);
+    	arrowheadPlacementSlider.setName("name");
+    	arrowheadPlacementSlider.setLabelTable(null);
+    	arrowheadPlacementSlider.setValue((int)Math.round(
+    			100 * GraphViewPreferences.getInstance().getArrowheadPlacement()));
+    	arrowheadPlacementSlider.addChangeListener(arrowheadPlacementChangeListener);
+    	visualizationPanel.add(arrowheadPlacementSlider);
+
+    	arrowPreviewPanel = new ArrowPreviewPanel();
+    	visualizationPanel.add(arrowPreviewPanel);
+
     	return visualizationPanel;
     }
@@ -239,5 +276,9 @@
         preferences.setNodeColor(nodeColorField.getBackground());
         preferences.setSegmentColor(segmentColorField.getBackground());
-        
+        preferences.setArrowheadFillColor(arrowheadFillColorField.getBackground());
+
+        preferences.setArrowheadPlacement(
+        		arrowheadPlacementSlider.getValue() / 100f);
+
         preferences.distributeChanges();
 
@@ -371,28 +412,53 @@
         }
     };
-    
+
     private final ActionListener chooseNodeColorActionListener = new ActionListener() {
         public void actionPerformed(ActionEvent e) {
-        	
+
         	Color selectedColor = JColorChooser.showDialog(
         			preferencePanel, tr("Choose node color"), nodeColorField.getBackground());
-        	
+
         	if (selectedColor != null) {
         		nodeColorField.setBackground(selectedColor);
         	}
-        	
-        }
-    };
-    
+
+        	arrowPreviewPanel.repaint();
+
+        }
+    };
+
     private final ActionListener chooseSegmentColorActionListener = new ActionListener() {
         public void actionPerformed(ActionEvent e) {
-        	
+
         	Color selectedColor = JColorChooser.showDialog(
         			preferencePanel, tr("Choose arrow color"), segmentColorField.getBackground());
-        	
+
         	if (selectedColor != null) {
         		segmentColorField.setBackground(selectedColor);
         	}
-        	
+
+        	arrowPreviewPanel.repaint();
+
+        }
+    };
+
+    private final ActionListener chooseArrowheadFillColorActionListener = new ActionListener() {
+        public void actionPerformed(ActionEvent e) {
+
+        	Color selectedColor = JColorChooser.showDialog(
+        			preferencePanel, tr("Choose arrowhead fill color"), segmentColorField.getBackground());
+
+        	if (selectedColor != null) {
+        		arrowheadFillColorField.setBackground(selectedColor);
+        	}
+
+        	arrowPreviewPanel.repaint();
+
+        }
+    };
+
+    private final ChangeListener arrowheadPlacementChangeListener = new ChangeListener() {
+    	public void stateChanged(ChangeEvent e) {
+        	arrowPreviewPanel.repaint();
         }
     };
@@ -426,3 +492,36 @@
     }
 
+    private class ArrowPreviewPanel extends JPanel {
+
+    	public ArrowPreviewPanel() {
+    		setPreferredSize(new Dimension(100, 50));
+			setBackground(Color.DARK_GRAY);
+		}
+
+    	@Override
+    	public void paint(Graphics g) {
+
+    		super.paint(g);
+
+    		Graphics2D g2D = (Graphics2D)g;
+
+    		Point p1 = new Point(15, this.getHeight() / 2);
+    		Point p2 = new Point(this.getWidth()-15, this.getHeight() / 2);
+
+    		g2D.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+    		g2D.setColor(segmentColorField.getBackground());
+    		g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
+
+    		GraphViewLayer.paintNode(g, p1, nodeColorField.getBackground());
+    		GraphViewLayer.paintNode(g, p2, nodeColorField.getBackground());
+
+    		GraphViewLayer.paintArrowhead(g2D, p1, p2,
+    				arrowheadPlacementSlider.getValue() / 100.0,
+    				segmentColorField.getBackground(),
+    				arrowheadFillColorField.getBackground());
+
+    	}
+
+    }
+
 }
Index: /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/GraphViewLayer.java
===================================================================
--- /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/GraphViewLayer.java	(revision 26480)
+++ /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/GraphViewLayer.java	(revision 26481)
@@ -66,4 +66,7 @@
     private static final Shape ARROW_HEAD;
 
+    /** arrow head core, can be colored differently and is rendered on top */
+    private static final Shape ARROW_HEAD_CORE;
+
     static {
 
@@ -71,8 +74,18 @@
 
         head.addPoint(  0,  0);
-        head.addPoint(-15, +4);
-        head.addPoint(-15, -4);
+        head.addPoint(-22, +6);
+        head.addPoint(-22, -6);
 
         ARROW_HEAD = head;
+
+        Polygon headCore = new Polygon();
+
+        headCore.addPoint(-12,  0);
+        headCore.addPoint(-19, +2);
+        headCore.addPoint(-19, -2);
+
+        ARROW_HEAD_CORE = headCore;
+
+
     }
 
@@ -80,4 +93,5 @@
 
     private ColorScheme colorScheme = null;
+    private Double arrowheadPlacement = null;
     private NodePositioner nodePositioner = new NonMovingNodePositioner();
 
@@ -101,4 +115,11 @@
     public void setColorScheme(ColorScheme colorScheme) {
         this.colorScheme = colorScheme;
+        Main.panel.repaint();
+    }
+
+    /** sets the arrowhead placement (relative offset from edge start) */
+    public void setArrowheadPlacement(double arrowheadPlacement) {
+    	assert arrowheadPlacement >= 0 && arrowheadPlacement <= 1;
+        this.arrowheadPlacement = arrowheadPlacement;
         Main.panel.repaint();
     }
@@ -124,12 +145,17 @@
 
         Color color = colorScheme != null ? colorScheme.getNodeColor(node) : Color.LIGHT_GRAY;
-
         Point p = getNodePoint(node, mv);
-        g.setColor(color);
+
+        paintNode(g, p, color);
+
+    }
+
+	public static void paintNode(final Graphics g, Point p, Color color) {
+		g.setColor(color);
         g.fillOval(p.x - NODE_RADIUS, p.y - NODE_RADIUS, 2 * NODE_RADIUS, 2 * NODE_RADIUS);
-
-    }
-
-    private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv) {
+	}
+
+    private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv,
+    		boolean drawLine, boolean drawDirectionIndicator) {
 
         if (!CONNECT_ALL_NODE_PAIRS && GraphViewPreferences.getInstance().getSeparateDirections()) {
@@ -175,5 +201,7 @@
                 }
 
-                g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
+                if (drawLine) {
+                	g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
+                }
 
             }
@@ -183,9 +211,11 @@
         	Color color = GraphViewPreferences.getInstance().getSegmentColor();
             g2D.setColor(color);
-            
+
             Point p1 = getNodePoint(e.getStartNode(), mv);
             Point p2 = getNodePoint(e.getTargetNode(), mv);
 
-            g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
+            if (drawLine) {
+            	g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
+            }
 
         }
@@ -197,18 +227,54 @@
             Point p2 = getNodePoint(e.getTargetNode(), mv);
 
-            if (edgeSegments.size() > 0) {
+            if (edgeSegments.size() > 1) {
                 Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
                 p1 = getNodePoint(lastSegment.getNode1(), mv);
             }
 
-            double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
-            Shape head = ARROW_HEAD;
-            head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
-            head = AffineTransform.getTranslateInstance(p2.x, p2.y).createTransformedShape(head);
-
-            g2D.fill(head);
-
-        }
-    }
+            if (drawDirectionIndicator) {
+
+	            paintArrowhead(g2D, p1, p2, arrowheadPlacement, null,
+	            		GraphViewPreferences.getInstance().getArrowheadFillColor());
+
+            }
+
+        }
+    }
+
+	public static void paintArrowhead(Graphics2D g2D,
+			Point p1, Point p2, Double arrowheadPlacement2,
+			Color casingColor, Color fillColor) {
+
+		Point pTip = new Point(
+				(int)(p1.x + arrowheadPlacement2 * (p2.x - p1.x)),
+				(int)(p1.y + arrowheadPlacement2 * (p2.y - p1.y)));
+
+		double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
+
+		{ //draw head shape
+
+			if (casingColor != null) {
+				g2D.setColor(casingColor);
+			}
+
+		    Shape head = ARROW_HEAD;
+		    head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
+		    head = AffineTransform.getTranslateInstance(pTip.x, pTip.y).createTransformedShape(head);
+		    g2D.fill(head);
+		}
+
+		{ //draw head core shape
+
+			if (fillColor != null) {
+				g2D.setColor(fillColor);
+			}
+
+		    Shape headCore = ARROW_HEAD_CORE;
+		    headCore = AffineTransform.getRotateInstance(angle).createTransformedShape(headCore);
+		    headCore = AffineTransform.getTranslateInstance(pTip.x, pTip.y).createTransformedShape(headCore);
+		    g2D.fill(headCore);
+		}
+
+	}
 
     private Point getNodePoint(GraphNode node, MapView mv) {
@@ -247,9 +313,9 @@
         return nodePoint;
     }
-    private Point getNodePoint(SegmentNode node, MapView mv) {
+    private static Point getNodePoint(SegmentNode node, MapView mv) {
         LatLonCoords coords = new LatLonCoords(node.getLat(), node.getLon());
         return getNodePoint(coords, mv);
     }
-    private Point getNodePoint(LatLonCoords coords, MapView mv) {
+    private static Point getNodePoint(LatLonCoords coords, MapView mv) {
         LatLon latLon = new LatLon(coords.getLat(), coords.getLon());
         EastNorth eastNorth = Main.getProjection().latlon2eastNorth(latLon);
@@ -263,5 +329,5 @@
      * @return  angle in radians, in range [-Pi .. +Pi]
      */
-    private double angleFromXAxis(Point p1, Point p2) {
+    private static double angleFromXAxis(Point p1, Point p2) {
         assert p1 != null && p2 != null;
 
@@ -293,5 +359,10 @@
 
             for (GraphEdge e : wayGraph.getEdges()) {
-                paintGraphEdge(e, g, mv);
+                paintGraphEdge(e, g, mv, true, false);
+            }
+
+            for (GraphEdge e : wayGraph.getEdges()) {
+            	//draw arrowheads last to make sure they end up on top
+                paintGraphEdge(e, g, mv, false, true);
             }
 
Index: /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferences.java
===================================================================
--- /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferences.java	(revision 26480)
+++ /applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferences.java	(revision 26481)
@@ -1,5 +1,3 @@
 package org.openstreetmap.josm.plugins.graphview.plugin.preferences;
-
-import static org.openstreetmap.josm.tools.I18n.marktr;
 
 import static org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes.AXLELOAD;
@@ -38,5 +36,5 @@
  * changes will also be synchronized (two-way) with JOSM's preference storage.
  * This is a singleton class.
- * 
+ *
  * Note: Currently, manual updates in the "advanced preferences" will not have any effect
  * because this class isn't registered as a preference listener.
@@ -69,7 +67,9 @@
     private Color nodeColor;
     private Color segmentColor;
+    private Color arrowheadFillColor;
 
     private boolean separateDirections;
 
+    private double arrowheadPlacement;
 
     public synchronized boolean getUseInternalRulesets() {
@@ -168,9 +168,23 @@
     }
 
-    public synchronized boolean getSeparateDirections() {
+    public synchronized Color getArrowheadFillColor() {
+		return arrowheadFillColor;
+	}
+	public synchronized void setArrowheadFillColor(Color arrowheadFillColor) {
+		this.arrowheadFillColor = arrowheadFillColor;
+	}
+
+	public synchronized boolean getSeparateDirections() {
         return separateDirections;
     }
     public synchronized void setSeparateDirections(boolean separateDirections) {
         this.separateDirections = separateDirections;
+    }
+
+    public synchronized double getArrowheadPlacement() {
+    	return arrowheadPlacement;
+    }
+    public synchronized void setArrowheadPlacement(double arrowheadPlacement) {
+        this.arrowheadPlacement = arrowheadPlacement;
     }
 
@@ -220,4 +234,8 @@
         currentColorScheme = new PreferencesColorScheme(this);
 
+        nodeColor = Color.WHITE;
+        segmentColor = Color.WHITE;
+        arrowheadFillColor = Color.BLACK;
+
         separateDirections = false;
 
@@ -244,8 +262,11 @@
         }
 
-        Main.pref.putColor(marktr("GraphView default node"), nodeColor);
-        Main.pref.putColor(marktr("Graphview default segment"), segmentColor);
+        Main.pref.put("graphview.defaultNodeColor", createColorString(nodeColor));
+        Main.pref.put("graphview.defaultSegmentColor", createColorString(segmentColor));
+        Main.pref.put("graphview.defaultArrowheadCoreColor", createColorString(arrowheadFillColor));
 
         Main.pref.put("graphview.separateDirections", separateDirections);
+
+        Main.pref.putDouble("graphview.arrowheadPlacement", arrowheadPlacement);
 
     }
@@ -289,7 +310,29 @@
         }
 
-        nodeColor = Main.pref.getColor(marktr("GraphView default node"), Color.white);
-        segmentColor = Main.pref.getColor(marktr("Graphview default segment"), Color.white);
+        if (Main.pref.hasKey("graphview.defaultNodeColor")) {
+            Color color = parseColorString(Main.pref.get("graphview.defaultNodeColor"));
+            if (color != null) {
+                nodeColor = color;
+            }
+        }
+        if (Main.pref.hasKey("graphview.defaultSegmentColor")) {
+            Color color = parseColorString(Main.pref.get("graphview.defaultSegmentColor"));
+            if (color != null) {
+                segmentColor = color;
+            }
+        }
+        if (Main.pref.hasKey("graphview.defaultArrowheadCoreColor")) {
+            Color color = parseColorString(Main.pref.get("graphview.defaultArrowheadCoreColor"));
+            if (color != null) {
+            	arrowheadFillColor = color;
+            }
+        }
+
         separateDirections = Main.pref.getBoolean("graphview.separateDirections", false);
+
+        arrowheadPlacement = Main.pref.getDouble("graphview.arrowheadPlacement", 1.0);
+        if (arrowheadPlacement < 0.0 || arrowheadPlacement >= 1.0) {
+        	arrowheadPlacement = 1.0;
+        }
 
     }
@@ -460,3 +503,23 @@
         }
     }
+
+    private static final Pattern COLOR_PATTERN =
+        Pattern.compile("^(\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})$");
+
+    private String createColorString(Color color) {
+        return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
+    }
+
+    private Color parseColorString(String string) {
+        Matcher matcher = COLOR_PATTERN.matcher(string);
+        if (!matcher.matches()) {
+            return null;
+        } else {
+            int r = Integer.parseInt(matcher.group(1));
+            int g = Integer.parseInt(matcher.group(2));
+            int b = Integer.parseInt(matcher.group(3));
+            return new Color(r, g, b);
+        }
+    }
+
 }
