Назад
Вперед
6.5. Панели с двигающимся текстом
Для привлечения внимания посетителей вашей
страницы Web вы можете использовать движующийся
текст. В этом примере мы создаем компоненты с
таким текстом.
Исходный текст примера
Архив проекта для Java WorkShop 2.0
Демонстрация
(ваш браузер должен уметь работать с аплетами
Java JDK 1.1)
Немного теории
Для отображения двигающегося теста можно
использовать две различные методики.
Первая из них основана на использовании метода
drawString, который вызывается из метода paint. В этом
случае отдельный поток вызывает периодическую
перерисовку окна, постоянно смещая координаты
отображения текстовой строки. Данный способ,
требующий, кстати, борьбы с мерцанием
изображения, будет проиллюстрирован в нашем
следующем примере.
Вторая методика заключается в сдвиге
содержимого части окна аплета методом copyArea с
очисткой освободившегося пространства методом
clearRect. Строка появляется в правой части окна по
буквам и сдвигается влево.
Описание примера
В окне нашего аплета размещается три панели,
созданные на базе одного и того же класса. Перед
размещением для каждой панели мы установили свою
текстовую строку, шрифт, размер символов и
скорость перемещения (рис. 1).
Рис. 1. Панели с двигающимся текстом
Исходный текст аплета описан ниже.
Главный класс аплета Scroller
Главный класс аплета создан на базе класса Applet
и не имеет никаких особенностей, связанных с
многопоточностью:
import java.applet.*;
import java.awt.*;
public class Scroller extends Applet
{
TextAutoScroller tas;
TextAutoScroller tas1;
TextAutoScroller tas2;
. . .
}
В этом классе мы определили три поля tas, tas1 и tas2,
хранящие ссылки на панели с двигающимся текстом.
Метод init аплета Scroller
Этот метод выполняет инициализацию аплета.
Прежде всего мы устанавливаем режим размещения
компонент GridLayout таким образом, чтобы компоненты
размещались в одном столбце таблицы:
setLayout(new GridLayout(0, 1));
Далее мы получаем ссылку на контекст
отображения:
Graphics g = getGraphics();
Первая панель добавляется очень просто:
String ScrollingText =
" First scroller component";
tas = new TextAutoScroller(ScrollingText, g);
add(tas);
Здесь мы передаем соответствующем
конструктору класса TextAutoScroller ссылку на
сдвигаемую текстовую строку и контекст
отображения.
При добавлении второй панели текстовая строка
задается методом setText (определенном в классе
TextAutoScroller), причем уже после вызова метода add:
ScrollingText = "";
tas1 = new TextAutoScroller(ScrollingText, g);
tas1.setFont(
new Font("TimesRoman", Font.BOLD, 40));
tas1.setDelay(20);
add(tas1);
tas1.setText(" Second scroller component");
Дополнительно мы устанавливаем шрифт и
задержку, вызывая методы setFont и setDelay,
соответственно
Третья панель добавляется аналогично:
ScrollingText = " Last component";
tas2 = new TextAutoScroller(ScrollingText, g);
tas2.setDelay(5);
tas2.setFont(
new Font("Courier", Font.BOLD, 36));
add(tas2);
Метод start аплета Scroller
При инициализации аплета метод start запускает
анимацию, вызывая для каждой панели свой метод
start:
public void start()
{
tas.start();
tas1.start();
tas2.start();
}
Метод stop аплета Scroller
Аналогично, при завершении работы аплета метод
stop останавливает потоки анимации в панелях,
вызывая метод stop из класса TextAutoScroller:
public void stop()
{
tas.stop();
tas1.stop();
tas2.stop();
}
Класс TextAutoScroller
Этот класс создан на базе класса Panel и реализует
интерфейс Runnable:
class TextAutoScroller extends Panel
implements Runnable
{
. . .
}
В результате вы можете добавлять произвольное
количество объектов класса TextAutoScroller в любой
контейнер, например, в окно аплета или в другую
панель.
Поля класса TextAutoScroller
В поле TextAutoScroller мы определили несколько полей.
Поле tiktakThread хранит ссылку на поток анимации:
Thread tiktakThread = null;
В поле ScrollingText хранится сдвигаемая строка:
String ScrollingText = " ";
Поле delay предназначено для хранения времени
задержки, выполняемой на каждой итерации цикла в
потоке анимации:
int delay = 10;
Поле dimMinSize хранит размеры окна панели:
Dimension dimMinSize;
И, наконец, в поле fnt хранится ссылка на шрифт,
которым отображается сдвигаемая строка:
Font fnt;
Конструктор класса TextAutoScroller
При создании объекта класса TextAutoScroller
конструктор инициализирует поля класса:
ScrollingText = s;
fnt = new Font("Helvetica", Font.BOLD, 24);
g.setFont(fnt);
FontMetrics fm = g.getFontMetrics();
Далее для примера мы показали, как можно
определить минимальные размеры панели,
достаточные для отображения сдвигаемой строки:
int nTitileWidth =
fm.stringWidth(ScrollingText);
int nTitleHeight = fm.getAscent() -
fm.getLeading() - fm.getDescent();
int nWindowWidth = nTitileWidth + 20;
int nWindowHeight = nTitleHeight + 20;
dimMinSize = new Dimension(
nWindowWidth, nWindowHeight);
Метод setDelay класса TextAutoScroller
Вызвав метод setDelay, вы можете изменить скорость
перемещения текста внутри панели:
public void setDelay(int d)
{
delay = d;
}
Метод setFont класса TextAutoScroller
Метод setFont предназначен для установки шрифта,
которым отображается сдвигаемая в окне панели
строка:
public void setFont(Font f)
{
fnt = f;
}
Метод setText класса TextAutoScroller
Для изменения сдвигаемой строки вы можете
использовать метод setText:
public void setText(String s)
{
ScrollingText = s;
}
Метод paint класса TextAutoScroller
Когда контейнер перерисовывает панель, метод
paint определяет текущие размеры панели и
сохраняет их в поле dimMinSize:
public void paint(Graphics g)
{
dimMinSize = getSize();
}
Методы start и stop класса TextAutoScroller
С помощью методов start и stop приложение может,
соответственно, запустить и остановить поток
анимации:
public void start()
{
if (tiktakThread == null)
{
tiktakThread = new Thread(this);
tiktakThread.start();
}
}
public void stop()
{
if (tiktakThread != null)
{
tiktakThread.stop();
tiktakThread = null;
}
}
Использованные здесь приемы вам уже знакомы из
предыдущих примеров этого раздела и не требуют
комментариев.
Метод run класса TextAutoScroller
Рассмотрим исходный текст метода run, который
работает в отдельном потоке, выполняя сдвиг
строки.
Перед запуском цикла анимации метод выполняет
некоторые инициализирующие действия.
В переменную nCurrentChar, хранящую номер текущего
отображаемого символа в сдвигаемой строке,
записывается нулевое значение:
int nCurrentChar = 0;
Далее метод получает контекст отображения и
устанавливает в нем нужный шрифт:
Graphics g = getGraphics();
g.setFont(fnt);
Пользуясь метриками шрифта, метод run определяет
максимальную ширину символов nMaxCharWidth и
начальную позицию по вертикали для отображения
строки yPos:
FontMetrics fm = g.getFontMetrics();
int nMaxCharWidth = fm.charWidth('W') + 5;
int yPos = fm.getHeight() + 5;
Переменная nCurrentCharWidth предназначена для
хранения ширины текущего отображаемого символа:
int nCurrentCharWidth;
Цвет строки выбирается случайным образом и
устанавливается в контексте отображения:
int rColor = (int)(255 * Math.random());
int gColor = (int)(255 * Math.random());
int bColor = (int)(255 * Math.random());
g.setColor(new Color(rColor, gColor, bColor));
Далее запускается цикл анимации.
while (true)
{
try
{
. . .
}
catch (InterruptedException e)
{
stop();
}
}
При возникновении исключения InterruptedException во
время выполнения цикла поток анимации
останавливается.
Далее идет процесс отображения символов и их
сдвига. Этот процесс выполняется в теле
оператора try-catch. Когда в процессе извлечения
очередного символа из строки методом charAt
происходит исключение StringIndexOutOfBoundsException, метод
сбрасывает номер символа, хранящийся в
переменной nCurrentChar и выбирает новый цвет для
строки:
try
{
. . .
}
catch(StringIndexOutOfBoundsException e)
{
nCurrentChar = 0;
rColor = (int)(255 * Math.random());
gColor = (int)(255 * Math.random());
bColor = (int)(255 * Math.random());
g.setColor(
new Color(rColor, gColor, bColor));
}
Ширина очередного символа определяется
следующим образом:
nCurrentCharWidth =
fm.charWidth(ScrollingText.charAt(
nCurrentChar));
Далее мы рисуем извлеченный символ и
увеличиваем счетчик символов nCurrentChar:
char[] ch;
String s;
ch = new char[1];
ch[0] =
ScrollingText.charAt(nCurrentChar);
s = new String(ch);
g.drawString(s,
dimMinSize.width - nMaxCharWidth, yPos);
nCurrentChar++;
После этого метод медленно сдвигает символ
влево, очищая освобождающееся пространство:
for(int i = 0; i < nCurrentCharWidth; i++)
{
g.copyArea(nMaxCharWidth / 2, 0,
dimMinSize.width - nMaxCharWidth +
nCurrentCharWidth - i, dimMinSize.height,
-1, 0);
g.clearRect(dimMinSize.width -
nMaxCharWidth +
nCurrentCharWidth - i + 1, 0,
nMaxCharWidth, dimMinSize.height);
Thread.sleep(delay);
}
Назад Вперед |