Outliner.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package holeg.ui.view.window;
  2. import holeg.model.AbstractCanvasObject;
  3. import holeg.model.GroupNode;
  4. import holeg.model.Holon;
  5. import holeg.model.HolonObject;
  6. import holeg.preferences.ColorPreference;
  7. import holeg.preferences.ImagePreference;
  8. import holeg.ui.controller.Control;
  9. import holeg.ui.view.image.Import;
  10. import holeg.utility.listener.WindowClosingListener;
  11. import holeg.utility.math.decimal.Format;
  12. import java.awt.BorderLayout;
  13. import java.awt.Color;
  14. import java.util.logging.Logger;
  15. import java.util.stream.Stream;
  16. import javax.swing.ImageIcon;
  17. import javax.swing.JFrame;
  18. import javax.swing.JPanel;
  19. import javax.swing.JScrollPane;
  20. import javax.swing.JTabbedPane;
  21. import javax.swing.JTree;
  22. import javax.swing.tree.DefaultMutableTreeNode;
  23. import javax.swing.tree.DefaultTreeCellRenderer;
  24. /**
  25. * This is a class to get an overview over each HolonObject on the canvas.
  26. */
  27. public class Outliner extends JFrame {
  28. private static final Logger log = Logger.getLogger(Outliner.class.getName());
  29. private static final String ConsumptionFontHTMLBracket = "<font bgcolor='#"
  30. + Integer.toHexString(ColorPreference.Energy.Consumption.getRGB()).substring(2) + "'>";
  31. private static final String ProductionFontHTMLBracket = "<font bgcolor='#"
  32. + Integer.toHexString(ColorPreference.Energy.Production.getRGB()).substring(2) + "'>";
  33. private static final String FontClosingBracket = "</font> ";
  34. private static final String ProducerNodeText = getColoredHtmlText(
  35. ColorPreference.HolonObject.Producer, "Producer");
  36. private static final String OverSuppliedNodeText = getColoredHtmlText(
  37. ColorPreference.HolonObject.OverSupplied, "Over supplied");
  38. private static final String SuppliedNodeText = getColoredHtmlText(
  39. ColorPreference.HolonObject.Supplied, "Supplied");
  40. private static final String PartiallySuppliedNodeText = getColoredHtmlText(
  41. ColorPreference.HolonObject.PartiallySupplied, "Partially supplied");
  42. private static final String NotSuppliedNodeText = getColoredHtmlText(
  43. ColorPreference.HolonObject.NotSupplied, "Not supplied");
  44. private static final String NoEnergyNodeText = getColoredHtmlText(
  45. ColorPreference.HolonObject.NoEnergy, "No energy");
  46. private final Control control;
  47. private final JPanel hierarchyPanel = new JPanel(new BorderLayout());
  48. private final JPanel holonPanel = new JPanel(new BorderLayout());
  49. private final Runnable update = this::update;
  50. public Outliner(JFrame parentFrame, Control control) {
  51. setBounds(0, 0, 400, parentFrame.getHeight());
  52. this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
  53. this.setTitle("Outliner");
  54. setLocationRelativeTo(parentFrame);
  55. this.setVisible(true);
  56. this.control = control;
  57. update();
  58. JTabbedPane tabbedPane = new JTabbedPane();
  59. this.getContentPane().add(tabbedPane);
  60. this.addWindowListener(
  61. (WindowClosingListener) e -> control.OnCanvasUpdate.removeListener(update));
  62. control.OnCanvasUpdate.addListener(update);
  63. tabbedPane.addTab("Hierarchy", hierarchyPanel);
  64. tabbedPane.addTab("Holons", holonPanel);
  65. }
  66. /**
  67. * Pads a text with a color html.
  68. * @param color a color
  69. * @param text a text
  70. * @return the padded text
  71. */
  72. private static String getColoredHtmlText(Color color, String text) {
  73. return "<html><font bgcolor='#"
  74. + Integer.toHexString(color.getRGB()).substring(2) + "'>" +
  75. text + FontClosingBracket;
  76. }
  77. /**
  78. * Updates the outliner after changes to represent the new changes.
  79. */
  80. private void update() {
  81. hierarchyPanel.removeAll();
  82. holonPanel.removeAll();
  83. DefaultMutableTreeNode topListPanel = new DefaultMutableTreeNode();
  84. DefaultMutableTreeNode objects = new DefaultMutableTreeNode("HolonObjects");
  85. DefaultMutableTreeNode switches = new DefaultMutableTreeNode("Switches");
  86. DefaultMutableTreeNode nodes = new DefaultMutableTreeNode("Nodes");
  87. DefaultMutableTreeNode cables = new DefaultMutableTreeNode("Cable");
  88. topListPanel.add(objects);
  89. topListPanel.add(switches);
  90. topListPanel.add(nodes);
  91. topListPanel.add(cables);
  92. DefaultMutableTreeNode topHolonNode = createHolonNode();
  93. DefaultMutableTreeNode topHierarchyNode = createHierarchyNode();
  94. JTree hierarchyTree = new JTree(topHierarchyNode);
  95. signIconsForTree(hierarchyTree);
  96. hierarchyTree.setRootVisible(false);
  97. for (int i = 0; i < hierarchyTree.getRowCount(); i++) {
  98. hierarchyTree.expandRow(i);
  99. }
  100. hierarchyPanel.add(new JScrollPane(hierarchyTree));
  101. JTree holonTree = new JTree(topHolonNode);
  102. signIconsForTree(holonTree);
  103. holonTree.setRootVisible(false);
  104. for (int i = 0; i < holonTree.getRowCount(); i++) {
  105. holonTree.expandRow(i);
  106. }
  107. holonPanel.add(new JScrollPane(holonTree));
  108. holonPanel.revalidate();
  109. hierarchyPanel.repaint();
  110. }
  111. /**
  112. * Init of the HolonNode
  113. * @return the HolonNode
  114. */
  115. private DefaultMutableTreeNode createHolonNode() {
  116. DefaultMutableTreeNode topHolonNode = new DefaultMutableTreeNode();
  117. for (Holon holon : control.getModel().holons) {
  118. DefaultMutableTreeNode holonNode = new DefaultMutableTreeNode("Holon");
  119. DefaultMutableTreeNode producer = new DefaultMutableTreeNode(ProducerNodeText);
  120. DefaultMutableTreeNode overSupplied = new DefaultMutableTreeNode(OverSuppliedNodeText);
  121. DefaultMutableTreeNode supplied = new DefaultMutableTreeNode(SuppliedNodeText);
  122. DefaultMutableTreeNode partiallySupplied = new DefaultMutableTreeNode(
  123. PartiallySuppliedNodeText);
  124. DefaultMutableTreeNode notSupplied = new DefaultMutableTreeNode(NotSuppliedNodeText);
  125. DefaultMutableTreeNode noEnergy = new DefaultMutableTreeNode(NoEnergyNodeText);
  126. for (HolonObject hObject : holon.holonObjects) {
  127. DefaultMutableTreeNode holonObjectNode = createColoredTreeNodeFromHolonObject(hObject);
  128. switch (hObject.getState()) {
  129. case PRODUCER -> producer.add(holonObjectNode);
  130. case OVER_SUPPLIED -> overSupplied.add(holonObjectNode);
  131. case SUPPLIED -> supplied.add(holonObjectNode);
  132. case PARTIALLY_SUPPLIED -> partiallySupplied.add(holonObjectNode);
  133. case NOT_SUPPLIED -> notSupplied.add(holonObjectNode);
  134. case NO_ENERGY -> noEnergy.add(holonObjectNode);
  135. }
  136. }
  137. Stream.of(producer, overSupplied, supplied, partiallySupplied, notSupplied, noEnergy)
  138. .filter(node -> !node.isLeaf()).forEach(holonNode::add);
  139. topHolonNode.add(holonNode);
  140. }
  141. return topHolonNode;
  142. }
  143. /**
  144. * Init of the HierarchyNode
  145. * @return the HierarchyNode
  146. */
  147. private DefaultMutableTreeNode createHierarchyNode() {
  148. DefaultMutableTreeNode hierarchyNode = new DefaultMutableTreeNode();
  149. hierarchyNode.add(getNodeFromGroupNode(control.getModel().getCanvas()));
  150. DefaultMutableTreeNode edgeNode = new DefaultMutableTreeNode("Edges");
  151. control.getModel().getEdgesOnCanvas().forEach(edge -> {
  152. edgeNode.add(new DefaultMutableTreeNode(edge.toString()));
  153. });
  154. hierarchyNode.add(edgeNode);
  155. return hierarchyNode;
  156. }
  157. /**
  158. * Constructs a node from a groupNode.
  159. * @param groupNode the groupNode
  160. * @return a tree node
  161. */
  162. private DefaultMutableTreeNode getNodeFromGroupNode(GroupNode groupNode) {
  163. DefaultMutableTreeNode node = new DefaultMutableTreeNode(groupNode.getName());
  164. groupNode.getHolonObjects().forEach(obj -> node.add(canvasObjectToNode(obj)));
  165. groupNode.getSwitches().forEach(obj -> node.add(canvasObjectToNode(obj)));
  166. groupNode.getNodes().forEach(obj -> node.add(canvasObjectToNode(obj)));
  167. groupNode.getGroupNodes().forEach(obj -> node.add(getNodeFromGroupNode(obj)));
  168. return node;
  169. }
  170. /**
  171. * Constructs a node from a canvas object.
  172. * @param obj a canvas object
  173. * @return a tree node
  174. */
  175. private DefaultMutableTreeNode canvasObjectToNode(AbstractCanvasObject obj) {
  176. return new DefaultMutableTreeNode(obj.getName() + " [" + obj.getId() + "]");
  177. }
  178. /**
  179. * Updates the appearance of a JTree.
  180. * @param t a JTree
  181. */
  182. private void signIconsForTree(JTree t) {
  183. ImageIcon ClosedIcon = new ImageIcon(
  184. Import.loadImage(ImagePreference.Button.Outliner.Closed, 9, 9));
  185. ImageIcon OpenIcon = new ImageIcon(
  186. Import.loadImage(ImagePreference.Button.Outliner.Open, 9, 9));
  187. ImageIcon LeafIcon = new ImageIcon(
  188. Import.loadImage(ImagePreference.Button.Outliner.Leaf, 9, 9));
  189. DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  190. renderer.setClosedIcon(ClosedIcon);
  191. renderer.setOpenIcon(OpenIcon);
  192. renderer.setLeafIcon(LeafIcon);
  193. t.setCellRenderer(renderer);
  194. }
  195. /**
  196. * Create a colored node from a HolonObject.
  197. * @param obj a holonObject
  198. * @return the colored node
  199. */
  200. private DefaultMutableTreeNode createColoredTreeNodeFromHolonObject(HolonObject obj) {
  201. float energy = obj.getActualEnergy();
  202. String context = "<html>" + obj.getName() + "&nbsp;&nbsp;&nbsp;&nbsp;"
  203. + (obj.isConsumer() ? ConsumptionFontHTMLBracket : ProductionFontHTMLBracket)
  204. + Format.doubleTwoPlaces(energy) + FontClosingBracket
  205. + "</html>";
  206. return new DefaultMutableTreeNode(context);
  207. }
  208. }