package Connection; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.NumberFormat; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.text.NumberFormatter; import api.Algorithm; import classes.AbstractCpsObject; import classes.CpsUpperNode; import classes.HolonObject; import ui.controller.Control; /** * Easy Connection via Http Request. Repeat Request with a delay. * * @author tom * */ public class ConnectPhysical implements Algorithm{ //Holeg private Control control; //Gui private JPanel content = new JPanel(); private JTextArea textArea; JLabel rotorLabel; JLabel room1Label; JLabel room2Label; // Future future; private boolean lessInformation = false; private int delay = 1000; JLabel warningLabel; public enum HolonObjectStatus{ Connected , NotSelected, ObjectDeleted } public class PhysicalLinkWrapper{ public HolonObject hObject; public HolonObjectStatus status; public String postAddress; PhysicalLinkWrapper(HolonObject hObject, HolonObjectStatus status, String postAddress){ this.hObject = hObject; this.status = status; this.postAddress = postAddress; } } //Object to look at PhysicalLinkWrapper rotor = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/rotor/"); PhysicalLinkWrapper room1 = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/room1/"); PhysicalLinkWrapper room2 = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/room2/"); public static void main(String[] args) { JFrame newFrame = new JFrame("exampleWindow"); ConnectPhysical instance = new ConnectPhysical(); newFrame.setContentPane(instance.getAlgorithmPanel()); newFrame.pack(); newFrame.setVisible(true); newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public ConnectPhysical() { content.setLayout(new BorderLayout()); textArea = new JTextArea(); textArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(textArea); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createOptionPanel() , scrollPane); splitPane.setResizeWeight(0.0); content.add(splitPane, BorderLayout.CENTER); content.setPreferredSize(new Dimension(800,800)); } private Component createOptionPanel() { JPanel optionPanel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(createParameterPanel()); scrollPane.setBorder(BorderFactory.createTitledBorder("Settings")); optionPanel.add(scrollPane, BorderLayout.CENTER); optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END); return optionPanel; } private Component createParameterPanel() { JPanel parameterPanel = new JPanel(null); parameterPanel.setPreferredSize(new Dimension(510,300)); JLabel lessInformationLabel = new JLabel("Less information in Console:"); lessInformationLabel.setBounds(200, 150, 200, 20); parameterPanel.add(lessInformationLabel); JCheckBox lessInformationCheckBox = new JCheckBox(); lessInformationCheckBox.setSelected(false); lessInformationCheckBox.setBounds(400, 150, 25, 20); lessInformationCheckBox.addActionListener(actionEvent -> { lessInformation = lessInformationCheckBox.isSelected(); }); parameterPanel.add(lessInformationCheckBox); JLabel delayLabel = new JLabel("Delay:"); delayLabel.setBounds(200, 180, 50, 20); parameterPanel.add(delayLabel); JLabel delayUnitLabel = new JLabel("[ms]"); delayUnitLabel.setBounds(300, 180, 50, 20); parameterPanel.add(delayUnitLabel); warningLabel = new JLabel(stringToHtml(stringWithColor("You need to Stop and Run again to affect delay change.", "red"))); warningLabel.setBounds(200, 210, 400, 20); warningLabel.setVisible(false); parameterPanel.add(warningLabel); //Integer formatter NumberFormat format = NumberFormat.getIntegerInstance(); format.setGroupingUsed(false); format.setParseIntegerOnly(true); NumberFormatter integerFormatter = new NumberFormatter(format); integerFormatter.setMinimum(0); integerFormatter.setCommitsOnValidEdit(true); JFormattedTextField delayTextField = new JFormattedTextField(integerFormatter); delayTextField.setValue(delay); delayTextField.setToolTipText("Only positive Integer."); delayTextField.addPropertyChangeListener(actionEvent -> { delay = Integer.parseInt(delayTextField.getValue().toString()); if(future != null && !future.isCancelled()) { println("You need to Stop and Run again to affect this change."); warningLabel.setVisible(true); } }); delayTextField.setBounds(250, 180, 50, 20); parameterPanel.add(delayTextField); rotorLabel = new JLabel(stringToHtml("Rotor Status: " + statusToString(rotor.status))); rotorLabel.setBounds(200, 60, 220, 30); parameterPanel.add(rotorLabel); room1Label = new JLabel(stringToHtml("Room1 Status: " + statusToString(room1.status))); room1Label.setBounds(200, 90, 220, 30); parameterPanel.add(room1Label); room2Label = new JLabel(stringToHtml("Room2 Status: " + statusToString(room2.status))); room2Label.setBounds(200, 120, 220, 30); parameterPanel.add(room2Label); JButton selectRotorButton = new JButton("Select"); selectRotorButton.setBounds(420,65, 90, 20); selectRotorButton.addActionListener(actionEvent -> this.selectGroupNode(rotor)); parameterPanel.add(selectRotorButton); JButton selectRoom1Button = new JButton("Select"); selectRoom1Button.setBounds(420,95, 90, 20); selectRoom1Button.addActionListener(actionEvent -> this.selectGroupNode(room1)); parameterPanel.add(selectRoom1Button); JButton selectRoom2Button = new JButton("Select"); selectRoom2Button.setBounds(420,125, 90, 20); selectRoom2Button.addActionListener(actionEvent -> this.selectGroupNode(room2)); parameterPanel.add(selectRoom2Button); return parameterPanel; } private String stringToHtml(String string) { return "" + string + ""; } private String statusToString(HolonObjectStatus status) { switch(status) { case Connected: return stringWithColor("Connected", "green"); case NotSelected: return stringWithColor("Not selected", "red"); case ObjectDeleted: return stringWithColor("Object deleted", "red"); default: return ""; } } private String stringWithColor(String string, String color) { return "" + string + ""; } private void updateStatusLabels() { rotorLabel.setText(stringToHtml("Rotor Status: " + statusToString(rotor.status))); room1Label.setText(stringToHtml("Room1 Status: " + statusToString(room1.status))); room2Label.setText(stringToHtml("Room2 Status: " + statusToString(room2.status))); } private Component createButtonPanel() { JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JButton clearButton = new JButton("Clear Console"); clearButton.addActionListener(actionEvent -> clear()); buttonPanel.add(clearButton); JButton stopButton = new JButton("Stop"); stopButton.addActionListener(actionEvent -> stop()); buttonPanel.add(stopButton); JButton runButton = new JButton("Run"); runButton.addActionListener(actionEvent -> initSchedule()); buttonPanel.add(runButton); return buttonPanel; } private void stop() { if(future!= null) { if(future.isCancelled()) { println("Is cancelled."); } else { future.cancel(true); println("Stopped sending Requests on localhost:2019 ..."); } } else { println("Not started jet."); } } private void initSchedule() { if(future != null && !future.isCancelled()) { println("Is running."); return; } warningLabel.setVisible(false); println("Starting sending Requests on localhost:2019"); final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); final Runnable beeper = new Runnable() { //RepeatedMethod public void run() { if(lessInformation)print("."); checkWrapper(rotor); checkWrapper(room1); checkWrapper(room2); } private void checkWrapper(PhysicalLinkWrapper wrapper) { if(wrapper.status == HolonObjectStatus.Connected) checkConnected(wrapper); else if(!lessInformation)println(wrapper.postAddress +" is not connected."); } private void checkConnected(PhysicalLinkWrapper wrapper) { if(wrapper.hObject == null) { wrapper.status = HolonObjectStatus.ObjectDeleted; updateStatusLabels(); return; } if(wrapper.hObject.getNumberOfElements() > 0) { int value = Math.round(((float)wrapper.hObject.getNumberOfActiveElements()/(float) wrapper.hObject.getNumberOfElements())*(float) 100); sendRequest(wrapper, value); }else { sendRequest(wrapper, 0); } } private void sendRequest(PhysicalLinkWrapper wrapper, int value) { if(!lessInformation)println("Send " + "http://localhost:2019" + wrapper.postAddress + value); doHttpUrlConnectionAction("http://localhost:2019" + wrapper.postAddress + value); } /** * Send A Request to a URL. * * @param desiredUrl * @return */ private void doHttpUrlConnectionAction(String desiredUrl) { URL url = null; // create the HttpURLConnection try { url = new URL(desiredUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // just want to do an HTTP GET here connection.setRequestMethod("GET"); // give it 15 seconds to respond connection.setReadTimeout(1000); connection.connect(); } catch (MalformedURLException e) { println("MalformedURLException"); e.printStackTrace(); } catch (IOException e) { println("IOException: Connection refused"); e.printStackTrace(); } } }; future = executorService.scheduleAtFixedRate(beeper, 0, delay, TimeUnit.MILLISECONDS); } private void addObjectToList(List listToSearch, List listToAdd){ for (AbstractCpsObject aCps : listToSearch) { if (aCps instanceof HolonObject) listToAdd.add((HolonObject) aCps); else if(aCps instanceof CpsUpperNode) { addObjectToList(((CpsUpperNode)aCps).getNodes(),listToAdd); } } } //SelectGroupNode private void selectGroupNode(PhysicalLinkWrapper wrapper) { List holonObjectList = new ArrayList(); addObjectToList(control.getModel().getObjectsOnCanvas(),holonObjectList); Object[] possibilities = holonObjectList.stream().map(aCps -> new Handle(aCps)).toArray(); @SuppressWarnings("unchecked") Handle selected = (Handle) JOptionPane.showInputDialog(content, "Select HolonObject:", "HolonObject?", JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, ""); if(selected != null) { println("Selected: " + selected); wrapper.hObject = selected.object; wrapper.status = HolonObjectStatus.Connected; updateStatusLabels(); } } private class Handle{ public T object; Handle(T object){ this.object = object; } public String toString() { return object.toString(); } } @Override public JPanel getAlgorithmPanel() { return content; } @Override public void setController(Control control) { this.control = control; } private void clear() { textArea.setText(""); } private void print(String message) { textArea.append(message); } private void println(String message) { textArea.append(message + "\n"); } }