package ui.view; import classes.HolonBody; import classes.SubNet; import classes.Vector2d; import ui.controller.Control; import ui.controller.HolonCanvasController; import ui.model.Model; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; public class HolonCanvas extends JPanel implements MouseWheelListener, MouseListener, MouseMotionListener { /** * */ private static final long serialVersionUID = 1L; // Ball objects private ArrayList bodies = new ArrayList<>(); private int subCount; private long previousTime = System.currentTimeMillis(); private long currentTime = previousTime; private long totalElapsedTime = 0; private int frameCount = 0; private Dimension center; private ArrayList subnets; private HolonCanvasController hCController; private Control controller; private Model model; private JComboBox combo = new JComboBox<>(); private int comboChoice = 0; private JCheckBox chckbxSort = new JCheckBox("sort by size"); private boolean sizeChange = false; private HolonBody toDrag; HolonCanvas(Model mod, Control control) { // Wire up Events this.controller = control; this.model = mod; hCController = new HolonCanvasController(mod); JLabel lblBodyInfo = new JLabel("Holon Info:"); add(lblBodyInfo); this.add(combo); subnets = controller.getSimManager().getSubNets(); subCount = subnets.size(); previousTime = System.currentTimeMillis(); currentTime = previousTime; totalElapsedTime = 0; frameCount = 0; this.addMouseWheelListener(this); combo.addItem("ID"); combo.addItem("Nr. of Objects"); combo.addItem("Nr. of Edges"); combo.addItem("Nr. of Switches"); combo.addItem("Total Production"); combo.addItem("Total Consumption"); combo.addItem("Nr. of Elements"); combo.addItem("Nr. of Producers"); combo.addItem("Nr. of active Elements"); combo.addActionListener(e -> comboChoice = combo.getSelectedIndex()); this.addMouseListener(this); this.addMouseMotionListener(this); chckbxSort.addChangeListener(e -> sizeChange = true); add(chckbxSort); } // Start Render and Update Threads public void paintComponent(Graphics g) { super.paintComponent(g); // add new colors if necessary for (int i = 0; i < controller.getSimManager().getSubNets().size(); i++) { if (model.getSubNetColors().size() - 1 < i) { controller.addSubNetColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255))); } } // check if subnets have changed if (!controller.getSimManager().getSubNets().equals(subnets)) { subnets = controller.getSimManager().getSubNets(); subCount = subnets.size(); calcCenter(); hCController.addNewBodies(subCount,subnets, center, controller.getHolonBodyScale()); sizeChange = true; } currentTime = System.currentTimeMillis(); long elapsedTime = (currentTime - previousTime); totalElapsedTime += elapsedTime; if (totalElapsedTime > 1000) { // int currentFrameRate = frameCount; frameCount = 0; totalElapsedTime = 0; } // check if HolonBodys should be sorted after size if (chckbxSort.isSelected() && sizeChange) { hCController.rearrangeAfterSize(); sizeChange = false; } hCController.updateBodies(elapsedTime / 1000f); render(g); try { // Thread.sleep(getFpsDelay(maxFrameRate)); Thread.sleep(5); } catch (Exception e) { e.printStackTrace(); } previousTime = currentTime; frameCount++; repaint(); } private void render(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Render Background g2.setColor(Color.WHITE); g2.fillRect(0, 0, getWidth(), getHeight()); bodies = hCController.getBodies(); // Render Objects for (int i = 0; i < subCount; i++) { int bodyNr = bodies.get(i).getId(); String info; switch (comboChoice) { case 0: info = "" + bodyNr; break; case 1: info = "" + subnets.get(bodyNr).getObjects().size(); break; case 2: info = "" + subnets.get(bodyNr).getEdges().size(); break; case 3: info = "" + subnets.get(bodyNr).getSwitches().size(); break; case 4: info = "" + hCController.getTotalProduction(new ArrayList<>(subnets.get(bodyNr).getObjects())); break; case 5: info = "" + hCController.getTotalConsumption(new ArrayList<>(subnets.get(bodyNr).getObjects())); break; case 6: info = "" + hCController.getTotalElements(new ArrayList<>(subnets.get(bodyNr).getObjects())); break; case 7: info = "" + hCController.getTotalProducers(new ArrayList<>(subnets.get(bodyNr).getObjects())); break; case 8: info = "" + hCController.getActiveElements(new ArrayList<>(subnets.get(bodyNr).getObjects())); break; default: info = "" + bodyNr; break; } bodies.get(i).setRadius((subnets.get(bodies.get(i).getId()).getObjects().size() * 5 + 10) * controller.getHolonBodyScale() / 100); bodies.get(i).draw(g2, info); } } // calc the center of the canvas private void calcCenter() { center = this.getSize(); center.height /= 2; center.width /= 2; } @Override public void mouseWheelMoved(MouseWheelEvent e) { controller.setHolonBodyScale(model.getHolonBodyScale() + (-e.getScrollAmount() * e.getWheelRotation())); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { // Body Selection for (int i = 0; i < subCount; i++) { float cx = bodies.get(i).position.getX(); float cy = bodies.get(i).position.getY(); float cr = bodies.get(i).getRadius(); if (e.getX() - cr <= cx && e.getY() - cr <= cy && e.getX() + cr >= cx && e.getY() + cr >= cy) { controller.addSelectedHolonBody(bodies.get(i).getId()); hCController.setBodyToDrag(bodies.get(i).getId()); toDrag = bodies.get(i); break; } else { controller.addSelectedHolonBody(-1); toDrag = null; } hCController.setBodyToDrag(-1); } } @Override public void mouseReleased(MouseEvent e) { hCController.setDrag(false); } @Override public void mouseDragged(MouseEvent e) { hCController.setDrag(true); if (toDrag != null) { toDrag.position = new Vector2d(e.getX(), e.getY()); } repaint(); } @Override public void mouseMoved(MouseEvent e) { } }