- •Обозначения и сокращения
- •Введение
- •1 Простое SWT приложение
- •1.1 Создание приложения
- •1.2 Запуск SWT программы из командной строки
- •1.3 Структура приложения
- •1.4 Слушатели событий
- •1.5 Работа с подпроцессами
- •1.5.1 Диспетчеризация внутренних событий
- •1.5.2 Нить пользовательского интерфейса SWT
- •1.5.3 Выполнение кода за пределами нити UI
- •1.5.4 Рабочая среда и нити
- •2 Элементы управления
- •2.1 Стандартные виджеты
- •2.2 Пользовательские виджеты
- •2.3 Класс Label
- •2.3.1 Стили
- •2.3.2 Текст
- •2.3.3 Изображение
- •2.3.4 Разделители
- •2.3.5 Выравнивание
- •2.3.6 Перенос слов текста
- •2.3.7 Пример использования этикеток
- •2.4 Класс Text
- •2.5 Класс Button
- •2.5.1 Стили
- •2.5.2 Текст
- •2.5.3 Изображение
- •2.5.4 Выравнивание
- •2.5.5 Push Button
- •2.5.6 Toggle Button
- •2.5.7 Check Box
- •2.5.8 Radio Button
- •2.5.9 Selection (выбор)
- •2.5.10 Указание используемой по умолчанию кнопки
- •2.6 Класс List
- •2.6.1 Стили
- •2.6.2. Добавление элементов в список
- •2.6.3. Удаление элементов из списка
- •2.6.4 Получение элементов списка
- •2.6.5 Настройка значений элементов
- •2.6.6 Поиск элементов
- •2.6.7 Выбор элементов списка
- •2.6.8 Обработка событий списка List
- •2.7 Класс Link
- •2.7.1 Стили
- •2.7.2. Текст
- •2.7.3. Обработчики событий
- •2.8 Класс Table
- •2.9 Класс TableColumn
- •2.10 Класс TableItem
- •2.11 Класс Item
- •2.12 Класс Combo
- •2.13 Класс FileDialog
- •2.14 Класс Menu
- •2.15 Класс MenuItem
- •2.16 Класс MessageBox
- •2.17 Класс TabFolder
- •2.18 Class TabItem
- •3 Макеты
- •3.1 Класс FillLayout
- •3.2 Класс GridLayout
- •3.3 Класс GridData
- •3.4 Класс RowLayout
- •3.5 Класс RowData
- •3.6 Класс FormLayout
- •3.7 Класс FormAttachment
- •3.8 Класс FormData
- •4 Графика
- •4.1 Класс GC
- •4.2 Класс Canvas
- •5 Пакет printing
- •5.1 Класс PrintDialog
- •5.2 Класс Printer
- •5.3 Класс PrinterData
- •6 Пакет events
- •6.1 Класс Event
- •7 Разработка приложений
- •8 Разработка новых компонент
- •9 Дополнительные возможности библиотеки SWG
- •9.1 Компоненты управления
- •9.2 Виджеты
- •9.3 Плоские формы
- •9.4 Линии, точки и ломанные
- •9.5 Класс PathShape
- •10 Анимация
- •10.1 Типы анимации
- •10.2 Анимация во времени
- •10. 3 Поддержка времени
- •10.4 Пример приложения с элементами анимации
- •Список использованных источников
8 Разработка новых компонент
При разработке нестандартных приложений могут потребоваться новые компоненты, не входящие в набор библиотеки SWT. Для этого в языке Java и библиотеке SWT имеются инструменты разработки новых компонент [5]. Различают простые и составные компоненты. Простыми являются этикетки, редакторы, картинки и другие компоненты, не содержащие в себе включений . Простые компоненты расширяют класс Canvas. Составные компоненты расширяют класс композитов Composite и содержат в себе другие элементы.
Пусть нам необходимо разработать компонент для работы с календарем, позволяющим задавать год, месяц и день выбором из соответствующих элементов управления (рисунок 8.1).
Рисунок 8.1 – Внешний вид компонента для работы с календарем
Для разработки компонента создается новый класс – потомок класса Composite. В нем формируются необходимы группы, наполненные подходящими элементами. Для формирования события при выборе даты (можно реагировать на изменение года и месяца) необходимо описать класс ChangedEvent потомок класса EventObject для создания экземпляров события изменения даты (имя класса может быть выбрано по усмотрению программиста). Конструктор класса имеет один параметр source типа Object.
package calendar;
import java.util.EventObject;
public class ChangedEvent extends EventObject { public ChangedEvent(Object source) {
super(source);
}
}
151
Для обработчиков (слушателей) этого события необходимо описать интерфейс ChangedListener (имя интерфейса может быть выбрано по усмотрению программиста), который они должны реализовывать. Это имя будет использовано при их создании.
package calendar;
public interface ChangedListener extends java.util.EventListener { public void Changed(ChangedEvent event);
}
Код программы для создания и тестирования нового компонента с комментариями приведен ниже.
package calendar;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.custom.*; import org.eclipse.swt.events.*; import java.util.*;
Объявление класса MonthCalendar – потомка класса Composite с полями экземпляра curYear, curMonth, curDay для доступа к выбранной дате из приложения.
public class MonthCalendar extends Composite {
public int curYear = -1, curMonth = -1, curDay = -1;//
Досупные поля объекта |
|
|
|
|
private Spinner year; |
// Компонент Год |
|||
private Combo |
month; |
// |
Компонент |
Месяц |
private Table |
table; |
// |
Компонент |
Таблица |
Объект ChangedListeners предназначен для хранения ссылок на подключенные к календарю в приложении слушатели события, связанного с выбором даты пользователем.
private Vector ChangedListeners = new Vector();
Методы addChangedListener и removeChangedListener необходимы для обслуживания набора слушателей нового компонента.
public void addChangedListener(ChangedListener listener) {
ChangedListeners.addElement(listener);
}
public void removeChangedListener(ChangedListener listener) {
ChangedListeners.removeElement(listener);
}
Метод doChange оповещает всех слушателей о событии выбора даты.
152
public void doChange(Event event) {
ChangedEvent e = new ChangedEvent(this); int size = ChangedListeners.size();
for (int i = 0; i < size; i++) { ChangedListener listener =
(ChangedListener) ChangedListeners.elementAt(i); listener.Changed(e);
}
}
Метод drawTable производит перерисовку таблицы календаря на заданный месяц.
private void drawTable(){ |
// Рисовать Таблицу |
table.clearAll(); |
// Очистить Таблицу |
GregorianCalendar now = new GregorianCalendar(); //
Преобразователь даты
now.set(curYear, curMonth-1, 1); // Установка даты
int cntDays = now.getActualMaximum(Calendar.DAY_OF_MONTH);
//Дней в месяце
int firstDay = (now.get(Calendar.DAY_OF_WEEK) + 6) % 7;
//День недели на 1 число
if (firstDay == 0){ firstDay = 7; }; // С учетом
понедельника
String[ ][ ] days = new String[6][7]; // Массив клеток для таблицы
for (int i = 0; i<6; i++){ // Заполнили пустыми
клетками
for (int j = 0; j<7; j++){ days[i][j] = "";
}
};
int curWeek = 0; // Расчет дат в клетках таблицы for (int i = 0; i<cntDays; i++){ // По дням таблицы
int nDay = i + firstDay - 1 - curWeek * 7;
days[curWeek][nDay] = "" + (i+1); |
// Поместили номер |
дня в клетку массива |
|
if (nDay == 6){ curWeek++; }; |
|
}; |
|
for (int i = 0; i<6; i++){ // Перепись в таблицу |
|
TableItem item = table.getItems()[i]; // Неделя |
|
for (int j = 0; j<7; j++){ |
// Дни недели |
item.setText (j, days[i][j]); |
|
}; |
|
}; |
|
for (int i=0; i<7; i++) { // Установка ширины столбцов
таблицы
table.getColumn (i).setWidth(27);
153
}
};
Конструктор класса MonthCalendar
public MonthCalendar(Composite parent, int style) {
super(parent, style);
this.setLayout(new GridLayout(1,true)); // Макет объекта
Group gr0 = new Group(this, SWT.SHADOW_OUT); |
// Группа |
для календаря |
|
gr0.setText("Месячный календарь"); |
|
gr0.setLayout(new GridLayout(1, true)); |
|
Group gr1 = new Group(gr0, SWT.SHADOW_OUT); |
// Группа |
для года и месяца |
|
GridLayout layGr1 = new GridLayout(2,true); |
|
layGr1.marginWidth = 25; |
|
gr1.setLayout(layGr1);
GregorianCalendar now = new GregorianCalendar();
// Преобразователь дат |
|
|
|
curYear |
= now.get(Calendar.YEAR); // Текущий год числом |
||
curMonth = now.get(Calendar.MONTH)+1; // Текущий месяц |
|||
числом 1, ..., 12 |
|
|
|
curDay |
= now.get(Calendar.DAY_OF_MONTH); |
// Текущий день |
|
месяца |
|
|
|
Label yLabel = new Label(gr1, SWT.LEFT); |
// Надписи |
||
yLabel.setText("Год"); |
|
|
|
Label yMonth = new Label(gr1, SWT.LEFT); |
|
||
yMonth.setText("Месяц"); |
|
||
year = new Spinner (gr1, SWT.BORDER); // Ввод года |
|||
year.setMinimum(1900); |
|
|
|
year.setMaximum(2100); |
|
|
|
year.setSelection(curYear); // Год из таймера |
|||
year.setIncrement(1); |
|
|
|
year.setPageIncrement(10); |
|
||
this.year.addListener (SWT.Selection, new Listener () { |
|||
public void handleEvent (Event e) { |
|
||
curYear = year.getSelection(); |
// Год выбрал |
||
пользователь |
|
|
|
drawTable(); |
// Перерисовать таблицу |
//MonthCalendar.this.doChange(e); // Возбудить
событие о выборе года
}
});
month = new Combo (gr1, SWT.NONE); // Ввод месяца month.setItems (new String [ ] {"Январь", "Февраль",
"Март", "Апрель", "Май", "Июнь",
"Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь",
"Декабрь"});
154
this.month.addListener (SWT.Selection, new Listener () { public void handleEvent (Event e) {
curMonth = month.indexOf(month.getText()) + 1; //
Месяц выбрал пользователь |
|
|
|
|
drawTable(); |
// Перерисовать таблицу |
|
||
//MonthCalendar.this.doChange(e); // Возбудить |
||||
событие о выборе месяца |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
month.setText(month.getItem(curMonth-1)); |
// Установить |
|||
месяц из таймера |
|
|
|
|
//month.setSize(150,30); |
|
|
|
|
table = new Table (gr0, SWT.HIDE_SELECTION |
); |
// Место |
||
для таблицы на месяц |
|
|
|
|
table.setLinesVisible (true); |
|
|
|
|
table.setHeaderVisible (true); |
|
|
|
|
String[ ] titles = {"Пн", "Вт", "Ср", "Чт", "Пт", "Сб", |
||||
"Вс"}; |
|
|
|
|
for (int i=0; i<titles.length; i++) { |
// Колонки |
|||
TableColumn column = new TableColumn (table, SWT.CENTER |
||||
| SWT.SINGLE ); |
|
|
|
|
column.setText (titles [i]); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i<6; i++){ |
// Строки |
|
||
new TableItem (table, SWT.NONE); |
|
|
|
|
}; |
|
|
|
|
final TableCursor cursor = new TableCursor(table,
SWT.NONE); // Обработка выбора даты cursor.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) { try {
curDay =
Integer.parseInt(cursor.getRow().getText(cursor.getColumn())); //System.out.println(curDay); MonthCalendar.this.doChange(new Event());
// Возбудить событие о выборе дня месяца
} |
|
|
catch (RuntimeException e1) { |
// Если выбрана |
|
пустая клетка |
|
|
curDay = -1; |
|
|
System.out.println("Ошибка выбора даты"); |
||
}; |
|
|
} |
|
|
}); |
|
|
drawTable(); |
// Заполнить таблицу на месяц |
|
} |
|
|
public static void main(String[ ] args) { // Главная
155
программа
Display display = new Display();
Shell shell = new Shell(display); shell.setText("Пример разработки компонента"); shell.setLayout(new FillLayout());
final MonthCalendar cal = new MonthCalendar(shell,
SWT.NONE); // Объект календарь
final Button ok = new Button (shell, SWT.PUSH);
//Кнопка тестер
ok.setText ("Тест каледаря --> Жми сюда!"); ok.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ok.setText ("Выбрано " + cal.curDay + "." + cal.curMonth + "." + cal.curYear);
}
});
// Слушатель событий об изменении даты пользователем с
интерфейсом ChangedListener cal.addChangedListener(new ChangedListener() {
public void Changed(ChangedEvent event) { System.out.println("Произошло изменение даты");
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
На рисунке 8.2 показана схема связей объектов и функций создаваемого компонента MonthCalendar.
156
public class ChangedEvent extends EventObject { public ChangedEvent(Object source) {
super(source); }}
ChangedListeners
listener_1 addChangedListener(listener_1) listener_2 removeChangedListener(listener_2)
public void doChange(Event event) { |
|
ChangedEvent e = new ChangedEvent(this); |
|
int size = ChangedListeners.size(); |
|
for (int i = 0; i < size; i++) { |
|
ChangedListener listener = |
|
(ChangedListener) ChangedListeners.elementAt(i); |
|
listener.Changed(e); |
} } |
Форма |
Обработчик события выбора |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
|
|
|
|
.
.
doChange(…)
.
.
Рисунок 8.2 – Схема связей компонента
157