JDesktop Integration Components

Если вы уже успели побывать Java-разработчиком, то вам наверняка приходилось слышать много по поводу того, что Java не может всего, что под силу C и C++. Вы также, возможно, боролись с компонентом HTMLEditor, в то время как Windows-разработчики без особых проблем встраивали в свои приложения Internet Explorer с помощью всего лишь нескольких строчек кода. Все, дождались: теперь и мы можем все это, и не только. Если вам приходилось бродить по просторам веб-сайта java.net или читать новостные отчеты с JavaOne, то вы скорее всего уже слышали о проекте JDesktop Integration Com-ponents (JDIC). Это набор новых программных интерфейсов (далее API), которые позволяют Java-разработчикам использовать множество полезных вещей, которые были подвластны только нашим "родным"-собратьям. В этой статье мы рассмотрим возможности JDIC на примерах.

JDesktop Integration Components (JDIC) — это всеобъемлющий проект, состоящий из набора модулей, который позволяет Java-разработчикам получить доступ к системным сервисам посредством платформонезависимого API. Этот проект был начат группой исследователей Desktop из Sun, чтобы предоставить более качественную интеграцию программ с программными desktop-платформами, на которых они работают. Недавно они разместили этот проект с открытым исходным кодом, с тем чтобы ускорить и улучшить обратную связь с разработчиками.

JDIC разбит на 5 компонентов:
· Desktop: загрузчик различных программ для открытия, редактирования, печати и отправки файлов по почте.
· Filetypes: устанавливает привязку типов файлов к программам, которые следует использовать для открытия файлов этого типа.
· Browser: позволяет встраивать "родной" (native) веб-браузер (Internet Explorer или Mozilla) в любой AWT-канвас.
· Packager: инструмент для конвертирования Java Web Start программ в "родной" установочный исполняемый файл.
· Tray API: поддержка иконок системного трея и всплывающих меню.
· SaverBeans (как отдельный подпроект): системный скринсейвер, выполненный средствами Java (в этой статье рассматриваться не будет).

Компонент Desktop
Компонент Desktop — это наиболее простой и, возможно, самый полезный из JDIC-компонентов. Он предназначен для таких базовых настольных сервисов, как открытие файла в соответствующем редакторе, создание e-mail-сообщения или открытие URL-адреса в веб-браузере, установленном в системе по умолчанию. Для реализации этих возможностей потребовалось много работы, которая сама по себе скрыта от глаз и внимания разработчика. Пользоваться этим компонентом очень и очень просто. Если вы хотите, например, сказать своей операционной системе, чтобы она открыла презентацию Microsoft PowerPoint, то все, что вам придется для этого сделать, — вызвать следующий статический метод класса Desktop: Desktop.open(new File("introduction.ppt")). Это просто.

Пакет org.jdesktop.jdic.desktop содержит всего три класса: Desktop, Message и Desktop-Exception. Класс Desktop статический, и вы не можете создавать его экземпляры. У него есть методы для открытия, редактирования и печати файлов. Вы также можете открыть новое e-mail-сообщение и заполнить его нужным текстом. Для этого служит класс Message — с его помощью вы можете установить получателя, задать текст сообщения, прикрепить к письму вложенные файлы и определить многие другие части e-mail-сообщения. Самое лучшее, что есть в компоненте Desktop, — это то, насколько просто им пользоваться. Вам совсем не нужно регистрировать какие бы то ни было специальные драйверы или изменять конфигурацию для конкретной платформы — все эти операции уже сделаны за вас. Если в вашем CLASSPATH есть архив jdic.jar, и соответствующие native-библиотеки находятся в папке для загрузки системных библиотек (обычно native-библиотеки размещаются в одной папке с файлом jdic.jar), то все будет работать без проблем на всех платформах, для которых у вас есть native-библиотеки. Вот пример того, как можно запустить веб-браузер одной строкой:

