Оглавление
События |
В нашем аплете мы будем создавать объект класса Vector, который является массивом с динамически изменяемым размером. Здесь мы будем хранить координаты нарисованных линий.
Класс Vector имеет полное имя java.util.Vector, поэтому мы подключаем соответствующую библиотеку классов:
import java.util.*;
В нашем классе мы определили несколько полей, предназначенных для хранения текущих координат рисуемых линий:
Dimension dmDown; Dimension dmUp; Dimension dmPrev; boolean bDrawing; Vector lines;
В переменную dmDown класса Dimension записываются координаты курсора на момент нажатия клавиши мыши. Если пользователь нажал клавишу мыши для того чтобы приступить к рисованию линии, это будет координатами начала линии.
Когда пользователь отпускает клавишу мыши, координаты записываются в переменную dmUp.
В процессе рисования линии метод mouseDrag стирает ранее нарисованную линию и рисует новую. Координаты конца старой линии хранятся в переменной dmPrev.
Переменная bDrawing типа boolean хранит текущее состояние аплета. Когда аплет находится в состоянии рисования линии, в эту переменную записывается значение true, а когда нет - значение false.
И, наконец, переменная lines типа Vector является динамическим массивом, в котором хранятся координаты нарисованных линий.
Метод getAppletInfo возвращает название аплета и не имеет никаких особенностей.
Метод init сбрасывает признак рисования, записывая в поле bDrawing значение false, а также создает новый динамический массив в виде объекта класса Vector:
public void init() { bDrawing = false; lines = new Vector(); }
После изменения цвета фона и рисования рамки метод paint перебирает в цикле все элементы массива lines, рисуя линии:
for(int i=0; i < lines.size(); i++) { Rectangle p = (Rectangle)lines.elementAt(i); g.drawLine( p.width, p.height, p.x, p.y); g.drawString("<" + p.width + "," + p.height + ">", p.width, p.height); g.drawString("<" + p.x + "," + p.y+ ">", p.x, p.y); }
Для объектов класса Vector метод size возвращает количество элементов в массиве, чем мы воспользовались для проверки условия выхода из цикла.
Чтобы извлечь элемент массива по его номеру, мы применили метод elementAt, передав ему через единственный параметр номер извлекаемого элемента.
Так как в массиве хранятся объекты класса Rectangle, перед инициализацией ссылки p мы выполняем явное преобразование типов.
Координаты концов линий рисуются с помощью уже знакомого вам метода drawString.
Перед завершением работы метод paint сбрасывает признак рисования, записывая в поле bDrawing значение false:
bDrawing = false;
В начале своей работы метод mouseDown определяет, был ли сделан одинарный щелчок клавишей мыши, или двойной. Если был сделан двойной щелчок мышью, метод удаляет все элементы из массива list, а затем перерисовывает окно аплета, вызывая метод repaint:
lines.removeAllElements(); repaint();
После перерисовки окно аплета очищается от линий.
Если же был сделан одинарный щелчок клавишей мыши, метод mouseDown сохраняет текущие координаты курсора в переменных dmDown и dmPrev, а затем сбрасывает признак рисования:
dmDown = new Dimension(x, y); dmPrev = new Dimension(x, y); bDrawing = false;
Когда пользователь отпускает клавишу мыши, вызывается метод mouseUp. В его задачу входит сохранение текущих координат курсора мыши в поле dmUp, а также добавление нового элемента в массив lines:
dmUp = new Dimension(x, y); lines.addElement( new Rectangle(dmDown.width, dmDown.height, x, y)); repaint();
После добавления элемента в массив метод mouseUp инициирует перерисовку окна аплета, вызывая для этого метод repaint.
Заметим, что в качестве координат начала линии мы записываем в элемент массива координаты точки, где в последний раз пользователь нажимал курсор мыши. В качестве координат конца линии используются текущие координаты курсора на момент отпускания клавиши мыши.
До сих пор наши аплеты выполняли рисование только в методе paint, и так поступают большинство аплетов. Однако наш аплет должен рисовать линии во время перемещения курсора мыши, так как в противном случае пользователю не будет видно, как пройдет рисуемая линия.
Для того чтобы нарисовать что-либо в окне аплета, наобходимо получить контекст отображения. Методу paint этот контекст передается через парметр как объект класса Graphics. Если же вы собираетесь рисовать в другом методе, отличном от paint, необходимо получить контекст отображения, например, так:
Graphics g = getGraphics();
После получения контекста отображения и включения режима рисования (записью в переменную bDrawing значения true) метод mouseDrag стирает линию, которая была нарисована ранее, в процессе предыдущего вызова этого же метода:
g.setColor(Color.yellow); g.drawLine(dmDown.width, dmDown.height, dmPrev.width, dmPrev.height);
Для стирания линии мы рисуем ее на том же месте с использованием цвета, совпадающего с цветом фона.
Далее метод mouseDrag рисует новую линию черного цвета, соединяя точку, в которой была нажата клавиша мыши, с точкой текущего расположения курсора мыши:
g.setColor(Color.black); g.drawLine(dmDown.width, dmDown.height, x, y);
После рисования линии координаты ее конца сохраняются в поле dmPrev для стирания этой линии при следующем вызове метода mouseDrag:
dmPrev = new Dimension(x, y); return true;
Метод mouseMove не делает ничего, за исключением того, что он отключает режим рисования. Таким образом, простое перемещение курсора мыши над окном аплета не приводит к рисованию линий.