Selaa lähdekoodia

Adds expanding/collapsing functionalities

Andreas T. Meyer-Berg 6 vuotta sitten
vanhempi
commit
fcac85b7fd

+ 17 - 4
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/NetworkTreeSettings.java

@@ -2,6 +2,10 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration;
 
 import java.util.HashMap;
 
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+
 /**
  * Settings of the Network Tree and contains the settings for each node
  *
@@ -28,11 +32,20 @@ public class NetworkTreeSettings {
 	 */
 	public NetworkTreeNodeStatus getStatusOfObject(Object o){
 		NetworkTreeNodeStatus ret = map.get(o);
-		if(ret == null){
-			ret = new NetworkTreeNodeStatus(o);
-			map.put(o, ret);
+		if(o instanceof Link || o instanceof Connection || o instanceof SmartDevice || o instanceof String){
+			if(ret == null){
+				/**
+				 * if no status stored -> create and return new one
+				 */
+				ret = new NetworkTreeNodeStatus(o);
+				map.put(o, ret);
+			}
+			return ret;
 		}
-		return ret;
+		/**
+		 * Error for simple debug - should be
+		 */
+		throw new Error("Invalid Object in Tree: "+o);
 	}
 	
 	/**

+ 135 - 17
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/NetworkTreePanel.java

@@ -15,10 +15,13 @@ import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.JTree;
 import javax.swing.SwingUtilities;
+import javax.swing.event.TreeExpansionEvent;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeWillExpandListener;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.ExpandVetoException;
 import javax.swing.tree.TreePath;
 
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
@@ -27,6 +30,8 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.NetworkTreeNodeStatus;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.NetworkTreeSettings;
 
 /**
  * Network Tree Panel which visualizes the Network as a Tree
@@ -58,6 +63,10 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 	 * Reference to this for anonymous listener
 	 */
 	private NetworkTreePanel that;
+	/**
+	 * NetworkTreeSettings
+	 */
+	private NetworkTreeSettings networkTreeSettings;
 	/**
 	 * Network Controller
 	 */
@@ -86,6 +95,11 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 	 */
 	private Object clickedObject;
 	
+	/**
+	 * Mutex to prevent listeners from activating which building the JTree. If true, all listeners should not activate.
+	 */
+	private boolean mutexTreeUpdate = false;
+	
 	/**
 	 * Creates a new Network Tree Panel
 	 * 
@@ -99,6 +113,7 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 		this.parent = parent;
 		this.controller = controller;
 		network = this.controller.getNetworkController();
+		networkTreeSettings = controller.getSettingsController().getConfigurationManager().getNetworkTreeSettings();
 		tree = new JTree();
 		initializeRightClickMenu();
 
@@ -113,7 +128,8 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 		tree.addTreeSelectionListener(new TreeSelectionListener() {
 			@Override
 			public void valueChanged(TreeSelectionEvent e) {
-				System.out.println("Path selected" + e.getPath());
+				if(mutexTreeUpdate)return;
+				//System.out.println("Path selected" + e.getPath());
 			}
 		});
 
@@ -124,11 +140,70 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 
 			@Override
 			public void mouseClicked(MouseEvent e) {
+				if(mutexTreeUpdate)return;
+				
 				TreePath clicked = tree.getPathForLocation(e.getX(), e.getY());
-				System.out.println("Click on tree: " + clicked);
-
+				//Expand/Collapse
+				/*
+				if(SwingUtilities.isLeftMouseButton(e)&&e.getClickCount()==2&&clicked!=null&&clicked.getLastPathComponent()!=null){
+					//Collapse/expand
+					
+					NetworkTreeNodeStatus status = networkTreeSettings.getStatusOfObject(((DefaultMutableTreeNode)clicked.getLastPathComponent()).getUserObject());
+					System.out.println("Object: "+status.getNodeObject());
+					System.out.println("expanded: "+status.isExpanded());
+					status.setExpanded(!status.isExpanded());
+					controller.notifyObservers();
+				}*/
 				showRightClickMenu(e, clicked);
 				
+				
+			}
+		});
+		
+		/**
+		 * Tree expand/collapse Listener
+		 */
+		tree.addTreeWillExpandListener(new TreeWillExpandListener() {
+			
+			@Override
+			public void treeWillExpand(TreeExpansionEvent event)
+					throws ExpandVetoException {
+				// TODO Auto-generated method stub
+				TreePath clicked = event.getPath();
+				/*
+				System.out.println("Expand");
+				System.out.println("Source: "+event.getSource());
+				System.out.println("Path: "+event.getPath());*/
+				if(mutexTreeUpdate || event == null || event.getPath() == null || event.getPath().getLastPathComponent()==null)
+					return;
+				/**
+				 * Expand node
+				 */
+				NetworkTreeNodeStatus status = networkTreeSettings.getStatusOfObject(((DefaultMutableTreeNode)clicked.getLastPathComponent()).getUserObject());
+				status.setExpanded(true);
+				controller.notifyObservers();
+				
+			}
+			
+			@Override
+			public void treeWillCollapse(TreeExpansionEvent event)
+					throws ExpandVetoException {
+				//System.out.println(event.getPath().getLastPathComponent());
+				TreePath clicked = event.getPath();
+				/*
+				System.out.println("Collapse");
+				System.out.println("Source: "+event.getSource());
+				System.out.println("Path: "+event.getPath());*/
+				// TODO Auto-generated method stub
+				if(mutexTreeUpdate || event == null || event.getPath() == null || event.getPath().getLastPathComponent()==null)
+					return;
+				/**
+				 * Collapse the node
+				 */
+				NetworkTreeNodeStatus status = networkTreeSettings.getStatusOfObject(((DefaultMutableTreeNode)clicked.getLastPathComponent()).getUserObject());
+				status.setExpanded(false);
+				controller.notifyObservers();
+				
 			}
 		});
 		this.setViewportView(tree);
