TimePanel.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. package ui.view;
  2. import ui.controller.Control;
  3. import ui.model.Model;
  4. import javax.swing.*;
  5. import javax.swing.event.ChangeEvent;
  6. import javax.swing.event.ChangeListener;
  7. import javax.swing.plaf.basic.BasicSliderUI;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import java.util.Hashtable;
  11. /**
  12. * This Class represents a Panel where the User can start and stop the
  13. * Simulation. He Can also reset the Simulation and click through every
  14. * Iteration.
  15. *
  16. * @author Gruppe14
  17. */
  18. public class TimePanel extends JPanel implements ActionListener{
  19. private static final long serialVersionUID = 1L;
  20. private static final int MAX_ITERATIONS=100000;
  21. /*
  22. * variable for calculating the performance
  23. */
  24. //private long performanceTime;
  25. final JButton playBtn = new JButton();
  26. final JButton timeResetBtn = new JButton();
  27. final JButton timeForwardBtn = new JButton();
  28. final JButton timeBackwardBtn = new JButton();
  29. JTextField iterationsField;
  30. final JLabel iterationsLabel=new JLabel(" Iterations ");
  31. private final JPanel btnAndSpeedPanel = new JPanel();
  32. private final JPanel speedPanel = new JPanel();
  33. private final JPanel timeBtnPanel = new JPanel();
  34. private final JPanel iterationsPanel=new JPanel();
  35. private final JPanel timePanel=new JPanel();
  36. JSlider timeSlider = new JSlider() {//TODO:
  37. /**
  38. *
  39. */
  40. private static final long serialVersionUID = 1L;
  41. {
  42. // Make the slider jump to mouse position on left click
  43. MouseListener[] listeners = getMouseListeners();
  44. for (MouseListener l : listeners)
  45. removeMouseListener(l); // remove UI-installed TrackListener
  46. final BasicSliderUI ui = (BasicSliderUI) getUI();
  47. BasicSliderUI.TrackListener tl = ui.new TrackListener() {
  48. // this is where we jump to absolute value of click
  49. @Override
  50. public void mouseClicked(MouseEvent e) {
  51. Point p = e.getPoint();
  52. int value = ui.valueForXPosition(p.x);
  53. setValue(value);
  54. }
  55. // disable check that will invoke scrollDueToClickInTrack
  56. @Override
  57. public boolean shouldScroll(int dir) {
  58. return false;
  59. }
  60. };
  61. addMouseListener(tl);
  62. }
  63. };
  64. //private Model model;
  65. private Control controller;
  66. private int dragResetIteration = 0;
  67. private JLabel simSpeedLabel = new JLabel("Speed:");
  68. private JSlider speedSlider = new JSlider();
  69. private Timer timer;
  70. private boolean running = false;
  71. private GUI parentGUI;
  72. /**
  73. * Constructor.
  74. *
  75. * @param mod
  76. * the Model
  77. * @param cont
  78. * the Controller
  79. */
  80. public TimePanel(GUI parent, Control cont) {
  81. super();
  82. this.controller = cont;
  83. this.parentGUI=parent;
  84. // One Iteration
  85. timer = new Timer(0, new ActionListener() {//TODO: Merge all these damned listeners.
  86. @Override
  87. public void actionPerformed(ActionEvent ae) {
  88. timeSlider.setValue(timeSlider.getValue() + 1);
  89. controller.setCurIteration(timeSlider.getValue());
  90. timer.setDelay(cont.getModel().getTimerSpeed());
  91. if (timeSlider.getValue() >= cont.getModel().getIterations() - 1) {
  92. /*/calc and print performance
  93. performanceTime = System.nanoTime()-performanceTime;
  94. System.out.println(performanceTime/1000000000 + " Sekunden "
  95. + (performanceTime%1000000000)/1000000 + " Millisekunden "
  96. + (performanceTime%1000000)/1000 + " Mikrosekunden ");
  97. //*/
  98. running = false;
  99. playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png", 30, 30, Image.SCALE_SMOOTH)));
  100. timer.stop();
  101. }
  102. }
  103. });
  104. // Time Slider. Panels and Buttons
  105. this.setLayout(new BorderLayout(0, 0));
  106. this.setBorder(null);
  107. // Slider
  108. timeSlider.setPaintTicks(true);
  109. timeSlider.setPaintLabels(true);
  110. timeSlider.setMajorTickSpacing((int)Math.ceil(((double)cont.getModel().getIterations())/20));
  111. timeSlider.setMinorTickSpacing((int)Math.ceil(((double)cont.getModel().getIterations())/100));
  112. timeSlider.setToolTipText(Languages.getLanguage()[93]);
  113. timeSlider.setMaximum(cont.getModel().getIterations() - 1);
  114. timeSlider.setValue(0);
  115. timeSlider.addChangeListener(changeEvent -> controller.setCurIteration(timeSlider.getValue()));
  116. timeSlider.addMouseListener(new MouseAdapter() {
  117. @Override
  118. public void mousePressed(MouseEvent e) {
  119. dragResetIteration = cont.getModel().getCurIteration();
  120. }
  121. });
  122. timeSlider.addMouseMotionListener(new MouseAdapter() {
  123. @Override
  124. public void mouseDragged(MouseEvent e) {
  125. if (dragResetIteration != cont.getModel().getCurIteration()) {
  126. controller.resetSimulation();
  127. if (running) {
  128. playBtn.doClick();
  129. }
  130. }
  131. }
  132. });
  133. // Panel
  134. timeBtnPanel.setBorder(null);
  135. timeBtnPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
  136. // Buttons
  137. playBtn.setToolTipText(Languages.getLanguage()[89]);
  138. playBtn.setContentAreaFilled(false);
  139. playBtn.setBorderPainted(false);
  140. playBtn.setBorder(null);
  141. playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png",30,30)));
  142. playBtn.addActionListener(new ActionListener() {
  143. @Override
  144. public void actionPerformed(ActionEvent e) {
  145. if(cont.getModel().getCurIteration()==cont.getModel().getIterations()-1)timeSlider.setValue(timeSlider.getMinimum());
  146. running = !running;
  147. controller.setIsSimRunning(running);
  148. if (running) {
  149. timer.setDelay(cont.getModel().getTimerSpeed());
  150. /*
  151. * start the Performance Test
  152. * /
  153. performanceTime = System.nanoTime();
  154. timeSlider.setValue(0);
  155. timer.setDelay(0);
  156. speedSlider.setValue(10);
  157. timeSlider.setValue(0);
  158. //*/
  159. timer.start();
  160. playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/pause.png", 30, 30, Image.SCALE_SMOOTH)));
  161. } else {
  162. timer.stop();
  163. playBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/play.png", 30, 30, Image.SCALE_SMOOTH)));
  164. }
  165. }
  166. });
  167. timeResetBtn.setToolTipText(Languages.getLanguage()[90]);
  168. timeResetBtn.setContentAreaFilled(false);
  169. timeResetBtn.setBorder(null);
  170. timeResetBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/reset.png", 30, 30)));
  171. timeResetBtn.addActionListener(new ActionListener() {
  172. public void actionPerformed(ActionEvent ae) {
  173. timeSlider.setValue(timeSlider.getMinimum());
  174. controller.setCurIteration(timeSlider.getValue());
  175. // controller.calculateStateForCurrentTimeStep();
  176. controller.resetSimulation();
  177. if (running) {
  178. playBtn.doClick();
  179. }
  180. }
  181. });
  182. timeForwardBtn.setToolTipText(Languages.getLanguage()[91]);
  183. timeForwardBtn.setContentAreaFilled(false);
  184. timeForwardBtn.setBorder(null);
  185. timeForwardBtn.setIcon(new ImageIcon(Util.loadImage(this,"/Button_Images/forward.png",30,30)));
  186. timeForwardBtn.addActionListener(new ActionListener() {
  187. public void actionPerformed(ActionEvent ae) {
  188. if (!cont.getModel().getIsSimRunning()) {
  189. controller.setIsSimRunning(true);
  190. }
  191. timeSlider.setValue(timeSlider.getValue() + 1);
  192. controller.setCurIteration(timeSlider.getValue());
  193. }
  194. });
  195. timeBackwardBtn.setToolTipText(Languages.getLanguage()[92]);
  196. timeBackwardBtn.setBorder(null);
  197. timeBackwardBtn.setIcon(new ImageIcon(Util.loadImage(this, "/Button_Images/backward.png", 30,30)));
  198. timeBackwardBtn.addActionListener(new ActionListener() {
  199. public void actionPerformed(ActionEvent ae) {
  200. timeSlider.setValue(timeSlider.getValue() - 1);
  201. controller.setCurIteration(timeSlider.getValue());
  202. }
  203. });
  204. timeBtnPanel.add(playBtn);
  205. timeBtnPanel.add(Box.createRigidArea(new Dimension(10, 0)));
  206. timeBtnPanel.add(timeResetBtn);
  207. timeBtnPanel.add(Box.createRigidArea(new Dimension(10, 0)));
  208. timeBtnPanel.add(timeForwardBtn);
  209. // Speed Panel
  210. speedPanel.add(simSpeedLabel);
  211. speedPanel.add(speedSlider);
  212. speedSlider.setPaintTicks(true);
  213. speedSlider.setPaintLabels(true);
  214. speedSlider.setMaximum(6);
  215. speedSlider.setMinimum(0);
  216. speedSlider.setValue(1);
  217. speedSlider.setPaintLabels(true);
  218. Hashtable<Integer, JLabel> table = new Hashtable<Integer, JLabel>();
  219. table.put (0, new JLabel("1x"));
  220. table.put (1, new JLabel("2x"));
  221. table.put (2, new JLabel("4x"));
  222. table.put (3, new JLabel("8x"));
  223. table.put (4, new JLabel("16x"));
  224. table.put (5, new JLabel("32x"));
  225. table.put (6, new JLabel("64x"));
  226. speedSlider.setLabelTable(table);
  227. speedSlider.addChangeListener(new ChangeListener() {
  228. @Override
  229. public void stateChanged(ChangeEvent e) {
  230. /**
  231. * Shifting Powers of two:
  232. * e.g. 1<<0 -> 1 step per Second
  233. * 1<<3 -> 8 steps per Second
  234. * and so on,
  235. */
  236. int calculationsPerSecond = 1 << speedSlider.getValue();
  237. controller.setTimerSpeed(1024 >> speedSlider.getValue());
  238. speedSlider.setToolTipText("Speed: " + calculationsPerSecond + " Calculations per Second.");
  239. }
  240. });
  241. speedSlider.setToolTipText("Change the Number of Calculations per Secons");
  242. // Buttons and Speed Panel
  243. btnAndSpeedPanel.setLayout(new BorderLayout(0, 0));
  244. btnAndSpeedPanel.setBorder(null);
  245. btnAndSpeedPanel.add(timeBtnPanel, BorderLayout.NORTH);
  246. btnAndSpeedPanel.add(speedPanel, BorderLayout.CENTER);
  247. iterationsPanel.setLayout(new GridLayout(3,1));
  248. iterationsPanel.add(iterationsLabel, BorderLayout.NORTH);
  249. iterationsField=new JTextField(6);//Considering hundreds of thousands in an extreme case
  250. iterationsField.setText(""+cont.getModel().getIterations());
  251. iterationsField.addActionListener(this);//TODO
  252. iterationsPanel.add(iterationsField);
  253. iterationsPanel.add(new JLabel(), BorderLayout.SOUTH);
  254. timePanel.setLayout(new BorderLayout());
  255. timePanel.add(iterationsPanel, BorderLayout.WEST);
  256. timePanel.add(timeSlider, BorderLayout.CENTER);
  257. this.add(btnAndSpeedPanel, BorderLayout.WEST);
  258. add(timePanel);
  259. //Disable Keys
  260. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP_ARROW");
  261. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN_ARROW");
  262. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0, false), "PAGE_DOWN");
  263. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0, false), "PAGE_UP");
  264. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0, false), "END");
  265. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0, false), "HOME");
  266. // Left arrow Key
  267. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "LEFT_ARROW");
  268. timeSlider.getActionMap().put("LEFT_ARROW", new AbstractAction() {
  269. private static final long serialVersionUID = 1L;
  270. @Override
  271. public void actionPerformed(ActionEvent e) {
  272. timeSlider.setValue(timeSlider.getValue() - 1);
  273. controller.resetSimulation();
  274. }
  275. });
  276. //Right arrow Key
  277. timeSlider.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "Right_ARROW");
  278. timeSlider.getActionMap().put("Right_ARROW", new AbstractAction() {
  279. private static final long serialVersionUID = 1L;
  280. @Override
  281. public void actionPerformed(ActionEvent e) {
  282. if (!cont.getModel().getIsSimRunning()) {
  283. controller.setIsSimRunning(true);
  284. }
  285. timeSlider.setValue(timeSlider.getValue() + 1);
  286. }
  287. });
  288. }
  289. /**
  290. * Returns the TimeSlider.
  291. *
  292. * @return the TimeSlider
  293. */
  294. public JSlider getTimeSlider() {
  295. return timeSlider;
  296. }
  297. @Override
  298. public void actionPerformed(ActionEvent arg0) {//I dislike anon classes.
  299. try{
  300. int iterations=Integer.parseInt(iterationsField.getText());
  301. boolean resetField=true;
  302. if(iterations<1)iterations=1;
  303. else if(iterations>MAX_ITERATIONS)iterations=MAX_ITERATIONS;
  304. else resetField=false;
  305. if(resetField)iterationsField.setText(""+iterations);
  306. controller.getModel().setIterations(Integer.parseInt(iterationsField.getText()));
  307. timeSlider.setMaximum(controller.getModel().getIterations()-1);//TODO forgot this
  308. timeSlider.setLabelTable(null);//Otherwise the ticks won't update
  309. timeSlider.setMajorTickSpacing((int)Math.ceil(((double)controller.getModel().getIterations())/20));
  310. timeSlider.setMinorTickSpacing((int)Math.ceil(((double)controller.getModel().getIterations())/100));
  311. parentGUI.updateIterations();
  312. }catch(NumberFormatException e){
  313. }
  314. }
  315. }