package ui.view; import ui.controller.Control; import ui.model.Model; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.basic.BasicSliderUI; import java.awt.*; import java.awt.event.*; /** * This Class represents a Panel where the User can start and stop the * Simulation. He Can also reset the Simulation and click through every * Iteration. * * @author Gruppe14 */ public class TimePanel extends JPanel { private static final long serialVersionUID = 1L; final JButton playBtn = new JButton(); final JButton timeResetBtn = new JButton(); final JButton timeForwardBtn = new JButton(); ; final JButton timeBackwardBtn = new JButton(); private final JPanel btnAndSpeedPanel = new JPanel(); private final JPanel speedPanel = new JPanel(); private final JPanel timeBtnPanel = new JPanel(); JSlider timeSlider = new JSlider() { /** * */ private static final long serialVersionUID = 1L; { // Make the slider jump to mouse position on left click MouseListener[] listeners = getMouseListeners(); for (MouseListener l : listeners) removeMouseListener(l); // remove UI-installed TrackListener final BasicSliderUI ui = (BasicSliderUI) getUI(); BasicSliderUI.TrackListener tl = ui.new TrackListener() { // this is where we jump to absolute value of click @Override public void mouseClicked(MouseEvent e) { Point p = e.getPoint(); int value = ui.valueForXPosition(p.x); setValue(value); } // disable check that will invoke scrollDueToClickInTrack @Override public boolean shouldScroll(int dir) { return false; } }; addMouseListener(tl); } }; private Model model; private Control controller; private int dragResetIteration = 0; private JLabel simSpeedLabel = new JLabel("Speed:"); private JSlider speedSlider = new JSlider(); private Timer timer; private boolean running = false; /** * Constructor. * * @param mod * the Model * @param cont * the Controller */ public TimePanel(Model mod, Control cont) { super(); this.model = mod; this.controller = cont; // One Iteration timer = new Timer(0, new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { timeSlider.setValue(timeSlider.getValue() + 1); controller.setCurIteration(timeSlider.getValue()); timer.setDelay(model.getTimerSpeed()); if (timeSlider.getValue() == model.getIterations() - 1) { running = false; playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png", 30, 30, Image.SCALE_SMOOTH))); timer.stop(); } } }); // Time Slider. Panels and Buttons this.setLayout(new BorderLayout(0, 0)); this.setBorder(null); // Slider timeSlider.setPaintTicks(true); timeSlider.setPaintLabels(true); timeSlider.setMinorTickSpacing(1); timeSlider.setMajorTickSpacing(5); timeSlider.setToolTipText(Languages.getLanguage()[93]); timeSlider.setMaximum(model.getIterations() - 1); timeSlider.setValue(0); timeSlider.addChangeListener(changeEvent -> controller.setCurIteration(timeSlider.getValue())); timeSlider.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { dragResetIteration = model.getCurIteration(); } }); timeSlider.addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { if (dragResetIteration != model.getCurIteration()) { controller.resetSimulation(); if (running) { playBtn.doClick(); } } } }); // Panel timeBtnPanel.setBorder(null); timeBtnPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); // Buttons playBtn.setToolTipText(Languages.getLanguage()[89]); playBtn.setContentAreaFilled(false); playBtn.setBorderPainted(false); playBtn.setBorder(null); playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png",30,30))); playBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { running = !running; controller.setIsSimRunning(running); if (running) { timer.start(); timer.setDelay(model.getTimerSpeed()); playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/pause.png", 30, 30, Image.SCALE_SMOOTH))); } else { timer.stop(); playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png", 30, 30, Image.SCALE_SMOOTH))); } } }); timeResetBtn.setToolTipText(Languages.getLanguage()[90]); timeResetBtn.setContentAreaFilled(false); timeResetBtn.setBorder(null); timeResetBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/reset.png", 30, 30))); timeResetBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { timeSlider.setValue(timeSlider.getMinimum()); controller.setCurIteration(timeSlider.getValue()); // controller.calculateStateForCurrentTimeStep(); controller.resetSimulation(); if (running) { playBtn.doClick(); } } }); timeForwardBtn.setToolTipText(Languages.getLanguage()[91]); timeForwardBtn.setContentAreaFilled(false); timeForwardBtn.setBorder(null); timeForwardBtn.setIcon(new ImageIcon(Util.loadImage(this,"/Button_Images/forward.png",30,30))); timeForwardBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { if (!model.getIsSimRunning()) { controller.setIsSimRunning(true); } timeSlider.setValue(timeSlider.getValue() + 1); controller.setCurIteration(timeSlider.getValue()); } }); timeBackwardBtn.setToolTipText(Languages.getLanguage()[92]); timeBackwardBtn.setBorder(null); timeBackwardBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/backward.png", 30,30))); timeBackwardBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { timeSlider.setValue(timeSlider.getValue() - 1); controller.setCurIteration(timeSlider.getValue()); } }); timeBtnPanel.add(playBtn); timeBtnPanel.add(Box.createRigidArea(new Dimension(10, 0))); timeBtnPanel.add(timeResetBtn); timeBtnPanel.add(Box.createRigidArea(new Dimension(10, 0))); timeBtnPanel.add(timeForwardBtn); // Speed Panel speedPanel.add(simSpeedLabel); speedPanel.add(speedSlider); speedSlider.setPaintTicks(true); speedSlider.setPaintLabels(true); speedSlider.setMaximum(5000); speedSlider.setMinimum(500); speedSlider.setValue(1000); // speedSlider.setMajorTickSpacing(100); speedSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { controller.setTimerSpeed(speedSlider.getValue()); speedSlider.setToolTipText("Speed: " + speedSlider.getValue()); } }); // Buttons and Speed Panel btnAndSpeedPanel.setLayout(new BorderLayout(0, 0)); btnAndSpeedPanel.setBorder(null); btnAndSpeedPanel.add(timeBtnPanel, BorderLayout.NORTH); btnAndSpeedPanel.add(speedPanel, BorderLayout.CENTER); this.add(btnAndSpeedPanel, BorderLayout.WEST); this.add(timeSlider); //Disable Keys timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP_ARROW"); timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN_ARROW"); timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0, false), "PAGE_DOWN"); timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0, false), "PAGE_UP"); timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0, false), "END"); timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0, false), "HOME"); // Left arrow Key timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "LEFT_ARROW"); timeSlider.getActionMap().put("LEFT_ARROW", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { timeSlider.setValue(timeSlider.getValue() - 1); controller.resetSimulation(); } }); //Right arrow Key timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "Right_ARROW"); timeSlider.getActionMap().put("Right_ARROW", new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { if (!model.getIsSimRunning()) { controller.setIsSimRunning(true); } timeSlider.setValue(timeSlider.getValue() + 1); } }); } /** * Retunrs the TimeSlider. * * @return the TimeSlider */ public JSlider getTimeSlider() { return timeSlider; } }