Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

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 не делает ничего, за исключением того, что он отключает режим рисования. Таким образом, простое перемещение курсора мыши над окном аплета не приводит к рисованию линий.

[Назад] [Содеожание] [Дальше]