
Книги по Java и Eclipse / Eclipse / ibm - SWT_JFace_2
.pdf
Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
Русский |
Войти (или Регистрация) |
|
|
Технические материалы |
Пробное ПО |
Сообщество |
Пакеты SWT и JFace, Часть 2: Небольшой обзор
Обзор меню, списков, комбо, таблиц и деревьев
Барри Фейгенбаум (Barry Feigenbaum), программист-консультант, IBM
Описание: Вторая часть серии статей о пакетах SWT и JFace раскрывает те знания, которые вы получили в процессе создания простых Standard Widget Toolkit (SWT) приложений с использованием технологий Java™, Eclipse, а также библиотек пакетов SWT и JFace. Этот инструментарий показывает, как использовать элементы комбо, списки, таблицы и деревья, а также менеждеры форм и повторно используемые вспомогательные методы.
Дата: 19.07.2005
Уровень сложности: простой Активность: 3349 просмотров
Комментарии: 0 (Посмотреть | Добавить комментарий - Войти)
Средний показатель рейтинга (14 голоса) Оценить эту статью
Пакет Standard Widget Toolkit (SWT) и библиотеки JFace используются программистами для разработки графических интерфейсов пользователя (GUIs) для среды Eclipse, а также для разработки отдельных приложений с графическим интерфейсом.
Впервой части данной серии я рассказал вам о пакете Eclipse, Eclipse SWT, а также об инструментарии JFace GUI для создания Eclipse приложений и отдельных графических интерфейсов. Я также провел обзор основных элементов управления, таких как: метки, элементы управления текстом и кнопки, а также композиты, группы и контейнеров типа shell. И наконец, я привел пример объединения этих элементов для работы в простом приложении.
Вэтом выпуске вы узнаете о том, как добавлять в ваши приложения элемент меню, использовать списки, а также использовать более продвинутые элементы контейнеров таблиц и деревьев. Я также продемонстрирую некоторые наиболее удачные примеры использования сервисных методов для легкого построения графических интерфейсов. И в конце я покажу как вызывать функцию повторного использования в базовом классе приложения.
Везде, но только где это не указано специально, все описываемые widgets и элементы находятся в пакете org.eclipse.swt.widgets.
Меню
Едва ли не все простые приложения с графическим интерфейсом нуждаются в меню. Меню привносят в любой графический интерфейс юзабилити. Они представляют собой динамические списки выбора, которые реализуют доступные функции (команды) или состояния интерфейса. Как и предполагается, вы будете создавать меню с помощью средства menu widget. Меню могут содержать другие меню или объекты menuItems, которые сами могут быть меню (иерархическая структура). Объекты MenuItems могут представлять собой исполняемые команды или же состояния по выбору. Меню могут быть связаны с панелью меню приложения (оболочкой), а также быть всплывающим меню. Необходимо определять каждое отдельное меню, как один из трех взаимно исключающих видов:
1.BAR – панель меню работает, как панель меню верхнего уровня для оболочки
2.DROP_DOWN – выпадающее меню, связанное с элементом меню верхнего уровня или объектом меню
3.POP_UP – окно, всплывающее из оболочки, но контекстно привязанное к некоторому элементу
Меню также поддерживают использование дополнительных параметров:
Стр. 1 из 14 |
29.06.2012 01:35 |
Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
NO_RADIO_GROUP – не действует как группа радио. Следует использовать его, когда меню содержит объекты
стиля RADIO
LEFT_TO_RIGHT или RIGHT_TO_LEFT – выбирает направление текста
Вы должны определить объекты меню menuItems, как один из пяти взаимоисключающих видов:
1.CHECK – может быть выбран в течении продолжительного времени (если поставлен флажок)
2.CASCADE – объект содержит меню, которое должно выпадать
3.PUSH – объект действует как кнопка, вызывая мгновенное действие
4.RADIO – действует как CHECK, но при этом может быть выбран только один объект данного типа
5.SEPARATOR – действует как разделитель (часто как полоса) между группами объектов. Этот объект не
имеет ассоциированого действия
Создание системы меню является достаточно сложной процедурой. В листинге 1 показан пример кода, реализующего работающую систему меню.
Листинг 1. Создание системы меню и всплывающего меню
import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.*;
:
Shell shell = ...;
:
Label body = ...;
:
// Создание системы меню
Menu main = createMenu(shell, SWT.BAR | SWT.LEFT_TO_RIGHT); shell.setMenuBar(main);
MenuItem fileMenuItem = createMenuItem(main, SWT.CASCADE, "&File", null, -1, true, null);
Menu fileMenu = createMenu(shell, SWT.DROP_DOWN, fileMenuItem, true); MenuItem exitMenuItem = createMenuItem(fileMenu, SWT.PUSH, "E&xit\tCtrl+X",
null, SWT.CTRL + 'X', true, "doExit");
MenuItem helpMenuItem = createMenuItem(main, SWT.CASCADE, "&Help", null, -1, true, null);
Menu helpMenu = createMenu(shell, SWT.DROP_DOWN, helpMenuItem, true); MenuItem aboutMenuItem = createMenuItem(helpMenu, SWT.PUSH, "&About\tCtrl+A",
null, SWT.CTRL + 'A', true, "doAbout");
// добавление всплывающего меню
Menu popup = createPopupMenu(shell, body);
MenuItem popupMenuItem1 = createMenuItem(popup, SWT.PUSH, "&About", null, -1, true, "doAbout");
MenuItem popupMenuItem2 = createMenuItem(popup, SWT.PUSH, "&Noop", null, -1, true, "doNothing");
Данный код создает следующую панель меню с объектами типа подменю и всплывающим меню (см. Рисунок1, Рисунок2, Рисунок3 и Рисунок4). Значение body представляет собой метку со строкой "Sample body". Всплывающее меню контекстно ассоциировано с этим элементом управления.
О данной серии статей
Эта серия статей, SWT и Jface, включает в себя основные статьи по разработке приложений с использованием Standard Widget Toolkit (SWT) и библиотек JFace, которые поставляются с базовым пакетом программного обеспечения Eclipse software development kit (SDK). В данной серии статей внимание уделяется использованию SWT и JFace для разработки отдельных приложений. Однако, большая часть примеров, которые вы изучите, может быть применима для Eclipse.
Мы начнем с простых графических приложений с ограниченными функциями и постепенно будем продвигаться в изучении действующих приложений. Мы покажем большую часть стандартных и кастомизируемых SWT widgets, а также множество особенностей JFace. В нашем обзоре для каждой технологии будет использоваться по крайней мере один пример.
Стр. 2 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
Данная серия статей подразумевает, что вы знакомы с языком и разработкой в среде Java, а также имеете
некоторое понимание о работе инструментария Java AWT или Swing GUI.
Рисунок 1. Панель меню с объектами меню File и Help
Рисунок 2. Выпадающее меню File
Рисунок 3. Выпадающее меню Help
Рисунок 4. Всплывающее меню
Как вы можете видеть, объекты меню могут иметь горячие клавиши (Ctrl+?) и мнемонику (подчеркнутые символы, идентифицируемые символом &), чтобы облегчить пользователю выбор объектов меню с помощью клавиатуры.
Я создал эти меню с помощью набора вспомогательных методов, показанных в листинге 2. Рекомендуется создавать такие методы для повторяющихся частей графического интерфейса, таких как меню. Со временем вы сможете добавлять к ним больше функций и применять их во всех своих приложениях. Эти методы также напоминают вам о требуемых параметрах.
Листинг 2. Создание меню с помощью вспомогательных средств
protected Menu createMenu(Menu parent, boolean enabled) { Menu m = new Menu(parent);
m.setEnabled(enabled); return m;
}
protected Menu createMenu(MenuItem parent, boolean enabled) { Menu m = new Menu(parent);
m.setEnabled(enabled); return m;
}
protected Menu createMenu(Shell parent, int style) { Menu m = new Menu(parent, style);
return m;
}
protected Menu createMenu(Shell parent, int style,
MenuItem container, boolean enabled) { Menu m = createMenu(parent, style);
m.setEnabled(enabled);
container.setMenu(m); return m;
}
protected Menu createPopupMenu(Shell shell) { Menu m = new Menu(shell, SWT.POP_UP); shell.setMenu(m);
return m;
}
Стр. 3 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
protected Menu createPopupMenu(Shell shell, Control owner) {
Menu m = createPopupMenu(shell); owner.setMenu(m);
return m;
}
protected MenuItem createMenuItem(Menu parent, int style, String text, Image icon, int accel, boolean enabled, String callback) {
MenuItem mi = new MenuItem(parent, style); if (text != null) {
mi.setText(text);
}
if (icon != null) { mi.setImage(icon);
}
if (accel != -1) { mi.setAccelerator(accel);
}
mi.setEnabled(enabled); if (callback != null) {
registerCallback(mi, this, callback);
}
return mi;
}
В листинге 3 показано, как использовать средство Java отображение для привязки кода обработчика к объектам меню. Данное средство позволяет просто добавлять методы с модификаторами доступа public (например, doExit, doAbout и или doNothing) в класс вашего приложения для обработки команды.
Листинг 3. Вызываемые процедуры Callback для обработки команды меню
protected void registerCallback(final MenuItem mi, final Object handler,
final String handlerName) { mi.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) { try {
Method m = handler.getClass(). getMethod(handlerName, null);
m.invoke(handler, null);
}
catch (Exception ex) { ex.printStackTrace();
}
}
});
}
Я описал особенности использования метода SelectionListener в части 1 данной серии статей.
Пожалуйста, имейте ввиду, что объекты меню (а также объекты в списке, комбо-боксе, таблице и элементы дерева, показанные ниже) поддерживают только строковые значения. Другие типы перед добавлением должны быть преобразованы в строку.
Комбо и списки
Часто вы хотели бы давать пользователю вашего графического интерфейса возможность выбирать параметры из списка. Элемент Список – самый простой способ этого добиться. Список показывает предопределенный набор строковых значений, из которых может выбирать пользователь. Списки обычно требуют большое пространство экрана. Если вам необходимо сэкономить пространство, вы можете использовать элемент combo, который позволяет при необходимости развернуть список. Комбо также опционально разрешают пользователю вводить желаемые значения в текстовое поле.
Вы должны определить комбо как один из двух взаимоисключающих стилей:
1. SIMPLE – показывает список значений
Стр. 4 из 14 |
29.06.2012 01:35 |
Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
2. DROP_DOWN – реализует выпадающий список значений
Комбо также поддерживают использование дополнительного параметра:
READ_ONLY – запрещает пользователю редактировать в комбо текстовое поле
Все обсуждаемые мной элементы (списки, комбо, таблицы и деревья) поддерживают использование одного из двух взаимоисключающих стилей:
1.SINGLE – пользователи могут выбрать только один объект
2.MULTI users - пользователи могут выбрать сразу несколько объектов
Эти элементы также поддерживают использование дополнительных параметров:
H_SCROLL
V_SCROLL
-реализует горизонтальную полосу прокрутки при необходимости
-реализует вертикальную полосу прокрутки при необходимости
Создание комбо и списка является достаточно легким занятием. Создайте элементы управления и добавьте требуемые строковые значения, как показано в листинге 4.
Листинг 4. Создание комбо и списка с использованием FormLayout
import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; import org.eclipse.swt.events.*; import org.eclipse.swt.layout.*;
:
setLayout(new FormLayout());
String[] data = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10" };
Combo c = createCombo(this, data); configureLayout(c, new FormAttachment(0, 5), new FormAttachment(0, 5),
new FormAttachment(100, -5), null);
List l = createList(this, data); configureLayout(l, new FormAttachment(0, 5), new FormAttachment(c, 5),
new FormAttachment(100, -5), new FormAttachment(100, -5));
// Создание комбо
protected Combo createCombo( Composite parent, String[] data) {
Combo combo = new Combo(parent,
SWT.DROP_DOWN | SWT.MULTI |
SWT.V_SCROLL | SWT.H_SCROLL); combo.addSelectionListener(new SelectionListener() {
:
});
setComboContents(data);
return combo;
}
// Создание списка
protected List createList(Composite parent, String[] data) { List list = new List(parent, SWT.MULTI |
SWT.V_SCROLL | SWT.H_SCROLL); list.addSelectionListener(new SelectionListener() {
:
});
setListContents(data);
return list;
}
public void setComboContents(String[] data) { combo.removeAll();
for (int i = 0; i < data.length; i++) { combo.add(data[i]);
Стр. 5 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
}
}
public void setListContents(String[] data) { list.removeAll();
for (int i = 0; i < data.length; i++) { list.add(data[i]);
}
}
Если вы добавите метод SelectionListener, он дает возможность приложению предпринимать определенное действие в ответ на изменение пользователем выбранных объектов.
Основное тело кода в листинге 4 предполагает, что оно включено в некоторый композит с указателем this. Он создает комбо и список (частично закрытый), показанные на рисунке 5.
Рисунок 5. Пример комбо и списка
Вы можете использовать и другую реализацию элемента комбо, называемую CCombo (из пакета org.eclipse.swt.custom). CCombo схож с Combo, за исключением того, что он поддерживает некоторые дополнительные функции, самой важной особенностью которых является то, что вы можете программным образом указать Ccombo вырезать, копировать или вставить текст в или из включенной в него метки. CCombo также всегда имеет стиль DROP_DOWN и потому не поддерживает другие.
Элементы CCombo также поддерживают использование дополнительных параметров:
BORDER – отрисовывает границы вокруг текстовой области
READ_ONLY – запрещает пользователям редактировать в этом комбо текстовое поле
Менеджер FormLayout
Пример в Листинге 4 использует менеджер FormLayout для позиционирования комбо и списка. FormLayout – один из самых полезных менеджеров компоновки, так как он позволяет вам автоматически размещать каждый элемент относительно других элементов. Он позволяет присоединять любые стороны элемента (левую, верхнюю, праву или низ) к (обычно противоположным) сторонам другого элемента или стороне контейнера. Невыровненные стороны принимают обычные размеры элемента. Используйте экземпляр класса FormAttachment для точного определения размера элемента управления или его процентного соотношения относительно размера контейнера, а также для указания размера пробела в пикселях экрана от этой точки. Код в Листинге 4 использует вспомогательный метод из листинга 5.
Листинг 5. configureLayout: вспомогательный метод FormLayout
protected static void configureLayout(Control c, FormAttachment left, FormAttachment top, FormAttachment right, FormAttachment bottom) {
FormData fd = new FormData(); if (left != null) {
fd.left = left;
}
if (top != null) { fd.top = top;
}
Стр. 6 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
if (right != null) { fd.right = right;
}
if (bottom != null) { fd.bottom = bottom;
}
c.setLayoutData(fd);
}
Таблицы
Таблицы – это расширенная форма списков, поддерживающих TableColumns. Эти столбы располагают данные в более читаемом формате. Они также включают поддержку имен столбцов и возможность изменять размер столбцов. Для создания таблиц, сначала создайте элемент таблица, добавьте в него столбцы, а затем добавьте строковые данные, завернутые в объекты TableItems.
Таблицы поддерживают опциональные стили:
CHECK - добавляет флажки в первый столбец
VIRTUAL - поддерживает крупные таблицы (является платформенно-зависимым)
FULL_SELECTION – выбирает все столбцы (не только первый)
В листинге 6 создается таблица, показанная на рисунке 6.
Листинг 6. Создание таблицы с использованием вспомогательных методов
// Создает таблицу и TableColumns
protected Table createTable(Composite parent, int mode, Object[] contents) { table = new Table(parent, mode | SWT.SINGLE | SWT.FULL_SELECTION |
SWT.V_SCROLL | SWT.H_SCROLL); table.setHeaderVisible(true); table.setLinesVisible(true);
createTableColumn(table, SWT.LEFT, |
"Column 1", 100); |
|
createTableColumn(table, SWT.CENTER, "Column 2", |
100); |
|
createTableColumn(table, SWT.RIGHT, |
"Column 3", |
100); |
addTableContents(contents); return table;
}
protected TableColumn createTableColumn
(Table table, int style, String title, int width) { TableColumn tc = new TableColumn(table, style); tc.setText(title);
tc.setResizable(true);
tc.setWidth(width); return tc;
}
protected void addTableContents(Object[] items) { for (int i = 0; i < items.length; i++) { String[] item = (String[])items[i];
TableItem ti = new TableItem(table, SWT.NONE); ti.setText(item);
}
}
:
// примера использования protected void initGui() {
Object[] items = |
{ |
new String[] |
{"A", "a", "0"}, new String[] {"B", "b", "1"}, |
new String[] |
{"C", "c", "2"}, new String[] {"D", "d", "3"}, |
new String[] |
{"E", "e", "4"}, new String[] {"F", "f", "5"}, |
new String[] |
{"G", "g", "6"}, new String[] {"H", "h", "7"}, |
new String[] |
{"I", "i", "8"}, new String[] {"J", "j", "9"} |
}; |
|
table = createTable(this, SWT.CHECK, items);
}
Стр. 7 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
Рисунок 6. Пример таблицы
Флажки в первой колонке являются необязательными. Обратите внимание на расположение столбцов.
Деревья
Дерево – это список, который может показывать данные, расположенные в иерархическом порядке. Деревья поддерживают возможность вашего приложения раскрывать и схлопывать промежуточные уровни иерархии.
Так как деревья часто изображают иерархические структуры, вам необходимо предоставить модель данных (я еще раз вернусь к упоминанию этой модели, когда буду говорить о JFace). Для этих целей в моем примере я использую внутренний класс Node, показанный в листинге 7.
Листинг 7. Класс Node модели дерева
public class Node {
protected java.util.List children; public java.util.List getChildren() {
return children;
}
public void setChildren(java.util.List children) { this.children = children;
}
public void addChild(Node node) { children.add(node);
}
protected String name; public String getName() {
return name;
}
public void setName(String name) { this.name = name;
}
public Node(String name) { this(name, new ArrayList());
}
public Node(String name, java.util.List children) { setName(name);
setChildren(children);
}
}
Для создания деревьев сначала инициализируйте элемент дерева, затем добавьте строковые данные, завернутые в объекты TreeItems. TreeItems могут содержать другие объекты TreeItems, создавая тем самым иерархию значений. В листинге 8 создается дерево, показанное на рисунке 7.
Листинг 8. Создание дерева с использованием вспомогательных методов
// Создание дерева
protected Tree createTree(Composite parent, int mode, Node root) { tree = new Tree(parent, mode
Стр. 8 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
|SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); tree.addSelectionListener(new SelectionListener() {
:
});
setTreeContents(root);
return tree;
}
protected void setTreeContents(Node root) { tree.removeAll();
TreeItem ti = new TreeItem(tree, SWT.NONE); setTreeItemContents(ti, root);
}
protected void setTreeItemContents(TreeItem ti, Node root) { ti.setText(root.getName());
java.util.List children = root.getChildren(); if (children != null && children.size() > 0) {
for (Iterator i = children.iterator(); i.hasNext();) { Node n = (Node)i.next();
TreeItem tix = new TreeItem(ti, SWT.NONE); setTreeItemContents(tix, n);
}
}
}
:
// пример использования
protected void addChildren(Node n, int count, int depth, String prefix) { if (depth > 0) {
for (int i = 0; i < count; i++) { String name = prefix + '.' + i; Node child = new Node(name); n.addChild(child);
addChildren(child, count, depth - 1, name);
}
}
}
Node root = new Node("<root>"); addChildren(root, 3, 3, "Child");
tree = createTree(this, SWT.CHECK, root);
Рисунок 7. Пример дерева
Флажки являются необязательными.
Создание основной программы
За исключением примера создания меню все примеры в этом материале используют основной класс, называемый BasicApplication, использующийся для облегчения их реализации. В качестве другого отличного примера, я разложил общие особенности приложения SWT GUI в этом базовом классе (включая вспомогательные методы из примера создания меню), чтобы сделать их легко доступными.
Класс BasicApplication является композитным, создающим свою оболочку. Этот класс предоставляет дополнительные сервисы такие как, диалоговое окно, подтверждающее выход из приложения (см. Рисунок 8), а также возможность выгружать дерево widget, как помощник в диагностике (смотрите урезанный пример из листинга 9). Смотрите раздел Ресурсы для просмотра кода этого класса.
Стр. 9 из 14 |
29.06.2012 01:35 |

