Вывод вспомогательной информации |
215 |
Надпись JLabel позволяет вывести на экран текст, значок, или оба элемента вместе. Текст и/или значок чаще всего задаются в конструкторе надписи, у которого имеются пять перегруженных версий на все случаи жизни, но можно также задать или изменить текст или значок потом, после создания объекта, манипулируя свойствами icon и text с помощью соответствующих методов get/set (это свойства JavaBeans). Вы также можете изменить шрифт вывода текста, используя метод setFont() (в примере мы этого не делаем, а по умолчанию применяется шрифт, предоставленный менеджером внешнего вида). В нашем примере мы создаем окно, в панель содержимого которого добавляем несколько надписей. Первая надпись — самый простой и наиболее распространенный вариант: просто некий необходимый пользователю текст выводится на экран. Рядом с ней было специально добавлено текстовое поле, и картина становится полной: надпись описывает, для чего предназначен другой компонент. Чаще всего так она и используется. Далее мы добавляем более сложные варианты надписей JLabel, одну со значком и вторую и со значком, и с текстом.
Вы видите, что для этих надписей вызывается вспомогательный метод adjustLabel(), позволяющий им, во-первых, быть непрозрачными (свойство opaque устанавливается в true), что помогает определить, какое пространство занимает надпись на экране и использовать нестандартный цвет фона, а, во-вторых, этот метод меняет их размер на заведомо больший, чем необходимо (только так мы сможем оценить изменения в выравнивании). Для того чтобы было видно, какую часть экрана занимает надпись, ее фон сделан белым (стандартная надпись обычно не выделяется в приложении цветом, ее роль сводится к выводу информации). Для загрузки значков используется вспомогательный класс ImageIcon, который мы вскоре обсудим подробнее, пока же достаточно того, что ему можно указать название файла с изображением. Кроме того, что мы с помощью надписей выводим текст и значки на экран, мы меняем их выравнивание относительно границ надписи и относительно друг друга. Для этого используются свойства, перечисленные в табл. 8.1.
Таблица 8.1. Свойства для выравнивания содержимого надписей
Свойства |
Предназначение |
|
|
verticalAlignment, horizontalA- |
Позволяют задать расположение содержимого надписи (и текста, |
lignment (и соответствующие |
и значка) относительно ее границ. Возможные положения описаны |
методы get/set) |
константами из интерфейса SwingContants, у вас есть три вариан- |
|
та расположения по вертикали (центр, верх, низ) и столько же по |
|
горизонтали (центр, справа, слева). Всего получается девять воз- |
|
можных позиций |
verticalTextPosition, horizon- |
Дают возможность указать надписи, как ей следует располагать |
talTextPosition (и соответ- |
текст относительно значка. Вы можете задать положение текста |
ствующие методы get/set) |
по вертикали (по центру значка, по его верхней или нижней грани- |
|
це) и по горизонтали (по центру значка, слева или справа от него). |
|
Витогетакжеполучаетсядевятьвариантов(можнодажеразместить |
|
текст поверх значка) |
iconTextGap |
В нашем примере мы не использовали это свойство, но оно очень |
|
просто и позволяет указать расстояние между текстом и значком |
|
в пикселах |
Для того чтобы было проще использовать константы выравнивания, мы в нашем классе реализовали (implements) интерфейс SwingConstants, в котором они описаны, его подробное описание легко найти в интерактивной документации. Надпись со значком меняет расположение своего значка, а надпись со значком и текстом меняет не только расположение всего содержимого, но и положение текста относительно значка. Запустив программу с примером, вы увидите результаты наших действий и сможете убедиться в том, что у вас действительно очень широкие возможности по настройке содержи-
216 |
ГЛАВА 8 |
мого надписей. Однако стоит помнить, что если положение текста относительно значка всегда актуально, то нестандартное расположение содержимого будет заметно, только когда надпись займет больше места, чем ей нужно, что в случае использования менеджера расположения случается редко.
Стоит также отметить (хоть мы и не создали такой надписи в примере), что надписи JLabel могут быть «отключенными», так же как и большая часть других компонентов, таких как кнопки, надо лишь вызвать метод setEnabled(false). Это позволяет придать интерфейсу большую выразительность: если какие-то функции приложения недоступны, отключаются все элементы интерфейса, даже надписи. Если в надписи используется значок, то в отключенном состоянии он с помощью специального фильтра изображений1 переводится в черно-белые цвета. Впрочем, вы можете задать собственный значок для отключенного состояния, вызвав метод setDisabledIcon().
Значки Icon
Только что при рассмотрении примера с надписями JLabel мы видели, что для загрузки значков использовался класс ImageIcon. На самом деле в библиотеке Swing для вывода значков во всех компонентах библиотеке применяется интерфейс Icon, а класс ImageIcon — его самая популярная реализация с изображением в качестве значка2. «Поче-
1 Этот фильтр изображений называется GrayFilter, находится в пакете javax.swing и используется всеми компонентами Swing с поддержкой значков Icon, чтобы создавать «отключенные» версии значков (в том случае если вы не предоставляете отключенные значки самостоятельно). Задействовать данный фильтр можно и напрямую: удобный статический метод getDisabledImage() позволяет мгновенно получить черно-белый вариант любого изображения.
2 В данный момент JDK поддерживает форматы изображений JPEG, GIF (в том числе и анимированный) и PNG, то есть все самые популярные форматы Web. Особое внимание стоит обратить на формат PNG, который не имеет проблем с лицензированием и полностью поддерживает альфаканал (различные степени прозрачности).
Вывод вспомогательной информации |
217 |
му же в библиотеке сразу не используются изображения Image?» — спросите вы. Все дело
втом, что интерфейс Icon можно легко реализовать самому. Это позволяет использовать
вкачестве значков не только готовые изображения из файлов (которые легко украсть и трудно защитить), но и нарисованные прямо в программе (например, с помощью библиотеки Java2D). Такие рисунки заимствовать гораздо тяжелее, а создать иногда проще. К примеру, практически все стандартные значки и текстуры, используемые в поставляемых вместе с JDK внешних видах Swing, рисуются внутри классов в виде значков Icon, а не поставляются в виде изображений.
Создать свой значок Icon, используя только графические свойства Java, нетрудно:
//RedBullet.java
//Создание собственного значка
import javax.swing.*; import java.awt.*;
public class RedBullet implements Icon { public int getIconWidth() {
return 16;
}
public int getIconHeight() { return 16;
}
public void paintIcon(
Component c, Graphics g, int w, int h) { g.setColor(Color.red);
g.fillRect(0, 0, 16, 16);
}
}
Здесь мы создаем значок в виде красного квадрата. Первые два метода позволяют задать размеры значка, в третьем методе вы рисуете свой значок. Иногда такой подход может быть быстрее и эффективнее создания изображения из файла. Использовать такие значки можно в любых компонентах Swing с их поддержкой (то есть почти во всех). Тем не менее, чаще все-таки используется класс ImageIcon. Он позволяет загрузить изображение поддерживаемого формата из файла, сетевого ресурса, заданного URLадресом (Uniform Resource Locator — унифицированный указатель ресурса), и способен создавать изображение даже из массива байтов3. В отличие от стандартного метода загрузки изображений getImage() из класса java.awt.Toolkit, класс ImageIcon всегда загружает изображение полностью (метод getImage() сразу возвращает управление, даже если изображение загружено частично, в результате на экране может появиться совсем не то, что вы ожидаете). Для этого задействуется специальный класс MediaTracker, который в противном случае пришлось бы использовать самостоятельно. Остается лишь сказать, что в пути к изображению указывается прямой слеш, который автоматически заменяется разделителем пути текущей платформы:
new ImageIcon("data/resources/menu");
3 Возможность создать изображение на основе массива байтов значительно облегчает распространение приложения в виде единого исполняемого JAR-файла, ресурсы из которого можно получить только в виде подобного массива.
218 |
ГЛАВА 8 |
На какой бы платформе ваше приложение ни оказалось, такая форма записи обеспечит правильный доступ к файлам и избавит вас от головной боли. В дальнейшем мы еще не раз будем использовать значки для своих компонентов.
Использование HTML
Возможность с помощью надписи JLabel выводить произвольные сочетания значков и текста, при желании менять цвет текста, шрифт и цвет фона надписи позволяет вам легко отображать на экране самую разнообразную информацию. Впрочем, бывают ситуации, когда относительно простые вещи нельзя вывести с помощью обычных надписей, к примеру, определенные трудности вызывает необходимость использования в одной надписи нескольких шрифтов или нескольких строк.
В состав Swing входит пакет javax.swing.text.html, поддерживающий для текстовых компонентов язык разметки HTML версии 3.2. Окончательный вывод текста на экран выполняет объект View (мы рассмотрим его в главе 16, посвященной текстовым возможностям Swing), который может использовать для вывода текста любой компонент. В любом объекте JLabel в виде клиентского свойства находится объект View, который и выполняет вывод текста на экран (что интересно, он занимается этим, даже если вы выводите простой текст, а не HTML). Чтобы вывести на надписи HTML-текст, достаточно указать в начале строки его отличительный признак — символы <html>. Рассмотрим пример:
//HTMLabel.java
//Использование в надписях языка HTML import javax.swing.*;
public class HTMLabel extends JFrame { private String html1 =
"<html><b>Слава</b><font size=5 color=red> HTML"; private String html2 =
"<html><font size=4 color=blue>" + "<ul>Список:<li>Один<li>Два";
private String html3 =
"<html><body bgcolor=white><h2>Любой цвет фона"; private String html4 =
"<html><h2>Изображения:<img src=\"file:monkey.gif\">"; public HTMLabel() {
super("HTMLabel");
//при закрытии окна выход setDefaultCloseOperation(EXIT_ON_CLOSE);
//добавляем надписи
JPanel contents = new JPanel(); contents.add(new JLabel(html1)); contents.add(new JLabel(html2)); contents.add(new JLabel(html3)); contents.add(new JLabel(html4)); // выводим окно на экран
Вывод вспомогательной информации |
219 |
add(contents); setSize(400, 300); setVisible(true);
}
public static void main(String[] args) { SwingUtilities.invokeLater(
new Runnable() {
public void run() { new HTMLabel(); } });
}
}
В примере мы добавляем в окно с рамкой четыре надписи, поддерживающие возможности встроенного языка HTML. Главное при использовании HTML — помнить, что строка с текстом должна начинаться с «волшебных» символов <html>, иначе все теги будут выведены в виде обычного текста. Мы задействовали разнообразные возможности HTML: различные стили и размеры текста, разные цвета для фона страницы и ее текста, и даже вывели изображение. Вы можете видеть, что даже список некоторых элементов в надписи JLabel благодаря HTML организовать не сложно. Как все это выглядит, можно посмотреть, запустив программу с примером.
Все возможности, описанные в спецификации языка HTML версии 3.2, поддерживаются встроенным в надписи элементом View. Как видно, поддерживаются и изображения, однако при работе с ними надо помнить, что встроенный язык HTML в качестве источника изображений распознает только правильные URL-адреса. Это могут быть адреса файлов на локальной машине (причем задавать файлы вы можете и относительно текущего каталога пользователя, как мы сделали это в примере, и с помощью абсолютных путей, таких как file:C:/images/pub/img.jpg) или полные сетевые адреса, например http://somehost/dir/image.gif. Впрочем, изображения с помощью встроенного языка HTML выводят все же редко, хотя возможность эта захватывающая. Дело в том, что приложения обычно распространяют в виде единственного архивного JAR-файла, в котором в том числе хранятся и изображения. Загрузка изображений из архива происходит уже во время работы программы, так что для их вывода чаще используют возможности надписей JLabel, позволяющих выводить значки и выстраивать их относительно текста.