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

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

Оглавление
Простейший пример
Создание двух потоков
Управление потоками
Спрайтовая анимация
Панели с двигающимся текстом
Бегущая строка с мерцанием
Устранение мерцания
Поток для записи в файл
Контроль за выводом в файл
Чтение с сервера Web

Назад Вперед

6.5. Панели с двигающимся текстом

Для привлечения внимания посетителей вашей страницы Web вы можете использовать движующийся текст. В этом примере мы создаем компоненты с таким текстом.

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

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

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

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

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

Первая из них основана на использовании метода drawString, который вызывается из метода paint. В этом случае отдельный поток вызывает периодическую перерисовку окна, постоянно смещая координаты отображения текстовой строки. Данный способ, требующий, кстати, борьбы с мерцанием изображения, будет проиллюстрирован в нашем следующем примере.

Вторая методика заключается в сдвиге содержимого части окна аплета методом copyArea с очисткой освободившегося пространства методом clearRect. Строка появляется в правой части окна по буквам и сдвигается влево.

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

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

pic1.gif (6734 bytes)

Рис. 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);
}

Назад Вперед

[Назад]