Просмотр исходного кода

Multiple Bug fixes in SymbolLayer

- increased performance when dragging world map around
- deselect edges and nodes when switching to symbol layer
- deactivate context menu in symbol layer
dominik 8 лет назад
Родитель
Сommit
f60d6ce960

+ 13 - 2
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/ButtonManager.java

@@ -5,6 +5,7 @@ import java.util.ArrayList;
 import org.graphstream.graph.implementations.Graphs;
 import org.jxmapviewer.viewer.WaypointPainter;
 
+import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
 import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
@@ -15,6 +16,7 @@ import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.WorldView;
 import javafx.beans.value.ObservableValue;
 import javafx.event.ActionEvent;
 import javafx.scene.control.Button;
+import javafx.scene.control.TableRow;
 
 /**
  * Manager to contain the various handlers for the buttons of the UI.
@@ -91,9 +93,12 @@ public final class ButtonManager {
 			// show toolbox and hide VBox
 			controller.toolbox.setVisible(true);
 			controller.symbolToolVBox.setVisible(false);
-
+			
 			// make properties editable again
 			controller.propertiesObjectColumn.setEditable(true);
+			
+			// enabel context menu
+			controller.properties.setRowFactory(PropertiesManager.rightClickCallback);
 
 			// show graph instead of map view
 			controller.swingNodeWorldView.setVisible(false);
@@ -106,6 +111,12 @@ public final class ButtonManager {
 			// make graph non mouse transparent
 			controller.pane.setMouseTransparent(false);
 			controller.swingNode.setMouseTransparent(false);
+			
+			// deselect graph element
+			PropertiesManager.showNewDataSet(null);
+			
+			// reset loaded images
+			MapViewFunctions.resetImageMap();
 
 		}
 	}
@@ -192,7 +203,7 @@ public final class ButtonManager {
 
 		// make properties uneditable
 		controller.propertiesObjectColumn.setEditable(false);
-
+		
 		// make map view non mouse transparent
 		controller.stackPane.setMouseTransparent(false);
 		controller.swingNodeWorldView.setMouseTransparent(false);

+ 30 - 0
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/GraphDisplayManager.java

@@ -17,6 +17,8 @@ import de.tu_darmstadt.informatik.tk.scopviz.io.GraphMLImporter;
 import de.tu_darmstadt.informatik.tk.scopviz.main.CreationMode;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
 import javafx.event.EventHandler;
 import javafx.scene.input.ScrollEvent;
 import javafx.scene.layout.Pane;
@@ -49,6 +51,28 @@ public final class GraphDisplayManager {
 
 	/** The currently active Layer. */
 	private static Layer currentLayer = Layer.UNDERLAY;
+	
+	
+	/**
+	 * Observable boolean value, true when currentLayer = symbol layer, false otherwise
+	 */
+	private static BooleanProperty inSymbolLayer = new SimpleBooleanProperty(); 
+	
+	/**
+	 * set inSymbolLayer to true
+	 */
+	private static final void changeToSymbolLayer(){inSymbolLayer.set(true);};
+	
+	/**
+	 * set inSymbolLayer to false
+	 */
+	private static final void changeToOtherLayer(){inSymbolLayer.set(false);};
+	
+	/**
+	 * 
+	 * @return inSymbolLayer property 
+	 */
+	public static BooleanProperty inSymbolLayerProperty(){return inSymbolLayer;};
 
 	/**
 	 * An empty GraphManager to use with Layers not yet filled with another
@@ -291,6 +315,12 @@ public final class GraphDisplayManager {
 			initMappingLayer();
 		}
 		GraphDisplayManager.currentLayer = currentLayer;
+		
+		if(currentLayer.equals(Layer.SYMBOL)){
+			changeToSymbolLayer();
+		}else{
+			changeToOtherLayer();
+		}
 	}
 
 	/**

+ 18 - 3
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/PropertiesManager.java

@@ -1,6 +1,7 @@
 package de.tu_darmstadt.informatik.tk.scopviz.ui;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Optional;
 
 import org.graphstream.algorithm.Toolkit;
@@ -57,6 +58,9 @@ public final class PropertiesManager {
 	public static boolean nameSet;
 	/** Flag whether the value has been set. */
 	public static boolean valueSet;
