Назад
Вперед
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).
Рис. 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;
}
Наличие этих методов необходимо для
правильного позиционирования компонента в окне
контейнера.
Назад Вперед |