Назад
Вперед
3.3. Кнопка в виде аплета
Приведен пример аплета, выполняющего роль
кнопки в документе HTML. С помощью этой кнопки
можно организовать ссылки на другие документы HTML
или любые объекты, имеющие адрес URL.
Кнопка утапливается вглубь окна при нажатии.
Когда пользователь располагает над ее
поверхностью курсор мыши, цвет надписи
периодически меняется с черного на красный и
обратно.
Исходный текст примера
Архив проекта для Java WorkShop 2.0
Демонстрация
(ваш браузер должен уметь работать с аплетами
Java)
Немного теории
Для оформления ссылок в документах HTML часто
используют кнопки в виде графических
изображений кнопок. Однако эти кнопки не
нажимаются, что является заметным недостатком.
Отсутствие видимой реакции на действие может
побудить посетителя вашего сервера повторит это
действие. Если кнопка не нажимается, а на
загрузку новой страницы, привязанной к этой
кнопке, требуется время, он скорее всего
попробует нажать кнопку еще раз. В том случае
когда кнопка применяется для отправления
заполненной формы, данные могут быть посланы
несколько раз подряд, что нежелательно.
Простейший выход из этой ситуации -
использование сценариев JavaScript. С помощью такого
сценария вы можете отслеживать действия
пользователя. Когда он попытается нажать на
кнопку, сценарий JavaScript нарисует эту кнопку в
нажатом состоянии.
Тем не менее, и у этого способа имеются
недостатки. Самый заметный из них - необходимость
подготавливать несколько графических
изображений для каждой кнопки. Если на странице
расположено много кнопок, она будет загружаться
достаточно долго.
Между тем нетрудно сделать аплет Java, который
решит все перечисленные выше проблемы сразу.
Он будет выполнять роль кнопки, рисуя в своем
окне ее изображение в нажатом и отжатом
состоянии, а также изменяя рисунок, когда
пользователь помещает курсор мыши над
поверхностью кнопки.
Такой аплет может сам подписывать кнопки,
поэтому вам нужно подготовить только два
изображения - для нажатого и отжатого состояния
кнопок. Если на странице расположено много
кнопок (десять и больше), это может дать заметный
выигрыш в скорости загрузки.
Описание примера
Основной класс аплета, представляющего собой
кнопку, создан на базе Applet и дополнительно
реализует интерфейс Runnable. Этот
интерфейс необходим для анимации в
многопоточном режиме.
Дополнительно к классам java.applet.* и java.awt.* мы
включили библиотеку классов java.net.*. Она
необходима для выполнения загрузки в окно
браузера документа с заданным адресом URL.
Поля основного класса
Наш аплет принимает ряд параметров,
определяющих внешний вид и режим работы кнопки.
Ниже мы перечислили параметры аплета, название
поля, в котором хранится значение этого
параметра, а также краткое описание параметров:
Параметр |
Поле |
Описание |
Width |
parmWidth |
Ширина окна кнопки |
Height |
parmHeight |
Высота окна кнопки |
ImageUp |
parmImageUp |
Графическое изображение кнопки в
отжатом состоянии. Размеры этого изображения
должны быть равны размерам окна кнопки |
ImageDn |
parmImageDn |
Графическое изображение кнопки в
нажатом состоянии |
Animate |
parmAnimate |
Флаг анимации. Если значение равно true,
при размещении курсора над поверхностью кнопки
цвет надписи будет периодически меняться с
черного на красный и обратно |
Title |
parmTitle |
Надпись на поверхности кнопки |
ShadowValue |
parmShadowValue |
Величина сдвига надписи для нажатой
кнопки в пикселах |
TitleFont |
parmTitleFont |
Шрифт для надписи на кнопке |
TitleFontSize |
parmTitleFontSize |
Размер указанного выше шрифта |
TitleBold |
parmTitleBold |
Выделение надписи жирным шрифтом |
TitleItalic |
parmTitleItalic |
Выделение надписи наклоном |
URL |
parmURL |
Адрес URL документа, который будет
загружаться в окно браузера при нажатии на
кнопку |
URLWindow |
parmURLWindow |
Имя окна для загрузки указанного выше
документа. Нужно главным образом для работы с
фреймами |
Вы не обязаны указывать все перечисленные
параметры, так как они имеют значения по
умолчанию:
private String parmWidth = "80";
private String parmHeight = "20";
private String parmImageUp = "btnup.gif";
private String parmImageDn = "btndn.gif";
private String parmAnimate = "true";
private String parmTitle = "Button";
private String parmShadowValue = "1";
private String parmTitleFont = "Helvetica";
private String parmTitleFontSize = "12";
private String parmTitleBold = "true";
private String parmTitleItalic = "false";
private String parmURL = null;
private String parmURLWindow = "_self";
Если вас устраивают эти параметры, то можете
ограничится указанием в документе HTML только
параметров Title и URL.
В следующих полях хранятся преобразованные
значения параметров аплета:
int nWidth = 80;
int nHeight = 20;
boolean bAnimate = true;
Image imgButtonUp;
Image imgButtonDn;
int nShadowValue;
boolean bTitileBold;
boolean bTitileItalic;
Dimension dimAppletWindow;
int nWindowWidth;
int nWindowHeight;
int nTitleFontSize;
Поле bButtonUp хранит текущее состояние кнопки
(нажата или отжата):
boolean bButtonUp = true;
Значение true соответствует отжатой кнопке,
значение false - нажатой.
В поле threadAnimate хранится ссылка на поток, в
задачу которого входит анимация кнопки:
Thread threadAnimate = null;
Поле clrTitleColor хранит текущее значение цвета
надписи, изменяющееся в процессе анимации:
Color clrTitleColor = Color.black;
И, наконец, последняя группа полей хранит имена
параметров аплета:
private final String
name_parmWidth = "Width";
private final String
name_parmHeight = "Height";
private final String
name_parmImageUp = "ImageUp";
private final String
name_parmImageDn = "ImageDn";
private final String
name_parmAnimate = "Animate";
private final String
name_parmTitle = "Title";
private final String
name_parmShadowValue = "ShadowValue";
private final String
name_parmTitleFont = "TitleFont";
private final String
name_TitleFontSize = "TitleFontSize";
private final String
name_TitleBold = "TitleBold";
private final String
name_TitleItalic = "TitleItalic";
private final String
name_URL = "URL";
private final String
name_URLWindow = "URLWindow";
Метод getParameterInfo
Метод getParameterInfo возвращает ссылку на массив
описаний параметров аплета. Его исходный текст
приведен ниже (в сокращенном виде):
public String[][] getParameterInfo()
{
String[][] paramInfo =
{
{
name_parmWidth,
"String", "Button width"
},
{
name_parmHeight,
"String", "Button height"
},
. . .
{
name_URLWindow,
"String", "URL window"
}
};
return paramInfo;
}
Метод init
При инициализации аплета метод init прежде всего
получает значения всех параметров. Если параметр
не задан, используется значение по умолчанию.
Вот, например, как мы получаем значение
параметра Width:
String parm;
parm = getParameter(name_parmWidth);
if(parm != null)
parmWidth = parm;
При помощи метода getParameter мы пытаемся получить
значение параметра. Если этот метод возвращает
null, значит параметр не задан. В этом случае мы
просто оставляем в поле parmWidth то значение,
которое указано при его определении.
Числовые параметры мы преобразуем следующим
образом:
try
{
Integer intVal = new Integer(parmWidth);
nWidth = intVal.intValue();
}
catch(Exception ex) {}
Так как числовой параметр может быть задан
неверно, при работе конструктора объекта класса
Integer возможно возникновение исключения. Мы
игнорируем его, оставляя таким образом
нетронутым значение, заданное по умолчанию.
Логические параметры обрабатываются следующим
образом:
if(parmAnimate.equals("true"))
bAnimate = true;
else
bAnimate = false;
Для загрузки графических изображений кнопки мы
создаем объекты класса Image:
imgButtonUp =
getImage(getCodeBase(), parmImageUp);
imgButtonDn =
getImage(getCodeBase(), parmImageDn);
Так как в качестве адреса URL файлов изображений
мы указываем значение, полученное от метода getCodeBase, эти файлы должны находиться
в том же каталоге сервера Web, что и файл байт-кода
аплета.
На завершающем этапе метод init определяет
текущие размеры окна аплета и сохраняет их в
соответствующих полях:
dimAppletWindow = size();
nWindowWidth = dimAppletWindow.width;
nWindowHeight = dimAppletWindow.height;
Метод paint
В задачу этого метода входит рисование
изображения кнопки в окне аплета. Внешний вид
этого изображения зависит от многих условий.
Прежде всего определяется стиль заголовка. По
умолчанию используется заголовок без выделения:
int nFontStyle = Font.PLAIN;
Если же в параметрах аплета указано, что
заголовок должен быть выделен жирным шрифтом или
наклоном, выполняется соответствующее изменение
стиля:
if(bTitileBold)
nFontStyle |= Font.BOLD;
if(bTitileItalic)
nFontStyle |= Font.ITALIC;
Далее метод paint устанавливает в контексте
отображения окна аплета шрифт, указанный в
параметре аплета TitleFont:
g.setFont(new Font(parmTitleFont,
nFontStyle, nTitleFontSize));
После этого определяются метрики шрифта и
выполняется позиционирование надписи по центру
окна аплета:
FontMetrics fm = g.getFontMetrics();
int nTitileWidth =
fm.stringWidth(parmTitle);
int nTitleHeight = fm.getAscent() -
fm.getLeading() - fm.getDescent();
int x0 =
(nWindowWidth - nTitileWidth) / 2;
int y0 =
((nWindowHeight - nTitleHeight) / 2) +
nTitleHeight;
В поля x0 и y0 записываются координаты для
рисования надписи.
Далее метод paint проверяет текущее состояние
кнопки и выбирает соответствующее изображение
для рисования в своем окне:
if(bButtonUp)
{
g.drawImage(imgButtonUp, 0, 0, this);
g.setColor(clrTitleColor);
g.drawString(parmTitle, x0, y0);
}
else
{
g.drawImage(imgButtonDn, 0, 0, this);
g.setColor(Color.blue);
g.drawString(parmTitle,
x0 - nShadowValue, y0 - nShadowValue);
}
После рисования графического изображения
метод paint устанавливает текущий цвет надписи и
рисует ее методом drawString.
Метод mouseDown
Когда пользователь нажимает мышью на окно
вашего аплета, управление передается методу
mouseDown:
public boolean mouseDown(
Event ev, int x, int y)
{
if(bButtonUp)
{
bButtonUp = false;
repaint();
doButtonAction();
}
return true;
}
Этот метод проверяет текущее состояние кнопки,
и если она отжата, переводит кнопку в нажатое
состояние. Для этого в поле bButtonUp записывается
значение false.
Затем аплет перерисовывает свое окно и
вызывает метод doButtonAction, загружающий в окно
браузера документ HTML, адрес которого задан
параметром аплета с именем URL.
Метод mouseUp
Этот метод просто переключает кнопку в отжатое
состояние и затем перерисовывает окно аплета:
public boolean mouseUp(
Event ev, int x, int y)
{
if(!bButtonUp)
{
bButtonUp = true;
repaint();
}
return true;
}
Метод mouseEnter
Когда пользователь располагает курсор мыши над
поверхностью окна нашего аплета, управление
передается методу mouseEnter.
Он проверяет, задан ли в параметре аплета Animate
режим анимации. Если задан, то метод mouseEnter
запускает на выполнение поток анимации threadAnimate:
public boolean mouseEnter(
Event ev, int x, int y)
{
if(bAnimate)
{
if(threadAnimate == null)
{
threadAnimate = new Thread(this);
threadAnimate.start();
}
}
return true;
}
В результате метод run, определенный в главном
классе нашего аплета, будет выполнять анимацию в
окне аплета-кнопки.
Метод mouseExit
Если пользователь убирает курсор из окна
аплета, метод mouseExit останавливает запущенный
ранее поток анимации:
public boolean mouseExit(
Event ev, int x, int y)
{
if(bAnimate)
{
if(threadAnimate != null)
{
threadAnimate.stop();
threadAnimate = null;
clrTitleColor = Color.black;
}
}
bButtonUp = true;
repaint();
return true;
}
После остановки на поверхности кнопки
устанавливается черный цвет надписи.
Эти действия выполняются только в том случае,
если в параметре аплета Animate задан режим анимации
Метод stop
Когда документ с кнопками исчезает из окна
браузера, метод stop останавливает запущенную
ранее анимацию:
public void stop()
{
if(bAnimate)
{
if(threadAnimate != null)
{
threadAnimate.stop();
threadAnimate = null;
clrTitleColor = Color.black;
}
}
}
Метод run
Этот метод работает как отдельный поток, когда
пользователь держит курсор мыши над
поверхностью окна аплета.
Его задача заключается в периодическом
изменении цвета надписи, хранящегося в поле
clrTitleColor. Эта операция выполняется в бесконечном
цикле с задержкой на каждой итерации, равной 300
миллисекундам:
public void run()
{
boolean bFlipFlop = true;
while(true)
{
if(bFlipFlop)
{
clrTitleColor = Color.red;
bFlipFlop = false;
}
else
{
clrTitleColor = Color.black;
bFlipFlop = true;
}
repaint();
try
{
Thread.sleep(300);
}
catch (InterruptedException ex)
{
stop();
}
}
}
При каждом проходе цикла окно аплета
перерисовывается методом repaint.
Метод doButtonAction
Метод doButtonAction получает управление, когда
пользователь нажимает на нашу кнопку. Исходный
текст этого метода приведен ниже:
void doButtonAction()
{
if(parmURL != null)
{
URL url = null;
AppletContext appletContext;
appletContext = getAppletContext();
try
{
url = new URL(parmURL);
}
catch (MalformedURLException e) { }
if (url != null)
{
appletContext.showDocument(
url, parmURLWindow);
}
}
}
Здесь мы вначале получаем ссылку на контекст appletContext, в котором исполняется
аплет. С помощью этой ссылки можно загрузить в
окно браузера новый документ HTML и выполнить
другие операции над браузером.
Перед загрузкой мы создаем новый объект класса
URL, передавая ему строку из одноименного
параметра аплета. Если создание прошло успешно,
документ загружается методом showDocument в окно
браузера, заданное параметром аплета URLWindow. В
качестве имени окна вы можете использовать, в
частности, имена окон фреймов, такие как _self, _top,
_parent, а также имя _blank.
Назад Вперед |