Microsoft Visual J++. Создание приложений и аплетов на языке Java. Часть 1© Александр Фролов, Григорий ФроловТом 30, М.: Диалог-МИФИ, 1997, 288 стр. Приложение LineDrawСледующее приложение тоже работает с мышью. В его окне вы можете рисовать прямые линии черного цвета (рис. 4.3). Рис. 4.3. Аплет, в окне которого можно рисовать прямые линии Для того чтобы нарисовать линию в окне аплета LineDraw, вы должны установить курсор в начальную точку, нажать клавишу мыши и затем, не отпуская ее, переместить курсор в конечную точку. После отпускания клавиши мыши координаты линии будут сохранены аплетом в массиве, после чего произойдет перерисовка окна аплета. По мере того как вы будете рисовать линии, аплет будет заполнять массив с координатами линий. Каждый раз, когда окно аплета будет перерисовываться, метод paint перерисует все линии заново, пользуясь координатами, сохраненными в массиве. Для того чтобы стереть содержимое окна аплета, вам достаточно сделать двойной щелчок в его окне. При этом из массива координать линий будут удалены все элементы. Исходные тексты приложенияИсходный текст аплета LineDraw приведен в листинге 4.3. Листинг 4.3. Файл LineDraw\LineDraw.java // ========================================================= // Рисование прямых линий // // (C) Фролов А.В, 1997 // // E-mail: frolov@glas.apc.org // WWW: http://www.glasnet.ru/~frolov // или // http://www.dials.ccas.ru/frolov // ========================================================= import java.applet.*; import java.awt.*; // Добавляем для класса Vector import java.util.*; public class LineDraw extends Applet { // Координаты курсора при нажатии кнопки мыши Dimension dmDown; // Координаты курсора при отжатии кнопки мыши Dimension dmUp; // Предыдущие координаты конца линии Dimension dmPrev; // Признак включения режима рисования boolean bDrawing; // Массив координат линий Vector lines; // ------------------------------------------------------- // getAppletInfo // Метод, возвращающей строку информации об аплете // ------------------------------------------------------- public String getAppletInfo() { return "Name: LineDraw\r\n" + "E-mail: frolov@glas.apc.org" + "WWW: http://www.glasnet.ru/~frolov" + "Author: Alexandr Frolov\r\n" + "Created with Microsoft Visual J++ Version 1.0"; } // ------------------------------------------------------- // init // Метод, получающий управление при инициализации аплета // ------------------------------------------------------- public void init() { // Сброс признака рисования bDrawing = false; // Создание массива для хранения координат линий lines = new Vector(); } // ------------------------------------------------------- // paint // Метод paint, выполняющий рисование в окне аплета // ------------------------------------------------------- public void paint(Graphics g) { // Определяем текущие размеры окна аплета Dimension dimAppWndDimension = size(); // Выбираем в контекст отображения желтый цвет g.setColor(Color.yellow); // Закрашиваем внутреннюю область окна аплета g.fillRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1); // Выбираем в контекст отображения черный цвет g.setColor(Color.black); // Рисуем рамку вокруг окна аплета g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1); // Рисуем в цикле линии, координаты которых // хранятся в массиве 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); } // Сбрасываем режим рисования bDrawing = false; } // ------------------------------------------------------- // mouseDown // Обработка щелчка кнопкой мыши // ------------------------------------------------------- public boolean mouseDown(Event evt, int x, int y) { // Если количествао щелчков больше 1, считаем что // сделан двойной щелчок if(evt.clickCount > 1) { // Удаляем все строки из массива lines lines.removeAllElements(); // Перерисовываем окно аплета repaint(); return true; } // Сохраняем текущие координаты начала линии dmDown = new Dimension(x, y); // В начале процесса рисования линии устанавливаем // предыдущие координаты конца линии равными // координатам начала линии dmPrev = new Dimension(x, y); // Отключаем режим рисования bDrawing = false; return true; } // ------------------------------------------------------- // mouseUp // Отпускание клавиши мыши // ------------------------------------------------------- public boolean mouseUp(Event evt, int x, int y) { // Проверяем, включен ли режим рисования if(bDrawing) { // Если режим рисования включен, добавляем // новый элемент в массив lines // Сохраняем координаты конца линии dmUp = new Dimension(x, y); // Добавляем линию в массив lines.addElement( new Rectangle(dmDown.width, dmDown.height, x, y)); // Перерисовываем окно аплета repaint(); // Отключаем режим рисования bDrawing = false; } return true; } // ------------------------------------------------------- // mouseDrag // Перемещение курсора мыши при нажатой клавише // ------------------------------------------------------- public boolean mouseDrag(Event evt, int x, int y) { // Получаем контекст отображения для окна аплета Graphics g = getGraphics(); // Включаем режим рисования bDrawing = true; // Закрашиваем предыдущую линию цветом фона // (то есть стираем ее) g.setColor(Color.yellow); g.drawLine(dmDown.width, dmDown.height, dmPrev.width, dmPrev.height); // Рисуем новую линию черным цветом g.setColor(Color.black); g.drawLine(dmDown.width, dmDown.height, x, y); // Сохраняем координаты предыдущей линии, // чтобы стереть ее в следующий раз dmPrev = new Dimension(x, y); return true; } // ------------------------------------------------------- // mouseMove // Перемещение курсора мыши при отжатой клавише // ------------------------------------------------------- public boolean mouseMove(Event evt, int x, int y) { // Отключаем режим рисования bDrawing = false; return true; } } Исходный текст документа HTML, созданного для аплета LineDraw, вы найдете в листинге 4.4. Листинг 4.4. Файл LineDraw\LineDraw.html <html> <head> <title>LineDraw</title> </head> <body> <hr> <applet code=LineDraw.class id=LineDraw width=320 height=240 > </applet> <hr> <a href="LineDraw.java">The source.</a> </body> </html> Описание исходного текстаВ нашем аплете мы будем создавать объект класса Vector, который является массивом с динамически изменяемым размером. Этот класс имеет полное имя java.util.Vector, поэтому мы подключаем соответствующую библиотеку классов: import java.util.*; Поля класса LineDrawВ нашем классе мы определили несколько полей, предназначенных для хранения текущих координат рисуемых линий. В переменную dmDown класса Dimension записываются координаты курсора на момент нажатия клавиши мыши. Если пользователь нажал клавишу мыши для того чтобы приступить к рисованию линии, это будет координатами начала линии. Когда пользователь отпускает клавишу мыши, координаты записываются в переменную dmUp. В процессе рисования линии метод mouseDrag стирает ранее нарисованную линию и рисует новую. Координаты конца старой линии хранятся в переменной dmPrev. Переменная bDrawing типа boolean хранит текущее состояние аплета. Когда аплет находится в состоянии рисования линии, в эту переменную записывается значение true, а когда нет - значение false. И, наконец, переменная lines типа Vector является динамическим массивом, в котором хранятся координаты нарисованных линий. Метод getAppletInfoМетод getAppletInfo возвращает информацию об аплете и не имеет никаких особенностей. Метод initМетод init сбрасывает признак рисования, записывая в поле bDrawing значение false, а также создает новый динамический массив в виде объекта класса Vector: public void init() { bDrawing = false; lines = new Vector(); } Метод paintПосле обычной для наших аплетов раскраски фона и рисования рамки метод 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); } Для объектов класса Vector можно использовать метода size, возвращающий количество элементов в массиве, чем мы воспользовались для проверки условия выхода из цикла. Чтобы извлечь элемент массива по его номеру, мы воспользовались методом elementAt, передав ему через единственный параметр номер извлекаемого элемента. Так как в массиве хранятся объекты класса Rectangle, перед инициализацией ссылки p мы выполняем преобразование типов. Перед завершением работы метод paint сбрасывает признак рисования, записывая в поле bDrawing значение false: bDrawing = false; Метод mouseDownВ начале своей работы метод mouseDown определяет, был ли сделан одинарный щелчок клавишей мыши, или двойной. Если был сделан двойной щелчок мышью, метод удаляет все элементы из массива list, а затем перерисовывает окно аплета, вызывая метод repaint: lines.removeAllElements(); repaint(); После перерисовки окно аплета очищается от линий. Если же был сделан одинарный щелчок клавишей мыши, метод mouseDown сохраняет текущие координаты курсора в переменных dmDown и dmPrev, а затем сбрасывает признак рисования: dmDown = new Dimension(x, y); dmPrev = new Dimension(x, y); bDrawing = false; Метод mouseUpКогда пользователь отпускает клавишу мыши, вызывается метод mouseUp. В его задачу входит сохранение текущих координат курсора мыши в поле dmUp, а также добавление нового элемента в массив lines, как это показано ниже: dmUp = new Dimension(x, y); lines.addElement( new Rectangle(dmDown.width, dmDown.height, x, y)); repaint(); После добавления элемента в массив метод mouseUp инициирует перерисовку окна аплета, вызывая для этого метод repaint. Заметим, что в качестве координат начала линии мы записываем в элемент массива координаты точки, где в последний раз пользователь нажимал курсор мыши. В качестве координат конца линии используются текущие координаты курсора на момент отпускания клавиши мыши. Метод mouseDragДо сих пор наши аплеты выполняли рисование только в методе 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Метод mouseMove не делает ничего, за исключением того, что он отключает режим рисования. Таким образом, простое перемещение курсора мыши над окном аплета не приводит к рисованию линий. |