Пакеты SWT и JFace, Часть 2: Небольшой обзор |
http://www.ibm.com/developerworks/ru/library/os-jface2... |
Рисунок 8. Диалогове окно, показывающее сообщение подтверждения
Листинг 9. .Вывод (частичный) иерархии элемента
Shell {Tree1App Example}
Tree1App {}
Tree {}
TreeItem {<root>}
TreeItem {Child.0}
TreeItem {Child.0.0}
TreeItem {Child.0.0.0}
TreeItem {Child.0.0.1}
TreeItem {Child.0.0.2}
TreeItem {Child.0.1}
TreeItem {Child.0.1.0}
TreeItem {Child.0.1.1}
TreeItem {Child.0.1.2}
TreeItem {Child.0.2}
TreeItem {Child.0.2.0}
TreeItem {Child.0.2.1}
TreeItem {Child.0.2.2}
TreeItem {Child.1}
:
TreeItem {Child.2}
:
В листинге 10 показан метод main каждого внутреннего класса (из примера создания комбо и списка в Листинге 4), а также предоставлено название и размер оболочки, стиль композита приложения и любые другие данные, принимаемые на вход с командной строки.
Листинг 10. Метод main() для примера приложения
public static void main(String[] args) {
run(List1App.class.getName(), "List1App Example", SWT.NONE, 400, 300, args);
}
Каждый внутренний класс, загружаемый через технологию Java-отображения, должен описать конструктор и метод completeGui. Внутренние классы могут опционально предоставить метод initGui. В листинге 11 показаны методы, которые применяются в примере из листинга 4, где представлено использование комбо и списка.
Листинг 11. Необходимые методы, поставляемые с внутренним классом приложения
public List1App(Shell shell, int style) {
super(shell, style); // must always supply parent and style
}
// Allow subclasses to complete the GUI protected void completeGui(String[] args) {
// create GUI here
:
Стр. 10 из 14 |
29.06.2012 01:35 |