import org.jdesktop.jdic.desktop.*;
import java.net.*;

public class DesktopTest {
public static void main(String[] args) throws Exception {
Desktop.browse(
new URL(" http://java.linux.by/")
);
}
}

Компонент Filetypes
Следующий ключевой компонент проекта JDIC — это пакет Filetypes, который позволяет устанавливать ассоциации между типами файлов и программами, которые система будет использовать для открытия этих файлов. Это значит, что вы можете сказать своей операционной системе, какую программу для каких файлов использовать. Например, сделать так, чтобы можно было открывать текстовые файлы программой Microsoft Word вместо стандартного Notepad. С помощью этого API вы можете запрашивать информацию, устанавливать и удалять ассоциации между программами, расширениями файлов и/или mime-типами. Подобное задание ассоциаций типов файлов — достаточно специфичная для операционной системы функция. Этот API гораздо более полезен для получения информации об уже установленных ассоциациях или регистрации самого приложения, нежели для перерегистрации уже установленных ассоциаций в системе. Например, обычные текстовые файлы в Windows завязаны на файл notepad.exe, который находится в сами знаете какой папке. В Gnome (Linux), возможно, будет связь с программой /usr/local/bin/gedit. Поэтому, поскольку пути и имена файлов слишком зависят от платформы, установка ассоциаций будет неудобна и полезна только в том случае, если вы не завязываете тип файла со своим Java-приложением, путь к которому очень просто получить под любой платформой. В общем, не важно, как вы собираетесь использовать этот компонент — главное — что он выполняет достаточно много грязной работы за вас, работая с реестром и базой данных MIME-типов. Ниже приведен простой пример установки ассоциации:

import org.jdesktop.jdic.filetypes.*;
import java.net.URL;

public class FileTypesTest {
public static void main(String[] args) throws Exception {
Action action = new Action("open",
"C:\\WINDOWS\\system32\\ notepad.exe %1");

Association assoc = new Association();
assoc.addFileExtension(".mylog");
assoc.setMimeType("application/my-program-log-type");
assoc.addAction(action);

AssociationService svc = new AssociationService();
svc.registerUserAssociation(assoc);

}
}

Первые две строчки метода main создают объект класса Action, с помощью которого будет открываться файл (представлен в виде %1) с помощью программы notepad.exe. Следующие 4 строки создают ассоциацию между этим объектом и файлами с расширением .mylog. Устанавливать MIME-тип не обязательно. Просто в последнее время они слишком широко используются, поэтому это хороший тон — для каждого типа файла создавать MIME-тип. Последние две строки фактически регистрируют созданную ассоциацию в системе. Как и в случае со всем, что касается JDIC API, если у вас есть native-библотеки, и они расположены в правильной папке (вместе с jdic.jar), то нет необходимости делать что-либо еще. Код будет работать.

Компонент Browser
Третий компонент проекта JDIC — это Browser. В отличие от предыдущих двух, которые позволяют вам получить доступ к системным сервисам, этот компонент формирует для вас настоящий AWT-виджет для использования в графических приложениях. Раньше вы могли использовать встраиваемые инструменты от третьих производителей или все немногочисленные Java-браузеры. Но теперь с помощью JDIC и компонента Browser вы имеете возможность встраивать в ваши приложения веб-браузер, который пользователь использует по умолчанию. Такой вариант использования веб-браузера в приложениях открывает дверь для множества возможностей. Например, с использованием полнофункционального браузера становится возможным писать отличные RSS-клиенты для чтения новостей. Кроме этого, размер дистрибутива вашей программы не будет слишком большим, поскольку в него не нужно включать сам веб-браузер. Browser API также дает вам доступ к некоторым событиям веб-браузера и работе с историей открываемых страничек (т.е. вперед, назад, обновить). Будущие версии этого API планируют значительно расширить благодаря более тесной интеграции с основными функциями браузера, а также с загружаемыми им документами. Пример использования веб-браузера в приложении:

import org.jdesktop.jdic.browser.Web Browser;
import java.net.URL;
import javax.swing.JFrame;

public class BrowserTest {
public static void main(String[] args) throws Exception {

WebBrowser browser = new WebBrowser();
browser.setURL(new URL(" http:// www.theserverside.com"));

JFrame frame = new JFrame ("Пример использования Browser");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(browser);
frame.pack();
frame.setSize(640,480);
frame.setVisible(true);
}
}


Как видите, WebBrowser — это AWT-компонент, который вы можете поместить в любой Swing-контейнер. Первая строка метода main создает экземпляр класса WebBrowser, а вторая устанавливает адрес URL, который будет отображаться. Остальная часть кода просто создает фрейм, добавляет на него объект веб-браузера, задает размеры окна и его поведение и после этого отображает этот фрейм. Как только вы запустите приложение, вы увидите картину, похожую на изображение сверху.
Необходимо помнить о том, что WebBrowser — это родной AWT-компонент, поэтому проявляйте особую осторожность при чрезмерном комбинировании его с Swing. Вот два основных правила, которые следует соблюдать при этом:
1. Никогда не перекрывайте Swing- и AWT-компоненты.
2. Вызывайте метод setLightWeightPopupEnabled(false) ваших меню, иначе они будут исчезать рядом с компонентом браузера.
Для более подробного ознакомления с совместным использованием AWT и Swing вы можете прочитать англоязычную статью Swing Connection здесь: http://java.sun.com/products/jfc/tsc/articles/mixing/ .
В нашем примере с помощью JDIC мы используем браузер, выбранный по умолчанию пользователем. Обычно это либо Internet Explorer, либо Mozilla. При этом вам совсем не нужно упаковывать части Mozilla вместе со своим приложением, как было бы необходимо в случае использования JRex ( http://jrex.mozilla.org). Такой подход, т.е. с использованием JDIC, идеально подходит для операционных систем семейства Windows, поскольку на них гарантированно присутствует Internet Explorer. Однако с Linux могут возникнуть проблемы, где браузером по умолчанию может быть не Mozilla, а Konquorer в KDE, например. Вероятно, все будет значительно лучше в более зрелых релизах проекта JDIC, но несмотря ни на что на данный момент возможности компонента Browser окажут неоценимую помощь многим проектам и приложениям.

Компонент Packager
В отличие от всего остального проекта JDIC, компонент Packager — это не API. Packager — это набор инструментов командной строки, который позволяет конвертировать JNLP-приложения (Java Web Start, http://java.sun.com/products/javawebstart/ ) в "родные" инсталляторы (rpm для Linux, pkg для Solaris и msi для Windows). Это не значит, что вы получите исполняемые файлы вашего приложения (наподобие .exe), как это делают JSmooth ( http://jsmooth.sourceforge.net/ ) и JExePack ( http://www.duckware.com/jexepack/index.html ).
Вы просто получаете инсталлятор для вашего Java Web Start приложения. После того как программа установилась, она обновит себя через Интернет с помощью JNLP-дескриптора и выполнит все необходимые операции, которые выполняют любое Web Start приложение. Компонент Packager требует J2SE 5.0 и native-инструменты. Для Windows вам также понадобится установить MSI SDK от Microsoft. Как только вы настроите среду, можно будет приступать к использованию инструментов jnlp2msi, jnlp2rpm и jnlp2pkg, чтобы сконвертировать ваше Web Start приложение в специфичный для конкретной платформы инсталлятор.

Компонент Tray
Tray API некоторое время был инкубационным проектом, но благодаря усердию сообщества веб-сайта java.net он стал более зрелым и на данный момент носит звание полноправного компонента проекта JDIC. Он предназначен для создания небольших иконок вашей программы в правом нижнем углу экрана. Предполагается, что операционная система поддерживает идею системного трея. На практике это означает, что у вас должна стоять операционная система Windows или Linux. Пользователям MacOS X не повезло. Кроме просто иконок, этот компонент поддерживает всплывающие меню и автоматические tooltip-надписи для них.
Как и везде в проекте JDIC, для этого компонента вам нужно иметь native-библиотеки для каждой из операционных систем, на которых предположительно будет запускаться ваша программа. Поскольку по объему этот API довольно мал, он содержит только два класса: SystemTray и TrayIcon. Класс SystemTray содержит статический метод-фабрику для доступа к системному трею. Класс TrayIcon позволяет вам установить JPopupMenu и Icon-объекты на следующее свободное место в системном трее. И в завершение вызывается метод SystemTray.get DefaultSys-temTray().addTrayIcon(). Давайте рассмотрим простой пример:

import org.jdesktop.jdic.tray.*;
import java.awt.event.*;
import javax.swing.*;

public class SystemTrayTest {

public JMenuItem quit;
SystemTray tray = SystemTray. getDefaultSystemTray();

public SystemTrayTest() {
JPopupMenu menu = new JPopupMenu("Меню");
menu.add(new JMenuItem("Выбор 1"));
menu.add(new JMenuItem("Выбор 2"));
menu.addSeparator();
quit = new JMenuItem("Выход");
quit.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent evt) {
System.exit(0);
}});

menu.add(quit);

ImageIcon icon = new ImageIcon (SystemTrayTest.class.getResource("middle.gif"));
TrayIcon trayIcon = new TrayIcon(icon, "System Tray!", menu);

tray.addTrayIcon(trayIcon);
}