@@ -160,28 +235,64 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 
 	@Override
 	public void update(Observable o, Object arg) {
+		mutexTreeUpdate = true;
+		/**
+		 * Current row inside the JTree. Just nodes which are visible are counted as JTree rows, so all Nodes which are inside collapsed Nodes are skipped.
+		 */
+		int row = 1;
+		/**
+		 * Indices of Rows which should be expanded
+		 */
+		LinkedList<Integer> expandedRows = new LinkedList<Integer>();
+		
 		root = new DefaultMutableTreeNode("Network");
+			
+		/**
+		 * Counter for the rows in the tree autoExpand the expanded ones
+		 */
 		for (Link l : network.getLinks()) {
-			if (l == null)
+			if (l == null){
 				System.err.println("Warning: link = null in NetworkTreePanel");
+				continue;
+			}
+			
+			NetworkTreeNodeStatus linkStatus = networkTreeSettings.getStatusOfObject(l);
 			DefaultMutableTreeNode link = new DefaultMutableTreeNode(l);
+			root.add(link);
+			if(linkStatus.isExpanded())
+				expandedRows.add(row++);
+			else
+				row++;
+			
+			
 			for (Connection con : network.getConnections()) {
-				if (!l.getConnections().contains(con))
+				if (con == null || !l.getConnections().contains(con))
 					continue;
-				DefaultMutableTreeNode connection = new DefaultMutableTreeNode(
-						con);
+				DefaultMutableTreeNode connection = new DefaultMutableTreeNode(con);
+				NetworkTreeNodeStatus connectionStatus = networkTreeSettings.getStatusOfObject(con);
+				link.add(connection);
+				if(linkStatus.isExpanded()){
+					if(connectionStatus.isExpanded())
+						expandedRows.add(row++);
+					else
+						row++;
+				}
+				
 				for (Port p : con.getParticipants()) {
-					if (!l.getDevices().contains(p.getOwner())
+					if (p == null || !l.getDevices().contains(p.getOwner())
 							|| !con.getParticipants().contains(p))
 						continue;
 					DefaultMutableTreeNode port = new DefaultMutableTreeNode(
 							p.getOwner());
 					connection.add(port);
+					@SuppressWarnings("unused")//Later Hidden/Visible representation
+					NetworkTreeNodeStatus deviceStatus = networkTreeSettings.getStatusOfObject(p.getOwner());
+					// Leafs should not be expanded
+					if(linkStatus.isExpanded()&&connectionStatus.isExpanded())
+						row++;
 
 				}
-				link.add(connection);
 			}
-			root.add(link);
 		}
 		/**
 		 * Add devices without link to the network view
@@ -201,13 +312,26 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 		}
 		DefaultTreeModel model = new DefaultTreeModel(root);
 		tree.setModel(model);
+		expandTree(expandedRows);
 		/**
 		 * Repaint
 		 */
 		tree.repaint();
-
+		mutexTreeUpdate = false;
 	}
 	
+	/**
+	 * Expands the tree, as specified in the NetworkTreeSettingsController
+	 */
+	private void expandTree(LinkedList<Integer> expandedRows) {
+		tree.expandRow(0);
+		for(Integer i:expandedRows)
+			tree.expandRow(i);
+	}
+
+
+
+
 	/**
 	 * Initializes the rightClickMenu
 	 */
@@ -269,27 +393,21 @@ public class NetworkTreePanel extends JScrollPane implements Observer {
 				mntmEdit.setEnabled(true);
 				mntmDelete.setText("Delete Device");
 				mntmDelete.setEnabled(true);
-				System.out.println("Clicked SmartDevice");
-				if(clickedObject instanceof SmartDevice) System.out.println(((SmartDevice)clickedObject).getName());
 			} else if(clickedObject instanceof Connection){
 				mntmEdit.setText("Edit Connection");
 				mntmEdit.setEnabled(true);
 				mntmDelete.setText("Delete Connection");
 				mntmDelete.setEnabled(true);
-				System.out.println("Clicked Connection");
 			}else if(clickedObject instanceof Link){
 				mntmEdit.setText("Edit Link");
 				mntmEdit.setEnabled(true);
 				mntmDelete.setText("Delete Link");
 				mntmDelete.setEnabled(true);
-				System.out.println("Clicked Link");
 			}else{
 				mntmEdit.setText("Edit");
 				mntmEdit.setEnabled(false);
 				mntmDelete.setText("Delete");
 				mntmDelete.setEnabled(false);
-				
-				System.out.println("Clicked unknown: "+clickedObject.getClass().getSimpleName());
 			}
 			
 			rightClick.show(this,e.getX(), e.getY());