Создание многопоточного приложения с элементами вывода графической информации - Java

Узнай цену своей работы

Формулировка задачи:

В общем кодил тут програмку Суть заключается в том, что по экрану летают ромбы В меню управления есть три пункта 1. Приостановка выборочных фигур 2. Приостановка всех фигур 3. И возобновление движения суть вопроса заключается в том никак не могу понять как прописать что при нажатии кнопки приостановка выборочных фигур остонавливаются только те фигуры которые находят в диапазоне (угол скорости фигуры находится между 180 и 270 градусов (3-я четверть)) Прикрепил архив с кодом программирую в Eclipse Помогите разобраться)

Решение задачи: «Создание многопоточного приложения с элементами вывода графической информации»

textual
Листинг программы
  1. MainFrame
  2. package mainPackage;
  3. import java.awt.BorderLayout;
  4. import java.awt.Toolkit;
  5. import java.awt.event.ActionEvent;
  6. import javax.swing.AbstractAction;
  7. import javax.swing.Action;
  8. import javax.swing.JFrame;
  9. import javax.swing.JMenu;
  10. import javax.swing.JMenuBar;
  11. import javax.swing.JMenuItem;
  12. @SuppressWarnings("serial")
  13. public class MainFrame extends JFrame {
  14. // Константы, задающие размер окна приложения, если оно
  15. // не распахнуто на весь экран
  16. private static final int WIDTH = 700;
  17. private static final int HEIGHT = 500;
  18. private JMenuItem pauseMenuItem;
  19. private JMenuItem resumeMenuItem;
  20. // Поле, по которому движутся фигуры
  21. private Field field = new Field();
  22. // Конструктор главного окна приложения
  23. public MainFrame() {
  24. super("Программирование и синхронизация потоков");
  25. setSize(WIDTH, HEIGHT);
  26. Toolkit kit = Toolkit.getDefaultToolkit();
  27. // Отцентрировать окно приложения на экране
  28. setLocation((kit.getScreenSize().width - WIDTH)/2,
  29. (kit.getScreenSize().height - HEIGHT)/2);
  30. // Установить начальное состояние окна развернутым на весь экран
  31. setExtendedState(MAXIMIZED_BOTH);
  32. // Создать меню
  33. JMenuBar menuBar = new JMenuBar();
  34. setJMenuBar(menuBar);
  35. JMenu figuresMenu = new JMenu("Фигуры");
  36. Action addFigureAction = new AbstractAction("Добавить фигуру") {
  37. public void actionPerformed(ActionEvent event) {
  38. field.addFigure();
  39. if (!pauseMenuItem.isEnabled() &&
  40. !resumeMenuItem.isEnabled()) {
  41. // Ни один из пунктов меню не является
  42. // доступным - сделать доступным "Паузу"
  43. pauseMenuItem.setEnabled(true);
  44. }
  45. }
  46. };
  47. menuBar.add(figuresMenu);
  48. figuresMenu.add(addFigureAction);
  49. JMenu controlMenu = new JMenu("Управление");
  50. menuBar.add(controlMenu);
  51.  
  52.  
  53. pauseMenuItem = controlMenu.add(pauseAction);
  54. pauseMenuItem.setEnabled(false);
  55. Action resumeAction2 = new AbstractAction("Остановка рандомных фигурок"){
  56.     public void actionPerformed(ActionEvent event) {
  57.  
  58.         field.paused2();
  59.         pauseMenuItem.setEnabled(true);
  60.         resumeMenuItem.setEnabled(true);
  61.         pauseSelect.setEnabled(false);
  62.  
  63.     }
  64. };
  65.  
  66. Action pauseAction = new AbstractAction("Приостановить движение"){
  67. public void actionPerformed(ActionEvent event) {
  68. field.pause();
  69. pauseMenuItem.setEnabled(false);
  70. resumeMenuItem.setEnabled(true);
  71. }
  72. };
  73.  
  74.  
  75.  
  76.  
  77. pauseMenuItem = controlMenu.add(pauseAction);
  78. pauseMenuItem.setEnabled(false);
  79. Action resumeAction = new AbstractAction("Возобновить движение") {
  80. public void actionPerformed(ActionEvent event) {
  81. field.resume();
  82. pauseMenuItem.setEnabled(true);
  83. resumeMenuItem.setEnabled(false);
  84. }
  85. };
  86. resumeMenuItem = controlMenu.add(resumeAction);
  87. resumeMenuItem.setEnabled(false);
  88. // Добавить в центр граничной компоновки поле Field
  89. getContentPane().add(field, BorderLayout.CENTER);
  90. }
  91. // Главный метод приложения
  92. public static void main(String[] args) {
  93. // Создать и сделать видимым главное окно приложения
  94. MainFrame frame = new MainFrame();
  95. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  96. frame.setVisible(true);
  97. }
  98. }
  99.  
  100. MovingFigure
  101. package mainPackage;
  102. import java.awt.BasicStroke;
  103. import java.awt.Color;
  104. import java.awt.Graphics2D;
  105. import java.awt.Stroke;
  106. import java.awt.geom.AffineTransform;
  107. import java.awt.geom.Area;
  108. import java.awt.geom.Rectangle2D;
  109. public class MovingFigure implements Runnable {
  110. // Максимальный размер половины стороны квадрата, описывающего фигуру
  111. private static final int maxFramingSquareHalfSize = 60;
  112. // Минимальный размер половины стороны квадрата, описывающего фигуру
  113. private static final int minFramingSquareHalfSize = 10;
  114. // Минимальное время, на которое может засыпать поток после каждого смещения
  115. private static final int minSleepTime = 1;
  116. private Field field;
  117. // Характеристики фигуры
  118. // Половина стороны квадрата, описывающего фигуру
  119. private int framingSquareHalfSize;
  120. // Цвет для заливки внутреннего простанства фигуры
  121. private Color color;
  122. // Штриховка для рисования границы фигуры
  123. float [] dash = {8,2,8,2,2,2,2,2,4,2,4,2};
  124. private Stroke stroke = new BasicStroke(2.0f, BasicStroke.CAP_BUTT,
  125.         BasicStroke.JOIN_ROUND, 10.0f, dash, 0.0f);
  126. // Текущие координаты центра фигуры
  127. private double x;
  128. private double y;
  129. // Время сна потока между двумя пересчетами координат
  130. private int sleepTime;
  131. // Вертикальная и горизонтальная компоненты смещения
  132. private double shiftX;
  133. private double shiftY;
  134. //Конструктор класса MovingFigure
  135. public MovingFigure(Field field) {
  136. //Необходимо иметь ссылку на поле, по которому передвигается фигура,
  137. //чтобы отслеживать выход за его пределы через getWidth(), getHeight()
  138. this.field = field;
  139. //Случайно выбираем размер половины стороны квадрата, описывающего фигуру
  140. framingSquareHalfSize = minFramingSquareHalfSize + new Double(
  141. Math.random()*(maxFramingSquareHalfSize - minFramingSquareHalfSize)).intValue();
  142. //Абсолютное значение времени сна потока зависит от размера фигуры,
  143. //чем он больше, тем больше
  144. sleepTime = 16 -
  145. new Double(Math.round(210 / framingSquareHalfSize)).intValue();
  146. if (sleepTime < minSleepTime)
  147. sleepTime = minSleepTime;
  148. //Начальное направление движения случайно, угол в пределах от 0 до 2PI
  149. double angle = Math.random()*2*Math.PI;
  150. //Вычисляются горизонтальная и вертикальная компоненты смещения
  151. shiftX = 3*Math.cos(angle);
  152. shiftY = 3*Math.sin(angle);
  153. //Цвет фигуры выбирается случайно
  154. color = new Color((float)Math.random(), (float)Math.random(),
  155.         (float)Math.random());
  156. //Начальное положение фигуры случайно
  157. x = framingSquareHalfSize + Math.random()*
  158. (field.getSize().getWidth()-2*framingSquareHalfSize);
  159. y = framingSquareHalfSize + Math.random()*
  160. (field.getSize().getHeight()-2*framingSquareHalfSize);
  161. //Создаем новый экземпляр потока, передавая аргументом
  162. //ссылку на объект класса, реализующего Runnable (т.е. на себя)
  163. Thread thisThread = new Thread(this);
  164. //Запускаем поток
  165. thisThread.start();
  166. }
  167. //Метод run() исполняется внутри потока. Когда он завершает работу,
  168. //то завершается и поток
  169. public void run() {
  170. try {
  171. //Крутим бесконечный цикл, т.е. пока нас не прервут,
  172. //мы не намерены завершаться
  173. while(true) {
  174. //Синхронизация потоков выполняется на объекте field.
  175. //Если движение разрешено - управление будет возвращено в метод.
  176. //В противном случае - активный поток заснет
  177. field.canMove(this);
  178. if (x + shiftX <= framingSquareHalfSize) {
  179. //Достигли левой стенки, отскакиваем право
  180. shiftX = -shiftX;
  181. x = framingSquareHalfSize;
  182. } else if (x + shiftX >= field.getWidth()-
  183. framingSquareHalfSize) {
  184. // Достигли правой стенки, отскок влево
  185. shiftX = -shiftX;
  186. x=new Double(field.getWidth()-
  187. framingSquareHalfSize).intValue();
  188. } else if (y + shiftY <= framingSquareHalfSize) {
  189. // Достигли верхней стенки
  190. shiftY = -shiftY;
  191. y = framingSquareHalfSize;
  192. } else if (y + shiftY >= field.getHeight()-
  193. framingSquareHalfSize) {
  194. // Достигли нижней стенки
  195. shiftY = -shiftY;
  196. y=new Double(field.getHeight()-
  197. framingSquareHalfSize).intValue();
  198. } else {
  199. // Просто смещаемся
  200. x += shiftX;
  201. y += shiftY;
  202. }
  203. // Засыпаем на sleepTime миллисекунд
  204. Thread.sleep(sleepTime);
  205. }
  206. } catch (InterruptedException ex) {
  207. // Если нас прервали, то ничего не делаем
  208. // и просто выходим (завершаемся)
  209. }
  210. }
  211. // Метод прорисовки самой себя
  212. public void paint (Graphics2D canvas) {
  213.     Rectangle2D.Double rect1 = new Rectangle2D.Double(x-framingSquareHalfSize, y-framingSquareHalfSize,
  214.             2*framingSquareHalfSize, 2*framingSquareHalfSize);
  215.     Rectangle2D.Double rect2 = new Rectangle2D.Double(x-framingSquareHalfSize, y-framingSquareHalfSize,
  216.             2*framingSquareHalfSize, 2*framingSquareHalfSize);
  217.     Area figure = new Area(rect1);
  218.     AffineTransform at = AffineTransform.getRotateInstance(
  219.             Math.PI/3, rect1.getCenterX(), rect2.getCenterY());
  220.     figure.transform(at);
  221.     //figure.add(new Area(rect2));
  222.     canvas.setPaint(color);
  223.     canvas.fill(figure);
  224.    
  225.     canvas.setStroke(stroke);
  226.     canvas.setPaint(Color.black);
  227.     canvas.draw(figure);
  228.     //canvas.draw(line);
  229. }
  230.  
  231. }
  232.  
  233. Field
  234. package mainPackage;
  235. import java.awt.Color;
  236. import java.awt.Graphics;
  237. import java.awt.Graphics2D;
  238. import java.awt.event.ActionEvent;
  239. import java.awt.event.ActionListener;
  240. import java.util.ArrayList;
  241. import javax.swing.JPanel;
  242. import javax.swing.Timer;
  243. @SuppressWarnings("serial")
  244. public class Field extends JPanel {
  245. // Флаг приостановки движения
  246. private boolean paused;
  247. // Динамический список движущихся фигур
  248. private ArrayList<MovingFigure> figures = new ArrayList<MovingFigure>(10);
  249. // Класс таймер отвечает за регулярную генерацию событий ActionEvent
  250. // При создании его экземпляра используется анонимный класс,
  251. // реализующий интерфейс ActionListener
  252. private Timer repaintTimer = new Timer(10, new ActionListener() {
  253. public void actionPerformed(ActionEvent ev) {
  254. // Задача обработчика события ActionEvent - перерисовка окна
  255. repaint();
  256. }
  257. });
  258. // Конструктор класса Field
  259. public Field() {
  260. // Установить цвет заднего фона белым
  261. setBackground(Color.WHITE);
  262. // Запустить таймер
  263. repaintTimer.start();
  264. }
  265. // Унаследованный от JPanel метод перерисовки компонента
  266. public void paintComponent(Graphics g) {
  267. // Вызвать версию метода, унаследованную от предка
  268. super.paintComponent(g);
  269. Graphics2D canvas = (Graphics2D) g;
  270. // Последовательно запросить прорисовку от всех фигур из списка
  271. for (MovingFigure figure: figures)
  272. figure.paint(canvas);
  273. }
  274. // Метод добавления новой фигуры в список
  275. public void addFigure() {
  276.     // Заключается в добавлении в список нового экземпляра MovingFigure
  277.     // Всю инициализацию положения, скорости, размера, цвета
  278.     // MovingFigure выполняет в своем конструкторе
  279.     figures.add(new MovingFigure(this));
  280.     }
  281.     // Cинхронизированный метод приостановки движения фигур
  282.     // (только один поток может одновременно быть внутри)
  283.     public synchronized void pause() {
  284.         // Включить режим паузы
  285.         paused = true;
  286.         }
  287.         // Cинхронизированный метод возобновления движения фигур
  288.         // (только один поток может одновременно быть внутри)
  289.         public synchronized void resume() {
  290.         // Выключить режим паузы
  291.         paused = false;
  292.         // Будим все ожидающие продолжения потоки
  293.         notifyAll();
  294.         }
  295.         // Синхронизированный метод проверки, может ли фигура двигаться
  296.         // (не включен ли режим паузы?)
  297.         public synchronized void canMove(MovingFigure figure) throws InterruptedException {
  298.         // Если режим паузы включен, то поток, зашедший
  299.         // внутрь данного метода, засыпает
  300.         if (paused)
  301.         wait();
  302.         }
  303.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.111 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы