Назад
Вперед
4.6. Перемещение объектов мышью
Пример демонстрирует способы обработки
событий от мыши в модели JDK версии 1.1. Рассказано о
применении методов интерфейса MouseMotionListener.
Исходный текст примера
Архив проекта для Java WorkShop 2.0
Демонстрация
(ваш браузер должен уметь работать с аплетами
Java в стандарте JDK 1.1)
Немного теории
Как мы уже говорили в описании предыдущего
примера, для обработки событий от мыши в JDK 1.1
предусмотрены два интерфейса - MouseListener и
MouseMotionListener. Там же мы подробно рассмотрели
интерфейс MouseListener.
Теперь мы на конкретном примере расскажем об
использовании интерфейса MouseMotionListener. Этот
интерфейс предназначен для отслеживания
перемещения курсора мыши. Его регистрация
выполняется при помощи метода addMouseMotionListener.
Интерфейс MouseMotionListener предполагает реализацию
следующих методов:
Метод |
Действие пользователя, в результате
которого метод получает управление |
mouseMoved |
Перемещение курсора мыши |
mouseDraged |
Операция переноса объектов:
пользователь нажимает клавишу мыши, перемещает
курсор и затем отпускает клавишу мыши |
В процессе перемещения курсора или
перетягивания объекта методы вызываются
многократно.
В качестве единственного параметра указанным
методам передается ссылка на объект класса
MouseEvent, например:
public void mouseMoved(MouseEvent e)
{
}
Из предыдущих разделов нашей библиотеки
примеров вы уже знаете, что при помощи этой
ссылки приложение Java может извлечь
разнообразную информацию о мыши на момент
возникновения события.
Внутри методов mouseMoved и mouseDraged приложения обычно
вызывают методы getX и getY возвращающие координаты
курсора мыши. При необходимости воспользуйтесь
методом getPoint. Он возвращает ссылку на объект
класса Point, содержащий текущие координаты мыши.
Описание примера
Внутри окна нашего аплета имеется небольшое
изображение дискеты, которое можно перемещать
при помощи мыши (рис. 1).
Рис. 1. Окно аплета с изображением дискеты
В процессе перемещения аплет контролирует
выход дискеты за границы окна, отмеченные тонкой
рамкой черного цвета.
Как устроен наш аплет?
Класс MouseMove
Главный класс нашего аплета MouseMove реализует
сразу два интерфейса - MouseMotionListener и MouseListener:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class MouseMove extends Applet
implements MouseMotionListener, MouseListener
{
. . .
}
При помощи первого из них мы отслеживаем
изменение координат курсора мыши при выполнении
операции перемещения дискеты, а второй нужен нам
для определения координат этого курсора в начале
перемещения.
Расскажем о полях класса MouseMove.
В поле imFloppy записана ссылка на изображение
дискеты:
Image imFloppy;
Поля imHeight и imWidth хранят размеры этого
изображения в пикселах по вертикали и
горизонтали, соответственно:
int imHeight;
int imWidth;
В поле rcImage хранятся текущие границы области,
занимаемой изображением дискеты в окне аплета:
Rectangle rcImage;
Флаг bBeginDrag принимает значение true на время
выполнения операции перемещения изображения
дискеты:
boolean bBeginDrag = false;
Поля imX и imY хранят текущие координаты курсора
мыши при перемещении изображения дискеты:
int imX = 0;
int imY = 0;
Когда пользователь начинает перемещение
дискеты, он располагает курсор в произвольное
место изображения и начинает перемещение. В
переменных dx и dy мы храним смещение точки
"захвата" изображения дискеты относительно
верхнего левого угла этого изображения:
int dx = 0;
int dy = 0;
Заметим, что это смещение имеет отрицательный
знак.
И, наконец, в поле dm хранятся текущие размеры
окна аплета:
Dimension dm;
Метод init
При инициализации мы загружаем изображение
дискеты из файла disk.gif. Предполагается, что этот
файл находится в том же каталоге, что и файл
байт-кода аплета.
Однако загрузка файла через медленные каналы
Internet может занять некоторое время, поэтому мы
выполняем ожидание завершения процесса при
помощи специально предназначенного для этого
класса MediaTracker:
MediaTracker tr = new MediaTracker(this);
imFloppy = getImage(getCodeBase(),
"disk.gif");
tr.addImage(imFloppy, 0);
try
{
tr.waitForAll();
}
catch (InterruptedException e) {}
Когда загрузка будет завершена, метод init
определяет размеры изображения дискеты и
сохраняет их в соответствующих полях:
imHeight = imFloppy.getHeight(this);
imWidth = imFloppy.getWidth(this);
Далее инициализируется поле rcImage, содержащее
границы области, занимаемой изображением:
rcImage = new Rectangle(imX, imY,
imHeight, imWidth);
Мы также определяем и сохраняем размеры окна
аплета:
dm = getSize();
На завершающей стадии своей работы метод init
регистрирует интерфейсы MouseMotionListener и MouseListener:
this.addMouseMotionListener(this);
this.addMouseListener(this);
Метод paint
Этот метод обводит границы аплета тонкой
рамкой, рисует изображение дискеты в текущей
позиции и обновляет соответствующим образом
переменную rcImage:
public void paint(Graphics g)
{
g.drawRect(0, 0,
dm.width - 1, dm.height - 1);
g.drawImage(imFloppy,
imX + dx, imY + dy, this);
rcImage = new Rectangle(imX + dx, imY + dy,
imHeight, imWidth);
}
Заметим, что к текущим координатам курсора мыши
(imX, imY) мы прибавляем смещение курсора внутри
изображения (dx, dy).
Метод mousePressed
Когда пользователь нажимает клавишу мыши в
окне аплета, управление передается методу
mousePressed:
public void mousePressed(MouseEvent e)
{
bBeginDrag =
rcImage.contains(e.getX(), e.getY());
if(bBeginDrag)
{
dx = imX + dx - e.getX();
dy = imY + dy - e.getY();
}
}
Вначале с помощью метода contains класса Rectangle этот
метод проверяет, находится ли курсор мыши над
изображением дискеты. Если находится, то в поле
bBeginDrag (признак начала операции перемещения)
записывается значение true.
Кроме того, при этом метод mousePressed определяет
новое смещение курсора относительно верхнего
левого угла изображения.
Метод mouseReleased
Когда операция перемещения завершается,
пользователь отпускает кнопку мыши. Мы при этом
сбрасываем флаг перемещения bBeginDrag:
public void mouseReleased(MouseEvent e)
{
bBeginDrag = false;
}
Метод mouseDragged
В процессе перемещения изображения дискеты
управление многократно передается методу
mouseDragged.
При установленном флаге bBeginDrag он определяет
новые координаты курсора мыши и записывает их в
переменные newX и newY:
int newX;
int newY;
if(bBeginDrag)
{
newX = e.getX();
newY = e.getY();
. . .
}
Далее мы проверяем, не выходит ли изображение
дискеты за пределы окна аплета, ограниченные
тонкой рамкой.
Вот как эта операция выполняется для оси X:
if(newX < -dx)
imX = -dx;
else if((newX + imWidth + dx) > dm.width)
imX = dm.width - imWidth - dx;
else
imX = newX;
Аналогично, для оси Y:
if(newY < -dy)
imY = -dy;
else if((newY + imHeight + dy) > dm.height)
imY = dm.height - imHeight - dy;
else
imY = newY;
Затем метод перерисовывает окно аплета:
repaint();
Остальные методы
следующие четыре метода определены для полноты
реализации интерфейсов MouseListener и MouseMotionListener:
public void mouseMoved(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
Назад Вперед |