123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- package holeg.ui.view.main;
- import holeg.preferences.ColorPreference;
- import holeg.preferences.ImagePreference;
- import holeg.ui.controller.Control;
- import holeg.ui.model.GuiSettings;
- import holeg.ui.view.image.Import;
- import holeg.utility.listener.LostFocusListener;
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.FlowLayout;
- import java.awt.GridBagConstraints;
- import java.awt.GridBagLayout;
- import java.awt.Point;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import java.util.Hashtable;
- import java.util.concurrent.ScheduledFuture;
- import java.util.concurrent.ScheduledThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
- import javax.swing.AbstractAction;
- import javax.swing.Box;
- import javax.swing.ImageIcon;
- import javax.swing.JButton;
- import javax.swing.JLabel;
- import javax.swing.JPanel;
- import javax.swing.JSlider;
- import javax.swing.JTextField;
- import javax.swing.KeyStroke;
- import javax.swing.SwingConstants;
- import javax.swing.Timer;
- import javax.swing.event.ChangeEvent;
- import javax.swing.event.ChangeListener;
- import javax.swing.plaf.basic.BasicSliderUI;
- /**
- * 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 implements ActionListener {
- private static final int MAX_ITERATIONS = 100000;
- /*
- * variable for calculating the performance
- */
- // private long performanceTime;
- final JButton playBtn = new JButton();
- final JButton timeResetBtn = new JButton();
- final JButton timeForwardBtn = new JButton();
- final JButton timeBackwardBtn = new JButton();
- final JLabel iterationsLabel = new JLabel("Iterations:", SwingConstants.CENTER);
- private final Control control;
- private final JSlider speedSlider = new JSlider();
- private final Timer timer;
- JTextField iterationsField;
- JLabel hint = new JLabel("Invalid", SwingConstants.RIGHT);
- // private LabelHint iterationsLblHint;
- JSlider timeSlider = new JSlider() {
- {
- // 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 ScheduledFuture<?> futureTask;
- private int dragResetIteration = 0;
- private boolean running = false;
- /**
- * Constructor
- *
- * @param cont the Controller
- */
- public TimePanel(Control cont) {
- super();
- this.control = cont;
- // One Iteration
- timer = new Timer(0, clicked -> timerAction());
- // Time Slider. Panels and Buttons
- this.setLayout(new BorderLayout(0, 0));
- this.setBorder(null);
- // Slider
- timeSlider.setPaintTicks(true);
- timeSlider.setPaintLabels(true);
- timeSlider.setMajorTickSpacing(
- (int) Math.ceil(((double) cont.getModel().getMaxIterations()) / 20));
- timeSlider.setMinorTickSpacing(
- (int) Math.ceil(((double) cont.getModel().getMaxIterations()) / 100));
- timeSlider.setToolTipText("Time Slider");
- timeSlider.setMaximum(cont.getModel().getMaxIterations() - 1);
- timeSlider.setValue(0);
- timeSlider.addChangeListener(
- changeEvent -> control.getModel().setCurrentIteration(timeSlider.getValue()));
- this.setBorder(null);
- timeSlider.addChangeListener(changeEvent -> {
- control.updateStateForIteration(timeSlider.getValue());
- });
- timeSlider.addMouseListener(new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent e) {
- dragResetIteration = cont.getModel().getCurrentIteration();
- }
- });
- timeSlider.addMouseMotionListener(new MouseAdapter() {
- @Override
- public void mouseDragged(MouseEvent e) {
- if (dragResetIteration != cont.getModel().getCurrentIteration()) {
- if (running) {
- play();
- }
- }
- }
- });
- // Panel
- JPanel timeBtnPanel = new JPanel();
- timeBtnPanel.setBorder(null);
- timeBtnPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
- // Buttons
- playBtn.setToolTipText("Play");
- playBtn.setContentAreaFilled(false);
- playBtn.setBorderPainted(false);
- playBtn.setBorder(null);
- playBtn.setIcon(new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Play, 30, 30)));
- playBtn.addActionListener(clicked -> play());
- timeResetBtn.setToolTipText("Reset");
- timeResetBtn.setContentAreaFilled(false);
- timeResetBtn.setBorder(null);
- timeResetBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Reset, 30, 30)));
- timeResetBtn.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent ae) {
- timeSlider.setValue(timeSlider.getMinimum());
- control.getModel().setCurrentIteration(timeSlider.getValue());
- control.resetSimulation();
- control.updateStateForCurrentIteration();
- if (running) {
- play();
- }
- }
- });
- timeForwardBtn.setToolTipText("Forward");
- timeForwardBtn.setContentAreaFilled(false);
- timeForwardBtn.setBorder(null);
- timeForwardBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Forward, 30, 30)));
- timeForwardBtn.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent ae) {
- timeSlider.setValue(timeSlider.getValue() + 1);
- control.getModel().setCurrentIteration(timeSlider.getValue());
- }
- });
- timeBackwardBtn.setToolTipText("Backward");
- timeBackwardBtn.setBorder(null);
- timeBackwardBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Backward, 30, 30)));
- timeBackwardBtn.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent ae) {
- timeSlider.setValue(timeSlider.getValue() - 1);
- control.getModel().setCurrentIteration(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
- JPanel speedPanel = new JPanel();
- JLabel simSpeedLabel = new JLabel("Speed:");
- speedPanel.add(simSpeedLabel);
- speedPanel.add(speedSlider);
- speedSlider.setPaintTicks(true);
- speedSlider.setPaintLabels(true);
- speedSlider.setMaximum(6);
- speedSlider.setMinimum(0);
- speedSlider.setValue(1);
- speedSlider.setPaintLabels(true);
- Hashtable<Integer, JLabel> table = new Hashtable<Integer, JLabel>();
- table.put(0, new JLabel("1x"));
- table.put(1, new JLabel("2x"));
- table.put(2, new JLabel("4x"));
- table.put(3, new JLabel("8x"));
- table.put(4, new JLabel("16x"));
- table.put(5, new JLabel("32x"));
- table.put(6, new JLabel("64x"));
- speedSlider.setLabelTable(table);
- speedSlider.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- /**
- * Shifting Powers of two: e.g. 1<<0 -> 1 step per Second 1<<3 -> 8 steps per
- * Second and so on,
- */
- int calculationsPerSecond = 1 << speedSlider.getValue();
- GuiSettings.timerSpeed = (1024 >> speedSlider.getValue());
- speedSlider.setToolTipText("Speed: " + calculationsPerSecond + " Calculations per Second.");
- }
- });
- speedSlider.setToolTipText("Change the Number of Calculations per Secons");
- // Buttons and Speed Panel
- JPanel btnAndSpeedPanel = new JPanel();
- btnAndSpeedPanel.setLayout(new BorderLayout(0, 0));
- btnAndSpeedPanel.setBorder(null);
- btnAndSpeedPanel.add(timeBtnPanel, BorderLayout.NORTH);
- btnAndSpeedPanel.add(speedPanel, BorderLayout.CENTER);
- JPanel iterationsPanel = new JPanel();
- iterationsPanel.setLayout(new GridBagLayout());
- GridBagConstraints c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 0;
- c.gridy = 0;
- iterationsPanel.add(iterationsLabel, c);
- // iterationsLblHint=new LabelHint(iterationsLabel);
- hint.setForeground(Color.red);
- hint.setText(" ");
- iterationsField = new JTextField(6);// Considering hundreds of thousands in an extreme case
- iterationsField.setText("" + cont.getModel().getMaxIterations());
- iterationsField.setToolTipText("0-" + MAX_ITERATIONS);
- iterationsField.addActionListener(this);
- ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(1);
- iterationsField.addCaretListener((e) -> {
- try {
- iterationsField.setBackground(Color.WHITE);// red stings
- if (futureTask != null) {
- futureTask.cancel(true);
- }
- futureTask = s.schedule((Runnable) this::updateIterationsInput, 1, TimeUnit.SECONDS);
- hint.setText(" ");
- } catch (NumberFormatException n) {
- iterationsField.setBackground(ColorPreference.TimePanel.Invalid);// red stings
- hint.setText("Invalid");
- }
- });
- iterationsField.addFocusListener((LostFocusListener) (e) -> updateIterationsInput());
- c.gridy = 1;
- iterationsPanel.add(iterationsField, c);
- c.gridy = 2;
- iterationsPanel.add(hint, c);
- // iterationsPanel.add(new JLabel(), BorderLayout.SOUTH);
- JPanel timePanel = new JPanel();
- timePanel.setLayout(new BorderLayout());
- ;
- timePanel.add(iterationsPanel, BorderLayout.WEST);
- timePanel.add(timeSlider, BorderLayout.CENTER);
- this.add(btnAndSpeedPanel, BorderLayout.WEST);
- add(timePanel);
- // 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);
- control.resetSimulation();
- control.calculateStateForCurrentIteration();
- }
- });
- // 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) {
- timeSlider.setValue(timeSlider.getValue() + 1);
- }
- });
- }
- public void timerAction() {
- timeSlider.setValue(timeSlider.getValue() + 1);
- control.getModel().setCurrentIteration(timeSlider.getValue());
- timer.setDelay(GuiSettings.timerSpeed);
- if (timeSlider.getValue() >= control.getModel().getMaxIterations() - 1) {
- running = false;
- playBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Play, 30, 30)));
- timer.stop();
- }
- }
- public void play() {
- if (control.getModel().getCurrentIteration() == control.getModel().getMaxIterations() - 1) {
- timeSlider.setValue(timeSlider.getMinimum());
- }
- running = !running;
- if (running) {
- timer.setDelay(GuiSettings.timerSpeed);
- timer.start();
- playBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Pause, 30, 30)));
- } else {
- timer.stop();
- playBtn.setIcon(
- new ImageIcon(Import.loadImage(ImagePreference.Button.TimePanel.Play, 30, 30)));
- }
- }
- /**
- * Returns the TimeSlider.
- *
- * @return the TimeSlider
- */
- public JSlider getTimeSlider() {
- return timeSlider;
- }
- @Override
- public void actionPerformed(ActionEvent arg0) {
- updateIterationsInput();
- }
- /**
- * Update the Text field and apply valid changes to update Iterations from to model.
- * <p>
- * Executed by user input.
- */
- private void updateIterationsInput() {
- try {
- int iterations = Integer.parseInt(iterationsField.getText());
- // iterationsLblHint.reset();
- boolean resetField = true;
- if (iterations < 1) {
- iterations = 1;
- } else if (iterations > MAX_ITERATIONS) {
- iterations = MAX_ITERATIONS;
- } else {
- resetField = false;
- }
- if (resetField) {
- iterationsField.setText("" + iterations);
- }
- control.getModel().setIterations(Integer.parseInt(iterationsField.getText()));
- timeSlider.setMaximum(control.getModel().getMaxIterations() - 1);
- timeSlider.setLabelTable(null);// Otherwise the ticks won't update
- timeSlider.setMajorTickSpacing((int) Math.ceil(((double) iterations) / 20));
- timeSlider.setMinorTickSpacing(
- (int) Math.ceil(((double) iterations) / 100));// Even though the final mark
- // can't actually be
- // reached.
- } catch (NumberFormatException e) {
- }
- }
- }
|