+	
+	
+	public static HashSet<TableRow<KeyValuePair>> tableRows = new HashSet<TableRow<KeyValuePair>>();
 
 	/**
 	 * Private Constructor to prevent Instantiation.
@@ -120,7 +124,7 @@ public final class PropertiesManager {
 				Debug.out("Edited float Attribute " + key);
 
 			} else if (classType.equals(Double.class) && newValue.matches(IS_FLOAT)) {
-				selected.changeAttribute(key, Float.valueOf(newValue));
+				selected.changeAttribute(key, Double.valueOf(newValue));
 				editedPair.setValue(newValue);
 				Debug.out("Edited double Attribute " + key);
 
@@ -170,15 +174,23 @@ public final class PropertiesManager {
 				properties.getItems().remove(row.getItem());
 			});
 
+			// Disable MenuItem in symbol layer
+			//TODO
+			onlyAddPropMenuItem.disableProperty().bind(GraphDisplayManager.inSymbolLayerProperty()); 
+			addPropMenuItem.disableProperty().bind(GraphDisplayManager.inSymbolLayerProperty()); 
+			deletePropMenuItem.disableProperty().bind(GraphDisplayManager.inSymbolLayerProperty()); 
+			
 			// add MenuItem to ContextMenu
 			menuOnEmptyRows.getItems().add(onlyAddPropMenuItem);
 			menuOnNonEmptyRows.getItems().addAll(addPropMenuItem, deletePropMenuItem);
+			
 
 			// when empty row right-clicked open special menu (only add),
 			// otherwise normal menu (add & delete)
 			row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
 					.then(menuOnNonEmptyRows).otherwise(menuOnEmptyRows));
 
+			tableRows.add(row);
 			return row;
 		}
 	};
@@ -212,11 +224,14 @@ public final class PropertiesManager {
 	 * @param newData
 	 */
 	public static void showNewDataSet(Element selected) {
+
+		ObservableList<KeyValuePair> newData = FXCollections.observableArrayList();
+		
 		if (selected == null) {
+			properties.setItems(newData);
 			return;
 		}
-
-		ObservableList<KeyValuePair> newData = FXCollections.observableArrayList();
+		
 		// fix for concurrentModification exception
 		String[] temp = new String[0];
 		temp = selected.getAttributeKeySet().toArray(temp);

+ 24 - 9
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/CustomMapClickListener.java

@@ -9,25 +9,38 @@ import org.jxmapviewer.JXMapViewer;
 import org.jxmapviewer.input.MapClickListener;
 import org.jxmapviewer.viewer.GeoPosition;
 
+import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
 
 public class CustomMapClickListener extends MapClickListener {
 
-	private final HashSet<CustomWaypoint> nodePositions;
+	/*
+	 * World view viewer
+	 */
 	private final JXMapViewer viewer;
 
-	private static CustomWaypoint selected;
+	/*
+	 * selected waypoint
+	 */
+	public static CustomWaypoint selected;
 
-	private static HashSet<Edge> edges;
+	/*
+	 * all edges of the graph
+	 */
+	private final static HashSet<Edge> edges = WorldView.edges;
+	
+	/*
+	 * all waypoints of the graph
+	 */
+	private final static HashSet<CustomWaypoint> waypoints = WorldView.waypoints;
+	
 
-	public CustomMapClickListener(JXMapViewer viewer, HashSet<CustomWaypoint> waypoints, HashSet<Edge> edges) {
+	public CustomMapClickListener(JXMapViewer viewer) {
 		super(viewer);
 
 		this.viewer = viewer;
-		this.nodePositions = waypoints;
-		CustomMapClickListener.edges = edges;
 
 	}
 
@@ -40,7 +53,7 @@ public class CustomMapClickListener extends MapClickListener {
 		// a waypoint was clicked
 		Boolean wayPointSelected = false;
 
-		for (CustomWaypoint nodeWaypoint : this.nodePositions) {
+		for (CustomWaypoint nodeWaypoint : CustomMapClickListener.waypoints) {
 			// transform GeoPosition to point on screen
 			nodePoint = this.viewer.getTileFactory().geoToPixel(nodeWaypoint.getPosition(), this.viewer.getZoom());
 
@@ -64,8 +77,8 @@ public class CustomMapClickListener extends MapClickListener {
 
 				// deselect old waypoint and select new clicked waypoint
 				deselectAll();
-				selected = nodeWaypoint;
 				nodeWaypoint.select();
+				selected = nodeWaypoint;
 				viewer.repaint();
 				break;
 			}
@@ -111,8 +124,10 @@ public class CustomMapClickListener extends MapClickListener {
 	 * deselect all edges and the selected node
 	 */
 	public static void deselectAll() {
-		if (selected != null)
+		if (selected != null){
 			selected.deselect();
+			selected = null;
+		}
 		for (Edge edge : edges) {
 			edge.changeAttribute("ui.map.selected", false);
 		}

+ 12 - 1
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/CustomWaypoint.java

@@ -15,21 +15,24 @@ public class CustomWaypoint extends DefaultWaypoint {
 	private final String label;
 	private final URL resource;
 	private final String nodeID;
+	private final String deviceType;
 
 	private Boolean isSelected = false;
 
 	/**
 	 * @param label
 	 *            the text
+	 * @param deviceType 
 	 * @param color
 	 *            the color
 	 * @param coord
 	 *            the coordinate
 	 */
-	public CustomWaypoint(String label, String nodeID, URL resource, GeoPosition coord) {
+	public CustomWaypoint(String label, String nodeID, URL resource, String deviceType, GeoPosition coord) {
 		super(coord);
 		this.label = label;
 		this.resource = resource;
+		this.deviceType = deviceType;
 		this.nodeID = nodeID;
 	}
 
@@ -54,6 +57,14 @@ public class CustomWaypoint extends DefaultWaypoint {
 	public String getNodeID() {
 		return nodeID;
 	}
+	
+	/**
+	 * 
+	 * @return the device type 
+	 */
+	public String getDeviceType() {
+		return deviceType;
+	}
 
 	/**
 	 * change isSelected value to true

+ 15 - 20
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/CustomWaypointRenderer.java

@@ -23,40 +23,35 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 
 	private Boolean showLabels = true;
 
-	private static final Color STANDARD = Color.BLACK;
+	public static final Color STANDARD = Color.BLACK;
 
-	private static final Color CLICKED = Color.RED;
+	public static final Color CLICKED = Color.RED;
 
-	private static final int ALPHA = 255;
+	public static final int ALPHA = 255;
+	
+	public static final int SCALEWIDTH = 60;
+	
+	public static final int SCALEHEIGHT = 60;
 
 	@Override
 	public void paintWaypoint(Graphics2D g, JXMapViewer viewer, CustomWaypoint w) {
 
 		g = (Graphics2D) g.create();
-		BufferedImage origImage = null;
+	
+		// get pre loaded image
+		BufferedImage loadedImg = MapViewFunctions.imageMap.get(w.getDeviceType());
 
-		try {
-			origImage = ImageIO.read(w.getResource());
-			if (w.getIsSelected()) {
-				origImage = MapViewFunctions.colorImage(origImage, STANDARD, CLICKED, ALPHA);
-			}
-		} catch (Exception ex) {
-			log.warn("couldn't read Waypoint png", ex);
+		if (w.getIsSelected()) {
+			loadedImg = MapViewFunctions.colorImage(loadedImg, CustomWaypointRenderer.STANDARD, CustomWaypointRenderer.CLICKED, CustomWaypointRenderer.ALPHA);
 		}
-
-		if (origImage == null)
-			return;
-
-		// scale image down
-		BufferedImage myImg = MapViewFunctions.scaleImage(origImage, 60, 60);
-
+		
 		// get waypoint position
 		Point2D point = viewer.getTileFactory().geoToPixel(w.getPosition(), viewer.getZoom());
 
 		int x = (int) point.getX();
 		int y = (int) point.getY();
 
-		g.drawImage(myImg, x - myImg.getWidth() / 2, y - myImg.getHeight(), null);
+		g.drawImage(loadedImg, x - loadedImg.getWidth() / 2, y - loadedImg.getHeight(), null);
 
 		if (showLabels) {
 
@@ -76,7 +71,7 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 
 			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 			// Show label left middle of deviceType picture
-			g.drawString(label, x - myImg.getWidth() / 2 - tw - 5, y + th / 2 - myImg.getHeight() / 2);
+			g.drawString(label, x - loadedImg.getWidth() / 2 - tw - 5, y + th / 2 - loadedImg.getHeight() / 2);
 
 			g.dispose();
 		}

+ 68 - 6
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/MapViewFunctions.java

@@ -4,8 +4,13 @@ import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 import java.net.URL;
+import java.util.HashMap;
 import java.util.HashSet;
 
+import javax.imageio.ImageIO;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.graphstream.graph.Edge;
 import org.graphstream.graph.Node;
 import org.jxmapviewer.JXMapViewer;
@@ -17,19 +22,67 @@ import org.jxmapviewer.viewer.GeoPosition;
 import org.jxmapviewer.viewer.TileFactoryInfo;
 import org.jxmapviewer.viewer.WaypointPainter;
 
+import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
 import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphManager;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.main.MainApp;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
 
 public final class MapViewFunctions {
 
+	private static final Log log = LogFactory.getLog(MapViewFunctions.class);
+	
+	// Hash map to save, scaled images
+	public static HashMap<String, BufferedImage> imageMap = new HashMap<String, BufferedImage>(WorldView.waypoints.size());
+	
 	/**
 	 * private constructor to avoid instantiation
 	 */
 	private MapViewFunctions() {
 
 	}
+	
+	/**
+	 * resets the hash map with the pictures
+	 */
+	public static void resetImageMap(){
+		imageMap = new HashMap<String, BufferedImage>(WorldView.waypoints.size());
+	}
+	
+	/**
+	 * load and scale waypoint images and save them in a HashMap
+	 */
+	public static void initializeWaypointImages(){
+		
+		for(CustomWaypoint w : WorldView.waypoints){
+		
+			BufferedImage origImage = null;
+
+			// image not loaded
+			if(!imageMap.containsKey(w.getDeviceType())){
+				
+				// try load image
+				try {
+					origImage = ImageIO.read(w.getResource());
+					
+				} catch (Exception ex) {
+					log.warn("couldn't read Waypoint png", ex);
+				}
+				
+				// loading complete
+				if (origImage != null) {	
+					// scale image down
+					BufferedImage myImg = MapViewFunctions.scaleImage(origImage, CustomWaypointRenderer.SCALEWIDTH, CustomWaypointRenderer.SCALEHEIGHT);
+					
+					// save image in hash map
+					imageMap.put(w.getDeviceType(), myImg);
+				}
+			}
+			
+		}
+
+	}
 
 	/**
 	 * Scale a given BufferedImage down to given width w and given height h
@@ -64,18 +117,20 @@ public final class MapViewFunctions {
 	public static BufferedImage colorImage(BufferedImage image, Color toChange, Color changeWith, int alpha) {
 		int width = image.getWidth();
 		int height = image.getHeight();
+		
+		BufferedImage imgOut = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
 
 		for (int xx = 0; xx < width; xx++) {
 			for (int yy = 0; yy < height; yy++) {
 				Color originalColor = new Color(image.getRGB(xx, yy), true);
 
-				// Pixel is Black -> paint it Red
+				// pixel needs to be changed
 				if (originalColor.equals(toChange) && originalColor.getAlpha() == alpha) {
-					image.setRGB(xx, yy, changeWith.getRGB());
+					imgOut.setRGB(xx, yy, changeWith.getRGB());
 				}
 			}
 		}
-		return image;
+		return imgOut;
 	}
 
 	/**
@@ -111,13 +166,20 @@ public final class MapViewFunctions {
 
 				// Create waypoints with device type dependent pictures
 				String deviceType = (String) node.getAttribute("typeofDevice");
-				URL resource = getDeviceType(deviceType);
+				URL resource = getDeviceTypeURL(deviceType);
 
 				// create a new waypoint with the node information
-				waypoints.add(new CustomWaypoint(node.getAttribute("ui.label"), node.getId(), resource, geoPos));
+				waypoints.add(new CustomWaypoint(node.getAttribute("ui.label"), node.getId(), resource, deviceType, geoPos));
 
 			}
 		}
+		
+		// deselect all previously clicked waypoints or edges
+		PropertiesManager.showNewDataSet(null);
+		
+		// load and save waypoint images
+		MapViewFunctions.initializeWaypointImages();
+		
 	}
 
 	/**
@@ -126,7 +188,7 @@ public final class MapViewFunctions {
 	 * @param deviceType
 	 * @return
 	 */
-	public static URL getDeviceType(String deviceType) {
+	public static URL getDeviceTypeURL(String deviceType) {
 
 		URL image = MainApp.class.getResource("/png/symbol_icons/" + deviceType + ".png");
 

+ 15 - 5
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/WorldView.java

@@ -37,7 +37,17 @@ public class WorldView {
 	 * GUIController with UI elements
 	 */
 	public static GUIController controller;
+	
+	/*
+	 * All waypoints in the WorldView
+	 */
+	public static HashSet<CustomWaypoint> waypoints;
 
+	/*
+	 * All edges in the WorldView
+	 */
+	public static HashSet<Edge> edges;
+	
 	/**
 	 * private constructor to avoid instantiation
 	 */
@@ -61,8 +71,8 @@ public class WorldView {
 	public static void loadWorldView() {
 
 		HashSet<GeoPosition> nodePositions = new HashSet<GeoPosition>();
-		HashSet<CustomWaypoint> waypoints = new HashSet<CustomWaypoint>();
-		HashSet<Edge> edges = new HashSet<Edge>();
+		waypoints = new HashSet<CustomWaypoint>();
+		edges = new HashSet<Edge>();
 
 		// Get GeoPositions of nodes and get all waypoints created
 		MapViewFunctions.fetchGraphData(nodePositions, waypoints, edges);
@@ -77,8 +87,8 @@ public class WorldView {
 
 		// Create a compound painter that uses all painters
 		List<Painter<JXMapViewer>> painters = new ArrayList<Painter<JXMapViewer>>();
-		painters.add(waypointPainter);
 		painters.add(edgePainter);
+		painters.add(waypointPainter);
 
 		CompoundPainter<JXMapViewer> painter = new CompoundPainter<JXMapViewer>(painters);
 
@@ -96,8 +106,8 @@ public class WorldView {
 		internMapViewer.setOverlayPainter(painter);
 
 		// "click on waypoints" listener
-		internMapViewer.addMouseListener(new CustomMapClickListener(internMapViewer, waypoints, edges));
-
+		internMapViewer.addMouseListener(new CustomMapClickListener(internMapViewer));
+		
 		internMapViewer.repaint();
 	}