|
@@ -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());
|