SWT и JFace Сергей Бердачук
Содержание Лицензионное соглашение 1. Введение в SWT 1. Введение в SWT 2. Простое SWT приложение 3. Состав пакетов SWT 1. Основные пакеты SWT 4. Простые SWT компоненты 1. Label 1.1. Стили 1.2. Текст 1.3. Изображение 1.4. Разделители 1.5. Выравнивание 1.6. Перенос текста 1.7. Пример использования 2. Button 2.1. Стили 2.2. Текст 2.3. Изображение 2.4. Выравнивание 2.5. Push Button 2.6. Toggle Button 2.7. Check Box 2.8. Radio Button 2.9. Selection (выбор) 2.10. Указание используемой по умолчанию кнопки 5. List 5.1. Стили 5.2. Добавление элементов в список 5.3. Удаление элементов из списка 5.4. Получение элементов списка 5.5. Настройка значений элементов 5.6. Поиск элементов 5.7. Выбор элементов списка 5.8. Слушатели событий списка List 6. Link 6.1. Стили 6.2. Текст 6.3. Слушатели событий 7. Меню (классы Menu и MenuItem) 7.1. Стили класса Menu 7.2. MenuItem The SWT Faq
1. Введение в SWT SWT – кросс платформенная библиотека компонент для построения графического интерфейса пользователя (Graphical user interface (GUI)). Первым java фреймворком для построения графического интерфейса пользователя была созданная корпорацией Sun Microsystems библиотека AWT (Abstract Windowing Toolkit). Данный фреймворк использовал визуальные компоненты операционной системы. А так как требовалось обеспечить кроссплатформенность, то возникла проблема различия состава визуальных компонент в различных операционных системах (ОС). По этой причине часть полезных компонент была исключена из состава AWT. В терминологии большинства ОС такие компоненты называют Widget ("гаджет", "штуковина" - небольшой поли-, пара-, гипер- и метафункциональный предмет. Перочинный ножик с нужными и ненужными, но потенциально полезными функциями, например). Для решения данной проблемы корпорацией Sun была начата разработка нового фреймуорка. В результате была создана очень мощная, включающая большое количество компонент библиотека Swing. В отличие от AWT компоненты Swing не зависят от widget'ов операционной системы. За прорисовку и поведение GUI элементов полностью отвечает библиотека Swing. Это позволило создать GUI компонетны, которые одинаково выглядят и функционируют на различных операционных системах. Для каждой операционной системы были разработаны настройки внешнего вида и поведения (LookAndFeel), которые максимально эмулировали компоненты конкретной операционной системы. Использование lookAndFeel позволило создавать красочные и привлекательные интерфейсы java приложений. Популярность языка java привлекла разработчиков корпорации IBM. Использование java позволяло решить проблему создания множества версий одних и тех же продуктов для различных операционных систем. Ранее, в процессе разработки визуального интерфейса для VisualAge/SmallTalk, в сотрудничестве корпорации IBM и копании Object Technology International, Inc. (OTI). Была разработана библиотека для построения визуального интерфейса CommonWidgets. (Позднее, компания ATI стала одним из подразделений корпорации IBM). Имея большой штат разработчиков VisualAge/SmallTalk, корпорацией IBM был инициирован проект по разработке универсальной платформы для создания java приложений Eclipse (впоследствии был создан консорциум Eclipse и данный проект, стоимостью в 40 миллионов $, был вместе с исходными кодами передан в свободное пользование (opensource)). Причем лицензия на Eclipse позволяет создавать "закрытые" коммерческие продукты. В процессе разработки Eclipse при сотрудничестве IBM и OTI был разработан новый графический фреймуорк, который позволил использовать ранее накопленный опыт без переучивания персонала и упрощения портирования ранее созданных продуктов на новую платформу. Этот фреймуорк получил название Standard Widget Toolkit (SWT). В SWT, как и AWT максимально используются компоненты операционной системы. Но в отличие от AWT, отсутствующие в конкретной операционной системе компоненты не исключены, а эмулируются. В результате, была создана быстрая высокоэффективная кросс платформенная библиотека компонент, которые выглядят и ведут себя как нативные компоненты операционной системы. Что в свою очередь упрощает процесс обучения пользователей java приложений, так как SWT программы не отличаются от обычных приложений. Библиотеку SWT можно использовать не только для разработки приложений на платформе Eclipse, но также и для разработки любых других приложений. При этом можно использовать любую среду разработки java приложений Integrated Development Enviroment (IDE), например Oracle Java Developer или Borland Java Builder. Для этого достаточно включить необходимые библиотеки SWT в состав java приложения. Фреймуорк SWT поддерживает большинство популярных операционных систем. Так же существует возможность компиляции SWT java приложений в нативный бинарный код, что повышает производительность созданных приложений и не требует установки java машины - Java Runtime Enviroment (JRE). Такие приложения ничем не отличаются от нативных приложений
конкретной операционной системы, а использование современных IDE позволяет быстро создавать качественные кросс платформенные продукты для различных операционных систем.
Глава 2. Простое SWT приложение Создадим новый java проект. Для этого выберем меню File->New->Project . Выберем « JavaProject » в дереве мастеров. В следующей закладке мастера проекта введем имя проекта « ru.jugabook.swt.hello ». В закладке « Libraries » страницы « Java settings » мастера создания проекта добавим требуемую библиотеку (эту операцию можно сделать потом, редактируя свойства проекта). Нажмем кнопку « Add Library » и выберем « Standard Widget Toolkit (SWT) » Рисунок 2.1, «Добавление библиотеки SWT». Если данной библиотеки не окажется в списке библиотек вашей версии Eclipse, то библиотеку swt.jar можно будет добавить, нажав кнопку « Add External Jars » (пути поиска данной библиотеки для различных платформ указаны далее). Рисунок 2.1. Добавление библиотеки SWT
Создадим пакет « ru.jugabook.swt » и добавим в него новый класс «HelloSwt», который будет содержать следующий код: package ru.jugabook.swt.hello; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SwtHello { public static void main(String[] args) { //Создаем объект Display для связи SWT //с дисплеем операционной системы Display display = new Display(); //Создаем окно программы Shell shell = new Shell(display);
shell.setText("SWT Hello"); shell.setSize(200, 100); shell.open(); //Обработка закрытия окна while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } //Ресурсы операционной системы //должны быть освобождены display.dispose();
} }
Для старта stand-alone SWT приложения нужно добавить в закладку « Librares » свойств проекта файл swt.jar, который находится в каталоге plugins/org.eclipse.swt..ws.<window system>. Пути к библиотеке swt.jar для различных платформ данные сведены в Таблица 2.1, «Настройка пути к библиотеке sw для различных платформ». Таблица 2.1. Настройка пути к библиотеке sw для различных платформ ОС
Путь к библиотеке swt
win32 INSTALLDIR\eclipse\plugins\org.eclipse.swt.win32_3.0.0\ws\win32\swt.jar gtk
INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_3.0.0/ws/gtk/swt.jar
motif
INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_3.0.0/ws/motif/swt.jar
photon INSTALLDIR/eclipse/plugins/org.eclipse.swt.photon_3.0.0/ws/photon/swt.jar macosx INSTALLDIR/eclipse/plugins/org.eclipse.swt.carbon_3.0.0/ws/carbon/swt.jar Например, для win32: \jide\eclipse3\plugins\org.eclipse.swt.win32_3.0.0\ws\win32\swt.jar
Замечание Файл swt.jar был добавлен в мастере проектов ранее. Для некоторых платформ требуется дополнительные библиотеки. Например, для GTK требуются swt.jar, swt-pi.jar и swt-mozilla.jar. Соответственно, все эти файлы должны быть добавлены в путь поиска библиотек. Также, для отладки или запуска (stand alone) swt java приложений, нужно в редакторе «VM arguments» указать путь к нативной библиотеке swt (закладка «Arguments» панели параметров запуска приложения). Для различных операционных систем это: Таблица 2.2, «Настройка пути к библиотеке swt для различных платформ». Таблица 2.2. Настройка пути к библиотеке swt для различных платформ Платформа Строка параметров win32
-Djava.library.path=INSTALLDIR\plugins\org.eclipse.swt.win32_3.0.0\os\win32\x86
linux gtk
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_3.0.0/os/linux/x86
linux motif
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_3.0.0/os/linux/x86
solaris motif
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_3.0.0/os/solaris/sparc
aix motif
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_3.0.0/os/aix/ppc
hpux motif
Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_3.0.0/os/hpux/PA_RISC
Платформа Строка параметров photon qnx
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.photon_3.0.0/os/qnx/x86
macosx
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.carbon_3.0.0/os/macosx/ppc
Пример строки параметров запуска для win32: -Djava.library.path=D:\jide\eclipse3\plugins\org.eclipse.swt.win32_3.0.0\os\win32\x86.
Создадим профиль отладки приложения. Для этого вызовем меню « Run->Debug ». Добавим новую конфигурацию « Java Application » и укажем требуемые аргументы для Java машины (Рисунок 2.2, «Настройка параметров отладки»). Рисунок 2.2. Настройка параметров отладки
Если вы работаете с большим количеством SWT проектов, то аргументы для java машины удобнее будет задать глобально в меню ' Window->Preferences->Java->Installed JREs " выбираем используемую jre и в ее свойствах указываем аргументы запуска. Этот же прием позволяет упростить работу под различными операционными системами, так как настройки сохраняются в контексте eclipse IDE, а не проекта.Запускаем созданное приложение. В результате получим Рисунок 2.3, «Простое SWT приложение».Рисунок 2.3. Простое SWT приложение
3. Основные пакеты SWT Библиотека SWT включает следующие основные пакеты: org.eclipse.swt включает предустановленные константы, классы исключений и ошибок. Рисунок 3.1. Иерархия классов пакета org.eclipse.swt
org.eclipse.swt.widgets включает в основном визуальные компоненты. Рисунок 3.2. Иерархия классов пакета org.eclipse.swt.widgets
org.eclipse.swt.events
включает классы и интерфейсы обработки событий. Рисунок 3.3. Иерархия классов пакета org.eclipse.swt.events
org.eclipse.swt.dnd включает классы поддержки drag-and-drop.
Рисунок 3.4. Иерархия классов пакета org.eclipse.swt.dnd
org.eclipse.swt.layout включает классы менеджеров размещения компонент. Рисунок 3.5. Иерархия классов пакета org.eclipse.swt.layout
org.eclipse.swt.printing включает классы поддержки печати.
Рисунок 3.6. Иерархия классов пакета org.eclipse.swt.printing
org.eclipse.swt.graphics включает обеспечивающие работу с графикой классы. Рисунок 3.7. Иерархия классов пакета org.eclipse.swt.graphics
Label Класс Label предназначен для вывода текста, изображений, вертикальных или горизонтальных разделителей. Выводимый текст или изображение могут изменяться только программным путем. Экземпляр класса Label не получает фокус ввода при перемещении курсора например клавишей Tab или при кликании по нему мышкой. Обработчики событий не применимы для данного класса, несмотря на то, что класс Label является наследником класса Control. Для создания экземпляра класса Label используется следующий конструктор: public Label (Composite parent, int style)
Где parent – обязательный родительский компонент (контейнер), а style это один или несколько стилей определяющий параметры создания класса Label. Рисунок 4.1. Label. Иерархия классов
Рисунок 4.2. Компонент Label. Изображение в визуальном редакторе
1.1. Стили Стили формируют битовую маску по принципу логического «ИЛИ». Для объединения стилей используется символ "|". Стиль
Описание
Примечание
SWT.SEPARATOR
Вывод разделителя
По умолчанию устанавливается вертикальный разделитель
SWT.HORIZONTAL
Вывод горизонтального разделителя
SWT.VERTICAL
Вывод вертикального разделителя
SWT.SHADOW_IN
Вывод разделителя с эффектом выпуклости «внутрь»
SWT.SHADOW_OUT
Вывод разделителя с эффектом выпуклости «наружу»
SWT.SHADOW_NONE
Явное указание на отсутствие эффекта выпуклости
SWT.CENTER
Выравнивание по центру
SWT.LEFT
Выравнивание влево
SWT.RIGHT
Выравнивание вправо
SWT.WRAP
Разбивать(переносить) текст, для более полного заполнения занимаемого пространства
Только один атрибут из SWT.HORIZONTAL и SWT.VERTICAL может быть выбран Только один атрибут из SHADOW_IN, SHADOW_OUT и SHADOW_NONE может быть выбран
Только один атрибут из CENTER, LEFT и RIGHT может быть выбран
Label одновременно может находиться только в одном из трех режимов работы:
1. Вывод текста; 2. Вывод изображения; 3. Вывод разделителя.
Замечание При необходимости выводить сразу и текст и изображение можно воспользоваться классом CLabel.
1.2. Текст Для задания текста выводимого классом Label используется метод: public void setText (String text)
Текст может содержать разделители и мнемоники. Символ & указывает, что следующий за ним символ будет рассматриваться как мнемоника. Когда пользователь набирает на клавиатуре комбинацию символов мнемоники, то родительский объект получает фокус. Для большинства платформ символы мнемоник выделяются подчеркиванием, но могут выделяться и другим способом, который зависит от платформы. Если необходимо вывести в тексте символ &, то его надо набрать два раза подряд. Метод: public String getText()
возвращает текст или пустую строку, если текст не задавался, или использовалась маска SWT.SEPARATOR для объекта Label.
1.3. Изображение Для задания изображения предназначен метод: public void setImage(Image image)
Если image равно null , то изображение выводиться не будет. Метод: public Image getImage()
возвращает изображение или null (если изображение не установлено) объекта Label.
1.4. Разделители Если не установлен флаг разделителя SWT.SEPARATOR то будет изображен разделитель. Тип разделителя определяется значением маски SWT.HORIZONTAL для горизонтального разделителя и SWT.VERTICAL для вертикального разделителя. Выпуклость устанавливается одним из атрибутов SHADOW_IN, SHADOW_OUT и SHADOW_NONE. Разделители часто используются для формирования разделительных линий между компонентами.
Замечание Визуальный вид разделителя зависит от настроек операционной системы.
1.5. Выравнивание
Если не установлен флаг разделителя SWT.SEPARATOR, то можно задать метод выравнивания текста или изображения объекта Label. Для этого служит метод: public void setAlignment(int alignment)
Где аргумент alignment может принимать значения SWT.LEFT, SWT.RIGHT или SWT.CENTER для выравнивания по левому краю, правому краю или по центру соответственно. Метод: public int getAlignment()
возвращает метод выравнивания (SWT.LEFT, SWT.RIGHT или SWT.CENTER) текста или изображения объекта Label. Если не установлен флаг разделителя SWT.SEPARATOR, то возвращается значение SWT.NONE.
Замечание Для разделителей (установлен флаг SWT.SEPARATOR) выравнивание игнорируется.
1.6. Перенос текста Если при создании объекта Label была указана маска SWT.WRAP, то текст будет разбиваться (переноситься) на строки для более полного заполнения разбиения доступного пространства. Действие маски SWT.WRAP определяется правилами переноса в операционной системе и зависят от выбранной локали.
Замечание Для формирования принудительного, вне зависимости от маски SWT.WRAP, переноса строки можно использовать символ перевода строки \n.
1.7. Пример использования Пример 4.1. Пример использования класса Label с различными битовыми масками стилей package by.bs.swt; ... public void testLabel() { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Label test"); new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); Label lblHello = new Label(shell, SWT.NONE); lblHello.setText("Simple Label"); new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); shell.setLayout(new GridLayout()); Label lblDuke = new Label(shell, SWT.NONE); lblDuke.setImage(new Image(Display.getCurrent(), getClass() .getResourceAsStream("/by/bs/swt/images/duke_waving.gif"))); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } shell.dispose(); display.dispose(); }
Разделители. Просто текст Label с изображением
Рисунок 4.3. Результат работы программы
Button Класс Button предназначен для создания одного из компонент визуального интерфейса типа Push Button(кнопка), Check Box (флажковый переключатель), Radio Button (радио кнопка), Toggle Button (кнопка с состоянием), которые формируют сообщения в момент нажатия и отпускания. Для создания экземпляра класса Button используется следующий конструктор: public Button (Composite parent, int style)
Где parent – обязательный родительский компонент (контейнер), а style это один или несколько определяющий параметры создания компонента Button стилей. Рисунок 4.4. Button. Иерархия классов
Замечание Наследование класса Button не рекомендуется.
2.1. Стили Стили формируют битовую маску по принципу логического «ИЛИ». Для объединения стилей используется символ "|". Стиль
Пример
Описание
Примечание
SWT.ARROW
Кнопка с изображением стрелки, направление которой задается дополнительным флагом: UP-вверх, DOWN-вниз, LEFT-влево, или RIGHTвправо.
Допустимо указывать только один из флагов UP, DOWN, LEFT, или RIGHT.
SWT.CHECK
Check Box (флажковый переключатель)
SWT.PUSH
Обычная кнопка
SWT.RADIO
Радио кнопка
Данный тип кнопки используется по умолчанию
Стиль
Пример
SWT.TOGGLE
Описание
Примечание
Кнопка с состоянием
SWT.FLAT
Флаг для установки "Flat"(плоского) стиля изображения кнопки
SWT.BORDER
Флаг для прорисовки окантовки вокруг кнопки.
SWT.LEFT
Выравнивание текста по левому краю кнопки или стрелка влево для кнопки типа "SWT.ARROW"
SWT.RIGHT
Выравнивание текста по правому краю кнопки или стрелка влево для кнопки типа "SWT.ARROW"
SWT.CENTER
Выравнивание текста по центру кнопки или стрелка влево для кнопки типа "SWT.ARROW"
SWT.UP
Cтрелка вверх для кнопки типа "SWT.ARROW"
SWT.DOWN
Cтрелка вниз для кнопки типа "SWT.ARROW"
Для различных платформ flat режим отображается по разному. На платформе Win32 при flat режиме объемный контур кнопки не прорисовывается, и кнопки кажутся плоскими.
Допустимо указывать только один из флагов UP, DOWN, LEFT, или RIGHT.
2.2. Текст Для задания текста text выводимого классом Button используется метод: public void setText (String text)
Текст text может содержать мнемоники, но не должен содержать разделители строк. Символ & указывает, что следующий за ним символ будет рассматриваться как мнемоника. Когда пользователь
набирает на клавиатуре комбинацию символов мнемоники, то родительский объект получает фокус. Для большинства платформ символы мнемоник выделяются подчеркиванием, но могут выделяться и другим способом, который зависит от платформы. Если необходимо вывести в тексте символ & , то его надо набрать два раза подряд. Метод: public String getText()
возвращает текст или пустую строку, если текст не задавался, или использовался флаг ARROW при создании кнопки.
2.3. Изображение Для задания изображения предназначен метод: public void setImage(Image image)
Если image равно null , то изображение выводиться не будет. Метод: public Image getImage()
возвращает изображение или null (если изображение не установлено) объекта Button.
2.4. Выравнивание Для задания горизонтального выравнивания текста или изображения объекта Button можно указать стиль выравнивания в конструкторе или воспользоваться методом: public void setAlignment(int alignment)
Где аргумент alignment может принимать значения SWT.LEFT, SWT.RIGHT или SWT.CENTER для выравнивания по левому краю, правому краю или по центру соответственно. Если кнопка типа ARROW, то alignment указывает одно из направлений стрелки (UP-вверх, DOWN-вниз, LEFT-влево или RIGHT-вправо.). Метод: public int getAlignment()
возвращает метод выравнивания (SWT.LEFT, SWT.RIGHT или SWT.CENTER) текста или изображения объекта Button. Если кнопка типа ARROW, то возвращается одно из направлений стрелки (UP-вверх, DOWN-вниз, LEFT-влево или RIGHT-вправо).
Замечание Выравнивание редко используется в компонентах типа Button. По умолчанию используется предпочтительное значение для конкретной операционной системы.
2.5. Push Button Рисунок 4.5. Изображение Push Button в визуальном редакторе
Данный тип кнопки используется по умолчанию. При нажатии на нее кнопка переходит с состояние "нажата" и обычно обрабатывается некоторое событие. При отпускании кнопка возвращается в состояние "отжата". Пример 4.2. Программа создания кнопки типа PUSH и обработки ее нажатия public void testPushButton() { Button button = new Button(shell, SWT.NONE); button.setText("кнопка Push"); button.pack(); button.addSelectionListener( new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected( org.eclipse.swt.events.SelectionEvent e) { MessageBox messageBox = new MessageBox(shell); messageBox.setMessage("Кнопка нажата"); messageBox.open(); } }); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } }
2.6. Toggle Button Toggle Button это разновидность кнопки Push Button. Если установлен флаг SWT.TOGGLE то при нажатии на кнопку она переходит в состояние "нажата" и остается в таком состоянии до следующего нажатия. Данный вид кнопок используется в качестве альтернативы флажковым переключателям так как обладают двумя устойчивыми состояниями (эффект триггера). Для улучшения восприятия можно в обработчике нажатия кнопки менять изображение, которе наглядно показывало состояние кнопки соответственно функции кнопки в контексте программы. Пример 4.3. Модуль демонстрирующий состояние кнопки типа SWT.TOGGLE с помощью изображений buttonSwitch = new Button(shell, SWT.TOGGLE); buttonSwitch .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected( org.eclipse.swt.events.SelectionEvent e) { if (buttonSwitch.getSelection()) { buttonSwitch.setImage(new Image(Display .getCurrent(), getClass() .getResourceAsStream( "/by/bs/swt/images/on.png"))); } else { buttonSwitch.setImage(new Image(Display .getCurrent(), getClass() .getResourceAsStream( "/by/bs/swt/images/off.png"))); } } }); buttonSwitch.setImage(new Image(Display.getCurrent(), getClass() .getResourceAsStream("/by/bs/swt/images/off.png"))); buttonSwitch.pack();
Рисунок 4.6. Демонстрация отображения состояние кнопки типа SWT.TOGGLE с помощью изображений
Пример 4.4. Программа использования кнопки типа SWT.TOGGLE для имитации поведения реальных кнопок радиоприемника group = new Group(shell, SWT.NONE); group.setText("Канал 1"); group.setLayout(new FillLayout()); Listener changeChannelListener = new Listener() { public void handleEvent(Event e) { Control[] children = group.getChildren(); for (int i = 0; i < children.length; i++) { Control child = children[i]; if (e.widget != child && child instanceof Button && (child.getStyle() & SWT.TOGGLE) != 0) { ((Button) child).setSelection(false); } } ((Button) e.widget).setSelection(true); group.setText("Канал " + ((Button) e.widget).getText()); } }; for (int i = 0; i < 5; i++) { Button button = new Button(group, SWT.TOGGLE); if (i == 0) { button.setSelection(true); } button.setText("" + (i + 1)); button.addListener(SWT.Selection, changeChannelListener); } group.pack();
Рисунок 4.7. Имитация поведения кнопок радиоприемника
2.7. Check Box Рисунок 4.8. Изображение Check Box в визуальном редакторе
Флажковый переключатель Check Box чаще всего используется для установки или сброса логических состояний некоторых параметров (флагов) программы. Пример 4.5. Блок кода создания Check Box кнопок shell.setLayout(new GridLayout());
Button checkBoxRed = new Button(shell, SWT.CHECK); checkBoxRed.setText("Красный"); Button checkBoxGreen = new Button(shell, SWT.CHECK); checkBoxGreen.setText("Зеленый"); checkBoxGreen.setSelection(true); Button checkBoxBlue = new Button(shell, SWT.CHECK); checkBoxBlue.setText("Голубой");
Рисунок 4.9. Кнопки типа SWT.CHECK
2.8. Radio Button Рисунок 4.10. Изображение Radio Button в визуальном редакторе
Для создания радиокнопок используется стиль SWT.RADIO. Данный вид кнопок используется для выбора только одной кнопки из множества входящих в группу. Группа кнопок для выбора определяется общим родительским компонентом. При выборе (selection) одной из кнопок остальные кнопки в группе становятся не выбранными. В определенный момент времени может быть выбрана только одна кнопка. Пример 4.6. Тестовая программа демонстрации SWT.RADIO кнопок shell.setLayout(new FillLayout()); Group group = new Group(shell, SWT.NONE); Button radioButton = new Button(group, SWT.RADIO); radioButton.setText("Один"); Button radioButton1 = new Button(group, SWT.RADIO); radioButton1.setText("Два"); radioButton1.setSelection(true); Button radioButton2 = new Button(group, SWT.RADIO); radioButton2.setText("Три"); group.setLayout(new GridLayout()); Group group2 = new Group(shell, SWT.NONE); Button radioButton3 = new Button(group2, SWT.RADIO); radioButton3.setText("Красный"); radioButton3.setSelection(true); Button radioButton4 = new Button(group2, SWT.RADIO); radioButton4.setText("Зеленый"); Button radioButton5 = new Button(group2, SWT.RADIO); radioButton5.setText("Голубой"); group2.setLayout(new GridLayout());
Рисунок 4.11. Кнопки типа SWT.RADIO сгруппированные в разные контейнеры
2.9. Selection (выбор) Метод: public void setSelection (boolean selected)
устанавливает состояние выбора для кнопок типов CHECK, RADIO и TOGGLE. Если кнопка типа CHECK или RADIO, то при selected равном true они включаются (состояние checked ). При selected равном false они выключаются (состояние unchecked ). Если кнопка типа TOGGLE, то при selected равном true она нажимается (состояние нажата ). При selected равном false она отжимается (состояние отжата ). Метод: public boolean getSelection ()
предназначен для чтения состояние выбора кнопок типов CHECK, RADIO и TOGGLE. При выбранном ( checked или нажатом состоянии) возвращает true . В противном случае возвращается false .
Замечание В отличие от остальных типов кнопок событие SWT.Selection кнопкой типа Push Button не обрабатывается. Для кнопки данного типа метод getSelection() всегда возвращает значение false .
2.10. Указание используемой по умолчанию кнопки Контейнер shell включает в себя понятие кнопки по умолчанию default button которая выбирается при нажатии пользователем кнопки < Enter > в не зависимости от того, какой компонент в данный момент имеет фокус. Чаще всего данное свойство используется для подтверждения быстрой отмены в диалоговых окнах. Соответственно есть методы getDefaultButton() и setDefaultButton(Button button) для оперирования данным свойством. Пример 4.7. Указание кнопки по умолчанию GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; Label label = new Label(shell, SWT.NONE); label.setText("Новый пароль: "); Text text = new Text (shell, SWT.BORDER); Button buttonOk = new Button(shell, SWT.NONE); buttonOk.setText("Изменить"); Button buttonCancel = new Button(shell, SWT.NONE); buttonCancel.setText("Отмена"); shell.setDefaultButton (buttonCancel); shell.setLayout(gridLayout); shell.pack();
Рисунок 4.12. Указание кнопки по умолчанию
List Класс List предназначен для создания визуального компонента, который отображает столбец из списка строк. Он позволяет скроллировать отображаемый список и предоставляет возможность выбирать одну или несколько строк из списка. Данный компонент применяется довольно редко, так как позволяет оперировать только строками. Используя таблицы можно получить аналогичную функциональность, при больших возможностях. Для создания экземпляра класса List используется следующий конструктор: public List (Composite parent, int style)
Где parent – обязательный родительский компонент (контейнер), а style это один или несколько определяющих параметры создания класса List стилей. Рисунок 4.13. List. Иерархия классов
Рисунок 4.14. Компонент List. Изображение в визуальном редакторе
5.1. Стили Стили формируют битовую маску по принципу логического «ИЛИ». Для объединения стилей используется символ "|". Стиль
Описание
SWT.SINGLE
Может быть выбрана только одна строка.
SWT.MULTI
Позволяет выбирать несколько строк из списка
SWT.BORDER
Флаг для прорисовки окантовки компонента
SWT.H_SCROLL
Создает горизонтальную полосу прокрутки
SWT.V_SCROLL
Создает вертикальную полосу прокрутки
Примечание Допустимо указывать только один из стилей SWT.SINGLE или SWT.MULTI
Так как класс List наследуется от класса org.eclipse.swt.widgets.Scrollable, то можно указать на необходимость создания полос прокрутки. Для этого предназначены стили SWT.H_SCROLL и SWT.V_SCROLL создающие соответственно горизонтальную и вертикальную полосы прокрутки. Базовый класс org.eclipse.swt.widgets.Control предоставляет возможность прорисовки рамки вокруг компонента при указании стиля SWT.BORDER, а так же изменение направления вывода LEFT_TO_RIGHT, RIGHT_TO_LEFT для письма слева направо и справа налево.
5.2. Добавление элементов в список Для добавления строк в конец списка используется метод: add (String string)
где string - добавляемая строка. Метод: add (String string int index)
Добавляет строку в определенную позицию (отсчет начинается от нуля). Строка добавляется перед занимающим указанную позицию элементом (строкой). Остальные элементы сдвигаются на один элемент к концу списка.
Замечание Индекс для добавления в конец списка можно получить, вызвав метод getItemCount() . Пример 4.8. Инициализация списка List /** * Инициализация списка */ private void fillLists() { lstSource.add("Один"); lstSource.add("Два"); lstSource.add("Три"); lstSource.add("Четыре"); lstSource.add("Пять"); }
5.3. Удаление элементов из списка Для удаления элементов из списка предназначены методы: remove (int index)
Удаляет строку в определенной позиции index (отсчет начинается от нуля). remove (int start, int end)
Удаляет строки, начиная с позиции start по end включительно. remove (int [] indeces)
Удаляет строки с указанными в массиве indeces индексами. remove (String string)
Производится поиск первого вхождения строки string в список, и если она найдена, то данная строка удаляется из списка. removeAll ()
Удаляет все элементы списка.
5.4. Получение элементов списка Методы доступа к элементам списка List: getItem (int index)
Возвращает элемент в указанной позиции index (отсчет начинается от нуля). Если указан неверный индекс, то вызывается исключение. int getItemCount ()
Возвращает количество элементов в списке List. String [] getItems ()
Возвращает массив строк списка (может быть пустым).
Замечание Возвращаемый массив не является структурой хранения данных списка, так что его изменение не влияет на отображаемый список List. int getTopIndex ()
Возвращает индекс первого видимого элемента в списке List (отсчет начинается от нуля). Индекс элемента может изменяться при скроллировании, добавлении или удалении элементов. int getFocusIndex ()
Возвращает индекс элемента, на котором установлен фокус курсора (отсчет начинается от нуля). Если фокус не установлен, то возвращается (-1). int getItemHeight ()
Возвращает высоту элемента списка в пикселях при отображении на экране. Данное значение может быть использовано для вычисления предпочтительного размера списка List.
5.5. Настройка значений элементов Для настройки значений элементов списка List предназначены следующие методы: setItem (int index, String string)
Вставляет строку string в определенную позицию index (отсчет начинается от нуля). Строка string string замещает значение, занимающего указанную позицию элемента. Данный метод функционально аналогичен последовательному вызову методов remove ( index ) и add ( string , index ) по указанному индексу index списка. setItems (String [] items)
Замещает список элементов List значениями элементов массива items. void setFont (Font font)
Устанавливает используемый шрифт font. setTopIndex (int index)
Устанавливает индекс первого видимого элемента в списке List (отсчет начинается от нуля). Индекс элемента может изменяться при скроллировании, добавлении или удалении элементов.
5.6. Поиск элементов Методы поиска элементов списка: int indexOf (String string)
Возвращает индекс строки string если таковая найдена в списке (поиск начинается от нуля). Если строка string не найдена, то возвращается (-1). int indexOf (String string, int start)
Возвращает индекс найденной строки string. Поиск производится, начиная с позиции start (отсчет начинается от нуля). Если строка string не найдена или указан неверный индекс start , то возвращается (-1).
5.7. Выбор элементов списка В зависимости от выбранного стиля можно выбирать только один (SWT.SINGLE) или несколько строк списка (SWT.MULTI). Для проверки выбран элемент или нет, используется метод: isSelected (int index)
Если элемент выбран, возвращает true и false в противном случае. Для выбора (выделения) элементов списка List предназначены методы: select (int index)
Выбирает строку в определенной позиции index (отсчет начинается от нуля). Если указан неверный индекс, то операция игнорируются. select (int start, int end)
Начиная с позиции start по end включительно, выбирает элементы списка. Если указаны неверные значения индексов интервала, то такие элементы игнорируются. select (int [] indeces)
Выбирает строки с указанными в массиве indeces индексами. Если указаны неверные индексы, то они игнорируются. selectAll ()
Данный метод выбирает все элементы списка.
Замечание Методы выбора select(..) не сбрасывают состояние выбора элементов списка, которое было установлено до выполнения операции нового выбора. Так же не происходит скроллирования при выборе не видимых в данный момент элементов.
Если установлен флаг SWT.SINGLE и производится операция над множеством элементов, например selectAll(), то данная операция игнорируется. Пример 4.9. Выбор элементов из List источника и перенос их в List приемник с использованием массива элементов /** * Переносит все элементы списка источника в список List приемника. */ private void moveAllToTarget() { lstSource.selectAll(); moveSelectedToTarget(); } /** * Переносит выбранные элементы списка источника в список List приемника. */ private void moveSelectedToTarget() { String[] selectedItems = lstSource.getSelection(); for (int i = 0; i < selectedItems.length; i++) { lstSource.remove(selectedItems[i]); lstTarget.add(selectedItems[i]); } fireListsChanged(); } setSelection (int index)
Отменяет выбор всех ранее выбранных элементов и выбирает элемент с индексом index (отсчет начинается от нуля). setSelection (int [] indices)
Отменяет выбор всех ранее выбранных элементов и выбирает элементы с индексами массива indices (отсчет начинается от нуля). setSelection (int start, int end)
Отменяет выбор всех ранее выбранных элементов и начиная с позиции start по end включительно, выбирает элементы списка. Если указаны неверные значения индексов интервала, то такие элементы игнорируются. setSelection (String [] items)
Отменяет выбор всех ранее выбранных элементов и выбирает соответствующие массиву items элементы (отсчет начинается от нуля). Для получения информации о выбранных элементах предназначены следующие методы: String[] getSelection ()
Возвращает массив выбранных элементов списка. Выбранные элементы не сортируются. Пустой массив означает, что ничего не выбрано. int getSelectionCount ()
Возвращает количество выбранных элементов в списке. int getSelectionIndex ()
Возвращает индекс текущей выбранной строки если на ней установлен фокус курсора (отсчет начинается от нуля). В противном случае возвращается индекс первой выбранной строки в списке. Если ни одного элемента списка не выбрано, то возвращается -1. Пример 4.10. Пример контроля выбора элементов списка List /** * Настройка доступных действий по состоянию списков источника и приемника. */ private void fireListsChanged() { btnAdd.setEnabled((lstSource.getSelectionIndex() != -1)); btnAddAll.setEnabled(lstSource.getItemCount() > 0); btnRemove.setEnabled((lstTarget.getSelectionIndex() != -1)); btnRemoveAll.setEnabled(lstTarget.getItemCount() > 0); }
int [] getSelectionIndices ()
Возвращает массив индексов выбранных элементов списка List. Пример 4.11. Выбор элементов из List приемника и перенос их в List источник с использованием массива индексов private void moveSelectedToSource() { int[] selectedItems = lstTarget.getSelectionIndices(); for (int i = 0; i < selectedItems.length; i++) { lstSource.add(lstTarget.getItem(selectedItems[i])); } lstTarget.remove(selectedItems); fireListsChanged(); }
Метод: showSelection ()
Производит скроллирование элементов списка List до появления на экране первого выбранного элемента. Для отмены выбора применяются следующие методы: deselect (int index)
Отменяет выбор строки в определенной позиции index (отсчет начинается от нуля). Если указан неверный индекс или элемент ранее не был выбран, то операция игнорируются. deselect (int [] indices)
Отменяет выбор элементов с индексами массива индексов indeces . (отсчет начинается от нуля). Элементы с неверными индексами игнорируются. deselect (int start, int end)
Отменяет выбор строк, начиная с позиции start по end включительно. Если указаны неверные значения индексов интервала, то такие элементы игнорируются. deselectAll ()
Отменяет выбор всех элементов списка List.
5.8. Слушатели событий списка List Слушатели предназначены для фиксации некоторых событий в системе и выполнения адекватных действий в соответствии с типом события. addSelectionListener(SelectionListener listener)
Добавляет слушатель в коллекцию слушателей, который активизируется при изменении выбора List. Где listerner - одна из возможных реализаций интерфейса обработчика событий: • •
widgetSelected - вызывается при изменении выбора (например, при выборе элемента списка при помощи клавиатуры или мыши). widgetDefaultSelected - вызывается при выполнении платформо зависимой операции по умолчанию. На большинстве платформ это нажатие кнопки < Enter > или двойной клик мыши.
removeSelectionListener(SelectionListener listener)
Удаляет ранее созданный слушатель listener из коллекции слушателей. Пример 4.12. Слушатель, который контролирует изменение состояния выбора элементов списка List // Добавляем слушатель изменений списка источников lstSource.addSelectionListener( new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected( org.eclipse.swt.events.SelectionEvent e) { fireListsChanged(); } });
Рисунок 4.15. Пример тестового приложения выбора элементов List
Текст тестового примера работы с классом List приведен в файле by.berdachuk.swt.simplewidgets.ListSelector.java Архив демонстрационного проекта можно скачать по адресу http://forjava.dev.juga.ru/downloads/bs_swtexamples.zip
Link Класс Link предназначен для вывода текста включающего гиперлинки. Экземпляр класса Link в отличии от компонента Label получает фокус ввода при перемещении курсора например клавишей Tab или при кликании по нему мышкой. Создав, обработчик событий можно организовать обработку выбранного линка, например переход на WEB страницу. Для создания экземпляра класса Link используется следующий конструктор: public Link (Composite parent, int style)
Где parent – обязательный родительский компонент (контейнер), а style это один или несколько стилей определяющий параметры создания класса Link. Рисунок 4.16. Link. Иерархия классов
Рисунок 4.17. Компонент Link. Изображение в визуальном редакторе
6.1. Стили Стили формируют битовую маску по принципу логического «ИЛИ». Для объединения стилей используется символ "|". Базовый класс org.eclipse.swt.widgets.Control предоставляет возможность прорисовки рамки вокруг компонента при указании стиля SWT.BORDER, а так же изменение направления вывода LEFT_TO_RIGHT, RIGHT_TO_LEFT для письма слева направо и справа налево.
6.2. Текст Для задания текста выводимого классом Link используется метод: public void setText (String text)
Текст может содержать, как непосредственно текст, так и гиперлинки. Гиперлинки помещаются в теги привязки и . Внутри тегов привязки доступен атрибут href . При выборе гиперлинка в обработчик события передается текст гиперлинка или значение href если он указан. Текст может содержать мнемоники и разделители. Пример 4.13. Задание текста компонента Link siteLink = new Link(shell, SWT.NONE); siteLink.setText( "Код примеров использования SWT компонент\n" + "можно найти на сайте: " + "" + "http://forjava.dev.juga.ru");
Метод:
public String getText()
возвращает текст или пустую строку, если текст не задавался, или использовалась маска SWT.SEPARATOR.
6.3. Слушатели событий Слушатели предназначены для фиксации и обработки событий компонента Link. addSelectionListener(SelectionListener listener)
Добавляет слушатель в коллекцию слушателей, который активизируется при выборе линка. Где listerner - одна из возможных реализаций интерфейса обработчика событий: • •
widgetSelected - вызывается при изменении выбора (например, при выборе линка при помощи клавиатуры или мыши). widgetDefaultSelected - вызывается при выполнении платформо зависимой операции по умолчанию. На большинстве платформ это нажатие кнопки < Enter > или двойной клик мыши.
Пример 4.14. Слушатель, который обрабатывает выбор линков компонента Link siteLink.addSelectionListener( new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected( org.eclipse.swt.events.SelectionEvent e) { browser.setUrl(e.text); } }); removeSelectionListener(SelectionListener listener)
Удаляет ранее созданный слушатель listener из коллекции слушателей. Рисунок 4.18. Использование класса Link для ссылки на WEB ресурсы
Меню (классы Menu и MenuItem) Меню являются важнейшими элементами графического интерфейса. В большинстве приложений меню является основным средством для выполнения возможных операций приложения. Главное меню пожалуй не используется только в диалоговых окнах и специфических, нестандартных развлекательных приложениях. Для создания меню предназначены классы Menu и MenuItem. Различают три вида меню: •
• •
Bar menu - это обычно главная панель меню. Для большинства платформ главное меню размещается в верхей части родительской формы (В ОС Macintosh главное меню размещается на десктопе и является общим для всех приложений); Drop-down menu - это дочерние выпадающие меню, часто используются термины SubMenu или каскадные меню; Popup menu - это контекстное меню, которое динамически формируется в зависимости от текущего местоположения курсора и вызывается либо с клавиатуры либо при помощи мыши, в зависимости от настроек ОС (обычно по правой кнопке мыши).
Рисунок 5.1. Menu. Иерархия классов
Рисунок 5.2. MenuItem. Иерархия классов
Для создания экземпляра класса Menu используется следующий конструктор: public Menu (Decorations parent, int style)
Где parent – обязательный родительский компонент (контейнер), а style это один или несколько стилей определяющий параметры создания класса Menu. Конструктор без указания стиля создает popup меню (стиль SWT.POP_UP): public Menu (Control parent)
Где parent – обязательный родительский компонент (контейнер). Конструктор: public Menu (Menu parentMenu)
создает новый экземпляр класса Menu с родительским меню parentMenu (параметр parentMenu не может быть null). По умолчанию задается стиль выпадающего drop-down меню. Конструктор: public Menu (MenuItem parentItem)
создает новый экземпляр класса Menu с родительским элементом меню parentItem (параметр parentItem не может быть null). По умолчанию задается стиль выпадающего drop-down меню.
1.1. Menu
1.1.1. Стили класса Menu Стили формируют битовую маску по принципу логического «ИЛИ». Для объединения стилей используется символ "|". Стиль
Описание
SWT.BAR
Создается панель главного меню
SWT.DROP_DOWN Создается выпадающее меню SWT.POP_UP
Создается контекстное меню
NO_RADIO_GROUP
Отменяется режим поведения меню в стиле Radio button
LEFT_TO_RIGHT
Устанавливает ориентацию меню слева направо
RIGHT_TO_LEFT
Устанавливает ориентацию меню справа налево
Примечание Только один атрибут из BAR, DROP_DOWN и POP_UP может быть выбран.
Только один атрибут из LEFT_TO_RIGHT и RIGHT_TO_LEFT может быть выбран
1.2. MenuItem
Стиль
Описание Примечание
SWT.CHECK SWT.CASCADE SWT.PUSH SWT.SEPARATOR
Только один атрибут из CHECK, CASCADE, PUSH, RADIO и SEPARATOR может быть выбран.
The SWT FAQ If you have questions you believe should go in here, please let us know on the SWT developer mailing list. What packages make up SWT? Does SWT support JavaBeans? Is there a GUI Builder for SWT? What is a snippet and why do I care? How do I build an SWT jar for my platform? How do I build the SWT JNI libraries for my platform? How do I build the 64 bit version of SWT GTK? What do I need to run SWT on Linux/GTK? On carbon, how do I run an SWT application from the command line? How can I deploy my standalone SWT application with Java Web Start? What do I need to do to run SWT on the PocketPC? Where is the SWT library for the PocketPC? How do I make SWT use the Windows XP themes? On gtk, how do I change the default fonts and colors of widgets? On motif, how do I change the default fonts and colors of widgets? Why do I get the error "java.lang.NoClassDefFoundError: org/eclipse/swt/internal/XXX/OS."? Why do I get the error "java.lang.UnsatisfiedLinkError: no swt-win32-3232 in java.library.path."? Why do I get an error beginning with "...SWTException: Unsupported or unrecognized format" on startup? Why do I get the error "error while loading shared libraries: ./libXm.so.2: file too short" on startup? Why do I get the error "java.lang.UnsatisfiedLinkError: libXm.so.2: cannot open shared object file: No such file or directory."? Why do I get the warning "XmParseMappingCreate() is not implemented yet" on Linux/Motif? Why do I get an error beginning with "org.eclipse.swt.SWTError: Font not valid" on startup? Can I use Swing or AWT inside Eclipse? Why can't I subclass SWT widgets like Button and Table?
Why are some events like Selection not fired in response to programmatic widget changes? Why don't SWTError and SWTException override all printStackTrace methods? How do I print using my favorite Unix print program? How do I print a snapshot of a widget? Why does everything I print seem so small? What does computeTrim mean for a Printer? How can I implement user interaction test cases? On gtk, why does my widget's selection disappear when it loses focus? What is the SWT Browser widget? How do I use Mozilla as the Browser's underlying renderer? How can my Mozilla-based Browser find my Mozilla plug-ins? Can I specify which XULRunner installation is used? How do I use JavaXPCOM with the Browser? Which platforms support the SWT Browser? What do I need to run the SWT Browser inside Eclipse on Linux/GTK or Linux/Motif? What do I need to run the SWT Browser in a standalone application on Linux/GTK or Linux/Motif? How can I get the SWT Browser to work with the IBM 1.4 VM? Why can't I run Java applets in the SWT Browser? Why does the SWT_AWT bridge not work for me on OS X? Why does the SWT_AWT bridge not work for me on AIX or Solaris? Why is the Print menu item disabled in Eclipse on GTK (Linux, UNIX)? Why is the Print menu item disabled in Eclipse on Motif? Why do I get the error "org.eclipse.swt.SWTException: Invalid thread access"? Why do I have to resize my shell to get my changed widgets to lay out again? Why do I get "SWTException: Unable to load graphics library" using GC? Why doesn't mouse scrolling work on Linux/Motif?
Q: What packages make up SWT? A: Package names in SWT begin with the prefix org.eclipse.swt.
Here is the complete list: org.eclipse.swt org.eclipse.swt.accessibility org.eclipse.swt.awt org.eclipse.swt.browser org.eclipse.swt.custom org.eclipse.swt.dnd org.eclipse.swt.events org.eclipse.swt.graphics org.eclipse.swt.internal.* (Not API, do not reference classes in these packages) org.eclipse.swt.layout org.eclipse.swt.opengl org.eclipse.swt.ole.win32 (Windows only) org.eclipse.swt.printing org.eclipse.swt.program org.eclipse.swt.widgets
Classes that are not in these packages do not belong to SWT. Q: Does SWT support JavaBeans? A: To the extent that it makes sense, given the constraints of operating system compatibility, SWT mirrors the beans behavior. An example of this is the use of standard beans mechanisms for event dispatch (EventListener, EventObject and adapter classes). Some aspects of the beans paradigm, such as the ability to create beans with null constructors, run counter to the constraints of the underlying operating systems that SWT runs on. For example, operating systems do not typically support creating a widget without specifying its parent.
The essence of the problem is that if you allow a widget to be created with a null constructor, then you can't actually create the o/s resources at the time the constructor runs (you would have to wait until later, after the parent has been set). We can not do this, since we always create the o/s resources in the constructor, and for
performance/efficiency/consistency reasons do not keep slots in the object to hold whatever state would be required if the object were to be created later. Q: Is there a GUI Builder for SWT? A: SWT itself does not provide a GUI Builder (also known as "GUI Designer", "GUI Editor", "Visual Builder", "Visual Designer", "Visual Editor", or "Visual Composition Editor"). There are, however, several mature 'third-party' products listed at http://www.eclipseplugincentral.com/. Or you can follow the progress on the Eclipse Visual Editor Project. Q: What is a snippet and why do I care? A: A snippet is a minimal stand alone program that demonstrates functionality or lack of functionality.
Why is this important? Posting a snippet to the news group is the quickest way to get help. Including a snippet in a bug report is the fastest way to get a bug fixed. Taking the time to construct a snippet helps you understand the API of the library you are calling and focuses your thinking. For example, the SWT team uses C and Java snippets internally to prove or disprove problems in the operating system. Often, something you think is a bug is actually caused by something elsewhere in your program.
Snippets isolate problems. Code speaks louder than words.
Here is a minimal stand alone SWT program to help you get started: public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } For a list of sample snippets, see the SWT snippets page. Q: How do I build an SWT jar for my platform? A: The SWT jar can be built from the eclipse CVS repository using an Ant task: Connect a CVS client (such as eclipse) to :pserver:
[email protected]:/cvsroot/eclipse.
Check out the projects org.eclipse.swt and org.eclipse.swt.WS.OS.ARCH where WS.OS.ARCH are the names of the windowing system, operating system and architecture of interest, respectively. For example, org.eclipse.swt.gtk.linux.x86. In the project org.eclipse.swt.WS.OS.ARCH, locate the file build.xml. This is an Ant script. Run Ant on the target build.jars. If you are using eclipse as your development environment, you can run Ant by selecting the file in the Navigator or Packages view, then selecting Run Ant... from the context menu. This will create a file called swt.jar in the root of the org.eclipse.swt.WS.OS.ARCH project. Q: How do I build the SWT JNI libraries for my platform? A: SWT uses JNI to interact with the native widgets in the operating system. The SWT JNI libraries must be compiled for the windowing system, operating system and hardware architecture of interest. The libraries can be built either from the code in the CVS repository or from an eclipse SDK download.
In order to build the required libraries and run Eclipse, you will require a JDK (Java Development Kit) version that is supported by Eclipse. Check eclipse.org for details.
Building the SWT JNI libraries from the eclipse SDK download: Download an Eclipse distribution from http://www.eclipse.org/downloads/index.php. Unzip the distribution. This will create a directory called eclipse. This directory is subsequently referred to as <eclipseRoot>. In the directory <eclipseRoot>/plugins/org.eclipse.rcp.source.platform_X.X.X, find the source zip in the SWT subdirectory. Unzip contained file src.zip. Edit the file build.sh (or build.bat on Windows) in the current directory. Set the environment variables defined in that file to match the location of your JRE, etc. Save the file and close it. Run the build command (sh build.sh for UNIX and Linux platforms, build.bat for Windows). This will create the appropriate library file(s) in the current directory. For example, this will create swt-XXXX.dll files on windows, or libswt-XXXX.so files on Linux and Solaris.
This description was originally contributed by Colin R Devilbiss.
Building the SWT JNI libraries from the eclipse CVS repository: NOTE: These instructions require you to use Eclipse Follow these instructions to checkout SWT from CVS. Compile the project. This will create a folder called bin under the org.eclipse.swt project.
Change directory into org.eclipse.swt/bin/library Edit the file build.sh (or build.bat on Windows) in the current directory. Set the environment variables defined in that file to match the location of your JRE, etc. Save the file and close it. Run the build command (sh build.sh for UNIX and Linux platforms, build.bat for Windows). This will create the appropriate library file(s) in the current directory. For example, this will create swt-XXXX.dll files on windows, or libswt-XXXX.so files on Linux and Solaris. Q: How do I build the Eclipse executable for my platform? A: Eclipse is launched by a binary executable which puts up a splash screen and launches a Java VM. The executable must be compiled for the windowing system, operating system and hardware architecture of interest. The libraries can be built either from the code in the CVS repository or from an eclipse SDK download.
Building the Eclipse executable from the eclipse SDK download: In order to build the required libraries and run Eclipse, you will require a JDK (Java Development Kit) of version 1.4.2 or later. Download an Eclipse distribution from http://www.eclipse.org/downloads/index.php. Unzip the distribution. This will create a directory called eclipse. This directory is subsequently referred to as <eclipseRoot>. In the directory <eclipseRoot>/plugins/org.eclipse.platform.source_X.X.X/src, find the launchersrc.zip file under org.eclipse.platform_X.X.X. Unzip the file launchersrc.zip. This will create a directory called library. Change directory into library/WS, where WS is the name of the windowing system e.g. win32, motif, gtk, photon, or carbon. Modify any incorrect _HOME variables defined at the top of the appropriate .mak file. Run the build command (sh build.sh for UNIX and Linux, build.bat for Windows). This will create an executable launcher called eclipse. Move this eclipse executable to <eclipseRoot>. As of eclipse 3.3 an eclipse_ shared library is also created by the previous step. Move this library to the appropriate org.eclipse.equinox.launcher.<ws>..<arch> fragment.
This description was originally contributed by Colin R Devilbiss. Q: How do I build the 64 bit version of SWT GTK? Follow these steps to extract the 64 bit SWT GTK source code and produce your own build. Start Eclipse and download the following projects from dev.eclipse.org: org.eclipse.swt, org.eclipse.swt.gtk.linux.x86_64, org.eclipse.swt.tools Open the file build.xml located into the org.eclipse.swt.gtk.linux.x86_64 fragment. Run Ant to execute the ant task build.nativeLibraries defined in build.xml. Refresh the project org.eclipse.swt.gtk.linux.x86_64
The project org.eclipse.swt.gtk.linux.x86_64 now contains the 64 bit native libraries. The 64 bit java and C source code has been copied under the org.eclipse.swt.gtk.linux.x86_64/src folder. Q: What do I need to run SWT on Linux/GTK? A: SWT requires the following libraries with the specified versions or later:
For Eclipse 3.0 and newer: GTK 2.2.1 ATK 1.2.0 glib 2.2.1 Pango 1.2.1 Freetype 2.1.3
For Eclipse 2.1: GTK 2.0.6 ATK 1.0.1 glib 2.0.4 Pango 1.0.3 Freetype 2.1.2 Q: On carbon, how do I run an SWT application from the command line? A: If you run a Java application that uses Carbon via JNI, the application is not registered with the OS as a 'normal' UI application. As a consequence, it has no entry in the dock and it cannot be activated. AWT (or Swing) based applications don't have this problem because they seem to use undocumented SPI to register themselves.
To work around this problem you'll have to pass the -XstartOnFirstThread option to the java executable as follow: java -XstartOnFirstThread -cp swt.jar:. ControlExample
If you want to run a bundled application, take a look at this article. Q: How can I deploy my standalone SWT application with Java Web Start?
A: For steps that can be used to package and deploy an SWT application with Java Web Start (JWS) see How to deploy SWT Applications with Java Web Start. A related article that describes the deployment of SWT applications with JWS (but does not outline the process of packaging SWT) can be found at http://www-106.ibm.com/developerworks/opensource/library/os-jws/.
Note: As of eclipse 3.3, SWT applications cannot be deployed via JWS to clients on Mac OS X (see bug 63306). Q: What do I need to do to run SWT on the PocketPC? A: There is an experimental version of SWT for WinCE devices. If you wish to give it a try, the following steps may help you with getting started. Install a VM on your PocketPC. The port is tested using the J9 VM for ARM WinCE PocketPC. For information on how to get the J9 VM, see at the WebSphere Studio Device Developer website (which ships J9): http://www.embedded.oti.com/wdd For questions on how to use the J9 VM, see the WebSphere newsgroup: ibm.software.websphere.studio.device-developer Get the swt.jar and SWT dll for PocketPC. See Where is the SWT library for the PocketPC? Copy the swt.jar and SWT dll to your device. Copy your SWT app to your device. For example, compile the following class inside Eclipse and copy the resulting class file to your device. import org.eclipse.swt.*; import org.eclipse.swt.widgets.*; import org.eclipse.swt.layout.*;
public class HelloWorld { public static void main(String[] args) { Display display = new Display();
/* * Create a Shell with the default style
* i.e. full screen, no decoration on PocketPC. * Alternative: 'new Shell(display, SWT.CLOSE)' * to get the Pocket PC 'Ok' button. */ Shell shell = new Shell(display);
/* * Set a text so that the top level Shell * also appears in the Pocket PC task list */ shell.setText("HelloWorld");
/* * Set a menu bar to follow UI guidelines * on Pocket PC */ Menu mb = new Menu(shell, SWT.BAR); shell.setMenuBar(mb);
/* * Add widgets */ FillLayout layout = new FillLayout(); layout.type = SWT.VERTICAL; shell.setLayout(layout); Label label = new Label(shell, SWT.CENTER); label.setText("Hello World");
shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } } Run your SWT application. One way to start your application is to create a shortcut file. On your desktop, create a file 'HelloWorld.lnk'. Insert the following line. 68#\j9\bin\j9.exe -Djava.home=\j9 -cp:\java\swt.jar;\java HelloWorld This is assuming that you have installed the J9 VM in the folder \j9, and that you have copied the swt.jar and your application HelloWorld.class into the folder \java. It also assumes that the SWT dll was copied into the folder \j9\bin where it will be found by the VM. Save the shortcut file. Copy the file to your device. Using the file explorer on your device, click on the shortcut file. If everything is correctly setup, the SWT app should come up. Q: Where is the SWT library for the PocketPC? A: There is an experimental version of SWT for WinCE devices. The swt.jar and ARM Pocket PC dll are available from the Eclipse download page.
Choose which swt.jar fits your project requirements. You can also build a custom version. A custom version allows you, for example, to exclude image decoders or layouts, to further reduce the size. win32-ce-arm-ppc.zip J2SE profile Emulated Drag and Drop (no OLE support) Native widgets only (no custom widgets) No class file debug information (for reduced size)
win32-ce-arm-ppc-j2me.zip J2ME profile (CLDC) Emulated Drag and Drop (no OLE support) Native widgets only (no custom widgets) No class file debug information (for reduced size)
Custom SWT library From Eclipse, check out the projects org.eclipse.swt and org.eclipse.swt.win32.wce_ppc.arm from the head stream. These projects reside in the Eclipse repository Build the swt.jar Open the file org.eclipse.swt.win32.wce_ppc.arm/build_custom.xml The file contains indications on how to build the swt.jar as recommended for WinCE PocketPC. Get the corresponding dll The latest dll is available under org.eclipse.swt.win32.wce_ppc.arm Q: How do I make SWT use the Windows XP themes? A: In order for an application to use Windows XP themes, there must be a manifest file located in the same place as the executable that launches the application. Here is a sample manifest file to download.
The name of the manifest file must match the name of the executable. In the case of eclipse, the executable is javaw.exe and the manifest file must have the name javaw.exe.manifest. The manifest file must be in the jre\bin folder for the VM you use to launch Eclipse. Note: the eclipse.exe executable does not launch Eclipse; eclipse.exe displays a splash screen and then invokes the Java VM.
Note: As of SWT 3.2, the manifest file is no longer needed. Q: On GTK, how do I change the default fonts and colors of widgets? A: GTK uses a file called .gtkrc which is located in your home directory. On some versions of Linux, this file is called .gtkrc-2.0. Here is an example of the content of that file which sets the font and colors for Eclipse: style "eclipse" { font_name = "Sans 12" bg[NORMAL] = "#d6d3ce" bg[ACTIVE] = "#c7c2bc"
bg[INSENSITIVE] = "#828282" bg[PRELIGHT] = "#3a6ea5" fg[NORMAL] = "#000000" fg[ACTIVE] = "#000000" fg[INSENSITIVE] = "#d4d0c8" fg[PRELIGHT] = "#ffffff" } class "GtkWidget" style "eclipse"
To turn off anti-aliasing of fonts you should use the facilities available in your desktop if possible, such as the Gnome Font Properties dialog. An alternate approach is to ensure that your ~/fonts.conf or system-wide fonts.conf file contains the following: <match target="font"> <edit name="antialias" mode="assign">false <edit name="hinting" mode="assign">true <edit name="autohint" mode="assign">false
Q: On motif, how do I change the default fonts and colors of widgets? A: Motif uses a file called .Xdefaults which is located in your home directory. Here is an example of the content of that file which sets the font and colors for Eclipse: Eclipse*spacing:0 Eclipse*XmForm.background:#e8e7e3 Eclipse*XmList.background:#e8e7e3 Eclipse*XmTextField.background:#e8e7e3 Eclipse*background:#d6d3ce Eclipse*fontList:-misc-fixed-medium-r-normal-*-10-100-75-75-c-60-iso8859-1 After creating/modifying this file, you must run "xrdb ~/.Xdefaults" or restart X to make the changes take effect.
Q: Why do I get the error "java.lang.NoClassDefFoundError:
org/eclipse/swt/internal/XXX/OS."? A: On some platforms such as GTK, SWT is broken into multiple jars. Therefore, you must ensure that all required jars are on the classpath. The required jars are: swt.jar (all platforms) swt-pi.jar (some platforms like GTK and Carbon) swt-mozilla.jar (for Browser widget on GTK and Motif) swt-gtk.jar (on Linux Motif) Q: Why do I get the error "java.lang.UnsatisfiedLinkError: no swt-win32-3232 in
java.library.path."? A: The SWT JNI libraries must be found at runtime. As of Eclipse/SWT 3.3 this will happen automatically if the platform-specific SWT jar is on the java classpath. For older Eclipse/SWT versions you need to place the SWT JNI libraries in a place where the Java Virtual Machine will find them.
The SWT JNI libraries are included in the SWT download.
A Java application can be informed of the location of the libraries in several ways:
Set the library path in the VM launch arguments.
In the Launch Configuration Dialog of eclipse select the Arguments page, and in the VM arguments field enter: -Djava.library.path={runtime-library-path} Where the runtime-library-path is the absolute path to the directory containing the native code library (see above).
This solution means that the SWT libraries have to be manually added to every project that uses SWT.
Set the library location in an environment variable.
For Windows this is done by editing the PATH environment variable to include the above mentioned runtime-library-path. in Win 9X this is done by editing the autoexec.bat file,
on NT or 2K the variable is edited through My Computer > Properties > Advanced > Environment Variables.
On linux/unix, modify the LD_LIBRARY_PATH environment variable to include the runtime-library-path.
Copy the SWT library to a directory that is already on the Java library path. For example, the jre/bin directory.
The disadvantage of this solution is that every time you upgrade eclipse you have to remember to copy the native code library.
Starting with Eclipse 3.1, the SWT plugin that comes with Eclipse, includes the JNI libraries in the SWT jar. This was done to support OSGi and Eclipse RCP. If you are using the plugin you must extract the libraries to include them in the path. Q: Why do I get an error beginning with "...SWTException: Unsupported or
unrecognized format" on startup? A: There is a bug in the Konqueror decompressor which causes Eclipse to be improperly extracted if used. To avoid this the Eclipse archive should first be downloaded to your machine and then extracted using unzip at the command line. Q: Why do I get the error "error while loading shared libraries: ./libXm.so.2: file
too short" on startup? A: You must use unzip, not jar, to extract your eclipse download. Jar does not extract the libXm.so.2 link file properly. Q: Why do I get the error "java.lang.UnsatisfiedLinkError: libXm.so.2: cannot
open shared object file: No such file or directory."? A: On motif, the SWT library links against the open motif library libXm.so.2. On most platforms, the open motif library is installed and added to the library path by default. However, on some Linux platforms, either open motif is not installed or is not on the default library path, or lesstif is installed. Eclipse (and the standalone version of SWT) includes the libXm.so.2 library in the root of the Eclipse install.
You need to either launch Eclipse from the installed directory or modify the LD_LIBRARY_PATH environment variable to include the location of libXm.so.2.
Note -Djava.library.path is used by the VM to locate libraries for System.loadLibrary calls. However, it does not update the LD_LIBRARY_PATH and therefore does not help libraries locate other libraries.
Q: Why do I get the warning "XmParseMappingCreate() is not implemented yet"
on Linux/Motif? A: This warning is shown if you're accessing installed LessTif libraries instead of the shipped OpenMotif libraries. If you see this warning, add the eclipse install directory to your LD_LIBRARY_PATH before launching eclipse. For example, if you are using csh: setenv LD_LIBRARY_PATH /opt/eclipse:${LD_LIBRARY_PATH} Q: Why do I get an error beginning with "org.eclipse.swt.SWTError: Font not
valid" on startup? A: This error occurs if a recognized font cannot be resolved at startup time. The scenario where this has been observed to sometimes happen is when accessing a remote machine via Reflection X. This situation can be made to work by changing some settings in Reflection X. For information about how to do this see bug 33828. Q: Can I use Swing or AWT inside Eclipse? A: Yes. As of Eclipse 3.2, Swing and AWT can be embedded in SWT on Windows, Motif, GTK and OS X. However it is important to note that a supporting JDK is required on some platforms in order for this to work. Specifically, Motif and GTK require that JDK 1.5 or newer be used, and OS X requires that the JDK specified in Why does the SWT_AWT bridge not work for me on OS X? be used. Additionally, AIX and Solaris users must ensure that AWT is using XToolkit, as described in Why does the SWT_AWT bridge not work for me on AIX or Solaris?
See this snippet for an example of how to use the API. Q: Why can't I subclass SWT widgets like Button and Table? A: You can but it is not recommended. The article Creating Your Own Widget using SWT describes the reasons in detail: Subclassing Widgets Directly
In extreme circumstances, you may need to subclass a widget other than Canvas or Composite. We recommend against doing this unless all other avenues have been explored and exhausted. Try to wrap the widget first, before subclassing it. Here is why: Subclasses may inherit a lot of API that makes no sense, and must be overridden. In Java, you cannot override a method and change the return type; therefore you cannot reimplement some methods. Subclassing is typically not the safest way to extend a class that you do not own. For a simplified list of the common arguments, see the article by Bill Venners in the Nov '98 issue of Java World called "Inheritance versus composition: Which one should you choose?" at: http://www.javaworld.com/javaworld/jw-111998/jw-11-techniques.html Widget subclasses are almost certainly guaranteed to be platform-specific unless great care is taken to ensure that they work on all platforms. Subclassed widgets can be affected by changes in the non-API implementation of the superclass.
Subclassing may cause bad system-level bugs, and runs the risk of leaking resources. For example, if a subclass reimplements a method without making certain that dispose code from the superclass method is still called, then the new method will leak system resources. Binary incompatibility across releases becomes possible. If a method signature or field name changes, or new methods or fields are added, there may be a name conflict in the widget subclass. Only Canvas and Composite are guaranteed not to have name conflicts in future releases. See any paper by Leonid Mikhajlov on the "Fragile Base Class Problem". You can find his paper "A Study of The Fragile Base Class Problem" at: http://www.cas.mcmaster.ca/~emil/publications/fragile/
Subclassing Canvas or Composite is the best way to ensure that your widget works on all SWT platforms. The 'is-a' test in this case tests whether your widget is-a basic or compound widget. Subclassing anything else requires asking if the new widget is an SWT native widget of the type being subclassed. For example, a 100% Java portable PictureLabel is not an SWT native Label.
When subclassing anything other than Composite or Canvas you must override the method protected void checkSubclass() to do nothing. Make sure you read the method comment before overriding it. Q: Why are some events like Selection not fired in response to programmatic
widget changes? A: This is a design decision that was made in order to minimize notification of potentially unwanted events. For example, when the selection of a control is changed programmatically, SWT does not issue a selection event. If this were not the case then changing the selection multiple times would send multiple notifications and run application listener code multiple times, thereby leading to a potential performance problem. Clients that wish to notify widget listeners of changes made programatically can do so by creating an Event object and invoking Widget.notifyListeners(int, Event) on the widget. Note that some programmatically-triggered events are sent, typically in response to low-level widget operations such as focus, move and resize changes. Q: Why don't SWTError and SWTException override all printStackTrace
methods? A: SWTError and SWTException each contain a slot which records the original exception (if it is known) that caused the SWTError or SWTException to be thrown. The printStackTrace() method in these classes has been overridden to print the stacktrace of the original exception as well.
The problem with the other two API methods (i.e. printStackTrace(PrintStream) and printStackTrace(PrintWriter)) is that the classes mentioned in their arguments (PrintStream and PrintWriter) are not available in the CLDC class library. Because we need to maintain compatability with CLDC, we can not override them. Q: How do I print using my favorite Unix print program? A: You can use the External Tools support in Eclipse to print files using external programs. Just create a new Program launch config from the External Tools dialog that launches your favorite printing utility and you can pass the selected resource as a parameter. Select the file you want to print.
Run > External Tools > External Tools... Select "Program" in the Configurations: list. Click New Type: Print Selected File in the Name: field. Type the full path name of your favorite printing program in the Location: field. For example: /usr/bin/lpr Type: ${container_loc}/${resource_name} in the Arguments: field. Click Apply Click Run Q: How do I print a snapshot of a widget? A: To print an image, the image needs to be created on the printer. A common mistake is to try to print an image that was created on a display.
First take the snapshot into an image that was created on the display, and then get the imageData and create a new Image just for printing. Something like this: // Take the snapshot into a display Image Point size = myWidget.getSize(); Image image = new Image(display, size.x, size.y); GC gc = new GC(myWidget); gc.copyArea(image, 0, 0); gc.dispose();
// Get the ImageData and create a new printer Image from it ImageData imageData = image.getImageData(); Image printImage = new Image(printer, imageData);
Then print using printImage. (Remember to dispose both images when you are done with them).
This is true for all graphic objects that you want to use for printing: Fonts, Colors, and Images. You need to recreate them on the printer before you can use them for drawing on the printer GC. You might get lucky sometimes, if the printer happens to have this font or that color, but you won't get lucky on all platforms and for all printers, and you won't get lucky for images. So get into the habit of thinking "Did I create this graphics resource on the same device that I am now trying to draw to?" Q: Why does everything I print seem so small? A: When you are printing something from the screen to a printer device, you need to think about scaling. What is happening is that your figure is being drawn in something like 72 x 72 dots per inch on the screen, but then you are printing it to something like a 300 x 300 or 600 x 600 DPI printer. What you have to do is ask both the screen and the printer what their DPI is, and then figure out what scale factor you need to use when you draw to the printer GC. The code might look like this: Point screenDPI = display.getDPI(); Point printerDPI = printer.getDPI(); int scaleFactor = printerDPI.x / screenDPI.x;
Please see the ImageAnalyzer example in the org.eclipse.swt.examples project for an example of printing an image to a printer. Look at method menuPrint(). Note however that this is a pretty rough example, and it does not take into account what happens if the image is larger than the page - it just clips.
Text printing takes some thought also. You need to wrap words, put your page breaks in the right place, know where your margins are, etc. The SWT StyledText widget does its own text printing. If you need to see a more complicated example of printing a document, wrapping, margins, multi-page, etc., then please look at the inner class Printing in StyledText in org.eclipse.swt.custom. An instance of this class is created by the StyledText.print(Printer) API method.
Note also that when printing, any graphics objects that you use to draw, such as fonts, colors, and images, need to be re-created on the printer device before you can draw them to the printer GC.
We also recommend that you run your print job in a separate thread and not in the UI thread, because printing a long document to a slow printer can hang your entire UI while the printer spools.
Unfortunately, printing is not simply a matter of just passing in the printer GC instead of the screen GC. Printing has to be designed into your drawing classes. You don't have scrollbars anymore, so you have to either cut stuff off and print it on another page, or reorganize it, or scale it down, or wrap it somehow. Maybe you want to give some control to your users, and let them specify how many inches something should be, or whatever - maybe give them a ruler. There is no magic bullet - you will definitely have to give it some thought. Q: What does computeTrim mean for a Printer?
A: The "trim" is the area of the page that the printer cannot print on. Usually, computeTrim is used as follows: Rectangle trim = printer.computeTrim(0, 0, 0, 0);
A printer that can print edge-to-edge would have a trim.x and trim.y of 0,0. The trim.width and trim.height would be the same as the width and height of the physical paper.
A 600 dot per inch printer that cannot print on the leftmost 0.18 inch of the paper would have a trim.x of 108. So to print starting at precisely 1" from the left edge, take 600 (i.e. 1") and "add" -108 (i.e. subtract 0.18") to get the starting x position. Trim positions are negative because they are relative to the 0,0 position of the client area (or 'printable area') of the paper. Q: How can I implement user interaction test cases? A: The method org.eclipse.swt.widgets.Display.post(Event) can be used to post mouse and keyboard events into the OS, which emulates a user performing the specified action. Also, open source application "Abbot for SWT" assists in the writing of automated test suites. Q: On GTK, why does my widget's selection disappear when it loses focus? A: This effect may be seen if KDE color settings are being utilized. This can be fixed by unchecking the "Apply KDE colors to non-KDE apps" option in the KDE colors control panel. Q: What is the SWT Browser widget? A: The SWT Browser widget is used to display HTML documents. It is designed to provide a basic and portable API sufficient for essential HTML browsing and rendering on the platforms on which it is implemented. Q: How do I use Mozilla as the Browser's underlying renderer? A: The Browser has been extended as of Eclipse 3.3 to facilitate the use of Mozilla's HTML renderer on all supported browser platforms, provided that the following are satisfied: The Browser instance is created with style SWT.MOZILLA XULRunner is properly installed The installed XULRunner version is 1.8.1.2 or newer if any of the following are true: (download XULRunner 1.8.1.3) Running on OS X Browser.getWebBrowser() is used JavaXPCOM is referenced If none of these cases apply then any XULRunner version can be used. OSX only: The JRE must be "Java for Mac OS X 10.4, Release 5" or newer
Q: How can my Mozilla-based Browser find my Mozilla plug-ins? A: As of eclipse 3.3 the default set of Mozilla plug-in paths that are searched can be augmented by defining environment variable MOZ_PLUGIN_PATH. For example: export MOZ_PLUGIN_PATH=/usr/lib/browser-plugins. Q: Can I specify which XULRunner installation gets used? A: Typically a Mozilla-based Browser uses XULRunner's lookup mechanism to find a registered XULRunner at runtime. If you wish to override this mechanism you can set the value of java system property org.eclipse.swt.browser.XULRunnerPath to point at the target XULRunner's path. This property must be set before the first Browser instance is created. Q: How do I use JavaXPCOM with the Browser? A: First, ensure that you have all of the requirements listed in How do I use Mozilla as the Browser's underlying renderer?. Once these are in place then you can reference JavaXPCOM as follows:
If your application runs as an Eclipse plug-in: download the org.mozilla.xpcom Eclipse plug-in (download XULRunner 1.8.1.3 Eclipse plug-in) import it into your Eclipse workspace add it to your plug-in's list of Required Plug-ins (specified in your plug-in's META-INF/MANIFEST.MF file) If your application runs as a stand-alone application: download the XULRunner SDK for your platform (download XULRunner 1.8.1.3 SDK) add its lib/MozillaInterfaces.jar file to your application's java build path
You can use Browser.getWebBrowser() to access the JavaXPCOM nsIWebBrowser that represents the Browser instance. For an example of using JavaXPCOM see Snippet 267. Q: Which platforms support the SWT Browser? A: The SWT Browser is currently available on the following platforms: Windows (Internet Explorer 5 and above) Mac (Panther OS X 10.3 and above. Safari-based) Linux GTK and Linux Motif (XULRunner-1.8.0.1 and above, Firefox 1.0 and above, Mozilla 1.4 GTK2 and above) The following Linux distributions meet the Mozilla/Firefox requirements for using the Browser widget: RedHat Enterprise Linux 3
SuSE 9 Older Linux distributions may require a supported version of Mozilla to be installed. (instructions) Photon Q: What do I need to run the SWT Browser inside Eclipse on Linux/GTK or
Linux/Motif? A: You need one of the following: Mozilla 1.4 GTK2 - 1.6 GTK2 can be used with Eclipse 3.0 and newer. Mozilla 1.4 GTK2 - 1.7.8 GTK2 can be used with Eclipse 3.1 and newer. Mozilla 1.4 GTK2 - 1.7.12 GTK2 can be used with Eclipse 3.2 and newer. Firefox can be used with Eclipse 3.1 and newer (Linux only), provided that it has been compiled with linkable Gecko libraries. It is important to note that Firefox downloads from mozilla.org currently do not satisfy this criteria, but Firefox installations that are included in major Linux distributions often do in the absence of a XULRunner installation. Attempting to use a statically-linked Firefox install will display the error message "No more handles [NS_InitEmbedding...error -2147221164]". XULRunner 1.8.0.1 - 1.8.1.x can be used with Eclipse 3.3 and newer
The version of Mozilla or Firefox installed on your system varies with your Linux distribution. The following Linux distributions meet the Mozilla requirements for using the Browser widget. RedHat Enterprise Linux 3 Suse 9
The following Linux distributions meet the Firefox requirements for using the Browser widget. RedHat Enterprise Linux 4 Note that you may need to set the environment variable MOZILLA_FIVE_HOME to the folder containing your Firefox install. e.g. setenv MOZILLA_FIVE_HOME /usr/lib/firefox-1.0.4
If you use the IBM 1.4 VM check this.
If you are running with eclipse 3.2.1 or newer then you can just run eclipse and it will attempt to detect a browser on your system to use. If it fails to find one then you will need to download and install a GRE such as Mozilla, as outlined below: If you are using Eclipse 3.0, download the Mozilla 1.6 Xft and GTK2 build from Mozilla.org. If you are using Eclipse 3.1 or newer, you can choose to use a more recent Mozilla 1.7.x GTK2 from Mozilla.org.
Uninstall any prior Mozilla version. Extract and install the Mozilla download. Run Mozilla once. Verify that the application runs correctly and check the version number in the Mozilla About dialog.
If you are using an eclipse prior to version 3.2.1, or if you want the Browser to use a GRE (such as Mozilla) that you have installed yourself, then you must set the MOZILLA_FIVE_HOME environment variable to the folder containing your GRE (e.g. setenv MOZILLA_FIVE_HOME /usr/lib/mozilla), and prepend this directory to your LD_LIBRARY_PATH environment variable. Q: What do I need to run the SWT Browser in a standalone application on Linux
GTK or Linux Motif? A: Follow the steps below to use the SWT Browser widget in your standalone SWT application. A supported version of XULRunner, Firefox or Mozilla must be installed. (instructions) Set the environment variable MOZILLA_FIVE_HOME to your XULRunner/Firefox/Mozilla installation folder. e.g. setenv MOZILLA_FIVE_HOME /usr/lib/mozilla Set the environmnent variable LD_LIBRARY_PATH to include MOZILLA_FIVE_HOME. e.g. setenv LD_LIBRARY_PATH ${MOZILLA_FIVE_HOME}:${LD_LIBRARY_PATH} Your standalone SWT application can now use the Browser widget.
If you use the IBM 1.4 VM check this. Q: How can I get the SWT Browser to work with the IBM 1.4 VM? A: The IBM 1.4 VM accidentally removes certain entries of the environment variable LD_LIBRARY_PATH. This occurs in particular for entries starting with /usr/lib. It will leave untouched entries such as /usr/../usr/lib. Instructions for Red Hat Enterprise Linux 3 users: Mozilla is installed in /usr/lib/mozilla-1.x on this platform. Set the environment variable MOZILLA_FIVE_HOME to /usr/../usr/lib/mozilla-1.x Start Eclipse. If you are not using Eclipse, add MOZILLA_FIVE_HOME to LD_LIBRARY_PATH before starting your standalone SWT application. The Browser widget should now work with the IBM VM. Q: Why can't I run Java applets in the SWT Browser? A: Applets usually don't show up in the SWT Browser. On Windows (Internet Explorer) and OSX (Safari), the Java plugin fails to run a second Java virtual machine to execute the applet because two Java virtual machines cannot run in the same process. On Linux (Mozilla), the Java plug-in has been reported to work because it executes in its own process. See bug 59506 .
Q: Why does the SWT_AWT bridge not work for me on OS X? A: This was an SWT-AWT incompatibility that existed prior to eclipse 3.2. This problem has since been fixed in SWT, but requires that an OS X jre with support for this fix be used as well. Specifically, the jre must be version 1.5.0 Release 4 (or greater), and the additional "SWT Compatibility Libraries" must be installed. These libraries can be downloaded from the Downloads section of Apple Developer Connection. It's free to create an account at Apple Developer Connection to access the download, which is approximately 180K. For more information about this issue see bug 67384. Q: Why does the SWT_AWT bridge not work for me on AIX or Solaris? A: The SWT_AWT bridge requires that AWT be using XToolkit, since this implements the XEmbed protocol. However by default AWT on AIX and Solaris use MToolkit. This can be easily changed as described in XToolkit on Solaris/Linux. Q: Why is the Print menu item disabled in Eclipse on GTK (Linux, UNIX)? A: GTK+ began supporting printing in version 2.10. To print in Eclipse, you need to have Eclipse version 3.3 M1 or later, and at least GTK+ 2.10.0. To determine what GTK+ version you are running, type: rpm -q gtk2.
Prior to Eclipse 3.3 M1, printing was not implemented on GTK; however you can use the External Tools support in Eclipse to print files using lpr or some other printing utility. See here for the steps to set this up. Q: Why is the Print menu item disabled in Eclipse on Motif? A: Printing on Motif requires that Xprint be installed on your machine. A good FAQ regarding Xprint can be found at http://xprint.mozdev.org/docs/Xprint_FAQ.html. Q: Why do I get the error "org.eclipse.swt.SWTException: Invalid thread
access"? A: In SWT, by definition the thread that creates the Display is a UI-thread. This thread is responsible for reading and dispatching events from the operating system event queue, and invoking listeners in response to these events. Listener code is executed in the UI-thread. This makes an SWT application generally quite responsive, behaving like most other operating system programs. However, any long operation, when executed by a listener, will run in the UI-thread and prevent it from reading and dispatching events, thus hanging the application.
If a listener has a large amount of work to perform, instead of performing that work in the UI-thread, it can fork a separate thread so the UI-thread can continue dispatching events. If the other thread needs to execute code that accesses an SWT object, such as changing the string in a label, there is a concurrency issue. At the very least, some kind of synchronization is necessary to prevent the operating system or SWT from crashing, hanging or behaving unpredictably.
SWT implements a single-threaded UI model often called apartment threading. In this model, only the UIthread can invoke UI operations. SWT strictly enforces this rule. If you try and access an SWT object from outside the UI-thread, you get the exception "org.eclipse.swt.SWTException: Invalid thread access". Different operating systems have different rules governing threads, UI components and synchronization.
Some use a single-threaded UI model like SWT. Others allow only one thread at a time in the window system library, controlling access through a global lock. This type of multi-threaded UI model is often called free threading. Currently, in order to be simple, efficient and portable, SWT is apartment threaded.
To allow background threads to perform operations on objects belonging to the UI-thread, the methods syncExec(Runnable runnable) and asyncExec(Runnable runnable) of Display are used. These are the only methods in SWT that can be called from any thread. They allow a runnable to be executed by the UI-thread, either synchronously, causing the background thread to wait for the runnable to finish, or asynchronously allowing the background thread to continue execution without waiting for the result. A runnable that is executed using syncExec() most closely matches the equivalent direct call to the UI operation because a Java method call always waits for the result before proceeding, just like syncExec().
The following code sets the text of a label from a background thread and waits for the operation to complete: display.syncExec( new Runnable() { public void run(){ label.setText(text); } }); Q: Why do I have to resize my shell to get my changed widgets to lay out
again? A: A layout is only performed automatically on a Composite's children when the Composite is resized, including when it is initially shown. To make a Composite lay out its children under any other circumstances, such as when children are created or disposed, its layout() method must be called. For an example of this see SWT snippet create and dispose children of a composite. Q: Why do I get "SWTException: Unable to load graphics library" using GC? A: Support for advanced graphics operations such as path for curvers and lines, alpha blending, antialiasing, patterns and transformations was added to SWT 3.1. On Windows, GDI+ is required. On X Windows platforms (i.e. GTK and Motif), Cairo 0.4.0 is required. If your Windows platform does not have GDI+ by default then you can download a redistributable package from Microsoft. Q: Why doesn't mouse scrolling work on Linux/Motif? A: Mouse scrolling on Linux/Motif relies on the IMWheel driver. Here is how it works: The X Server gets the wheel event. Your /etc/X11/XF86Config must contain "ZAxisMap 4 5" (or the equivalent "Option" line if you use XFree86 4.x) in the Mouse section. This maps the wheel to emulated mouse buttons "4" and "5".
IMWheel has a global hook on the mouse, only looking for button4/5 events. When it sees one, it looks in /etc/X11/imwheel which is a table of what to do for which application. E.g., GTK-based applications support the idea of 5-button mice natively, so the imwheel file says "do nothing (pass through) for gtk". On the other hand, no known Motif-based app seems to know about these, so imwheel eats the mouse event and emits an accelerator event for "PgUp" or whatever your preference is. It has some clever pre-sets for xterm, netscape, and so on.