package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.*; import javax.swing.event.*; import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPerformance; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol; import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleLink; /** * Panel for editing of Ports of a SmartDevice * * @author Andreas T. Meyer-Berg */ @SuppressWarnings("serial") public class PortEditorPanel extends JPanel implements ListSelectionListener, FocusListener, ActionListener, MouseListener { /** * Panel, which contains the different Textfields and Selectors for editing a port */ private JPanel editPanel; /** * List for the selection of a port */ private JList list; /** * Split pane for the List */ private JSplitPane splitPane; /** * SmartDevice which is being edited */ private SmartDevice toEdit; /** * Label for the protocol name */ private JLabel lblProtocolName; /** * Textfield for the PortNumber */ private JTextField tfPortNumber; /** * ComboBox for the status */ private JComboBox cmbStatus; /** * Textfield for the trigger Interval */ private JTextField tfTriggerInterval; /** * Textfield for the responseTime */ private JTextField tfResponseTime; /** * Textfield for the last trigger */ private JTextField tfLastTrigger; /** * Textfield for the jitter */ private JTextField tfJitter; /** * Controller for notifying other parts of the Framework */ private Controller controller; /** * Creates a new PortEditorPanel, which allows editing of the Ports of toEdit * @param toEdit SmartDevice, which ports will be edited * @param controller Controller to modify the Model */ public PortEditorPanel(SmartDevice toEdit, Controller controller) { this.controller = controller; this.toEdit = toEdit; //Create the list of ports Port[] ports = new Port[toEdit.getPorts().size()]; for(int i = 0; i(ports);//Safe conversion //list = new JList(ports);//To enable Eclipse.WindowBuilder list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); list.addListSelectionListener(this); JScrollPane listScrollPane = new JScrollPane(list); editPanel = new JPanel(); editPanel.setFont(editPanel.getFont().deriveFont(Font.ITALIC)); editPanel.setLayout(null); String portNumberToolTip = "Number of this port, should be a 16bit short [0 - 65335].
A Port describes the Endpoint of an Connection."; JLabel lblPortnumber = new JLabel("PortNumber:"); lblPortnumber.setHorizontalAlignment(SwingConstants.RIGHT); lblPortnumber.setBounds(10, 10, 140, 20); lblPortnumber.setToolTipText(portNumberToolTip); editPanel.add(lblPortnumber); JScrollPane portsScrollPane = new JScrollPane(editPanel); tfPortNumber = new JTextField(); tfPortNumber.setBounds(160, 10, 130, 20); editPanel.add(tfPortNumber); tfPortNumber.setColumns(10); tfPortNumber.addFocusListener(this); tfPortNumber.addActionListener(this); tfPortNumber.addMouseListener(this); tfPortNumber.setToolTipText(portNumberToolTip); JLabel lblProtocol = new JLabel("Protocol:"); lblProtocol.setHorizontalAlignment(SwingConstants.RIGHT); lblProtocol.setBounds(10, 40, 140, 20); lblProtocol.setToolTipText("Protocol which this Port participates in."); editPanel.add(lblProtocol); lblProtocolName = new JLabel("Protocol"); lblProtocolName.setBounds(160, 40, 60, 20); lblProtocolName.setToolTipText("Name of the protocol, which is performed via this Port."); editPanel.add(lblProtocolName); JButton btnEditConnection = new JButton("Edit"); btnEditConnection.setBounds(230, 40, 60, 20); btnEditConnection.setToolTipText("Edit the Connection & Protocol performed via this port."); editPanel.add(btnEditConnection); btnEditConnection.addActionListener(a->{ if(list.getSelectedValue()==null||list.getSelectedValue().getConnection()==null) return; new ConnectionCreationDialog(list.getSelectedValue().getConnection(), controller, this); }); String toolTipStatus = "Status of this port, how it is acting:
" +" * sending: Port sends packets & responds to incoming packets
" +" * open: Port responds to incoming packets, but will not initialize new packets, without trigger
" +" * closed: Port won't send or respond to packets
" +""; JLabel lblStatus = new JLabel("Status:"); lblStatus.setHorizontalAlignment(SwingConstants.RIGHT); //lblStatus.setBounds(66, 66, 56, 16); lblStatus.setBounds(10, 70, 140, 20); lblStatus.setToolTipText(toolTipStatus); editPanel.add(lblStatus); cmbStatus = new JComboBox(); cmbStatus.addItem(Port.statusToString(Port.CLOSED)); cmbStatus.addItem(Port.statusToString(Port.OPEN)); cmbStatus.addItem(Port.statusToString(Port.SENDING)); cmbStatus.addItem(Port.statusToString((short) 4)); cmbStatus.setBounds(160, 70, 130, 20); editPanel.add(cmbStatus); cmbStatus.addFocusListener(this); cmbStatus.addActionListener(this); cmbStatus.addMouseListener(this); cmbStatus.setToolTipText(toolTipStatus); String toolTipTrigger = "Interval between to triggers of this port.
This port will sent a new outgoing packet every *triggerIntervall* milliseconds."; JLabel lblTriggerInterval = new JLabel("Trigger Interval:"); lblTriggerInterval.setHorizontalAlignment(SwingConstants.RIGHT); lblTriggerInterval.setBounds(10, 100, 140, 20); lblTriggerInterval.setToolTipText(toolTipTrigger); editPanel.add(lblTriggerInterval); tfTriggerInterval = new JTextField(); tfTriggerInterval.setBounds(160, 100, 130, 20); editPanel.add(tfTriggerInterval); //tfTriggerInterval.setColumns(10); //tfTriggerInterval.addFocusListener(this); //tfTriggerInterval.addActionListener(this); //tfTriggerInterval.addMouseListener(this); tfTriggerInterval.setToolTipText(toolTipTrigger); tfTriggerInterval.setEnabled(false); JButton btnEditTriggerInterval = new JButton("Edit Distribution"); btnEditTriggerInterval.setBounds(300, 100, 150, 20); btnEditTriggerInterval.addActionListener(l->openEditDistribution()); editPanel.add(btnEditTriggerInterval); //JLabel lblTriggerIntervalUnit = new JLabel("ms"); //lblTriggerIntervalUnit.setBounds(300, 100, 50, 20); //editPanel.add(lblTriggerIntervalUnit); String toolTipResponse = "Time in milliseconds which this port needs to calculate
" +" and respond to an incoming packet."; JLabel lblResponseTime = new JLabel("Response Time:"); lblResponseTime.setHorizontalAlignment(SwingConstants.RIGHT); lblResponseTime.setBounds(10, 130, 140, 20); lblResponseTime.setToolTipText(toolTipResponse); editPanel.add(lblResponseTime); tfResponseTime = new JTextField(); tfResponseTime.setBounds(160, 130, 130, 20); editPanel.add(tfResponseTime); tfResponseTime.setColumns(10); tfResponseTime.addFocusListener(this); tfResponseTime.addActionListener(this); tfResponseTime.addMouseListener(this); tfResponseTime.setToolTipText(toolTipResponse); JLabel lblResponseTimeUnit = new JLabel("ms"); lblResponseTimeUnit.setBounds(300, 130, 50, 20); editPanel.add(lblResponseTimeUnit); String toolTipLastTrigger = "Timestep in milliseconds, where this port sent its last packet.
" + "Just accounts for packets that originate from this port, no forwards or responses."; JLabel lblLasttrigger = new JLabel("LastTrigger:"); lblLasttrigger.setHorizontalAlignment(SwingConstants.RIGHT); lblLasttrigger.setBounds(10, 160, 140, 20); lblLasttrigger.setToolTipText(toolTipLastTrigger); editPanel.add(lblLasttrigger); tfLastTrigger = new JTextField(); tfLastTrigger.setBounds(160, 160, 130, 20); editPanel.add(tfLastTrigger); tfLastTrigger.setColumns(10); tfLastTrigger.addFocusListener(this); tfLastTrigger.addActionListener(this); tfLastTrigger.addMouseListener(this); tfLastTrigger.setToolTipText(toolTipLastTrigger); JLabel lblLastTriggerUnit = new JLabel("ms"); lblLastTriggerUnit.setBounds(300, 160, 50, 20); editPanel.add(lblLastTriggerUnit); String toolTipJitter = "Jitter describes the differences between the minimum and maximum delay of a connection.
" + "In this takes the Port may send packets jitter/2 ms earlier or later"; JLabel lblJitter = new JLabel("Jitter:"); lblJitter.setHorizontalAlignment(SwingConstants.RIGHT); lblJitter.setBounds(10, 190, 140, 20); lblJitter.setToolTipText(toolTipJitter); editPanel.add(lblJitter); tfJitter = new JTextField(); tfJitter.setBounds(160, 190, 130, 20); editPanel.add(tfJitter); tfJitter.setColumns(10); tfJitter.setToolTipText(toolTipJitter); JLabel lblJitterUnit = new JLabel("ms"); lblJitterUnit.setBounds(300, 190, 50, 20); editPanel.add(lblJitterUnit); tfJitter.addFocusListener(this); tfJitter.addActionListener(this); tfJitter.addMouseListener(this); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listScrollPane, portsScrollPane); splitPane.setDividerLocation(90); /** * minimum sizes of the panels */ Dimension minimumSize = new Dimension(150, 60); listScrollPane.setMinimumSize(minimumSize); listScrollPane.setMaximumSize(minimumSize); portsScrollPane.setMinimumSize(minimumSize); // Set the preferred size splitPane.setPreferredSize(new Dimension(500, 240)); if(!toEdit.getPorts().isEmpty()) updateLabel(toEdit.getPorts().get(list.getSelectedIndex())); } private void openEditDistribution() { if(list.getSelectedIndex() < 0 || list.getSelectedIndex() >= toEdit.getPorts().size())return; /** * Port, which is being edited at the moment */ Port toChange = toEdit.getPorts().get(list.getSelectedIndex()); PortDistributionConfigurationPopUp popUp = new PortDistributionConfigurationPopUp(toChange, controller); popUp.setEnabled(true); popUp.setVisible(true); popUp.setLocationRelativeTo(this); popUp.setFocusable(true); } //Listens to the list @SuppressWarnings("unchecked") public void valueChanged(ListSelectionEvent e) { if(!(e.getSource() instanceof JList)||!(((JList)e.getSource()).getSelectedValue() instanceof Port))return; JList list = (JList)e.getSource(); updateLabel(toEdit.getPorts().get(list.getSelectedIndex())); } /** * Updates the labels to the given Port * @param port Port which should be showed in this panel */ protected void updateLabel (Port port) { if(port == null)return; tfPortNumber.setText(""+port.getPortNumber()); tfPortNumber.setBackground(Color.WHITE); tfLastTrigger.setText(""+port.getLastTrigger()); tfLastTrigger.setBackground(Color.WHITE); tfResponseTime.setText(""+port.getResponseTime()); tfResponseTime.setBackground(Color.WHITE); tfTriggerInterval.setText(""+port.getTriggerInterval()+" ms"); tfTriggerInterval.setBackground(Color.WHITE); tfJitter.setText(""+port.getJitter()); tfJitter.setBackground(Color.WHITE); cmbStatus.setSelectedIndex(port.getStatus()); if(port.getConnection() == null || port.getConnection().getProtocol()==null) lblProtocolName.setText("null"); else lblProtocolName.setText(port.getConnection().getProtocol().getName()); } /** * Returns the SplitPane, which is the Main component of this Panel * @return panel, which represents this object */ public JSplitPane getSplitPane() { return splitPane; } /** * Test the Panel */ private static void testGUI() { JFrame frame = new JFrame("Port Editor"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); SmartDevice test = new SmartDevice("TestDevice"); Port p1 = new Port(test, (short) 1); Port p2 = new Port(test, (short) 2); test.addPort(p1); test.addPort(p2); MQTT_protocol testProtocol = new MQTT_protocol(); testProtocol.addDeviceOfRole(p1, 0); testProtocol.addDeviceOfRole(p2, 1); Link test_link = new SimpleLink("Test"); test_link.addDevice(test); Connection con = new ConnectionPerformance(test_link, testProtocol); p1.setConnection(con); p2.setConnection(con); con.addSmartDevice(p1); con.addSmartDevice(p2); PortEditorPanel portEditorPanel = new PortEditorPanel(test, new Controller(new Model())); frame.getContentPane().add(portEditorPanel.getSplitPane()); frame.pack(); frame.revalidate(); frame.setVisible(true); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { testGUI(); } }); } /** * Checks values of the textfields have changed, and updates the Protocol accordingly. * Invalid values are highlighted RED */ private void checkValueChange() { if(list.getSelectedIndex() < 0 || list.getSelectedIndex() >= toEdit.getPorts().size())return; /** * Port, which is being edited at the moment */ Port toChange = toEdit.getPorts().get(list.getSelectedIndex()); //Edit Port Number if(tfPortNumber.getText()!=""+toChange.getPortNumber()){ try { toChange.setPortNumber(Short.parseShort(tfPortNumber.getText())); tfPortNumber.setBackground(Color.WHITE); } catch (Exception e) { tfPortNumber.setBackground(Color.RED); } }else{ tfPortNumber.setBackground(Color.WHITE); } //Edit Status if(cmbStatus.getSelectedIndex()!=toChange.getStatus()) toChange.setStatus((short) cmbStatus.getSelectedIndex()); //Edit trigger Interval /** if(tfTriggerInterval.getText()!=""+toChange.getTriggerInterval()){ try { //TODO: Advanced Triggers ProbabilityDistributionHandler dist = toChange.getTriggerHandler(); if(dist instanceof ConstantValueDistribution){ ((ConstantValueDistribution)dist).setValue(Long.parseLong(tfTriggerInterval.getText())); toChange.resampleTriggerInterval(); } //toChange.setTriggerInterval(Long.parseLong(tfTriggerInterval.getText())); tfTriggerInterval.setBackground(Color.WHITE); } catch (Exception e) { tfTriggerInterval.setBackground(Color.RED); } }else{ tfTriggerInterval.setBackground(Color.WHITE); } */ //Edit Response time if(tfResponseTime.getText()!=""+toChange.getResponseTime()){ try { toChange.setResponseTime(Short.parseShort(tfResponseTime.getText())); tfResponseTime.setBackground(Color.WHITE); } catch (Exception e) { tfResponseTime.setBackground(Color.RED); } }else{ tfResponseTime.setBackground(Color.WHITE); } //Edit last Trigger if(tfLastTrigger.getText()!=""+toChange.getLastTrigger()){ try { toChange.setLastTrigger(Long.parseLong(tfLastTrigger.getText())); tfLastTrigger.setBackground(Color.WHITE); } catch (Exception e) { tfLastTrigger.setBackground(Color.RED); } }else{ tfLastTrigger.setBackground(Color.WHITE); } //Edit Jitter if(tfJitter.getText()!=""+toChange.getJitter()){ try { toChange.setJitter(Short.parseShort(tfJitter.getText())); tfJitter.setBackground(Color.WHITE); } catch (Exception e) { tfJitter.setBackground(Color.RED); } }else{ tfJitter.setBackground(Color.WHITE); } } @Override public void focusGained(FocusEvent e) { checkValueChange(); } @Override public void focusLost(FocusEvent e) { checkValueChange(); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { checkValueChange(); } @Override public void actionPerformed(ActionEvent e) { checkValueChange(); } }