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

Microsoft Visual J++. Создание приложений и аплетов на языке Java. Часть 1

© Александр Фролов, Григорий Фролов
Том 30, М.: Диалог-МИФИ, 1997, 288 стр.

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

Приложение FrameWnd

В приложении FrameWnd мы демонстрируем создание окон, меню и диалоговых панелей на базе классов, описанных в этой главе.

В окне аплета FrameWnd расположены две кнопки с названиями Show Frame Window и Hide Frame Window. Первая из них предназначена для отображения окна Main Frame Window, а вторая - для его временного удаления (скрытия).

В окне Main Frame Window мы создали главное меню, содержащее меню File и Help. При выборе любой строки из этого меню, кроме строки Exit меню File, на экране появляется окно диалоговой панели Dialog from Frame с названием выбранной строки меню (рис. 8.2).

Рис. 8.2. Окно и диалоговая панель, создаваемая аплетом FrameWnd

Помимо меню, в окне Main Frame Window находится кнопка OK, нажатие на которую вызывает удаление окна. Кроме того, в нижней части окна отображается строка “Окно класса Frame”.

В окне диалоговой панели, разделенном по вертикали на две части, находится текстовое поле для отображения сообщения и кнопка для завершения работы диалоговой панели.

Обратите также внимание на то, что в самой нижней части окно Main Frame Window и Dialog from Frame находится предупреждающее сообщение “Warning: Applet Window”. Это предупреждение пользователю, что данное окно или диалоговая панель выведена не локальным приложением, запущенным на компьютере пользователя, а аплетом, загруженным из сети. Пользователь должен понимать, что данные, введенные им в окнах, созданных аплетами, передаются по сети и могут оказаться доступной кому угодно. Поэтому он не должен вводить конфиденциальную информацию, например, номера своих кредитных карточек.

Исходные тексты приложения

Исходный текст приложения FrameWnd приведен в листинге 8.1.

Листинг 8.1. Файл FrameWnd\FrameWnd.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.*;

// =========================================================
// Класс FrameWnd
// Это наш аплет
// =========================================================
public class FrameWnd extends Applet
{
  // Окно, которое будет возникать из аплета
  MainFrameWnd fMainFrame;
  
  // Кнопка для отображения окна fMainFrame
  Button btnShowFrame;

  // Кнопка для удаления окна fMainFrame
  Button btnHideFrame;

  // -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
  public String getAppletInfo()
  {
    return "Name: FrameWnd\r\n" +
      "Author: Alexandr Frolov\r\n" +
      "E-mail: frolov@glas.apc.org" +
      "WWW:    http://www.glasnet.ru/~frolov" +
      "Created with Microsoft Visual J++ Version 1.0";
  }

  // -------------------------------------------------------
  // init
  // Метод, получающий управление при инициализации аплета
  // -------------------------------------------------------
  public void init()
  {
    // Создаем новое окно на базе класса MainFrameWnd
    fMainFrame = new MainFrameWnd("Main Frame Window");

    // Создаем кнопку для отображения этого окна
    btnShowFrame = new Button("Show Frame Window");
    
    // Добавляем кнопку в окно аплета
    add(btnShowFrame);
    
    // Создаем кнопку для удаления окна fMainFrame 
    btnHideFrame = new Button("Hide Frame Window");

    // Добавляем кнопку в окно аплета
    add(btnHideFrame);
  }

  // -------------------------------------------------------
  // destroy
  // Метод, получающий управление при завершении
  // работы аплета
  // -------------------------------------------------------
  public void destroy()
  {
    // Удаляем окно fMainFrame и освобождаем все связанные
    // с ним ресурсы
    fMainFrame.dispose();
  }

  // -------------------------------------------------------
  // action
  // Метод вызывается, когда пользователь выполняет
  // действие над компонентами
  // -------------------------------------------------------
  public boolean action(Event evt, Object obj)
  {
    // Ссылка на кнопку, от которой пришло сообщение
    Button btn;

    // Проверяем, что событие вызвано кнопкой, а не
    // другим компонентом
    if(evt.target instanceof Button)
    {
      // Получам ссылку на кнопку, вызвавшую событие
      btn = (Button)evt.target;

      // Если нажата кнопка отображения окна fMainFrame,
      // показываем его с помощью метода show
      if(evt.target.equals(btnShowFrame))
      {
        fMainFrame.show();
      }

      // Если нажата кнопка удаления окна fMainFrame,
      // удаляем его с помощью метода hide
      else if(evt.target.equals(btnHideFrame))
      {
        fMainFrame.hide();
      }
      // Если событие возникло от неизвестной кнопки,
      // мы его не обрабатываем
      else
        return false;

      return true;
    }

    // Если событие вызвано не кнопкой, 
    // мы его не обрабатываем
    return false;
  }
}

