Inspector.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package ui.view.inspector;
  2. import java.awt.BorderLayout;
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.Dimension;
  6. import java.awt.event.ItemEvent;
  7. import java.util.Set;
  8. import java.util.stream.Collectors;
  9. import javax.swing.Box;
  10. import javax.swing.GrayFilter;
  11. import javax.swing.ImageIcon;
  12. import javax.swing.JButton;
  13. import javax.swing.JComboBox;
  14. import javax.swing.JLabel;
  15. import javax.swing.JOptionPane;
  16. import javax.swing.JPanel;
  17. import javax.swing.JScrollPane;
  18. import javax.swing.JSplitPane;
  19. import javax.swing.JToolBar;
  20. import classes.HolonElement;
  21. import classes.HolonSwitch;
  22. import interfaces.TimelineDependent;
  23. import ui.controller.Control;
  24. import utility.FormatFloat;
  25. import utility.ImageImport;
  26. import utility.Maths;
  27. import utility.listener.ResizeListener;
  28. public class Inspector extends JSplitPane {
  29. private final UnitGraph unitGraph;
  30. private final InspectorTable table;
  31. private final Control control;
  32. private final JPanel scrollGraph = new JPanel();
  33. private final JPanel graphLabel = new JPanel();
  34. private final JLabel maxGraph = new JLabel("100%");
  35. private final JLabel medGraph = new JLabel("50%");
  36. private final JLabel minGraph = new JLabel("0%");
  37. private final JPanel globalCurveLabel = new JPanel();
  38. private final JLabel minEnergy = new JLabel("0.0");
  39. private final JLabel maxEnergy = new JLabel("0.0");
  40. private final JLabel zeroEnergy = new JLabel("0.0");
  41. private final JToolBar toolBarGraph = new JToolBar();
  42. private String[] comboContext = { "", "5", "10", "20", "100", "1000" };
  43. private JComboBox<String> localPeriodInput = new JComboBox<String>(comboContext);
  44. private JButton resetButton = new JButton("", new ImageIcon(ImageImport.loadImage("/Images/resetIcon3.png")));
  45. private final ImageIcon localPeriodButtonImageEnabled = new ImageIcon(ImageImport.loadImage("/Images/Graph.png"));
  46. private final ImageIcon localPeriodButtonImageDisabled = new ImageIcon(
  47. GrayFilter.createDisabledImage(ImageImport.loadImage("/Images/Graph.png")));
  48. private JButton localPeriodButton = new JButton("", localPeriodButtonImageEnabled);
  49. public Inspector(Control control) {
  50. this.control = control;
  51. table = new InspectorTable(control);
  52. unitGraph = new UnitGraph(control);
  53. table.OnElementSelectionChanged.addListener(this::updateUnitGraph);
  54. initUI();
  55. control.OnSelectionChanged.addListener(this::updateGlobalCurve);
  56. }
  57. private void initUI() {
  58. this.setOrientation(JSplitPane.VERTICAL_SPLIT);
  59. JScrollPane scrollPane = new JScrollPane(table);
  60. scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  61. this.setTopComponent(scrollPane);
  62. this.setBottomComponent(scrollGraph);
  63. this.setDividerLocation(550);
  64. scrollGraph.setLayout(new BorderLayout());
  65. scrollGraph.add(unitGraph, BorderLayout.CENTER);
  66. // Set up of the Properties section
  67. graphLabel.setLayout(new BorderLayout(0, 10));
  68. graphLabel.add(maxGraph, BorderLayout.NORTH);
  69. graphLabel.add(medGraph, BorderLayout.CENTER);
  70. graphLabel.add(minGraph, BorderLayout.SOUTH);
  71. globalCurveLabel.setLayout(null);
  72. globalCurveLabel.setMinimumSize(new Dimension(20, 0));
  73. globalCurveLabel.setPreferredSize(new Dimension(20, 0));
  74. maxEnergy.setForeground(Color.red);
  75. minEnergy.setForeground(Color.red);
  76. zeroEnergy.setForeground(Color.red);
  77. globalCurveLabel.add(maxEnergy);
  78. globalCurveLabel.add(zeroEnergy);
  79. globalCurveLabel.add(minEnergy);
  80. this.globalCurveLabel.addComponentListener((ResizeListener)resize -> updateGlobalCurve() );
  81. toolBarGraph.setFloatable(false);
  82. toolBarGraph.setAlignmentY(Component.RIGHT_ALIGNMENT);
  83. localPeriodButton.setToolTipText("Toggle Local/Global Mode");
  84. toolBarGraph.add(localPeriodButton);
  85. // ComboBox
  86. localPeriodInput.setEditable(true);
  87. localPeriodInput.setVisible(false);
  88. localPeriodInput.setMaximumSize(new Dimension(20, 23));
  89. localPeriodInput.addItemListener(aListener -> {
  90. if (aListener.getStateChange() == ItemEvent.DESELECTED) {
  91. validateInput(localPeriodInput.getEditor().getItem().toString(), true);
  92. }
  93. });
  94. toolBarGraph.add(localPeriodInput);
  95. // localPeriodButtonFunction
  96. localPeriodButton.addActionListener(actionEvent -> {
  97. boolean newState = !localPeriodInput.isVisible();
  98. changeLocalPeriodButtonAppeareance(newState);
  99. unitGraph.setUseLocalPeriod(newState);
  100. });
  101. toolBarGraph.add(Box.createHorizontalGlue());
  102. resetButton.setToolTipText("Reset");
  103. resetButton.addActionListener(actionEvent -> unitGraph.reset());
  104. toolBarGraph.add(resetButton);
  105. scrollGraph.add(graphLabel, BorderLayout.WEST);
  106. scrollGraph.add(globalCurveLabel, BorderLayout.EAST);
  107. scrollGraph.add(toolBarGraph, BorderLayout.NORTH);
  108. }
  109. /**
  110. * Validate the LocalMode Input and when its valid save on the Element.
  111. *
  112. * @param text the inputText to validate.
  113. * @param bShowMessage when true, open a MessageDialog when text invalid.
  114. */
  115. private void validateInput(String text, boolean bShowMessage) {
  116. int localPeriodInputValue;
  117. try {
  118. localPeriodInputValue = Integer.parseInt(text);
  119. } catch (NumberFormatException e) {
  120. if (bShowMessage)
  121. JOptionPane.showMessageDialog(null, '"' + text + '"' + " is not a valid Input. \n Use whole numbers.");
  122. return;
  123. }
  124. unitGraph.setLocalPeriod(localPeriodInputValue);
  125. }
  126. /**
  127. * This Method updates the UnitGraph, saves the old LocalModeState and load the
  128. * new LocalModeState.
  129. *
  130. * @param element The new Element to load the UnitGraph
  131. */
  132. private void updateUnitGraph(Set<HolonElement> elements) {
  133. // SaveOld LocalMode State.
  134. if (localPeriodInput.isVisible()) {
  135. // Save Old State
  136. validateInput(localPeriodInput.getEditor().getItem().toString(), false);
  137. }
  138. // Update UnitGraph
  139. unitGraph.clearSeries();
  140. for (TimelineDependent element : elements) {
  141. unitGraph.addNewSeries(element);
  142. }
  143. if (elements.isEmpty()) {
  144. control.getModel().getSelectedObjects().stream().filter(obj -> obj instanceof HolonSwitch)
  145. .forEach(obj -> unitGraph.addNewSeries((HolonSwitch) obj));
  146. }
  147. // if (elements.isEmpty()) {
  148. // this.setDividerLocation(1.0);
  149. // }
  150. // Load LocalMode State.
  151. changeLocalPeriodButtonAppeareance(unitGraph.isUsingLocalPeriod());
  152. localPeriodInput.getEditor()
  153. .setItem(unitGraph.isLocalPeriedDifferentInSeries() ? "-" : unitGraph.getFirstLocalPeriod());
  154. }
  155. private void updateGlobalCurve() {
  156. Set<HolonElement> elements = InspectorTable.extractElements(control.getModel().getSelectedObjects())
  157. .collect(Collectors.toSet());
  158. unitGraph.setGlobalCurve(elements);
  159. double maxEnergy = elements.stream().map(ele -> ele.getEnergy()).filter(energy -> energy > 0).reduce(0.0f,
  160. Float::sum);
  161. double minEnergy = elements.stream().map(ele -> ele.getEnergy()).filter(energy -> energy < 0).reduce(0.0f,
  162. Float::sum);
  163. double percentage = Maths.inverseLinearInterpolation(maxEnergy, minEnergy, 0.0);
  164. int widgetHeight = this.globalCurveLabel.getHeight();
  165. int textMiddle = this.zeroEnergy.getPreferredSize().height / 4;
  166. int zeroYPos = (int)(widgetHeight * percentage) - textMiddle;
  167. this.minEnergy.setText(FormatFloat.doubleTwoPlaces(minEnergy));
  168. this.maxEnergy.setText(FormatFloat.doubleTwoPlaces(maxEnergy));
  169. this.maxEnergy.setBounds(0, 0, this.maxEnergy.getPreferredSize().width,
  170. this.maxEnergy.getPreferredSize().height);
  171. this.minEnergy.setBounds(0, widgetHeight - this.minEnergy.getPreferredSize().height, this.minEnergy.getPreferredSize().width,
  172. this.minEnergy.getPreferredSize().height);
  173. this.zeroEnergy.setBounds(0, zeroYPos, this.zeroEnergy.getPreferredSize().width,
  174. this.zeroEnergy.getPreferredSize().height);
  175. this.globalCurveLabel.setPreferredSize(new Dimension(
  176. Math.max(this.zeroEnergy.getPreferredSize().width,
  177. Math.max(this.maxEnergy.getPreferredSize().width, this.minEnergy.getPreferredSize().width)),
  178. 0));
  179. }
  180. /**
  181. * Displayed the actual LocalModeState.
  182. *
  183. * @param enabled
  184. */
  185. private void changeLocalPeriodButtonAppeareance(boolean enabled) {
  186. localPeriodInput.setVisible(enabled);
  187. localPeriodButton.setIcon(enabled ? localPeriodButtonImageEnabled : localPeriodButtonImageDisabled);
  188. }
  189. }