PortEditorPanel.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;
  2. import java.awt.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. import java.awt.event.FocusEvent;
  6. import java.awt.event.FocusListener;
  7. import java.awt.event.MouseEvent;
  8. import java.awt.event.MouseListener;
  9. import javax.swing.*;
  10. import javax.swing.event.*;
  11. import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
  12. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
  13. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPerformance;
  14. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
  15. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
  16. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
  17. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
  18. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol;
  19. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleLink;
  20. /**
  21. * Panel for editing of Ports of a SmartDevice
  22. *
  23. * @author Andreas T. Meyer-Berg
  24. */
  25. @SuppressWarnings("serial")
  26. public class PortEditorPanel extends JPanel
  27. implements ListSelectionListener, FocusListener, ActionListener, MouseListener {
  28. /**
  29. * Panel, which contains the different Textfields and Selectors for editing a port
  30. */
  31. private JPanel editPanel;
  32. /**
  33. * List for the selection of a port
  34. */
  35. private JList<Port> list;
  36. /**
  37. * Split pane for the List
  38. */
  39. private JSplitPane splitPane;
  40. /**
  41. * SmartDevice which is being edited
  42. */
  43. private SmartDevice toEdit;
  44. /**
  45. * Label for the protocol name
  46. */
  47. private JLabel lblProtocolName;
  48. /**
  49. * Textfield for the PortNumber
  50. */
  51. private JTextField tfPortNumber;
  52. /**
  53. * ComboBox for the status
  54. */
  55. private JComboBox<String> cmbStatus;
  56. /**
  57. * Textfield for the trigger Interval
  58. */
  59. private JTextField tfTriggerInterval;
  60. /**
  61. * Textfield for the responseTime
  62. */
  63. private JTextField tfResponseTime;
  64. /**
  65. * Textfield for the last trigger
  66. */
  67. private JTextField tfLastTrigger;
  68. /**
  69. * Textfield for the jitter
  70. */
  71. private JTextField tfJitter;
  72. /**
  73. * Controller for notifying other parts of the Framework
  74. */
  75. private Controller controller;
  76. /**
  77. * Creates a new PortEditorPanel, which allows editing of the Ports of toEdit
  78. * @param toEdit SmartDevice, which ports will be edited
  79. * @param controller Controller to modify the Model
  80. */
  81. public PortEditorPanel(SmartDevice toEdit, Controller controller) {
  82. this.controller = controller;
  83. this.toEdit = toEdit;
  84. //Create the list of ports
  85. Port[] ports = new Port[toEdit.getPorts().size()];
  86. for(int i = 0; i<toEdit.getPorts().size();i++)
  87. ports[i]=toEdit.getPorts().get(i);
  88. list = new JList<Port>(ports);//Safe conversion
  89. //list = new JList(ports);//To enable Eclipse.WindowBuilder
  90. list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  91. list.setSelectedIndex(0);
  92. list.addListSelectionListener(this);
  93. JScrollPane listScrollPane = new JScrollPane(list);
  94. editPanel = new JPanel();
  95. editPanel.setFont(editPanel.getFont().deriveFont(Font.ITALIC));
  96. editPanel.setLayout(null);
  97. String portNumberToolTip = "<html>Number of this port, should be a 16bit short [0 - 65335].<br> A Port describes the Endpoint of an Connection.</html>";
  98. JLabel lblPortnumber = new JLabel("PortNumber:");
  99. lblPortnumber.setHorizontalAlignment(SwingConstants.RIGHT);
  100. lblPortnumber.setBounds(10, 10, 140, 20);
  101. lblPortnumber.setToolTipText(portNumberToolTip);
  102. editPanel.add(lblPortnumber);
  103. JScrollPane portsScrollPane = new JScrollPane(editPanel);
  104. tfPortNumber = new JTextField();
  105. tfPortNumber.setBounds(160, 10, 130, 20);
  106. editPanel.add(tfPortNumber);
  107. tfPortNumber.setColumns(10);
  108. tfPortNumber.addFocusListener(this);
  109. tfPortNumber.addActionListener(this);
  110. tfPortNumber.addMouseListener(this);
  111. tfPortNumber.setToolTipText(portNumberToolTip);
  112. JLabel lblProtocol = new JLabel("Protocol:");
  113. lblProtocol.setHorizontalAlignment(SwingConstants.RIGHT);
  114. lblProtocol.setBounds(10, 40, 140, 20);
  115. lblProtocol.setToolTipText("Protocol which this Port participates in.");
  116. editPanel.add(lblProtocol);
  117. lblProtocolName = new JLabel("Protocol");
  118. lblProtocolName.setBounds(160, 40, 60, 20);
  119. lblProtocolName.setToolTipText("Name of the protocol, which is performed via this Port.");
  120. editPanel.add(lblProtocolName);
  121. JButton btnEditConnection = new JButton("Edit");
  122. btnEditConnection.setBounds(230, 40, 60, 20);
  123. btnEditConnection.setToolTipText("Edit the Connection & Protocol performed via this port.");
  124. editPanel.add(btnEditConnection);
  125. btnEditConnection.addActionListener(a->{
  126. if(list.getSelectedValue()==null||list.getSelectedValue().getConnection()==null)
  127. return;
  128. new ConnectionCreationDialog(list.getSelectedValue().getConnection(), controller, this);
  129. });
  130. String toolTipStatus = "<html>Status of this port, how it is acting:<br>"
  131. +" * sending: Port sends packets & responds to incoming packets<br>"
  132. +" * open: Port responds to incoming packets, but will not initialize new packets, without trigger<br>"
  133. +" * closed: Port won't send or respond to packets<br>"
  134. +"</html>";
  135. JLabel lblStatus = new JLabel("Status:");
  136. lblStatus.setHorizontalAlignment(SwingConstants.RIGHT);
  137. //lblStatus.setBounds(66, 66, 56, 16);
  138. lblStatus.setBounds(10, 70, 140, 20);
  139. lblStatus.setToolTipText(toolTipStatus);
  140. editPanel.add(lblStatus);
  141. cmbStatus = new JComboBox<String>();
  142. cmbStatus.addItem(Port.statusToString(Port.CLOSED));
  143. cmbStatus.addItem(Port.statusToString(Port.OPEN));
  144. cmbStatus.addItem(Port.statusToString(Port.SENDING));
  145. cmbStatus.addItem(Port.statusToString((short) 4));
  146. cmbStatus.setBounds(160, 70, 130, 20);
  147. editPanel.add(cmbStatus);
  148. cmbStatus.addFocusListener(this);
  149. cmbStatus.addActionListener(this);
  150. cmbStatus.addMouseListener(this);
  151. cmbStatus.setToolTipText(toolTipStatus);
  152. String toolTipTrigger = "<html>Interval between to triggers of this port.<br> This port will sent a new outgoing packet every *triggerIntervall* milliseconds.<html>";
  153. JLabel lblTriggerInterval = new JLabel("Trigger Interval:");
  154. lblTriggerInterval.setHorizontalAlignment(SwingConstants.RIGHT);
  155. lblTriggerInterval.setBounds(10, 100, 140, 20);
  156. lblTriggerInterval.setToolTipText(toolTipTrigger);
  157. editPanel.add(lblTriggerInterval);
  158. tfTriggerInterval = new JTextField();
  159. tfTriggerInterval.setBounds(160, 100, 130, 20);
  160. editPanel.add(tfTriggerInterval);
  161. //tfTriggerInterval.setColumns(10);
  162. //tfTriggerInterval.addFocusListener(this);
  163. //tfTriggerInterval.addActionListener(this);
  164. //tfTriggerInterval.addMouseListener(this);
  165. tfTriggerInterval.setToolTipText(toolTipTrigger);
  166. tfTriggerInterval.setEnabled(false);
  167. JButton btnEditTriggerInterval = new JButton("Edit Distribution");
  168. btnEditTriggerInterval.setBounds(300, 100, 150, 20);
  169. btnEditTriggerInterval.addActionListener(l->openEditDistribution());
  170. editPanel.add(btnEditTriggerInterval);
  171. //JLabel lblTriggerIntervalUnit = new JLabel("ms");
  172. //lblTriggerIntervalUnit.setBounds(300, 100, 50, 20);
  173. //editPanel.add(lblTriggerIntervalUnit);
  174. String toolTipResponse = "<html>Time in milliseconds which this port needs to calculate<br>"
  175. +" and respond to an incoming packet.</html>";
  176. JLabel lblResponseTime = new JLabel("Response Time:");
  177. lblResponseTime.setHorizontalAlignment(SwingConstants.RIGHT);
  178. lblResponseTime.setBounds(10, 130, 140, 20);
  179. lblResponseTime.setToolTipText(toolTipResponse);
  180. editPanel.add(lblResponseTime);
  181. tfResponseTime = new JTextField();
  182. tfResponseTime.setBounds(160, 130, 130, 20);
  183. editPanel.add(tfResponseTime);
  184. tfResponseTime.setColumns(10);
  185. tfResponseTime.addFocusListener(this);
  186. tfResponseTime.addActionListener(this);
  187. tfResponseTime.addMouseListener(this);
  188. tfResponseTime.setToolTipText(toolTipResponse);
  189. JLabel lblResponseTimeUnit = new JLabel("ms");
  190. lblResponseTimeUnit.setBounds(300, 130, 50, 20);
  191. editPanel.add(lblResponseTimeUnit);
  192. String toolTipLastTrigger = "<html>Timestep in milliseconds, where this port sent its last packet.<br>"
  193. + "Just accounts for packets that originate from this port, no forwards or responses.</html>";
  194. JLabel lblLasttrigger = new JLabel("LastTrigger:");
  195. lblLasttrigger.setHorizontalAlignment(SwingConstants.RIGHT);
  196. lblLasttrigger.setBounds(10, 160, 140, 20);
  197. lblLasttrigger.setToolTipText(toolTipLastTrigger);
  198. editPanel.add(lblLasttrigger);
  199. tfLastTrigger = new JTextField();
  200. tfLastTrigger.setBounds(160, 160, 130, 20);
  201. editPanel.add(tfLastTrigger);
  202. tfLastTrigger.setColumns(10);
  203. tfLastTrigger.addFocusListener(this);
  204. tfLastTrigger.addActionListener(this);
  205. tfLastTrigger.addMouseListener(this);
  206. tfLastTrigger.setToolTipText(toolTipLastTrigger);
  207. JLabel lblLastTriggerUnit = new JLabel("ms");
  208. lblLastTriggerUnit.setBounds(300, 160, 50, 20);
  209. editPanel.add(lblLastTriggerUnit);
  210. String toolTipJitter = "<html>Jitter describes the differences between the minimum and maximum delay of a connection.<br>"
  211. + "In this takes the Port may send packets jitter/2 ms earlier or later</html>";
  212. JLabel lblJitter = new JLabel("Jitter:");
  213. lblJitter.setHorizontalAlignment(SwingConstants.RIGHT);
  214. lblJitter.setBounds(10, 190, 140, 20);
  215. lblJitter.setToolTipText(toolTipJitter);
  216. editPanel.add(lblJitter);
  217. tfJitter = new JTextField();
  218. tfJitter.setBounds(160, 190, 130, 20);
  219. editPanel.add(tfJitter);
  220. tfJitter.setColumns(10);
  221. tfJitter.setToolTipText(toolTipJitter);
  222. JLabel lblJitterUnit = new JLabel("ms");
  223. lblJitterUnit.setBounds(300, 190, 50, 20);
  224. editPanel.add(lblJitterUnit);
  225. tfJitter.addFocusListener(this);
  226. tfJitter.addActionListener(this);
  227. tfJitter.addMouseListener(this);
  228. splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
  229. listScrollPane, portsScrollPane);
  230. splitPane.setDividerLocation(90);
  231. /**
  232. * minimum sizes of the panels
  233. */
  234. Dimension minimumSize = new Dimension(150, 60);
  235. listScrollPane.setMinimumSize(minimumSize);
  236. listScrollPane.setMaximumSize(minimumSize);
  237. portsScrollPane.setMinimumSize(minimumSize);
  238. // Set the preferred size
  239. splitPane.setPreferredSize(new Dimension(500, 240));
  240. if(!toEdit.getPorts().isEmpty())
  241. updateLabel(toEdit.getPorts().get(list.getSelectedIndex()));
  242. }
  243. private void openEditDistribution() {
  244. if(list.getSelectedIndex() < 0 || list.getSelectedIndex() >= toEdit.getPorts().size())return;
  245. /**
  246. * Port, which is being edited at the moment
  247. */
  248. Port toChange = toEdit.getPorts().get(list.getSelectedIndex());
  249. PortDistributionConfigurationPopUp popUp = new PortDistributionConfigurationPopUp(toChange, controller);
  250. popUp.setEnabled(true);
  251. popUp.setVisible(true);
  252. popUp.setLocationRelativeTo(this);
  253. popUp.setFocusable(true);
  254. }
  255. //Listens to the list
  256. @SuppressWarnings("unchecked")
  257. public void valueChanged(ListSelectionEvent e) {
  258. if(!(e.getSource() instanceof JList<?>)||!(((JList<?>)e.getSource()).getSelectedValue() instanceof Port))return;
  259. JList<Port> list = (JList<Port>)e.getSource();
  260. updateLabel(toEdit.getPorts().get(list.getSelectedIndex()));
  261. }
  262. /**
  263. * Updates the labels to the given Port
  264. * @param port Port which should be showed in this panel
  265. */
  266. protected void updateLabel (Port port) {
  267. if(port == null)return;
  268. tfPortNumber.setText(""+port.getPortNumber());
  269. tfPortNumber.setBackground(Color.WHITE);
  270. tfLastTrigger.setText(""+port.getLastTrigger());
  271. tfLastTrigger.setBackground(Color.WHITE);
  272. tfResponseTime.setText(""+port.getResponseTime());
  273. tfResponseTime.setBackground(Color.WHITE);
  274. tfTriggerInterval.setText(""+port.getTriggerInterval()+" ms");
  275. tfTriggerInterval.setBackground(Color.WHITE);
  276. tfJitter.setText(""+port.getJitter());
  277. tfJitter.setBackground(Color.WHITE);
  278. cmbStatus.setSelectedIndex(port.getStatus());
  279. if(port.getConnection() == null || port.getConnection().getProtocol()==null)
  280. lblProtocolName.setText("null");
  281. else
  282. lblProtocolName.setText(port.getConnection().getProtocol().getName());
  283. }
  284. /**
  285. * Returns the SplitPane, which is the Main component of this Panel
  286. * @return panel, which represents this object
  287. */
  288. public JSplitPane getSplitPane() {
  289. return splitPane;
  290. }
  291. /**
  292. * Test the Panel
  293. */
  294. private static void testGUI() {
  295. JFrame frame = new JFrame("Port Editor");
  296. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  297. SmartDevice test = new SmartDevice("TestDevice");
  298. Port p1 = new Port(test, (short) 1);
  299. Port p2 = new Port(test, (short) 2);
  300. test.addPort(p1);
  301. test.addPort(p2);
  302. MQTT_protocol testProtocol = new MQTT_protocol();
  303. testProtocol.addDeviceOfRole(p1, 0);
  304. testProtocol.addDeviceOfRole(p2, 1);
  305. Link test_link = new SimpleLink("Test");
  306. test_link.addDevice(test);
  307. Connection con = new ConnectionPerformance(test_link, testProtocol);
  308. p1.setConnection(con);
  309. p2.setConnection(con);
  310. con.addSmartDevice(p1);
  311. con.addSmartDevice(p2);
  312. PortEditorPanel portEditorPanel = new PortEditorPanel(test, new Controller(new Model()));
  313. frame.getContentPane().add(portEditorPanel.getSplitPane());
  314. frame.pack();
  315. frame.revalidate();
  316. frame.setVisible(true);
  317. }
  318. public static void main(String[] args) {
  319. javax.swing.SwingUtilities.invokeLater(new Runnable() {
  320. public void run() {
  321. testGUI();
  322. }
  323. });
  324. }
  325. /**
  326. * Checks values of the textfields have changed, and updates the Protocol accordingly.
  327. * Invalid values are highlighted RED
  328. */
  329. private void checkValueChange() {
  330. if(list.getSelectedIndex() < 0 || list.getSelectedIndex() >= toEdit.getPorts().size())return;
  331. /**
  332. * Port, which is being edited at the moment
  333. */
  334. Port toChange = toEdit.getPorts().get(list.getSelectedIndex());
  335. //Edit Port Number
  336. if(tfPortNumber.getText()!=""+toChange.getPortNumber()){
  337. try {
  338. toChange.setPortNumber(Short.parseShort(tfPortNumber.getText()));
  339. tfPortNumber.setBackground(Color.WHITE);
  340. } catch (Exception e) {
  341. tfPortNumber.setBackground(Color.RED);
  342. }
  343. }else{
  344. tfPortNumber.setBackground(Color.WHITE);
  345. }
  346. //Edit Status
  347. if(cmbStatus.getSelectedIndex()!=toChange.getStatus())
  348. toChange.setStatus((short) cmbStatus.getSelectedIndex());
  349. //Edit trigger Interval
  350. /**
  351. if(tfTriggerInterval.getText()!=""+toChange.getTriggerInterval()){
  352. try {
  353. //TODO: Advanced Triggers
  354. ProbabilityDistributionHandler dist = toChange.getTriggerHandler();
  355. if(dist instanceof ConstantValueDistribution){
  356. ((ConstantValueDistribution)dist).setValue(Long.parseLong(tfTriggerInterval.getText()));
  357. toChange.resampleTriggerInterval();
  358. }
  359. //toChange.setTriggerInterval(Long.parseLong(tfTriggerInterval.getText()));
  360. tfTriggerInterval.setBackground(Color.WHITE);
  361. } catch (Exception e) {
  362. tfTriggerInterval.setBackground(Color.RED);
  363. }
  364. }else{
  365. tfTriggerInterval.setBackground(Color.WHITE);
  366. }
  367. */
  368. //Edit Response time
  369. if(tfResponseTime.getText()!=""+toChange.getResponseTime()){
  370. try {
  371. toChange.setResponseTime(Short.parseShort(tfResponseTime.getText()));
  372. tfResponseTime.setBackground(Color.WHITE);
  373. } catch (Exception e) {
  374. tfResponseTime.setBackground(Color.RED);
  375. }
  376. }else{
  377. tfResponseTime.setBackground(Color.WHITE);
  378. }
  379. //Edit last Trigger
  380. if(tfLastTrigger.getText()!=""+toChange.getLastTrigger()){
  381. try {
  382. toChange.setLastTrigger(Long.parseLong(tfLastTrigger.getText()));
  383. tfLastTrigger.setBackground(Color.WHITE);
  384. } catch (Exception e) {
  385. tfLastTrigger.setBackground(Color.RED);
  386. }
  387. }else{
  388. tfLastTrigger.setBackground(Color.WHITE);
  389. }
  390. //Edit Jitter
  391. if(tfJitter.getText()!=""+toChange.getJitter()){
  392. try {
  393. toChange.setJitter(Short.parseShort(tfJitter.getText()));
  394. tfJitter.setBackground(Color.WHITE);
  395. } catch (Exception e) {
  396. tfJitter.setBackground(Color.RED);
  397. }
  398. }else{
  399. tfJitter.setBackground(Color.WHITE);
  400. }
  401. }
  402. @Override
  403. public void focusGained(FocusEvent e) {
  404. checkValueChange();
  405. }
  406. @Override
  407. public void focusLost(FocusEvent e) {
  408. checkValueChange();
  409. }
  410. @Override
  411. public void mouseClicked(MouseEvent e) {
  412. }
  413. @Override
  414. public void mousePressed(MouseEvent e) {
  415. }
  416. @Override
  417. public void mouseReleased(MouseEvent e) {
  418. }
  419. @Override
  420. public void mouseEntered(MouseEvent e) {
  421. }
  422. @Override
  423. public void mouseExited(MouseEvent e) {
  424. checkValueChange();
  425. }
  426. @Override
  427. public void actionPerformed(ActionEvent e) {
  428. checkValueChange();
  429. }
  430. }