// =========================================================
// Класс MainFrameWnd
// На базе этого класса создается окно с меню
// =========================================================
class MainFrameWnd extends Frame
{
  // Кнопка, с помощью которой можно закрыть окно
  Button btnOK;

  // Главное меню окна
  MenuBar mbMainMenuBar;
  
  // Меню File
  Menu mnFile;

  // Меню Help
  Menu mnHelp;

  // -------------------------------------------------------
  // MainFrameWnd
  // Конструктор класса
  // -------------------------------------------------------
  public MainFrameWnd(String sTitle)
  {
    // Создаем окно, вызывая конструктор из базового класса
    super(sTitle);
    
    // Устанавливаем размеры окна
    resize(400, 200);

    // Устанавливаем цвет фона и изображения для окна
    setBackground(Color.yellow);
    setForeground(Color.black);

    // Устанавливаем режим добавления компонент FlowLayout
    setLayout(new FlowLayout());
    
    // Создаем и добавляем в окно кнопку OK
    btnOK = new Button("OK");
    add(btnOK);

    // Создаем главное меню
    mbMainMenuBar = new MenuBar();
    
    // Создаем меню File
    mnFile = new Menu("File");
    
    // Заполняем меню File
    mnFile.add("New");       // строка New
    mnFile.add("-");         // разделитель
    mnFile.add("Exit");      // строка Exit
  
    // Создаем меню Help
    mnHelp = new Menu("Help"); 

    // Заполняем меню Help
    mnHelp.add("Content");   // строка Content
    mnHelp.add("-");         // разделитель
    mnHelp.add("About");     // строка About

    // Добавляем меню File и Help в главное 
    // меню нашего окна
    mbMainMenuBar.add(mnFile);
    mbMainMenuBar.add(mnHelp);
    
    // Устанавливаем для окна главное меню
    setMenuBar(mbMainMenuBar);
  }

  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование 
  // в созданном нами окне 
  // -------------------------------------------------------
  public void paint(Graphics g)
  {
    // Устанавливаем шрифт
    g.setFont(new Font("Helvetica", Font.PLAIN, 12));

    // Рисуем строку
    g.drawString("Окно класса Frame", 10, 50);

    // Вызываем метод paint родительского класса
    super.paint(g);
  }

  // -------------------------------------------------------
  // handleEvent
  // Обработка событий для окна
  // -------------------------------------------------------
  public boolean handleEvent(Event evt)
  {
    // Если пользователь закрывает окно,
    // скрываем его с помощью метода hide
    if(evt.id == Event.WINDOW_DESTROY)
    {
      hide();
      return true;
    }
      
    else
      return super.handleEvent(evt);
  }
  
  // -------------------------------------------------------
  // action
  // Метод вызывается, когда пользователь выполняет
  // действие над компонентами в нашем окне
  // -------------------------------------------------------
  public boolean action(Event evt, Object obj)
  {
    // Ссылка на кнопку, от которой пришло сообщение
    Button btn;
  
    // Ссылка на элемент меню
    MenuItem mnItem;

    // Проверяем, что событие вызвано кнопкой, а не
    // другим компонентом
    if(evt.target instanceof Button)
    {
      // Получам ссылку на кнопку, вызвавшую событие
      btn = (Button)evt.target;

      // Если пользователь нажал кнопку OK, скрываем окно
      if(evt.target.equals(btnOK))
      {
        hide();
      }
      // Если событие возникло от неизвестной кнопки,
      // мы его не обрабатываем
      else
        return false;

      return true;
    }

    // Обработка событий от меню
    else if(evt.target instanceof MenuItem)
    {
      // Получам ссылку на элемент меню
      mnItem = (MenuItem)evt.target;

      // Если из меню File выбрана строка Exit,
      // завершаем работу виртуальной машины Java
      if(obj.equals("Exit"))
      {
        System.exit(0);
      }

      // Если из меню File выбрана строка New,
      // отображаем название строки в диалоговой панели
      else if(obj.equals("New"))
      {
        // Ссылка на диалоговую панель
        MessageBox mbox;

        // Создаем новую диалоговую панель
        mbox = new MessageBox("Item New selected",
          this, "Dialog from Frame", true);
        
        // Отображаем диалоговую панель
        mbox.show();
      }

      // Если из меню File выбрана строка Content,
      // отображаем название строки в диалоговой панели
      else if(obj.equals("Content"))
      {
        MessageBox mbox;

        mbox = new MessageBox("Item Content selected",
          this, "Dialog from Frame", true);
        
        mbox.show();
      }
      
      // Если из меню File выбрана строка About,
      // отображаем название строки в диалоговой панели
      else if(obj.equals("About"))
      {
        MessageBox mbox;
        mbox = new MessageBox("Item About selected",
          this, "Dialog from Frame", true);
        
        mbox.show();
      }

      else
        return false;

      return true;
    }
    return false;
  }
}

// =========================================================
// Класс MessageBox
// На базе этого класса мы создаем диалоговые панели
// =========================================================
class MessageBox extends Dialog
{
  // Поле для отображения текста сообщения
  Label lbMsg;

  // Кнопка для удаления диалоговой панели
  Button btnOK;

  // -------------------------------------------------------
  // MessageBox
  // Конструктор класса
  // -------------------------------------------------------
  public MessageBox(String sMsg, 
    Frame  parent, String  sTitle, boolean  modal)
  {
    // Создаем диалогвоую панель, вызывая конструктор
    // базового класса Dialog
    super(parent, sTitle, modal);

    // Устанавливаем размеры окна диалоговой панели
    resize(200, 100);

    // Устанавливаем режим размещения компонент GridLayout
    setLayout(new GridLayout(2, 1));
    
    // Создаем и добавляем поле для отображения сообщения
    lbMsg = new Label(sMsg, Label.CENTER);
    add(lbMsg);

    // Создаем и добавляем кнопку для завершения работы
    // диалоговой панели
    btnOK = new Button("OK");
    add(btnOK);
  }

  // -------------------------------------------------------
  // handleEvent
  // Обработка событий для диалоговой панели
  // -------------------------------------------------------
  public boolean handleEvent(Event evt)
  {
    // Если пользователь закрывает окно диалоговой панели,
    // скрываем его с помощью метода hide
    if(evt.id == Event.WINDOW_DESTROY)
    {
      dispose();
      return true;
    }
      
    else
      return super.handleEvent(evt);
  }

  // -------------------------------------------------------
  // action
  // Метод вызывается, когда пользователь выполняет
  // действие над компонентами в диалоговой панели
  // -------------------------------------------------------
  public boolean action(Event evt, Object obj)
  {
    // Ссылка на кнопку, от которой пришло сообщение
    Button btn;
  
    // Проверяем, что событие вызвано кнопкой, а не
    // другим компонентом
    if(evt.target instanceof Button)
    {
      // Получам ссылку на кнопку, вызвавшую событие
      btn = (Button)evt.target;

      // Если нажата кнопка OK, удаляем диалоговую панель
      // и освобождаем все связанные с ней ресурсы
      if(evt.target.equals(btnOK))
      {
        dispose();
      }
      
      // Если событие возникло от неизвестной кнопки,
      // мы его не обрабатываем
      else
        return false;

      return true;
    }
    return false;
  }
}

Исходный текст документа HTML, созданного для размещения аплета, приведен в листинге 8.2.

Листинг 8.2. Файл FrameWnd\FrameWnd.html


<html>
<head>
<title>FrameWnd</title>
</head>
<body>
<hr>
<applet
    code=FrameWnd.class
    id=FrameWnd
    width=320
    height=240 >
</applet>
<hr>
<a href="FrameWnd.java">The source.</a>
</body>
</html>

Описание исходного текста

Рассмотрим по очереди поля и методы классов, определенных в нашем приложении.

Поля класса FrameWnd

В поле fMainFrame класса MainFrameWnd хранится ссылка на окно, которое будет создано, если пользователь нажмет кнопку “Show Frame Window”, расположенную в окне аплета. Класс MainFrameWnd создан нами на базе класса Frame.

Поля с именами btnShowFrame и btnHideFrame предназначены, соответственно, для хранения ссылок на только что указанную кнопку и кнопку “Hide Frame Window”, с помощью которой можно скрыть окно.

Метод getAppletInfo класса FrameWnd

Этот метод возвращает информацию об аплете FrameWnd.

Метод init класса FrameWnd

В процессе инициализации аплета метод init создает объект класса MainFrameWnd - перекрывающееся окно с заголовком "Main Frame Window":


fMainFrame = new MainFrameWnd("Main Frame Window");

Для этого вызывается конструктор из класса MainFrameWnd, созданного нами на базе класса Frame.

После этого метод init создает две кнопки и добавляет их в окно аплета:


btnShowFrame = new Button("Show Frame Window");
add(btnShowFrame);
btnHideFrame = new Button("Hide Frame Window");
add(btnHideFrame);

Первая из этих кнопок предназначена для отображения перекрывающегося окна, а вторая - для временного удаления или скрытия этого окна.

Метод destroy класса FrameWnd

При завершении работы аплета мы удаляем созданное нами окно и освобождаем все связанные с ним ресурсы, вызывая для окна метод dispose:


fMainFrame.dispose();

Метод action класса FrameWnd

Назначение метода action класса FrameWnd - обработка событий, вызванных кнопками кнопку “Show Frame Window” и “Hide Frame Window”, созданных в окне аплета:


if(evt.target.equals(btnShowFrame))
  fMainFrame.show();
else if(evt.target.equals(btnHideFrame))
  fMainFrame.hide();

Если нажата кнопка “Show Frame Window”, для окна fMainFrame вызывается метод show, что приводит к появлению окна на экране. Если нажата кнопка “Hide Frame Window”, для этого окна вызывается метод hide, после чего окно исчезает с экрана. Исчезнувшее окно не уничтожается и вы можете снова отобразить его на экране, нажав кнопку “Show Frame Window”.

Класс MainFrameWnd

Класс MainFrameWnd предназначен для создания автономного перекрывающегося окна, которое существует вне окна навигатора. Этот класс был нами создан на базе класса Frame:


class MainFrameWnd extends Frame
{
  . . .
}

В классе мы определили несколько полей, конструктор для создания окна, метод paint для рисования в окне, метод handleEvent для обработки запроса на уничтожение окна, метод action для обработки события, вызванного кнопкой, расположенной в окне, а также выбором строк меню, созданного для окна.

Поля класса MainFrameWnd

В поле btnOK хранится ссылка на кнопку, при нажатии которой окно удаляется.

Поле mbMainMenuBar класса MenuBar предназначено для хранения ссылки на главное меню окна. В него мы будем добавлять меню “File” и “Help”, идентификаторы которых хранятся в полях mnFile и mnHelp, соответственно.

Конструктор класса MainFrameWnd

В качестве единственного параметра нашему конструктору передается заголовок создаваемого окна. В первой исполняемой строке наш конструктор вызывает конструктор из базового класса, передавая ему строку заголовка через параметр:


super(sTitle);

Далее конструктор определяет размеры окна, вызывая для него метод resize:


resize(400, 200);

Затем мы устанавливаем для нашего окна желтый цвет фона и черный цвет изображения:


setBackground(Color.yellow);
setForeground(Color.black);

По умолчанию для окон класса Frame устанавливается режим добавления компонент BorderLayout. Мы изменяем этот режим на FlowLayout, вызывая метод setLayout:


setLayout(new FlowLayout());

Установив новый режим добавления компонент, мы располагаем в нашем окне кнопку, предварительно создав ее с помощью конструктора класса Button:


btnOK = new Button("OK");
add(btnOK);

Далее метод init приступает к формированию главного меню окна. Это меню создается как объект класса MenuBar:


mbMainMenuBar = new MenuBar();

Затем мы создаем и наполняем меню “File”:


mnFile = new Menu("File");
mnFile.add("New");       // строка New
mnFile.add("-");         // разделитель
mnFile.add("Exit");      // строка Exit

Это меню создается на базе класса Menu. Обратите внимание, что между строками New и File расположен разделитель.

Аналогичным образом мы добавляем в главное меню другое меню - “Help”:


mnHelp = new Menu("Help"); 
mnHelp.add("Content");   // строка Content
mnHelp.add("-");         // разделитель
mnHelp.add("About");     // строка About

После своего окончательного формирования меню “File” и “Help” добавляются в главное меню окна mbMainMenuBar:


mbMainMenuBar.add(mnFile);
mbMainMenuBar.add(mnHelp);

И, наконец, когда главное меню будет сформировано, оно подключается к окну вызовом метода setMenuBar, как это показано ниже:


setMenuBar(mbMainMenuBar);

Метод paint класса MainFrameWnd

Метод paint получает в качестве параметра ссылку на контекст отображения, пригодный для рисования в нашем окне. Пользуясь этим контекстом, мы устанавливаем шрифт текста и рисуем текстовую строку. Затем мы вызываем метод paint из базового класса Frame, на основе которого создан наш класс MainFrameWnd:


g.setFont(new Font("Helvetica", Font.PLAIN, 12));
g.drawString("Окно класса Frame", 10, 50);
super.paint(g);

Метод handleEvent класса MainFrameWnd

Для того чтобы определить реакцию окна на попытку пользователя закрыть окно с помощью органов управления, расположенных в заголовке окна, или другим способом, мы переопределили метод handleEvent.

При получении кода события Event.WINDOW_DESTROY (удаление окна) мы просто скрываем окно, вызывая метод hide:


if(evt.id == Event.WINDOW_DESTROY)
{
  hide();
  return true;
}
else
  return super.handleEvent(evt);

Все другие события передаются для обработки методу handleEvent из базового класса.

Метод action класса MainFrameWnd

Этот метод обрабатывает события, связанные с кнопкой и меню.

Если пользователь нажимает на кнопку OK, расположенную в окне, окно скрывается методом hide:


if(evt.target.equals(btnOK))
{
  hide();
}

Здесь для вас нет ничего нового.

Рассмотрим более подробно процедуру обработки событий от меню.

Вначале метод action проверяет, вызвано ли событие выбором строки из меню, сравнивая объект события с классом MenuItem:


else if(evt.target instanceof MenuItem)
{
. . .
}
else
  return false;

Если это так, в поле mnItem сохраняется ссылка на элемент меню, вызвавший событие:


mnItem = (MenuItem)evt.target;

Однако мы не используем этот элемент, так как для определения строки, выбранной пользователем, нам достаточно проанализировать второй параметр метода action:


if(obj.equals("Exit"))
  System.exit(0);
else if(obj.equals("New"))
{
  MessageBox mbox;
  mbox = new MessageBox("Item New selected",
    this, "Dialog from Frame", true);
  mbox.show();
}
else if(obj.equals("Content"))
{
 . . .
}
else if(obj.equals("About"))
{
. . .
}

В данном случае второй параметр метода action будет представлять собой ссылку на строку, выбранную из меню, поэтому для определения выбранной строки мы можем выполнить простое сравнение методом equals.

Если пользователь выбрал из меню File строку Exit, мы вызываем метод System.exit, предназначенный для завершения работы виртуальной машины Java. Таким способом вы можете завершить работу аплета, когда он выполняется в среде Microsoft Visual J++ в процессе отладки. Если же аплет запущен автономно в навигаторе, то завершения работы навигатора не произойдет.

В том случае когда пользователь выбирает любую другую строку из меню, метод action создает диалоговую панель на базе определенного нами класса MessageBox. В этой диалоговой панели отображаетя название выбранной строки меню.

Заметим, что сразу после создания конструктором диалоговая панель не появляется на экране. Мы отображаем ее, вызывая метод show.

Класс MessageBox

Для отображения названий выбранных строк меню мы создаем диалоговую панель, определив свой класс MessageBox на базе класса Dialog, как это показано ниже:


class MessageBox extends Dialog
{
  . . .
}

В классе MessageBox есть два поля, конструктор, методы handleEvent и action.

Поля класса MessageBox

Внутри диалоговой панели мы расположили текстовое поле класса Label, предназначенное для отображения сообщения, и кнопку с надписью OK, с помощью которой можно завершить работу диалоговой панели.

Ссылка на текстовое поле хранится в поле lbMsg, на кнопку - в поле btnOK.

Конструктор класса MessageBox

Наш конструктор создает диалоговую панель с заданным сообщением внутри нее. Ссылка на строку сообщения передается конструктору через первый параметр. Остальные параметры используются конструктором базового класса Dialog для создания диалоговой панели:


super(parent, sTitle, modal);

После вызова конструктора из базового класса наш конструктор устанавливает размеры окна созданной диалоговой панели, вызывая метод resize:


resize(200, 100);

Отменяя установленный по умолчанию режим размещения компонент BorderLayout, конструктор устанавливает режим GridLayout:


setLayout(new GridLayout(2, 1));

Окно диалоговой панели при этом разделяется на две части по горизонтали. В верхнюю часть добавляется текстовое поле для отображения сообщения, в нижнюю - кнопка OK:


lbMsg = new Label(sMsg, Label.CENTER);
add(lbMsg);
btnOK = new Button("OK");
add(btnOK);

Метод handleEvent класса MessageBox

Когда пользователь пытается закрыть окно диалоговой панели, например, сделав двойной щелчок левой клавишей мыши по системному меню или одиночный щелчок по кнопке удаления окна, возникает событие Event.WINDOW_DESTROY. Мы его обрабатываем следующим образом:


if(evt.id == Event.WINDOW_DESTROY)
{
  dispose();
  return true;
}
else
  return super.handleEvent(evt);

Вызывая метод dispose, мы удаляем окно диалоговой панели и освобождаем все связанные с ним ресурсы.

Метод action класса MessageBox

Если пользователь нажимает кнопку OK, расположенную в окне диалоговой панели, метод action вызывает для панели метод dispose, удаляя эту панель с экрана и из памяти:


if(evt.target.equals(btnOK))
{
  dispose();
}
[Назад] [Содеожание] [Дальше]