410013796724260
• Webmoney
R335386147728
Z369087728698
Статусная строка StatusbarManagerОдним из важнейших элементов пользовательского интерфейса является статусная строка Statusbar, в которой, как правило, отображается дополнительная информация. К сожалению, библиотека SWT не содержит готового визуального компонента (по крайней мере, мне не удалость найти его). В данной статье рассматривается разработка собственного менеджера статусной строки StatusbarManager, который должен реализовывать следующие функции:
Структурно статусная строка может состоять из нескольких разделов Composite, в которых размещаются компоненты типа метки Label и выпадающие списки Combo. Менеджер статусной строки StatusbarManager позволяет установить в один или несколько разделов компоненты Control, созданные отдельно, т.е. не StatusbarManager'ом. Для каждого раздела можно установить определенный размер. Первый раздел (отсчет от 1) занимает все свободное пространство. StatusbarManager включает пустой метод onResize, который можно переписать, чтобы изменить порядок автоматической подстройки не только первого, но и других разделов. Ниже представлено полное описание менеджера статусной строки StatusbarManager, включающее поля, методы. Завершается описание примером использования StatusbarManager. Конструкторы StatusbarManager/** * Конструктор * @param parent родительский компонент размещения статусной строки */ public StatusbarManager(Composite parent) { super(parent, SWT.NONE); // Определение менеджера расположения setLayout(new FormLayout()); // Определение цвета фона setBackground(new Color(getDisplay(), 240, 240, 240)); // Определение шрифта font = new Font(parent.getDisplay(), new FontData(FONT_Lucida, 10, SWT.NORMAL)); } //------------------------------------------------------------------ /** * Конструктор * @param parent родительский компонент размещения статусной строки * @param background цвет фона */ public StatusbarManager(Composite parent, final Color background) { this(parent); setBackground(background); } В основном конструкторе (верхний) устанавливаются значения по умолчанию. В качестве входных параметров он принимает родительский компонент размещения parent. Можно использовать второй конструктор, которому дополнительно нужно передать цвет фона. Параметры настройки StatusbarManagerВ следующем листинге представлены параметры (поля класса), используемые менеджером статусной строки StatusbarManager по умолчанию. // Высота статусной строки private int STATUSBAR_HEIGTH = 27; // Параметры позиционирования компонентов private int OFFSET_TOP = 2; private int OFFSET_LEFT = 5; private int OFFSET_RIGHT = -5; private int OFFSET_BOTTOM = -2; // Шрифт по умолчанию private final String FONT_Lucida = "Lucida"; private Font font = null ; // Константы выравнивания private final String CENTER = "CENTER"; private final String RIGHT = "RIGHT" ; private final String RESIZE = "-1" ; // Слушатель изменения размера статусной строки private Listener ResizeListener = null; Общие параметры по умолчанию включают высоту статусной строки, отступ компонентов от границ разделов, шрифт текстовых меток. Кроме этого, по умолчанию в конструкторе определяется фоновый цвет компонентов. Все параметры, используемые по умолчанию, закрыты (private), но их можно изменить. Методы определения высоты StatusbarManager// Функция получения значения высота статусной строки public int getHeight() { return STATUSBAR_HEIGTH; } //------------------------------------------------------------------ // Процедура определения высоты статусной строки public void setHeight(final int height) { STATUSBAR_HEIGTH = height; } Методы определения шрифтаМетоды определения шрифта позволяют установить шрифт как для всех компонентов, так и для отдельного компонента, определенного идентификатором раздела. /** * Процедура определения шрифта компонентов * @param font шрифт */ public void setFont(final Font font) { Control[] ctrls = getChildren(); for (int i = 0; i < ctrls.length; i++) setFont(i, font); } //------------------------------------------------------------------ /** * Процедура определения шрифта компонента * @param idx идентификатор раздела * @param font шрифт */ public void setFont(final int idx, final Font font) { Control control = getControl(idx); if (control != null){ if (control instanceof Label) ((Label)control).setFont(font); else if (control instanceof CLabel) ((CLabel)control).setFont(font); else if (control instanceof Combo) ((Combo)control).setFont(font); } } Методы определения цвета текстаЦвет можно установить только для компонентов типа меток Label/CLabel и для выпадающих списков Combo. /** * Процедура определения цвета текста компонента * @param idx идентификатор раздела * @param color цвет текста */ public void setForeground(final int idx, final Color color) { Control control = getControl(idx); if (control != null){ if (control instanceof Label) ((Label)control).setForeground(color); else if (control instanceof CLabel) ((CLabel)control).setForeground(color); else if (control instanceof Combo) ((Combo)control).setForeground(color); } } Метод определения цвета фонаЦвет фона устанавливатеся как для раздела, так и для компонента раздела. public void setBackgroundColor(final Color color) { setBackground(color); for (Control control : getChildren()) { control.setBackground(getBackground()); for (Control ctrl : ((Composite)control).getChildren()) { ctrl.setBackground(getBackground()); } } } Методы извлечения раздела и компонента менеджера StatusbarManagerСледующие два метода позволяют получить раздел Composite статусной строки и компонент Control раздела. /** * Функция получения панели по идентификатору раздела * @param idx идентификатор раздела * @return панель */ private Composite getComposite(final int idx) { // Реальный идентификатор раздела int index = getChildren().length - 1 - idx; if (getChildren().length > 0) return (Composite) getChildren()[index]; else return null; } //------------------------------------------------------------------ /** * Функция получения компонента статусной строки по идентификатору * @param idx идентификатор раздела статусной строки * @return Control компонент */ public Control getControl(final int idx) { Composite panel = getComposite(idx); Control[] controls = panel.getChildren(); if ((controls != null) && (controls.length > 0)) return controls[controls.length - 1]; else return null; } Методы позиционирования компонентов StatusbarManagerМетоды позиционирования компонентов статусной строки позволяют определить отступы по горизонтали и вертикали как для всех компонентов (setOffsetHorizontal, setOffsetVertical), так и индивидуально для отдельных компонентов (перегруженный метод setOffset). /** * Процедура позиционирования компонентов по вертикали */ public void setOffsetVertical(final int top, final int bottom) { OFFSET_TOP = top; OFFSET_BOTTOM = -bottom; } //------------------------------------------------------------------ /** * Процедура позиционирования компонентов по горизонтали */ public void setOffsetHorizontal(final int left, final int right) { OFFSET_LEFT = left; OFFSET_RIGHT = -right; } //------------------------------------------------------------------ /** * Процедура позиционирования компонента * @param idx идентификатор раздела */ public void setOffset(final int idx, final int left, final int top, final int right) { Control control = this.getControl(idx); if (control == null) return; FormData fd_src = (FormData) control.getLayoutData(); FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, left ); fd.top = new FormAttachment( 0, top ); fd.right = new FormAttachment(100, -right); fd.bottom = fd_src.bottom; control.setLayoutData(fd); } //------------------------------------------------------------------ /** * Процедура позиционирования компонента * @param idx идентификатор раздела */ public void setOffset(final int idx, final int left, final int top, final int right, final int bottom) { Control control = this.getControl(idx); if (control == null) return; FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, left ); fd.top = new FormAttachment( 0, top ); fd.right = new FormAttachment(100,-right ); fd.bottom = new FormAttachment(100,-bottom); control.setLayoutData(fd); } Процедура формирования статусной строкиПроцедура формирования статусной строки setItems в качестве параметра принимает двухмерный массив items с описанием разделов. Формат описания включает три текстовых параметра:
Пример описания статусной строки:String[][] STATUSBAR = {{"left" , "-1", "label"}, {"right", "80", "label"}, {"" , "60", "combo"}, {"" , "90", "null"}}; В примере описания статусной строки должно быть 4 раздела. В первом, втором и третьем разделах компоненты определены, в четвертом разделе компонент не определен. Для меток в первом и втором разделах установлены выравнивания по левому и правому краю соответственно. Для всех компонентов кроме первого определены размеры разделов. Листинги методов setItems, createLabel, createComboВ методе setItems в цикле создаются разделы, начиная с последнего в обратном порядке, с привязкой правой стороной к предыдущему компоненту. Если определен компонент, то в зависимости от типа вызваются метод createLabel или createCombo. /** * Процедура формирования статусной строки. * Структура статусной строки включает набор панелей, на которых * размещаются компоненты * @param items */ public void setItems(final String[][] items) { if ((items == null) || (items.length < 1)) return; for (int i = items.length - 1; i >= 0; i--) { Composite last = null; if (i != items.length - 1) last = (Composite) getChildren()[getChildren().length - 1]; int width = 50; if (!items[i][1].equals(RESIZE)) { width = Integer.valueOf(items[i][1]); if (width < 10) width = 10; } FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.top = new FormAttachment( 0,0); fd.bottom = new FormAttachment(100,0); if (i == items.length - 1) { fd.width = width; fd.right = new FormAttachment(100, 0); if (items.length == 1) fd.left = new FormAttachment(0, 0); } else if (i != 0) { fd.width = width; fd.right = new FormAttachment(last, 1); } else { // 1-раздел занимает оставшееся пространство fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(last, 1); } Composite panel = new Composite(this, SWT.BORDER); panel.setBackground(this.getBackground()); panel.setLayoutData(fd); panel.setLayout(new FormLayout()); if (items[i][2].equalsIgnoreCase( Label.class.getSimpleName())) createLabel(panel, items[i]); else if (items[i][2].equalsIgnoreCase( Combo.class.getSimpleName())) createCombo(panel); } } //------------------------------------------------------------------ /** * Функция создания метки статусной строки * @param panel панель размещения * @param items описание метки */ private void createLabel(Composite panel, final String[] items) { int alignment = SWT.LEFT; if (items[0].equalsIgnoreCase(CENTER)) alignment = SWT.CENTER; else if (items[0].equalsIgnoreCase(RIGHT)) alignment = SWT.RIGHT; Label label = new Label(panel, SWT.NONE); label.setFont(font); label.setLayoutData(createFormData()); label.setAlignment(alignment); label.setBackground(this.getBackground()); } //------------------------------------------------------------------ /** * Функция создания выпадающего списка * @param panel панель размещения */ private void createCombo(Composite panel) { FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, 0); fd.top = new FormAttachment( 0, 0); fd.right = new FormAttachment(100, 0); Combo combo = new Combo(panel, SWT.READ_ONLY | SWT.DROP_DOWN); combo.setLayoutData(fd); } Размещение компонента в статусной строкеПри формировании разделов статусной строки в методе setItems менеджер сразу же размещает в них компоненты типа метка Label или выпадающий список Combo, если они определены в описании. Метод setControl позволяет в определенном разделе idx разместить готовый компонент Control. Если в разделе был уже размещен компонент, то он будет скрыт методом setVisible. /** * Процедура установки в статусную строку компонента * @param idx идентификатор раздела статусной строки * @param control компонент * @param position флаг определения параметров позиционирования */ public void setControl(final int idx, Control control, boolean position) { Composite panel = getComposite(idx); Control[] controls = panel.getChildren(); control.setParent(panel); if (control instanceof Label) ((Label)control).setBackground(this.getBackground()); else if (control instanceof CLabel) ((CLabel)control).setBackground(this.getBackground()); if ((controls != null) && (controls.length > 0)) { Control ctrl = controls[controls.length - 1]; if (position) control.setLayoutData(ctrl.getLayoutData()); ctrl.setVisible(false); } else { if (position) control.setLayoutData(createFormData()); } } Если логическое значение флага position равно true, то параметры позиционирования FormData будут получены у замещаемого компонента или созданы заново методом createFormData. /** * Функция определения параметров местоположения * @return FormData */ private FormData createFormData() { FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, OFFSET_LEFT ); fd.top = new FormAttachment( 0, OFFSET_TOP ); fd.right = new FormAttachment(100, OFFSET_RIGHT ); fd.bottom = new FormAttachment(100, OFFSET_BOTTOM); return fd; } Методы определения значений компонентов статусной строкиМенеджер статусной строки StatusbarManager включает метод определения значения текстовой метки раздела setText и выпадающего списка setComboItems. /** * Процедура определения текста метки статусной строки. * @param idx идентификатор раздела * @param text текст */ public void setText(final int idx, final String text) { Control control = getControl(idx); if ((control != null) && (control instanceof Label)) ((Label)control).setText(text); } //------------------------------------------------------------------ /** * Процедура определения значений выпадающего списка * @param idx идентификатор раздела * @param items массив значений */ public void setComboItems(final int idx, final String[] items) { Control control = getControl(idx); if ((control != null) && (control instanceof Combo)) ((Combo)control).setItems(items); } Слушатель изменения размера статусной строкиДля подключения/отключения слушателя изменения размера статусной строки можно использовать методы addResizeListener и removeResizeListener. При подключении слушателя ResizeListener в случае изменения размера строки будет вызван метод onResize(), который можно переопределить, чтобы определить свой способ позиционирования компонентов при изменении размеров статусной строки. /** * Процедура отключения слушателя ResizeListener */ public void removeResizeListener() { if (ResizeListener != null) removeListener(SWT.Resize, ResizeListener); } //------------------------------------------------------------------ /** * Процедура подключения слушателя ResizeListener */ public void addResizeListener() { if (ResizeListener == null) { ResizeListener = new Listener () { public void handleEvent (Event e) { onResize(); } }; addListener (SWT.Resize, ResizeListener); } } //------------------------------------------------------------------ /** * Процедура обработки события изменения размера статусной строки */ protected void onResize() { // System.out.println("Размер статусной строки изменился"); } Пример использования StatusbarManagerВ следующем примере создается менеджер статусной строки StatusbarManager, который размещается в нижней части формы. В примере используется модуль работы с изображениями IconCache, подробное описание которого с примером представлено на странице Toolbar, ToolItem, IconCache. Описание статусной строки STATUSBAR включает 4 раздела. Во втором и четвертом разделах будут размещены отдельные компоненты. Значения для выпадающего списка определены в массиве COMBO_ITEMS. Сначала будут созданы только разделы статусной строки. Метод createStatusbarItems с дополнительными настройками не будет вызван. public class StatusbarTest { public static Display display = null; public static Shell shell = null; private StatusbarManager statusbar = null; protected IconCache iconCache; protected final int ICON_print = 0; private final int ICON_SHELL = 1; protected final int ICON_file = 2; private final String[] IMAGES = {"print.gif" , "shell.gif" , "file.gif" }; private final String[][] STATUSBAR = {{"left" , "-1", "label"}, {"left" , "90", "null" }, {"right" , "60", "combo"}, {"center", "90", "null"}}; private final String[] COMBO_ITEMS = {" 10", " 25", " 50", " 75", " 100", " 250"}; //------------------------------------------------------------------ public StatusbarTest() { shell.setLayout(new FormLayout()); // Кэш изображений iconCache = new IconCache(); iconCache.setImagesDir("/images/"); // Загрузка изображений iconCache.loadImages (display, IMAGES); statusbar = new StatusbarManager(shell); FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, 0 ); fd.right = new FormAttachment(100, 0 ); fd.bottom = new FormAttachment(100, 0); fd.height = statusbar.getHeight(); statusbar.setLayoutData(fd); statusbar.setItems(STATUSBAR); // Установка иконки приложения shell.setImage(iconCache.getImage(ICON_SHELL)); // createStatusbarItems(); // Подключение/отключение слушателя ResizeListener // statusbar.removeResizeListener(); // statusbar.addResizeListener(); } //------------------------------------------------------------------ public static void main(String[] args) { display = new Display(); shell = new Shell (display); shell.setText("Пример использования StatusbarManager"); new StatusbarTest(); shell.setSize(420, 200); shell.open (); while (!shell.isDisposed()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); System.exit(0); } } Интерфейс примера использования менеджера статусной строки StatusbarManager без вызова метода createStatusbarItems представлен на следующем скриншоте. Листинг метода createStatusbarItemsВ методе createStatusbarItems будут выполнены следующие настройки статусной строки:
private void createStatusbarItems() { statusbar.setText(0, "Тестовая строка"); statusbar.setForeground(0, new Color(display, 32, 32, 255)); Font font = new Font(display, new FontData("Courier New", 10, SWT.ITALIC)); statusbar.setFont(0, font); CLabel label = new CLabel(shell, SWT.NONE); label.setImage(iconCache.getImage(ICON_file)); label.setText("Файл"); label.setAlignment(SWT.LEFT); statusbar.setControl(1, label, true); statusbar.setComboItems(2, COMBO_ITEMS); ((Combo)statusbar.getControl(2)).select(1); FormData fd = new FormData(SWT.DEFAULT, SWT.DEFAULT); fd.left = new FormAttachment( 0, 0); fd.top = new FormAttachment( 0, 0); fd.right = new FormAttachment(100, -0); fd.bottom = new FormAttachment(100, -0); Button button = new Button (shell, SWT.NONE); button.setImage(iconCache.getImage(ICON_print)); button.setText("Печать"); button.setLayoutData(fd); statusbar.setControl(3, button, false); } Интерфейс примера использования менеджера статусной строки StatusbarManager с вызовом метода createStatusbarItems представлен на следующем скриншоте. Скачать SWT пример тестирования StatusbarManagerИсходный код рассмотренного примера SWT StatusbarTest в виде проекта Eclipse можно скачать здесь (6.42 Мб). Библиотека labir.utils.jar, используемая в примере, включает StatusbarManager, полное описание которого (поля, методы) представлено на этой странице. Также библиотека включает класс IconCache, полное описание которого (поля, методы) представлено на странице Toolbar, ToolItem, IconCache. |