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

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

Оглавление
Режим FlowLayout
Режим GridLayout
Режим BorderLayout
Режим CardLayout
GridBagLayout -  пример 1
GridBagLayout - заполнение формы
Инструментальная линейка
Панели
Точное размещение компонент
Прилипчивая кнопка

Назад Вперед

5.4. Режим CardLayout

Пример демонстрирует использование режима размещения CardLayout системы Layout Manager для поочередного просмотра нескольких графических изображений в окне аплета.

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

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

Демонстрация
(ваш браузер должен уметь работать с аплетами Java JDK 1.1)

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

Режим размещения CardLayout предназначен для поочередного размещения нескольких компонент в одном контейнере (например, класса Panel).

При добавлении компонента в контейнер необходимо передать его имя методу add через первый параметр, например:

picFrame pf;

pf = new picFrame();
add("pic0", pf);

Остальные компоненты добавляются аналогичным образом.

В классе CardLayout предусмотрено несколько методов, предназначенных для выбора отображаемого компонента:

Метод Какой компонент выбирается для отображения
first Первый
last Последний
next Следующий
previous Предыдущий
show Произвольный, заданный своим именем

Всем указанным методам, кроме метода show, передается через единственный параметр ссылка на родительский контейнер, в котором выполняется размещение. Методу show через второй параметр дополнительно передается имя компонента (как строка класса String).

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

В окно нашего аплета мы добавляем пять компонентов. Первый из них представляет собой контейнер класса picViewer, предназначенный для просмотра небольших рисунков, любезно предоставленных нам художником Алексеем Абрамкиным. Остальные - это кнопки, с помощью которых можно выбирать для просмотра один из нескольких рисунков по очереди (рис. 1).

pic1.gif (4762 bytes)

Рис. 1. Аплет для просмотра рисунков

Кнопка Next позволяет просматривать рисунки в прямом направлении, кнопка Prev - в обратном. Если нажать кнопку First, вы увидите первый рисунок, а если Last - последний.

Рассмотрим исходный текст аплета.

Класс CardDemo

Главный класс аплета создан на базе класса Applet и реализует интерфейс ActionListener, необходимый для обработки событий от кнопок:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class CardDemo extends Applet
  implements ActionListener
{
  . . .
}

В этом классе мы определили несколько полей и методов.

Поле pv хранит ссылку на контейнер, отображающий рисунки:

picViewer pv;

Следующие четыре поля предназначены для хранения ссылок на соответствующие кнопки:

Button btnNext;
Button btnPrev;
Button btnFirst;
Button btnLast;
Метод init

Прежде всего метод init загружает семь графических изображений из файлов с именами вида pic0x.gif, где x - номер рисунка:

Image[] imgSlides;
imgSlides = new Image[7];
    
MediaTracker tr = new MediaTracker(this);
    
for(int i = 0; i < 7; i++)
{
  imgSlides[i] = getImage(getCodeBase(), 
    "pic0" + (i + 1) + ".gif");
        
  tr.addImage(imgSlides[i], 0);
  try
  {
    tr.waitForAll();
  }
  catch (InterruptedException e) {}
}

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

Ссылки на загруженные изображения сохраняются в массиве imgSlides. Этот массив затем передается в качестве параметра конструктору контейнера класса picViewer, отображающему рисунки:

pv = new picViewer(imgSlides); 
add(pv);

Контейнер добавляется в окно аплета методом add, причем система Layout Manager в данном случае использует по умолчанию режим размещения компонент FlowLayout.

Далее мы создаем четыре кнопки и тоже добавляем их в окно контейнера:

btnNext = new Button("Next");
btnPrev = new Button("Prev");
btnFirst = new Button("First");
btnLast = new Button("Last");
  
add(btnNext);
add(btnPrev);
add(btnFirst);
add(btnLast);

На последнем этапе метод init регистрирует обработчики событий от кнопок, применяя метод addActionListener:

