Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Часть 6. Программный интерфейс JavaBeans

Читайте также:
  1. Betfair для начинающих. Часть вторая
  2. Betfair для начинающих. Часть первая
  3. Betfair для начинающих. Часть третья
  4. Betfair для начинающих. Часть четвертая
  5. FM передатчик начинающего радиопирата. Часть№2
  6. I часть
  7. II Практическая часть
  8. II часть
  9. II. ОСНОВНАЯ ЧАСТЬ
  10. II. Основная часть

 

Программный интерфейс JavaBeans предоставляет возможности для разработки многократно используемых, встраиваемых, модульных программных компонентов. Такие компоненты обычно используются для решения следующих задач:

· для разработки контейнерных средств приложений (элементов графического интерфейса пользователя GUI, конструкторов приложений application builders и др.), где интерфейс JavaBeans упрощает процессы манипулирования компонентами внутри инструментальных средств. Программа управления компонентами получила название beanbox (контейнер компонентов) и входит в состав пакета JavaBeans Development Kit (BDK);

· для разработки собственных компонентов приложений;

· при использовании нестандартных компонентов, разработанных ранее.

Интерфейс JavaBeans поддерживает ту же модель событий, которая используется в графических пользовательских интерфейсах Swing и AWT. Основной задачей контейнерного приложения является предоставление пользователю возможности настройки компонента путем установки значений свойств. При необходимости задания свойства более сложного типа, используется классы PropertyEditor и Customizer, создающие графический интерфейс для конфигурации и задания значений свойств.

Пример 6.1. Определение пользовательского JavaBeans-компонента, позволяющего отображать несколько строк в статическом элементе Label.

 

