[Java] Рисование картинки, обработка клика мышки
Сдача задания на уроке: не уходите пожалуйста пока я не успею отметить ваши успехи за урок. Если я вдруг не успел или забыл к вам подойти - скажите.
Сдача домашнего задания: на следующем уроке нужно будет запустить на компьютере то что вы выполнили дома и получить оценку за домашнее задание.
Цель вводного задания - сделать окно в котором единорог постепенно убегает из окна но при клик мышкой телепортирует его обратно в середину окна.
Создаем опять окно с панелью
Начнем с того чтобы сделать простое окно с нарисованным внутри эллипсом.
1) Создайте новый проект
2) Создайте новый класс MyPanel
(разверните сверху слева структуру проекта, там src -> правый клик -> New -> Java Class)
3) Укажите что он наследуется от JPanel
(import javax.swing.JPanel;
)
4) Переопределите метод public void paintComponent(Graphics g)
5) Создайте новый класс Main
и в нем main
-функцию и создайте в ней примитивное окно (не забыв в него добавить вашу панель):
JFrame frame = new JFrame(); // создали объект 'окно'
frame.setSize(640, 480); // сделали его чуть побольше
frame.setDefaultCloseOperation(EXIT_ON_CLOSE); // настроили окно так чтобы при его закрытии ваша программа завершалась
MyPanel p = new MyPanel(); // создали объект 'ваша панель' (в которой мы будем рисовать)
frame.add(p); // не забыли ее добавить на окно (чтобы она в нем рисовалась)
frame.setVisible(true); // теперь когда окно готово - делаем его видимым
while (true) { // в вечном цикле
frame.repaint(); // будем постоянно просить окно переотрисовываться (т.о. перерисовывая и вашу панель, вызывая ее метод paintComponent)
}
P.S. не забудьте импортировать JFrame
и EXIT_ON_CLOSE
(кликаете на них, затем Alt+Enter, затем Import class
).
6) Теперь в MyPanel
в вашем методе paintComponent
можно начать что-то рисовать - нарисуйте эллипс, запустите программу и убедитесь что он рисуется.
Рисуем картинку
Теперь давайте сделаем так чтобы ваша MyPanel
хранила картинку единорога и рисовала ее вместо эллипса.
7) Загрузите на диск из интернета эту картинку - откройте ее и затем нажмите Ctrl+S
. Скопируйте эту картинку в папку src
вашего проекта чтобы картинки были рядом с исходными файлами. Папку src
можно легко найти в проводнике если в IDEA нажать на ней правой кнопкой и там Show in Explorer
или что-то вроде Показать в проводнике
. Или просто перетащите скачанную картинку из проводника в папку src
в IDEA (чтобы переместить ее туда).
8) Чтобы хранить картинку в вашей панеле MyPanel
- нужно в ней создать поле BufferedImage unicornImage;
9) Теперь это поле нужно инициализировать (считать в поле unicornImage
с диска картинку) - сделайте это в конструкторе вашей панели:
- Создайте конструктор у вашей панели:
public MyPanel() { ... }
- Внутри этого конструктора инициализируйте поле:
this.unicornImage = ImageIO.read(new File("C:\\...\\src\\unicorn.png"));
(поправьте путь, самый удобный способ: в IDEA правый клик по картинке -> Copy Path -> Absolute Path и затем Ctrl+V) - Обратите внимание что
ImageIO
иFile
- красные, это потому что их нужно импортировать - импортируем - Теперь подсвечивается ошибкой
ImageIO.read(
- это потому что чтение может кинуть ошибку (при неверном пути например), кликните на read -> Alt+Enter -> Add exception to method signature.
10) Наконец давайте заменим рисование эллипса на рисование картинки: g.drawImage(this.unicornImage, 100, 200, null);
(т.е. рисуем по координатам x=100, y=200). Запустите программу чтобы проверить что картинка рисуется!
Двигаем картинку
Теперь давайте сделаем так чтобы единорог двигался на 1 пиксель при каждой отрисовке - для этого надо хранить его координаты в полях int x;
и int y;
в классе MyPanel
.
11) Создайте в MyPanel
поля хранящие координаты единорога. В конструкторе панели инициализируйте эти поля значениями соответствующими середине окошка.
12) Теперь при каждой отрисовке:
- Увеличивайте обе координаты (т.е. оба поля) на единицу
- Рисуйте единорога не по фиксированным координатам, а по этим координатам хранящимся в этих двух полях
Добавляем обработку клика мышкой
Хотим добавить пользователю возможность взаимодействовать с программой - давайте добавим обработку кликов мышки. Сначала пусть это будет телепортация единорога назад в середину экрана, затем пусть это будет телепортация единорога в место клика.
Было бы здорово если бы было достаточно переопределить метод “обработка клика мышки” подобно тому как это было с переопределением метода “отрисовываем панель”, и почти так и выйдет!
Но не любая панель умеет обрабатывать клики мышки.
13) Чтобы ваша панель явно заявила это умение - надо добавить в MyPanel к уже имеющемуся наследованию от JPanel (extends JPanel
) еще и гордое заявление “я являюсь сертифицированным слушателем мышки - MouseListener” - я реализую (на английском - implements
) контракт MouseListener
:
public class MyPanel extends JPanel implements MouseListener {
14) Не забываем добавить импорт для MouseListener.
15) Теперь красная ошибка сообщает нам что мы заявили что мы якобы умеем обрабатывать клики мышки, но пока не рассказали как это делаем - кликаем -> Alt+Enter -> Implement methods (реализовать методы обработки событий мышки) -> OK
16) У вас появились пустые методы обработки разных событий - их названия говорящие, давайте в каждый из этих методов добавим отладочный вывод в коноль чтобы проверить что они срабатывают (в mouseClicked
напишите System.out.println("mouseClicked");
, в остальные четыре метода - соответствующие сообщения)
17) И теперь надо зарегистрировать себя как слушателия мышки - добавьте в конструктор панели this.addMouseListener(this);
. Запустите программу, покликайте мышкой по окну. Убедитесь что в консоли появляются сообщения. Что же каждый метод означает? Исследуйте этот вопрос, если остались непонятки - спросите.
18) Сделайте так чтобы при клике мышкой значение полей хранящих координаты единорога сбрасывались на середину окна (единорог телепортировался при нажатии). Убедитесь что рабоатет.
19) Заметьте что эти методы принимают в скобочках аргумент - MouseEvent e
- он описывает событие более подробно, например там есть информация о координатах клика (e.getX()
и e.getY()
) и том какая кнопка мышки была нажата (e.getButton()
) - проверьте что эти методы возвращают правильные значения - добавьте вывод результатов их вызова в консоль.
20) Измените логику с “телепорт единорога в середину экрана” на “телепорт единорога в место где пользователь нажал мышкой”.
21) Сделайте так чтобы единорог убегал не так быстро:
- сделайте так чтобы координаты единорога хранились в вещественных числах а не целых, и при каждой отрисовке увеличивались не на 1, а на 0.01 например
- или сделайте так чтобы ваше окно переотрисовывалось не слишком часто - добавьте в
while(true)
небольшую задержку -Thread.sleep(30);
- например 30 миллисекунд (т.е. окно в секунду будет перерисовано 1000/30 раз)
22) Добавьте еще одного единорога. Пусть он убегает в другую сторону. Сделайте так чтобы один телепортировался только по левой кнопке мыши, а другой - только по правой.
23) Добавьте еще 100 единорогов (массивом или динамическим списком) разбегающихся в случайных направлениях.
Домашнее задание
Если не доделали описанное выше задание - сначала доделайте его.
Затем придумайте какую-нибудь классную интерактивную анимацию (собранную из разных картинок) и реализуйте ее.
Набросы идей для вдохновения:
- Найдите в интернете маленькую картинку-иконку зайки, нарисуйте 10 заек (в цикле), сделайте так чтобы при клике мышки зайки подпрыгивали
- Найдите в интернете картинки планет солнечной системы, сделайте так чтобы они вращались по осям только пока кнопка мыши зажата (а как только отжата - планеты замирали)
- Найдите картинку какого-нибудь интересного вам персонажа, найдите картинку закрытых и открытых глаз, сделайте так чтобы при клике мышки персонаж моргал (если кнопка мыши зажата - пусть поверх рисуются закрытые глаза, иначе - открытые)
- Найдите картинки метеоритов - при клике добавляйте в динамический список (
ArrayList
) новую пару координат (место клика мышки) - это то где находится еще один метеорит. И при каждой отрисовке двигайте каждый метеорит из списка в случайном направлении (и отрисовывайте по текущим координатам). При клике правой кнопкой мыши - проверьте не попал ли клик в один из метеоритов, и если попал - меняйте его цвет или удаляйте его из списка (пользователь его “подстрелил”).
Если вам захочется заглянуть вперед - можете еще использовать вращение картинок.
Как переносить проект
Рекомендуемый простой и надежный способ переноса проекта с компьютера на компьютер (при выполнении домашки вам наверняка поможет принесенный домой результат работы на уроке):
1) Открыть папку с исходниками (называется src
, можно легко найти в проводнике если в IDEA нажать на ней правой кнопкой и там Show in Explorer
или что-то вроде Показать в проводнике
)
2) В этой папке несколько ваших исходных файлов с расширением .java
(картинки тоже храните в этой папке для удобства)
3) Выделите все исходные файлы (включая картинки) -> правый клик -> Отправить -> Сжатая ZIP-папка
4) Теперь у вас есть ZIP-архив со всеми исходными файлами и картинками - отправьте его себе на почту например или скиньте на флешку
5) Перенесите ZIP-архив на другой компьютер
6) Создайте новый пустой проект в IDEA, откройте в проводнике src
папку (просто нажмите на нее правой кнопкой в IDEA -> Show in Explorer
или что-то вроде Показать в проводнике
)
7) В эту пустую папку для исходников нового проекта скопируйте все что было в ZIP-архиве
8) Вернитесь обратно в IDEA - в папке src
должны были появится все исходники и картинки т.к. вы их только что сюда скопировали
9) Чтобы запустить - нужно кликнуть правой кнопкой на файл с main
-функцией и там кликнуть на Run
(зеленая стрелочка)