btnNext.addActionListener(this);
btnPrev.addActionListener(this);
btnFirst.addActionListener(this);
btnLast.addActionListener(this);
Метод actionPerformed

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

Если нажата кнопка Next, наш метод вызывает для родительского контейнера метод next, как это показано ниже:

if(e.getSource().equals(btnNext))
{
  ((CardLayout)
      pv.getLayout()).next(pv);
}

Как работает этот фрагмент кода?

Прежде всего с помощью метода getLayout мы получаем ссылку на интерфейс системы Layout Manager, установленный в контейнере pv. Мы знаем, что этот контейнер применяет схему размещения CardLayout, и потому выполняем явное приведение типа.

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

Аналогичным образом обрабатываются события и от других кнопок:

else if(e.getSource().equals(btnPrev))
{
  ((CardLayout)
    pv.getLayout()).previous(pv);
}
      
else if(e.getSource().equals(btnFirst))
{
  ((CardLayout)
    pv.getLayout()).first(pv);
}
      
else if(e.getSource().equals(btnLast))
{
  ((CardLayout)
    pv.getLayout()).last(pv);
}

Класс picViewer

Реализация класса picViewer, созданного на базе класса Container, достаточно проста:

class picViewer extends Container
{
  picFrame[] pf;
  
  public picViewer(Image[] imgSlides)
  {
    int nSlides = imgSlides.length;
    
    setLayout(new CardLayout());
    pf = new picFrame[nSlides];
  
    for(int i = 0; i < nSlides; i++)
    {
      pf[i] = new picFrame(imgSlides[i]);
      add("pic0" + (i + 1) + " ", pf[i]);
    }
  }
}

Конструктор класса определяет размер массива изображений, переданный ему в качестве параметра. Затем он устанавливает режим размещения компонент CardLayout.

Далее конструктор создает массив объектов класса picFrame, каждый из которых служит компонентом, отображающим свой рисунок из массива. Ссылки на эти рисунки передаются конструктору класса picFrame в цикле.

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

add("pic0" + (i + 1) + " ", pf[i]);

Это необходимо делать из-за примененного в контейнере режима размещения компонент CardLayout

Класс picFrame

Класс picFrame создан на базе класса Canvas и предназначен для отображения рисунка, ссылка на который передается конструктору.

class picFrame extends Canvas
{
  . . .
}

В классе picFrame определено несколько полей.

Поля imHeight и imWidth хранят, соответственно, высоту и ширину отображаемого рисунка:

int imHeight;
int imWidth;

В поле im находится ссылка на сам рисунок, являющийся объектом класса Image:

Image im;

И, наконец, в поле dimMinSize находятся "габаритные" размеры компонента, которые в нашем случае равны размерам рисунка:

Dimension dimMinSize;
Конструктор класса picFrame

Исходный текст конструктора класса picFrame представлен ниже:

public picFrame(Image img)
{
  im = img;
  imHeight = im.getHeight(this);
  imWidth = im.getWidth(this);
    
  dimMinSize = 
    new Dimension(imWidth, imHeight);
}

Как видите, конструктор сохраняет ссылку на изображение в поле im, определяет и сохраняет размеры этого изображения в полях imHeight и imWidth. Затем он устанавливает размеры компонента, равными размерам рисунка.

Метод paint

Метод paint рисует изображение в окне компонента:

public void paint(Graphics g)
{
  g.drawImage(im, 0, 0, this);
}

Так как размеры этого окна равны размерам рисунка, последний занимает все окно.

Другие методы класса picFrame

Следующие методы возвращают размеры окна компонента, равные размерам отображаемого рисунка:

public Dimension getPreferredSize()
{
  return dimMinSize;
}
  
public Dimension getMinimumSize()
{
  return dimMinSize;
}
  
public Dimension preferredSize()
{
  return dimMinSize;
}
  
public Dimension minimumSize()
{
  return dimMinSize;
}

Наличие этих методов необходимо для правильного позиционирования компонента в окне контейнера.


Назад Вперед

[Назад]