FlexWindow.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. package holeg.ui.view.window;
  2. import holeg.model.Constrain;
  3. import holeg.model.Flexibility;
  4. import holeg.model.Flexibility.FlexState;
  5. import holeg.model.GroupNode;
  6. import holeg.model.HolonElement;
  7. import holeg.model.HolonElement.Priority;
  8. import holeg.model.HolonObject;
  9. import holeg.preferences.ColorPreference;
  10. import holeg.preferences.ImagePreference;
  11. import holeg.ui.controller.Control;
  12. import holeg.ui.view.image.Import;
  13. import holeg.utility.listener.WindowClosingListener;
  14. import java.awt.BorderLayout;
  15. import java.awt.Color;
  16. import java.awt.Component;
  17. import java.awt.Dialog.ModalityType;
  18. import java.awt.Dimension;
  19. import java.awt.FlowLayout;
  20. import java.awt.GridBagConstraints;
  21. import java.awt.GridBagLayout;
  22. import java.awt.Insets;
  23. import java.awt.Rectangle;
  24. import java.awt.event.ItemEvent;
  25. import java.awt.event.MouseAdapter;
  26. import java.awt.event.MouseEvent;
  27. import java.awt.image.BufferedImage;
  28. import java.math.RoundingMode;
  29. import java.text.NumberFormat;
  30. import java.util.List;
  31. import java.util.Locale;
  32. import java.util.Optional;
  33. import java.util.stream.Collectors;
  34. import javax.swing.BorderFactory;
  35. import javax.swing.Box;
  36. import javax.swing.BoxLayout;
  37. import javax.swing.DefaultComboBoxModel;
  38. import javax.swing.ImageIcon;
  39. import javax.swing.JButton;
  40. import javax.swing.JCheckBox;
  41. import javax.swing.JComboBox;
  42. import javax.swing.JDialog;
  43. import javax.swing.JFormattedTextField;
  44. import javax.swing.JFrame;
  45. import javax.swing.JLabel;
  46. import javax.swing.JMenu;
  47. import javax.swing.JMenuBar;
  48. import javax.swing.JMenuItem;
  49. import javax.swing.JOptionPane;
  50. import javax.swing.JPanel;
  51. import javax.swing.JPopupMenu;
  52. import javax.swing.JScrollPane;
  53. import javax.swing.JTabbedPane;
  54. import javax.swing.JTree;
  55. import javax.swing.SwingUtilities;
  56. import javax.swing.border.EmptyBorder;
  57. import javax.swing.text.NumberFormatter;
  58. import javax.swing.tree.DefaultMutableTreeNode;
  59. import javax.swing.tree.DefaultTreeModel;
  60. import javax.swing.tree.TreePath;
  61. /**
  62. * An overview for flexibilities in holeg, with basic manipulation of flexibilities.
  63. */
  64. public class FlexWindow extends JFrame {
  65. private final static int boxSideLength = 70;
  66. private final JTabbedPane contentPanel = new JTabbedPane();
  67. private final Control control;
  68. //Flexibility Intermediate
  69. private final Flexibility intermediateFlex = new Flexibility(null);
  70. private final JPopupMenu menu = new JPopupMenu();
  71. private final JMenuItem priorityItem = new JMenuItem("EditPriorities");
  72. private final JMenuItem flexItem = new JMenuItem("AddFlex");
  73. //Tabs
  74. String gridTabString = "Grid";
  75. String orderTabString = "Order";
  76. private JPanel nothingSelectedPanel;
  77. private JPanel selectedPanel;
  78. private JScrollPane usageViewPanel;
  79. private boolean offered = true, onConstrain = true, offConstrain = false;
  80. //JTree
  81. private DefaultMutableTreeNode listOfAllSelectedHolonObjects;
  82. private JTree stateTree;
  83. private DefaultTreeModel treeModel;
  84. Runnable update = this::update;
  85. /**
  86. * Construct the window.
  87. * @param parentFrame parent
  88. * @param control control
  89. */
  90. public FlexWindow(JFrame parentFrame, Control control) {
  91. this.intermediateFlex.name = "name";
  92. this.control = control;
  93. //InitWindow
  94. createMenuBar();
  95. initWindowPanel(parentFrame);
  96. this.addWindowListener(
  97. (WindowClosingListener) e -> control.OnCanvasUpdate.removeListener(update));
  98. updateSelectedPanel();
  99. control.OnCanvasUpdate.addListener(update);
  100. }
  101. /**
  102. * Init panel
  103. * @param parentFrame parent
  104. */
  105. private void initWindowPanel(JFrame parentFrame) {
  106. this.setBounds(0, 0, 400,
  107. parentFrame.getHeight() > 20 ? parentFrame.getHeight() - 20 : parentFrame.getHeight());
  108. this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
  109. this.setTitle("Flexibility");
  110. this.setLocationRelativeTo(parentFrame);
  111. this.setVisible(true);
  112. //this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  113. createNothingSelectedPanel();
  114. createSelectedPanel();
  115. createUsageViewPanel();
  116. contentPanel.addTab(gridTabString, nothingSelectedPanel);
  117. contentPanel.addTab(orderTabString, usageViewPanel);
  118. contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
  119. this.setContentPane(contentPanel);
  120. this.revalidate();
  121. }
  122. /**
  123. * Creates the menu bar of this frame.
  124. */
  125. private void createMenuBar() {
  126. JMenuBar menuBar = new JMenuBar();
  127. JMenu canvas = new JMenu("Canvas");
  128. menuBar.add(canvas);
  129. JMenuItem updateMenuItem = new JMenuItem("Update");
  130. updateMenuItem.addActionListener(clicked -> updateSelectedPanel());
  131. canvas.add(updateMenuItem);
  132. JMenu flex = new JMenu("Flex");
  133. menuBar.add(flex);
  134. JMenuItem addMenuItem = new JMenuItem("Add Flexibility");
  135. addMenuItem.addActionListener(clicked -> createAddDialog(null));
  136. flex.add(addMenuItem);
  137. JMenuItem deleteMenuItem = new JMenuItem("Delete Flexibility");
  138. deleteMenuItem.addActionListener(clicked -> createDeleteDialog());
  139. flex.add(deleteMenuItem);
  140. this.setJMenuBar(menuBar);
  141. }
  142. private void createUsageViewPanel() {
  143. JPanel panel = new JPanel(new GridBagLayout());
  144. usageViewPanel = new JScrollPane(panel);
  145. panel.setBackground(Color.white);
  146. FlexState[] titles = FlexState.values();
  147. for (int i = 0; i < 5; i++) {
  148. final int titleIndex = i;
  149. List<Flexibility> flexList = control.getModel().getAllFlexibilities();
  150. List<Flexibility> listOfFlexWithState = flexList.stream()
  151. .filter(flex -> flex.getState().equals(titles[titleIndex])).toList();
  152. JLabel label = new JLabel(titles[i].toString() + "[" + listOfFlexWithState.size() + "]");
  153. GridBagConstraints labelC = new GridBagConstraints();
  154. labelC.gridx = 1;
  155. labelC.gridy = i * 2;
  156. labelC.anchor = GridBagConstraints.LINE_START;
  157. labelC.fill = GridBagConstraints.HORIZONTAL;
  158. labelC.weightx = 0.5;
  159. labelC.weighty = 0.0;
  160. panel.add(label, labelC);
  161. JPanel listPanel = new JPanel(new GridBagLayout());
  162. createFlexPanel(listPanel, listOfFlexWithState);
  163. GridBagConstraints panelC = new GridBagConstraints();
  164. panelC.gridx = 0;
  165. panelC.gridwidth = 2;
  166. panelC.gridy = i * 2 + 1;
  167. panelC.fill = GridBagConstraints.BOTH;
  168. panel.add(listPanel, panelC);
  169. JButton expandButton = new JButton("-");
  170. GridBagConstraints buttonC = new GridBagConstraints();
  171. buttonC.gridx = 0;
  172. buttonC.gridy = i * 2;
  173. panel.add(expandButton, buttonC);
  174. expandButton.addActionListener(clicked -> {
  175. listPanel.setVisible(!listPanel.isVisible());
  176. expandButton.setText(listPanel.isVisible() ? "-" : "+");
  177. });
  178. }
  179. //Add Spacer
  180. JLabel spacer = new JLabel();
  181. GridBagConstraints c = new GridBagConstraints();
  182. c.gridx = 0;
  183. c.gridy = 5 * 2;
  184. c.fill = GridBagConstraints.VERTICAL;
  185. c.weightx = 0.0;
  186. c.weighty = 1;
  187. panel.add(spacer, c);
  188. }
  189. private void createFlexPanel(JPanel listPanel, List<Flexibility> flexList) {
  190. listPanel.setBackground(Color.white);
  191. Insets insets = new Insets(2, 2, 2, 2);
  192. int panelWidth = Math.max(boxSideLength, this.getWidth() - 90);
  193. int maxButtonsPerLine = panelWidth / boxSideLength;
  194. int i = 0;
  195. for (Flexibility flex : flexList) {
  196. GridBagConstraints c = new GridBagConstraints();
  197. c.gridx = Math.floorMod(i, maxButtonsPerLine);
  198. c.weightx = 0.0;
  199. c.insets = insets;
  200. JButton labelButton = new JButton(flex.name);
  201. labelButton.setPreferredSize(new Dimension(boxSideLength, boxSideLength));
  202. labelButton.setBorder(BorderFactory.createLineBorder(Color.black));
  203. listPanel.add(labelButton, c);
  204. labelButton.addActionListener(clicked -> {
  205. flex.order();
  206. control.calculateStateForCurrentIteration();
  207. });
  208. labelButton.setToolTipText(createToolTipText(flex));
  209. i++;
  210. }
  211. //AddSpacer
  212. JLabel spacer = new JLabel();
  213. GridBagConstraints c = new GridBagConstraints();
  214. c.gridx = maxButtonsPerLine;
  215. c.gridy = 0;
  216. c.fill = GridBagConstraints.VERTICAL;
  217. c.weightx = 1;
  218. c.weighty = 0;
  219. listPanel.add(spacer, c);
  220. }
  221. /**
  222. * Create a tooltip text for a flexibility.
  223. * @param actual flexibility
  224. * @return description
  225. */
  226. private String createToolTipText(Flexibility actual) {
  227. return "<html>" +
  228. "<b>" + actual.name + "( </b>" + actual.getElement().getName() + "<b> )</b><br>"
  229. + ((actual.remainingDuration() != 0) ? "<i>Remaining Duration:" + actual.remainingDuration()
  230. + "</i><br>" : "")
  231. + ((actual.remainingTimeTillActivation() != 0) ? "<i>Remaining TimeTillActivation:"
  232. + actual.remainingTimeTillActivation() + "</i><br>" : "")
  233. + "Duration: " + actual.getDuration() + "<br>"
  234. + "Cooldown: " + actual.getCooldown() + "<br>"
  235. + "Cost: " + actual.cost + "<br>"
  236. + "EnergyReleased: " + actual.energyReleased() + "<br>"
  237. + "Constrains: " + actual.constrainList.stream().map(Constrain::getName)
  238. .collect(Collectors.joining(",")) + "<br>"
  239. + "</html>";
  240. }
  241. /**
  242. * Updates the panel
  243. */
  244. private void update() {
  245. updateSelectedPanel();
  246. createUsageViewPanel();
  247. contentPanel.setComponentAt(contentPanel.indexOfTab(orderTabString), usageViewPanel);
  248. contentPanel.revalidate();
  249. }
  250. private void createSelectedPanel() {
  251. listOfAllSelectedHolonObjects = new DefaultMutableTreeNode("HolonObjects");
  252. treeModel = new DefaultTreeModel(listOfAllSelectedHolonObjects);
  253. stateTree = new JTree(treeModel);
  254. JPopupMenu menu = createPopUpMenu();
  255. stateTree.addMouseListener(new MouseAdapter() {
  256. public void mousePressed(MouseEvent e) {
  257. if (SwingUtilities.isRightMouseButton(e)) {
  258. TreePath pathUnderCursor = stateTree.getPathForLocation(e.getX(), e.getY());
  259. Rectangle pathBounds = stateTree.getUI().getPathBounds(stateTree, pathUnderCursor);
  260. if (pathBounds != null && pathBounds.contains(e.getX(), e.getY())) {
  261. TreePath[] selectedPaths = stateTree.getSelectionPaths();
  262. if (selectedPaths == null) {
  263. stateTree.addSelectionPath(pathUnderCursor);
  264. } else {
  265. boolean isInSelectedPaths = false;
  266. for (TreePath path : stateTree.getSelectionPaths()) {
  267. if (path.equals(pathUnderCursor)) {
  268. isInSelectedPaths = true;
  269. break;
  270. }
  271. }
  272. if (!isInSelectedPaths) {
  273. stateTree.clearSelection();
  274. stateTree.addSelectionPath(pathUnderCursor);
  275. }
  276. }
  277. menu.show(stateTree, pathBounds.x, pathBounds.y + pathBounds.height);
  278. }
  279. }
  280. }
  281. });
  282. selectedPanel = new JPanel(new BorderLayout());
  283. selectedPanel.add(new JScrollPane(stateTree));
  284. }
  285. private JPopupMenu createPopUpMenu() {
  286. priorityItem.addActionListener(clicked -> getInfoFromSelection().ifPresent(eleInfo -> {
  287. Priority priority = (Priority) JOptionPane.showInputDialog(stateTree,
  288. "Select the Priority:", "Priority?", JOptionPane.INFORMATION_MESSAGE,
  289. new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)),
  290. Priority.values(), "");
  291. if (priority == null) {
  292. return;
  293. }
  294. eleInfo.ele.setPriority(priority);
  295. control.updateStateForCurrentIteration();
  296. }));
  297. flexItem.addActionListener(
  298. clicked -> getInfoFromSelection().ifPresent(eleInfo -> createAddDialog(eleInfo.ele)));
  299. menu.add(priorityItem);
  300. menu.add(flexItem);
  301. return menu;
  302. }
  303. private Optional<ElementInfo> getInfoFromSelection() {
  304. TreePath path = stateTree.getSelectionPath();
  305. if (path == null) {
  306. return Optional.empty();
  307. }
  308. Object userObject = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
  309. if (userObject instanceof ElementInfo eleInfo) {
  310. return Optional.of(eleInfo);
  311. }
  312. return Optional.empty();
  313. }
  314. private void createNothingSelectedPanel() {
  315. nothingSelectedPanel = new JPanel();
  316. nothingSelectedPanel.setLayout(new BoxLayout(nothingSelectedPanel, BoxLayout.PAGE_AXIS));
  317. JLabel nothingSelectedTextLabel = new JLabel("No HolonObject exist.");
  318. nothingSelectedTextLabel.setForeground(Color.gray);
  319. nothingSelectedTextLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
  320. nothingSelectedPanel.add(Box.createVerticalGlue());
  321. nothingSelectedPanel.add(nothingSelectedTextLabel);
  322. nothingSelectedPanel.add(Box.createVerticalGlue());
  323. }
  324. private void updateSelectedPanel() {
  325. //Should not remove add so many Components
  326. listOfAllSelectedHolonObjects.removeAllChildren();
  327. //Init with HolonObjects
  328. control.getModel().getCanvas().getObjectsInThisLayer().forEach(aCps -> {
  329. DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(
  330. aCps.getName() + " ID:" + aCps.getId());
  331. if (aCps instanceof HolonObject hO) {
  332. expandTreeHolonObject(hO, newObjectChild);
  333. }
  334. if (aCps instanceof GroupNode groupnode) {
  335. expandTreeUpperNode(groupnode, newObjectChild);
  336. }
  337. listOfAllSelectedHolonObjects.add(newObjectChild);
  338. });
  339. treeModel.nodeStructureChanged(listOfAllSelectedHolonObjects);
  340. stateTree.revalidate();
  341. expandAll(stateTree);
  342. selectedPanel.revalidate();
  343. contentPanel.setComponentAt(contentPanel.indexOfTab(gridTabString), selectedPanel);
  344. contentPanel.revalidate();
  345. this.revalidate();
  346. }
  347. /**
  348. * Helper function to expand the branches of a JTree.
  349. * @param tree the JTree
  350. */
  351. private void expandAll(JTree tree) {
  352. for (int i = 0; i < tree.getRowCount(); i++) {
  353. tree.expandRow(i);
  354. }
  355. }
  356. private void expandTreeUpperNode(GroupNode groupNode, DefaultMutableTreeNode root) {
  357. groupNode.getHolonObjects().forEach(object -> {
  358. DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(
  359. object.getName() + " ID:" + object.getId());
  360. root.add(newObjectChild);
  361. });
  362. groupNode.getGroupNodes().forEach(childGroupNode -> {
  363. DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(
  364. childGroupNode.getName() + " ID:" + childGroupNode.getId());
  365. expandTreeUpperNode(childGroupNode, newObjectChild);
  366. root.add(newObjectChild);
  367. });
  368. }
  369. private void expandTreeHolonObject(HolonObject hObject, DefaultMutableTreeNode root) {
  370. hObject.elementsStream().forEach(hE -> {
  371. DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(new ElementInfo(hE));
  372. expandTreeFlex(hE, newChild);
  373. root.add(newChild);
  374. });
  375. }
  376. private void expandTreeFlex(HolonElement hElement, DefaultMutableTreeNode root) {
  377. for (Flexibility flex : hElement.flexList) {
  378. String flexState;
  379. Color color = ColorPreference.Flexibility.getStateColor(flex.getState());
  380. flexState = "<font bgcolor='#" + Integer.toHexString(color.getRGB()).substring(2) + "'>"
  381. + flex.getState().name() + "</font>";
  382. DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(
  383. "<html>" + flexState + " <b>" + flex.name + "</b>" + "</html>");
  384. root.add(newChild);
  385. }
  386. }
  387. private void createDeleteDialog() {
  388. Object[] allFlexes = control.getModel().getAllFlexibilities().toArray();
  389. if (allFlexes.length == 0) {
  390. JOptionPane.showMessageDialog(this,
  391. "No Flexibility exist.",
  392. "Warning",
  393. JOptionPane.WARNING_MESSAGE);
  394. return;
  395. }
  396. Flexibility toDeleteFlex = (Flexibility) JOptionPane.showInputDialog(this,
  397. "Select to Delete Flexibility:", "Flexibility?", JOptionPane.INFORMATION_MESSAGE,
  398. new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)), allFlexes, "");
  399. if (toDeleteFlex != null) {
  400. toDeleteFlex.getElement().flexList.remove(toDeleteFlex);
  401. control.calculateStateForCurrentIteration();
  402. updateSelectedPanel();
  403. }
  404. }
  405. //Add Element
  406. private void createAddDialog(HolonElement element) {
  407. if (control.getModel().getCanvas().getAllHolonObjectsRecursive().findAny().isEmpty()) {
  408. JOptionPane.showMessageDialog(this,
  409. "No HolonObject exist.",
  410. "Warning",
  411. JOptionPane.WARNING_MESSAGE);
  412. return;
  413. }
  414. JDialog addDialog = new JDialog();
  415. addDialog.setTitle("Create Flexibility");
  416. addDialog.setBounds(0, 0, 820, 400);
  417. addDialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  418. JPanel dialogPanel = new JPanel(new BorderLayout());
  419. addDialog.setContentPane(dialogPanel);
  420. JPanel selectionPanel = new JPanel(null);
  421. dialogPanel.add(selectionPanel, BorderLayout.CENTER);
  422. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  423. dialogPanel.add(buttonPanel, BorderLayout.PAGE_END);
  424. addDialog.setModalityType(ModalityType.APPLICATION_MODAL);
  425. //Create HolonObject selection Box
  426. HolonObject[] holonObjects = control.getModel().getCanvas().getAllHolonObjectsRecursive()
  427. .toArray(HolonObject[]::new);
  428. DefaultComboBoxModel<HolonObject> comboBoxModel = new DefaultComboBoxModel<>(holonObjects);
  429. JComboBox<HolonObject> holonObjectSelector = new JComboBox<>(comboBoxModel);
  430. holonObjectSelector.setBounds(10, 30, 800, 30);
  431. DefaultComboBoxModel<HolonElement> comboBoxModelElements = new DefaultComboBoxModel<>(
  432. holonObjects[0].elementsStream().toArray(HolonElement[]::new));
  433. JComboBox<HolonElement> holonElementSelector = new JComboBox<>(comboBoxModelElements);
  434. holonElementSelector.setBounds(10, 80, 800, 30);
  435. holonObjectSelector.addItemListener(aListener -> {
  436. if (aListener.getStateChange() == ItemEvent.SELECTED) {
  437. DefaultComboBoxModel<HolonElement> newComboBoxModelElements = new DefaultComboBoxModel<>(
  438. ((HolonObject) aListener.getItem()).elementsStream().toArray(HolonElement[]::new));
  439. holonElementSelector.setModel(newComboBoxModelElements);
  440. }
  441. });
  442. if (element == null) {
  443. selectionPanel.add(holonObjectSelector);
  444. selectionPanel.add(holonElementSelector);
  445. JLabel selectObjectLabel = new JLabel("Select HolonObject:");
  446. selectObjectLabel.setBounds(10, 10, 200, 20);
  447. selectionPanel.add(selectObjectLabel);
  448. JLabel selectElementLabel = new JLabel("Select HolonElement:");
  449. selectElementLabel.setBounds(10, 60, 200, 20);
  450. selectionPanel.add(selectElementLabel);
  451. } else {
  452. JLabel selectElementLabel = new JLabel("Selected: " + element);
  453. selectElementLabel.setBounds(10, 60, 2000, 20);
  454. selectionPanel.add(selectElementLabel);
  455. }
  456. JPanel flexAttributesBorderPanel = new JPanel(null);
  457. flexAttributesBorderPanel.setBounds(10, 120, 800, 200);
  458. flexAttributesBorderPanel.setBorder(BorderFactory.createTitledBorder("Flexibility Attributes"));
  459. selectionPanel.add(flexAttributesBorderPanel);
  460. JLabel flexNameLabel = new JLabel("Name:");
  461. flexNameLabel.setBounds(10, 20, 50, 20);
  462. flexAttributesBorderPanel.add(flexNameLabel);
  463. JFormattedTextField nameTextField = new JFormattedTextField(intermediateFlex.name);
  464. nameTextField.addPropertyChangeListener(
  465. changed -> intermediateFlex.name = nameTextField.getText());
  466. nameTextField.setBounds(80, 15, 200, 30);
  467. flexAttributesBorderPanel.add(nameTextField);
  468. JLabel flexSpeedLabel = new JLabel("Speed:");
  469. flexSpeedLabel.setBounds(10, 55, 50, 20);
  470. flexAttributesBorderPanel.add(flexSpeedLabel);
  471. //Integer formatter
  472. NumberFormat format = NumberFormat.getIntegerInstance();
  473. format.setGroupingUsed(false);
  474. format.setParseIntegerOnly(true);
  475. NumberFormatter integerFormatter = new NumberFormatter(format);
  476. integerFormatter.setMinimum(0);
  477. integerFormatter.setCommitsOnValidEdit(true);
  478. JFormattedTextField speedTextField = new JFormattedTextField(integerFormatter);
  479. speedTextField.setValue(intermediateFlex.speed);
  480. speedTextField.setToolTipText("Only positive Integer.");
  481. speedTextField.addPropertyChangeListener(
  482. actionEvent -> intermediateFlex.speed = Integer.parseInt(
  483. speedTextField.getValue().toString()));
  484. speedTextField.setBounds(80, 50, 200, 30);
  485. flexAttributesBorderPanel.add(speedTextField);
  486. speedTextField.setEnabled(false);
  487. JLabel flexDurationLabel = new JLabel("Duration:");
  488. flexDurationLabel.setBounds(10, 90, 70, 20);
  489. flexAttributesBorderPanel.add(flexDurationLabel);
  490. NumberFormatter moreThenZeroIntegerFormatter = new NumberFormatter(format);
  491. moreThenZeroIntegerFormatter.setMinimum(1);
  492. moreThenZeroIntegerFormatter.setCommitsOnValidEdit(true);
  493. JFormattedTextField durationTextField = new JFormattedTextField(moreThenZeroIntegerFormatter);
  494. durationTextField.setValue(intermediateFlex.getDuration());
  495. durationTextField.setToolTipText("Only positive Integer bigger then 0.");
  496. durationTextField.addPropertyChangeListener(actionEvent -> intermediateFlex.setDuration(
  497. Integer.parseInt(durationTextField.getValue().toString())));
  498. durationTextField.setBounds(80, 85, 200, 30);
  499. flexAttributesBorderPanel.add(durationTextField);
  500. JLabel flexCostsLabel = new JLabel("Costs:");
  501. flexCostsLabel.setBounds(10, 125, 70, 20);
  502. flexAttributesBorderPanel.add(flexCostsLabel);
  503. //Double Format:
  504. NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
  505. doubleFormat.setMinimumFractionDigits(1);
  506. doubleFormat.setMaximumFractionDigits(2);
  507. doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
  508. //CostFormatter:
  509. NumberFormatter costsFormatter = new NumberFormatter(doubleFormat);
  510. costsFormatter.setMinimum(0.0);
  511. JFormattedTextField costTextField = new JFormattedTextField(costsFormatter);
  512. costTextField.setValue(intermediateFlex.cost);
  513. costTextField.setToolTipText("Only non negative Double with DecimalSeparator Point('.').");
  514. costTextField.addPropertyChangeListener(
  515. propertyChange -> intermediateFlex.cost = Float.parseFloat(
  516. costTextField.getValue().toString()));
  517. costTextField.setBounds(80, 120, 200, 30);
  518. flexAttributesBorderPanel.add(costTextField);
  519. JLabel flexCooldownLabel = new JLabel("Cooldown:");
  520. flexCooldownLabel.setBounds(310, 20, 70, 20);
  521. flexAttributesBorderPanel.add(flexCooldownLabel);
  522. JFormattedTextField cooldownTextField = new JFormattedTextField(moreThenZeroIntegerFormatter);
  523. cooldownTextField.setValue(intermediateFlex.getCooldown());
  524. cooldownTextField.setToolTipText("Only positive Integer.");
  525. cooldownTextField.addPropertyChangeListener(actionEvent -> intermediateFlex.setCooldown(
  526. Integer.parseInt(cooldownTextField.getValue().toString())));
  527. cooldownTextField.setBounds(380, 15, 200, 30);
  528. flexAttributesBorderPanel.add(cooldownTextField);
  529. JCheckBox offeredCheckBox = new JCheckBox("Offered");
  530. offeredCheckBox.setSelected(this.offered);
  531. offeredCheckBox.setBounds(310, 55, 200, 20);
  532. flexAttributesBorderPanel.add(offeredCheckBox);
  533. JCheckBox onConstrainCheckBox = new JCheckBox("On_Constrain");
  534. onConstrainCheckBox.setSelected(this.onConstrain);
  535. onConstrainCheckBox.setBounds(310, 80, 200, 20);
  536. flexAttributesBorderPanel.add(onConstrainCheckBox);
  537. JCheckBox offConstrainCheckBox = new JCheckBox("Off_Constrain");
  538. offConstrainCheckBox.setSelected(this.offConstrain);
  539. offConstrainCheckBox.setBounds(310, 105, 200, 20);
  540. flexAttributesBorderPanel.add(offConstrainCheckBox);
  541. //Both cant be true....
  542. onConstrainCheckBox.addActionListener(clicked -> {
  543. if (onConstrainCheckBox.isSelected()) {
  544. offConstrainCheckBox.setSelected(false);
  545. }
  546. });
  547. offConstrainCheckBox.addActionListener(clicked -> {
  548. if (offConstrainCheckBox.isSelected()) {
  549. onConstrainCheckBox.setSelected(false);
  550. }
  551. });
  552. JButton createFlexButton = new JButton("Create");
  553. createFlexButton.addActionListener(clicked -> {
  554. HolonElement ele;
  555. if (element == null) {
  556. ele = (HolonElement) holonElementSelector.getSelectedItem();
  557. } else {
  558. ele = element;
  559. }
  560. Flexibility toCreateFlex = new Flexibility(ele);
  561. toCreateFlex.name = intermediateFlex.name;
  562. toCreateFlex.speed = intermediateFlex.speed;
  563. toCreateFlex.setDuration(intermediateFlex.getDuration());
  564. toCreateFlex.cost = intermediateFlex.cost;
  565. toCreateFlex.setCooldown(intermediateFlex.getCooldown());
  566. toCreateFlex.offered = offeredCheckBox.isSelected();
  567. if (onConstrainCheckBox.isSelected()) {
  568. toCreateFlex.constrainList.add(Constrain.createOnConstrain());
  569. }
  570. if (offConstrainCheckBox.isSelected()) {
  571. toCreateFlex.constrainList.add(Constrain.createOffConstrain());
  572. }
  573. assert ele != null;
  574. ele.flexList.add(toCreateFlex);
  575. //save checkboxes
  576. this.offered = offeredCheckBox.isSelected();
  577. this.onConstrain = onConstrainCheckBox.isSelected();
  578. this.offConstrain = offConstrainCheckBox.isSelected();
  579. control.updateStateForCurrentIteration();
  580. addDialog.dispose();
  581. });
  582. buttonPanel.add(createFlexButton);
  583. JButton cancelButton = new JButton("Cancel");
  584. cancelButton.addActionListener(clicked -> addDialog.dispose());
  585. buttonPanel.add(cancelButton);
  586. //last
  587. addDialog.setLocationRelativeTo(this);
  588. addDialog.setVisible(true);
  589. }
  590. /**
  591. * Wrapper class for a Element
  592. */
  593. static class ElementInfo {
  594. HolonElement ele;
  595. public ElementInfo(HolonElement ele) {
  596. this.ele = ele;
  597. }
  598. @Override
  599. public String toString() {
  600. return ele.getName() + " Priority:" + ele.getPriority();
  601. }
  602. }
  603. }