Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2013_1 / ООП / Введение_SWG.pdf
Скачиваний:
82
Добавлен:
23.02.2015
Размер:
3.32 Mб
Скачать

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

Соседние файлы в папке ООП