package MultiLineLabel.java;import java.awt.*;import java.util.*; /** * пользовательский компонент, позволяющий размещать * несколько строк текста с заданными отступами и выравниванием **/public class MultiLineLabel extends Canvas { // определяемые пользователем свойства protected String label; // надпись protected int margin_width; // левое и правое поля protected int margin_height; // верхнее и нижнее поля protected Alignment alignment; // выравнивание текста // вычисляемые значения protected int num_lines; // число строк protected String[] lines; // надпись, разбитая на строки protected int[] line_widths; // длина строки protected int max_width; // максимальная длина protected int line_height; // высота шрифта protected int line_ascent; // высота шрифта над базовой линией protected boolean measured = false; // измерение строк // 5 версий конструктора. public MultiLineLabel(String label, int margin_width, int margin_height, Alignment alignment) { this.label = label; // запомнить все свойства. this.margin_width = margin_width; this.margin_height = margin_height; this.alignment = alignment; newLabel(); // разбить надпись на строки. } public MultiLineLabel(String label, int margin_width, int margin_height) { this(label, margin_width, margin_height, Alignment.LEFT); } public MultiLineLabel(String label, Alignment alignment) { this(label, 10, 10, alignment); } public MultiLineLabel(String label) { this(label, 10, 10, Alignment.LEFT);} public MultiLineLabel() { this(""); } // методы установки и опроса атрибутов компонента. public void setLabel(String label) { this.label = label; newLabel(); // деление надписи на строки. measured = false; // запрос на измерение строк. repaint(); // перерисовка. } public void setFont(Font f) { super.setFont(f); // установка нового шрифта. measured = false; // повторное измерение строк. repaint(); // перерисовка. } public void setForeground(Color c) { super.setForeground(c); // новый цвет. repaint(); // перерисовка без изменения размера } public void setAlignment(Alignment a) { alignment = a; repaint(); } public void setMarginWidth(int mw) { margin_width = mw; repaint(); } public void setMarginHeight(int mh) { margin_height = mh; repaint(); } // методы получения значений свойств getFont(), getForeground(), и др. // унаследованы от базового класса. public String getLabel() { return label; } public Alignment getAlignment() { return alignment; } public int getMarginWidth() { return margin_width; } public int getMarginHeight() { return margin_height; } /** * метод вызывается менеджером компоновки для определения желаемого * размера */ public Dimension preferredSize() { if (!measured) measure(); return new Dimension(max_width + 2*margin_width, num_lines * line_height + 2*margin_height); } /** * метод для определения минимального размера места */ public Dimension minimumSize() { return preferredSize(); } /** * метод рисования компонента. **/ public void paint(Graphics g) { int x, y; Dimension size = this.size(); // use getSize() in Java 1.1 if (!measured) measure(); y = line_ascent + (size.height - num_lines * line_height)/2; for(int i = 0; i < num_lines; i++, y += line_height) { if (alignment == Alignment.LEFT) x = margin_width; else if (alignment == Alignment.CENTER) x = (size.width - line_widths[i])/2; else x = size.width - margin_width - line_widths[i]; g.drawString(lines[i], x, y); } } /** * внутренний метод разбивает надпись на массив строк, * используя класс StringTokenizer. **/ protected synchronized void newLabel() { StringTokenizer t = new StringTokenizer(label, "\n"); num_lines = t.countTokens(); lines = new String[num_lines]; line_widths = new int[num_lines]; for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken(); } /** * внутренний метод для определения размеров шрифта, строк **/ protected synchronized void measure() { FontMetrics fm = this.getToolkit().getFontMetrics(this.getFont()); line_height = fm.getHeight(); line_ascent = fm.getAscent(); max_width = 0; for(int i = 0; i < num_lines; i++) { line_widths[i] = fm.stringWidth(lines[i]); if (line_widths[i] > max_width) max_width = line_widths[i]; } measured = true; }}

 

Пример 6.2. Определяет три константы для выравнивания текста с использованием класса Alignment.

 

package Alignment.java; /** класс, определяющий перечислимый тип из трех значений */public class Alignment { /** закрытый конструктор, предотвращающий создание экземпляров /** класса */ private Alignment() {}; // три константы, являющиеся единственными экземплярами класса public static final Alignment LEFT = new Alignment(); public static final Alignment CENTER = new Alignment(); public static final Alignment RIGHT = new Alignment();}

 

Для того чтобы подготовить компонент к использованию в контейнере, его необходимо упаковать вместе с требуемыми ресурсами в файл с расширением JAR (Java archives). Так как один компонент может иметь много вспомогательных файлов, а JAR-файл может содержать несколько компонентов, то должен быть создан манифест JAR-файла, где описывается, какие элементы файла являются компонентами. Для указания того, что файл класса является компонентом, необходимо в элемент манифеста файла добавить следующую строку: Java-Bean: true.

Для установки компонента требуется скопировать JAR-файл с компонентом в каталог jars, находящийся внутри каталога BDK, после чего он будет появляться в палитре компонентов при запуске приложения. Другая возможность состоит в загрузке JAR-файла компонента во время выполнения выбором команды Load JAR в меню File утилиты beanbox.

Пример 6.3. Компонент, отображающий сообщение для пользователя и три кнопки выбора, который часто используется внутри диалоговых окон.

 

package YesNoPanel.java;import java.awt.*;import java.awt.event.*;import java.util.*; /** * компонент JavaBean для вывода многострочного сообщения и трех кнопок * активизирует AnswerEvent при нажатии одной из них **/public class YesNoPanel extends Panel { // свойства компонента protected String messageText; // сообщение для вывода protected Alignment alignment; // выравнивание protected String yesLabel; // техт для кнопок yes, no, & cancel protected String noLabel; protected String cancelLabel; // внутренние компоненты панели protected MultiLineLabel message; protected Button yes, no, cancel; /** безаргументный конструктор со значениями свойств по умолчанию */ public YesNoPanel() { this("здесь\nВаше\nсообщение"); } public YesNoPanel(String messageText) { this(messageText, Alignment.LEFT, "Yes", "No", "Cancel"); } /** конструктор для использования класса */ public YesNoPanel(String messageText, Alignment alignment, String yesLabel, String noLabel, String cancelLabel) { // создание компонентов панели setLayout(new BorderLayout(15, 15)); // надпись посреди окна message = new MultiLineLabel(messageText, 20, 20, alignment); add(message, BorderLayout.CENTER); // панель для кнопок с размещением внизу компонента, // используя менеджер компоновки FlowLayout. Panel buttonbox = new Panel(); buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 15)); add(buttonbox, BorderLayout.SOUTH); // создание кнопок и слушателей событий для них yes = new Button(); // создание кнопок no = new Button(); cancel = new Button(); // размещение их в панели buttonbox.add(yes); buttonbox.add(no); buttonbox.add(cancel); // регистрация слушателей yes.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEvent(new AnswerEvent(YesNoPanel.this, AnswerEvent.YES)); } }); no.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEvent(new AnswerEvent(YesNoPanel.this, AnswerEvent.NO)); } }); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEvent(new AnswerEvent(YesNoPanel.this, AnswerEvent.CANCEL)); } }); // вызов методов установки свойств сообщений и кнопок setMessageText(messageText); setAlignment(alignment); setYesLabel(yesLabel); setNoLabel(noLabel); setCancelLabel(cancelLabel); } // get-методы для свойств компонента public String getMessageText() { return messageText; } public Alignment getAlignment() { return alignment; } public String getYesLabel() { return yesLabel; } public String getNoLabel() { return noLabel; } public String getCancelLabel() { return cancelLabel; } // set-методы для свойств компонента public void setMessageText(String messageText) { this.messageText = messageText; message.setLabel(messageText); validate(); } public void setAlignment(Alignment alignment) { this.alignment = alignment; message.setAlignment(alignment); } public void setYesLabel(String l) { yesLabel = l; yes.setLabel(l); yes.setVisible((l!= null) && (l.length() > 0)); validate(); } public void setNoLabel(String l) { noLabel = l; no.setLabel(l); no.setVisible((l!= null) && (l.length() > 0)); validate(); } public void setCancelLabel(String l) { cancelLabel = l; cancel.setLabel(l); cancel.setVisible((l!= null) && (l.length() > 0)); validate(); } public void setFont(Font f) { super.setFont(f); // вызов метода базового класса message.setFont(f); yes.setFont(f); no.setFont(f); cancel.setFont(f); validate(); } /** список зарегистрированных ActionListeners */ protected Vector listeners = new Vector(); /** регистрация слушателя действий */ public void addAnswerListener(AnswerListener l) { listeners.addElement(l); } /** удаление слушателя событий Answer */ public void removeAnswerListener(AnswerListener l) { listeners.removeElement(l); } /** посылка события всем зарегистрированным слушателям */ public void fireEvent(AnswerEvent e) { // копия списка с активизацией событий. Vector list = (Vector) listeners.clone(); for(int i = 0; i < list.size(); i++) { AnswerListener listener = (AnswerListener)list.elementAt(i); switch(e.getID()) { case AnswerEvent.YES: listener.yes(e); break; case AnswerEvent.NO: listener.no(e); break; case AnswerEvent.CANCEL: listener.cancel(e); break; } } } /** метод main() для демонстрации класса */ public static void main(String[] args) { // создание InfoPanel с заголовком и сообщением: YesNoPanel p = new YesNoPanel("Вы действительно уверены?"); // регистрируем слушатель событий p.addAnswerListener(new AnswerListener() { public void yes(AnswerEvent e) { System.exit(0); } public void no(AnswerEvent e) { System.out.println("No"); } public void cancel(AnswerEvent e) { System.out.println("Cancel"); } }); Frame f = new Frame(); f.add(p); f.pack(); f.setVisible(true); }}

 

Пример 6.4. Определение нового класса событий компонентов.

 

package AnswerEvent.java; /** * класс YesNoPanel активизирует событие при нажатии кнопок * поле id идентифицирует кнопки **/public class AnswerEvent extends java.util.EventObject { public static final int YES = 0, NO = 1, CANCEL = 2; // константы кнопок protected int id; // определение кнопки public AnswerEvent(Object source, int id) { super(source); this.id = id; } public int getID() { return id; } // возвращение кнопки}

 

Пример 6.5. Определение слушателей событий от компонента YesNoPanel.

 

package AnswerListener.java; /** * кдассы, заинтересованные в уведомлениях панели * YesNoPanel должны реализовать этот интерфейс. **/public interface AnswerListener extends java.util.EventListener { public void yes(AnswerEvent e); public void no(AnswerEvent e); public void cancel(AnswerEvent e);}

 

Для работы нашего приложения диалогового окна необходимо использовать все пять классов, являющихся необходимой частью компонента. Дополнительно распространяются и вспомогательные необязательные классы, например, BeanInfo, лредоставляющий дополнительную информацию о компоненте. Класс BeanInfo определяет для компонента несколько информационных частей:

· изображение, представляющее компонент;

· объект BeanDescriptor, содержащий ссылку на класс Customizer;

· список поддерживаемых свойств компонента с кратким описанием;

· метод, возвращающий часто используемое свойство;

· ссылка на класс PropertyEditor для свойств.




Дата добавления: 2015-09-11; просмотров: 22 | Поможем написать вашу работу | Нарушение авторских прав

Пример 2.19. | Пример 2.20. | Пример 2.21. | Пример 2.26. | Пример 3.1. | Пример 3.4. Обработка изображений. | Пример 3.5. Улучшенная анимация. | Пример 3.6. | Пример 4.1. | Простая сериализация. |


lektsii.net - Лекции.Нет - 2014-2024 год. (0.009 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав