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

Библиотека примеров приложений Java

Оглавление
Выбор файлов
Простейший редактор текста
Копирование файлов UNICODE
Сохранение объекта Java в файле
Произвольные классы и файлы
Буферизация потоков
Разбор конфигура-
ционного файла

Работа с консолью
Работа с классом PrintWriter
Разбор строк класса String
Загрузка и просмотр изображений
Потоки в оперативной памяти
Конвейерные потоки
Комбинирование двух потоков
Комбинирование нескольких потоков
Поиск слова в текстовом файле
Произвольный доступ к файлу
Информация о файле
Работа с каталогами
Просмотр содержимого каталога
Просмотр каталога с фильтром
Панель для выбора каталога
Список системных свойств
Сохранение списка системных свойств
Контрольная сумма файла
Копирование, переименование, удаление файлов
Архивы ZIP
Создание архива ZIP
Распаковка архива ZIP
Обход дерева каталогов

Назад Вперед

7.5. Произвольные классы и файлы

Мы покажем как сохранять содержимое объектов произвольных классов в файле и затем восстанавливать его, пользуясь классами ObjectOutputStream и ObjectInputStream.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Немного теории

В предыдущем примере мы показали, как с применением классов ObjectOutputStream и ObjectInputStream можно сохранять в файле и затем восстанавливать содержимое встроенных и стандартных классов Java.

Заметим, что такая техника может быть использована для любых классов, реализующих интерфейс Serializable.

Если посмотреть исходный текст этого интерфейса, то нетрудно убедиться, что в его рамках не определено ни одного метода или поля. Поэтому пользоваться этим интерфейсом чрезвычайно просто - вам не нужно определять никаких методов. Достаточно указать, что класс реализует интерфейс Serializable, после чего появляется возможность работать с этим классом через потоки ObjectOutputStream и ObjectInputStream.

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

Описание примера

В окне нашего приложения вы можете рисовать прямоугольники, цвет которых выбирается автоматически случайным образом (рис. 1).

pic1.gif (5274 bytes)

Рис. 1. Главное окно приложения

С помощью строки Save As меню File рисунок сохраняется в файле, а с помощью строки Open - восстанавливается из файла.

Исходный текст приложения напоминает исходный текст предыдущего приложения, поэтому мы остановимся лишь на отличиях.

Класс MyRects

Для хранения координат прямоугольников, их размеров и цвета мы создаем объект класса MyRects, определение которого приведено ниже:

class MyRects
  implements Serializable
{
  Vector lines;
  Vector colors;
  String s;
  int nVersionMajor;
  int nVersionMinor;
  
  public MyRects()
  {  
    lines = new Vector();    
    colors = new Vector();    
    s = "My own serializable class";  
    nVersionMajor = 1;
    nVersionMinor = 0;
  }  
}

Обратите внимание, что этот класс реализует интерфейс Serializable, не определяя при этом ни одного дополнительного метода (так как данный интерфейс не содержит методов).

Расположение и размеры прямоугольников хранятся в массиве lines класса Vector. Массив colors этого же класса предназначен для хранения цветов прямоугольников. Другие поля в классе определены только для примера и в нашем приложении не используются.

Конструктор класса MyRects создает массивы lines и colors, а также инициализирует другие поля класса.

Класс FrameWindow

Мы рассмотрим только те методы класса FrameWindow, которые имеют отношение к работе с классом MyRects. Описание остальных методов вы найдете в предыдущем примере этого раздела нашей библиотеки.

В классе FrameWindow мы определили поле mr класса MyRects и проинициализировали его:

MyRects mr = new MyRects();

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

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

В процессе перерисовки окна приложения метод paint перебирает в цикле элементы списков lines и colors, хранящихся в объекте mr класса MyRects:

for (int i=0; i < mr.lines.size(); i++) 
{
  Rectangle p = 
   (Rectangle)mr.lines.elementAt(i);
        
  Color clr = (Color)mr.colors.elementAt(i);
  g.setColor(clr);
        
  g.drawRect(p.x, p.y, p.width, p.height);
}

При этом он выбирает из списков расположение и размеры прямоугольника, а также его цвет. После установки нового цвета в контексте отображения прямоугольник рисуется методом drawRect.

Метод actionPerformed класса FrameWindow

Когда пользователь открывает новый файл при помощи строки Open меню File, метод actionPerformed выводит на экран стандартную диалоговую панель выбора входного файла:

fdlg = new FileDialog(this, "Open file", 
  FileDialog.LOAD);
fdlg.show();

После этого метод actionPerformed создает входной поток класса ObjectInputStream и читает из него содержимое объекта класса MyRects методом readObject:

ObjectInputStream ois;
     
try
{
  ois = new ObjectInputStream(
    new FileInputStream(
      fdlg.getDirectory() +
      fdlg.getFile()));
            
  mr = (MyRects)ois.readObject();    
  ois.close();
}
catch (IOException ex)
{
  System.out.println(ex.toString());
}
catch (ClassNotFoundException ex)
{
  System.out.println(ex.toString());
}

Обратите внимание на необходимое здесь явное приведение типа.

После выполнения операции чтения окно приложения перерисовывается:

repaint();

При сохранении рисунка в файле метод actionPerformed отображает стандартную диалоговую панель для выбора выходного файла:

fdlg = new FileDialog(this,
  "Save drawing as...", 
  FileDialog.SAVE);
fdlg.show();

Далее он создает выходной поток класса ObjectOutputStream и выводит в него содержимое объекта mr класса MyRects методом writeObject:

ObjectOutputStream oos;
     
try
{
  oos = new ObjectOutputStream(
    new FileOutputStream(
      fdlg.getDirectory() +
      fdlg.getFile()));
            
  oos.writeObject(mr);    
  oos.flush();
  oos.close();
}
catch (IOException ex)
{
  System.out.println(ex.toString());
}
Метод mousePressed класса FrameWindow

Исходный текст этого метода аналогичен исходному тексту метода mousePressed предыдущего приложения. Отличие заключается лишь в способе адресации к массиву lines, который теперь стал полем класса mr:

. . .
if(e.getClickCount() > 1)
{
  mr.lines.removeAllElements();
  repaint();
  return;
}
. . .
Метод mouseReleased класса FrameWindow

Когда пользователь отпускает клавишу мыши после завершения процесса рисования, метод mouseReleased сохраняет координаты прямоугольника в массиве mr.lines:

mr.lines.addElement(
new Rectangle(
  dmDown.width, dmDown.height, 
  x - dmDown.width, y - dmDown.height));

Затем он получает случайный цвет и сохраняет его в массиве mr.colors:

int rColor, gColor, bColor;
        
rColor = (int)(255 * Math.random());
gColor = (int)(255 * Math.random());
bColor = (int)(255 * Math.random());
Color clr = 
  new Color(rColor, gColor, bColor);
        
mr.colors.addElement(clr);

Далее метод выполняет перерисовку окна приложения и сбрасывает флаг рисования:

repaint();      
bDrawing = false;

Назад Вперед

[Назад]