public static void main(String[] args) {
new SystemTrayTest();
}

}

Вот что имеем в результате. Иконка имеет форму желтого пятна.

Как видно из исходного кода нашего примера, сначала мы получаем объект системного трея. После этого в самом начале конструктора мы создаем всплывающее меню JMenu Popup с тремя элементами и одним разделителем. На последний элемент quit мы вешаем слушатель событий Action Listener, чтобы можно было выйти. Теперь вместо добавления созданного нами меню в строку меню или какой-нибудь объект JComponent мы передаем его конструктору TrayIcon. ImageIcon, который играет роль иконки для системного трея, также передается конструктору TrayIcon вместе с текстом tooltip'ом. В завершение добавляем наш объект TrayIcon в SystemTray. Скомпилируйте этот пример с файлом tray.jar в CLASSPATH и tray.dll (для Windows), находящимся в директории библиотек (-Djava. library.path=<путь к директории> ). Tray API также поддерживает анимированные GIF-иконки и возможность обработки левого щелчка мыши. С помощью этого API вы можете скрывать свое приложение из панели задач в трей и обратно.

Инкубационные проекты
С самого начала проект JDIC имел целью всячески поощрять и разрабатывать новые API. Чтобы способствовать росту они открыли так называемый проект-инкубатор, куда разработчики могут выкладывать свой код и испытывать разные интересные идеи. Если их идеи достаточно хороши и реализованы достойно, то такой инкубационный проект может стать частью JDIC или даже отдельным полноценным проектом.
Команда JDIC постоянно ищет помощников. Для того, чтобы присоединиться к ней, вам нужно подписать и отправить по факсу соглашение JCA (Joint Copyright Agreement), поскольку некоторые части или весь проект JDIC в дальнейшем вполне могут слиться с будущими версиями Java.

Резюме
Учитывая тот факт, что на данный момент проект JDIC находится в стадии бета-версии, можно сказать, что он подает очень большие надежды. JDIC постоянно растет и изменяется. Сейчас идет работа над исправлением ошибок, улучшением поддержки Mac и попытками мигрировать некоторые части JDIC в родную Java Runtime среду.

Алексей Литвинюк, litvinuke@tut.by


Компьютерная газета. Статья была опубликована в номере 51 за 2004 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета