63472

Настройка страницы свойств

Лекция

Информатика, кибернетика и программирование

При создании кода компонента JavaBeans следует помнить о том, что этот компонент помимо пассивных имеет и активных пользователей, которые могут применять для него визуальные инструменты разработки.

Русский

2014-06-20

102.5 KB

0 чел.

I. Настройка страницы свойств                                                                                                    Лекция 7.

При создании кода компонента JavaBeans следует помнить о том, что этот компонент помимо пассивных имеет и активных пользователей, которые могут применять для него визуальные инструменты разработки. Например, если пользователи применяют только такие простые свойства, как цвет (класс java.awt.color), то будет вполне достаточно принятой по умолчанию компонента страницы свойств. Однако при использовании более сложных свойств может возникнуть необходимость более тонкой настройки внешнего вида компонентов JavaBeans. Для этого в визуальной среде разработки предусмотрены перечисленные ниже классы и интерфейс.

-. Это производный от SimpleBeanInfo  класс следует использовать для настройки внешнего вида компонента JavaBeans в программе-конструкторе.

- PropertyEditorSupport. Этот базовый класс следует расширить т реализовать в нем пользовательский редактор, предназначенный для настройки некоторого специфического свойства.

- Customizer. Интерфейс java.beans.Customizer  следует применять для создания собственного варианта страницы свойств с графическим интерфейсом пользователя.

BeanInfo

При создании компонента JavaBeans на основе некоторого класса рекомендуется (хотя это и не обязательно) создать класс BeanInfo. Благодаря созданию класса BeanInfo компонент JavaBeans сможет предоставить странице свойств более подробную информацию о том, каким образом пользователь может применять инструменты визуального проектирования.

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

Если имя вашего класса MyBean, то имя описывающего класса должно быть MyBeanBeanInfo.

Через SmartGuide можно добавлять новые методы, поля, события. Если вы примете решение предоставить какой-либо элемент интерфейса для использования, необходимо указать его атрибут, а именно: открытый ли он для всех пользователей, скрытый или специальный. Скрытый (hidden) метод (свойство или событие) доступен только для инструмента, а специальный (expert) – только в режиме работы квалифицированных пользователей (expert mode), причем способ работы инструмента-пользователя в этом режиме задает инструмент-конструктор. Существует еще выделенный (preffered), который подсвечивается, когда вы выбираете бин в визуальной композиции – правая клавиша – Connect - …

Для указания атрибутов свойств, событий и методов применяются классы PropertyDescriptor, EventDescriptor, MethodDescriptor соответственно, которые являются производными от класса FeatureDescriptor.

public java.beans.EventSetDescriptor [ ] getEventSetDescriptors ( )

public java.beans.MethodDescriptor [ ] getMethodDescriptors ( )

public java.beans.PropertyDescriptor [ ] getProperty Descriptors ( )

Рис.1

Рис.2

Рис.3

Рис.4

Рис.5

Рис.6

Рис.7

public java.beans.MethodDescriptor  firstMethodMethodDescriptor ( )

public java.beans.MethodDescriptor  secondMethodMethodDescriptor ( )

public java.beans.PropertyDescriptor  firstPropertyPropertyDescriptor ( )

public java.beans.PropertyDescriptor secondPropertyPropertyDescriptor ( )

public java.beans.EventSetDescriptor  ancestorEventSetDescriptor ( )

public java.beans.MethodDescriptor

        ancestorancestorAdded_javaxswingeventAncestorEventDescriptor ( )

public java.beans.MethodDescriptor

        ancestorancestorMoved_javaxswingeventAncestorEventDescriptor ( )

public java.beans.MethodDescriptor

        ancestorancestorRemoved_javaxswingeventAncestorEventDescriptor ( )

public static java.lang.reflect.Method findMethod (

      java.lang.Class aClass,

      java.lang.String methodName,

      int parameterCount ) - Find the method by comparing ( name & parameter size ) against the methods in the                     

      class

public static java.lang.Class getBeanClass ( )

public static java.lang.String getBeanClassName ( )

public java.beans.BeanInfo [ ] getAdditionalBeanInfo ( ) – Returns the BeanInfo of the superclass of this bean to                                                            

      inherit its features

public  java.beans.BeanDescriptor getBeanDescriptor ( ) – передает подробную информацию о свойствах

      компонента в среду визуального проектирования   

java.beans.PropertyEditorSupport

addPropertyChangeListener (PropertyChangeListener )

firePropertyChange (  )

getAsText (  )

            Gets the property value as string suitable for presentation to human to edit.

getCustomEditor (  )

           A Property Editor may choose to make available a full custom Component that edits its property value.

getJavaInitializationString (  )

          This method is intended for use when generating Java code to set the value of the property.

getTags (  )

          If the property value must be one of a set of known tagged values, then this method should return an array of

          the tag values.

getValue (  )

          Gets the value of the property.

isPaintable (  )

          Determines whether the class will honor the pain Value method.

paintValue ( Graphics, Rectangle )

          Paint a representation of the value into a given area of screen real estate.

removePropertyChangeListener ( PropertyChangeListener )

setAsText ( String )

          Sets the property value by parsing a given String.

setValue ( Object )

          Set ( or change ) the object that is to be edited.

supportsCustomEditor ( )

          Determines whether the propertyEditor can provide a custom editor.

1. Создание propertyEditor для фиксированного набора значений выбранного свойства

-  необходимо создать поле класса, аналогичного свойству класса бина ( и соответственно методы доступа к нему )

- реализовать методы:

 public String [ ] getTags (  )

 public Object getValue (  )

 public void setAsText ( String s ) – по выбору

Interface java.beans.Customizer

Класс, реализующий интерфейс Customizer обеспечивает самодостаточный GUI для переделки некоторого свойства в Java Bean.

Каждый Customizer должен наследоваться от java.awt.Component класс, т.о. он может быть использован внутри AWT диалога или панели.

Каждый Customizer должен иметь конструктор по умолчанию.

addPropertyChangeListener (PropertyChangeListener )

           Register a listener for the PropertyChange event

removePropertyChangeListener ( PropertyChangeListener )

           Remove a listener for the PropertyChange event

setObject ( Object )

           Set the object to be customized. This method should be called only once, before the Customizer has been

           added to any parent AWT container.

2.    Создание propertyEditor с поддержкой произвольного пользовательского интерфейса

- необходимо создать поле класса, аналогичного свойству класса бина и соответственно методы доступа к нему)

- необходимо создать поле класса наследника от java.awt.Component

- реализовать методы:

public java.awt.Component getCustomEditor (  ) – возвращает компонент-редактор

public Object getValue (  ) –  возвращает значение редактируемого свойства

public void setValue (Object param) – устанавливает редактируемое свойство

public boolean supportsCustomEditor ( ) – метод должен возвращать true

public void paintValue (java.awt.Graphics gfx, java.awt.Rectangle box) – метод позволяет отображать в удобной для пользователя форме значение поля

Рис.8

В первых трех методах необходимо учитывать, проинициализирован ли объект компонента-редактора. Возвращать из метода getCustomEditor (  ) ссылку на объект, если она проинициализирована, в противном случае – сначала провести инициализацию. Из метода getValue (  ) возвращать значение информационного параметра компонента-редактора, если он не проинициализирован – значение информационного поля из propertyEditor. В методе setValue (Object param) устанавливать информационное поле через param, если компонент-редактор не проинициализирован, иначе – через значение информационного параметра компонента-редактора.

 II. Многозадачность и компоненты JavaBeans

Процесс – автономно выполняемая программа, запущенная в своем собственном адресном пространстве. Многозадачная операционная система способна запускать более одного процесса (программы) одновременно, это выглядит так, как будто каждая выполняется сама по себе, за счет периодической передачи кванта времени процессора для каждой задачи. Поток – одиночное последовательное выполнение команд в процессоре. Таким образом, один процессор может выполнять несколько конкурирующих потоков.

Для многозадачности существует много приложений, но в основном, если некоторая часть вашей программы будет обрабатывать событие или ресурсы, вы не хотели бы, чтобы остальная часть программы терпеливо ожидала конца этих вычислений. Хороший пример этому кнопка «Выход» - не хотелось бы опрашивать ее состояние в каждом куске кода программы, но, в то же время, она должна реагировать на нажатие так, как будто регулярно проверяется. Фактически одна из наиболее привлекательных причин использования многозадачности в создании чуткого пользовательского интерфейса.

Простейшим путем для создания процесса является наследование от класса Thread, который имеет все необходимое для создания и запуска процесса. Наиболее важный метод для Thread это run ( ), который необходимо переопределить, чтобы процесс выполнял то, что вам необходимо. Таким образом, run ( ) есть код, который будет запущен «одновременно» с другими процессами в программе.

Совместное использование ограниченных ресурсов

Можете думать о программе с одним процессом как об одиноком объекте, решающим ваши проблемы и выполняющем только одно действие за единицу времени. Из-за того, что это единственный объект, вам

Никогда не придется думать о проблеме использования одного и того же ресурса разными объектами в одно и то же время, подобно тому, как два человека пытаются припарковаться в одном и том же месте, или пройти через дверь в одно и то же время, или даже говорить в одно и то же время.

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

В Java есть встроенная поддержка предотвращения коллизий при использовании одного типа ресурсов – объектов в памяти. Поскольку элементы данных класса объявляются как private и доступ к этой области памяти возможен только посредством методов, то можно избежать коллизий, объявив эти методы как synchronized. Одновременно только один процесс может вызвать synchronized метод для определенного объекта (хотя этот же процесс может вызвать более одного синхронизированного метода объекта). Ниже приведены простые synchronized методы:

       synchronized void f ( )    { /*  .  .  .  */ }

       synchronized void g ( )  { /*  .  .  .  */ }

Каждый объект содержит один блок (также называемый monitor), который автоматически является частью объекта (т.е. нет необходимости писать специальный код). При вызове любого synchronized метода, этот объект блокируется и ни один другой synchronized метод этого объекта не может быть вызван до тех пор, пока первый не закончится и не разблокирует объект. В выше приведенном примере, если f ( ) вызван для объекта, то g ( ) не может быть вызван для того же объекта до тех пор, пока f ( ) не завершится и не снимет блокировку. Таким образом, существует блок, который используется всеми synchronized методами отдельного объекта, и этот блок предотвращает возможность использования общей памяти более чем одним методом одновременно.

Создавая Bean, вы должны предполагать, что он будет использован в многозадачном окружении. Это значит, что:

  1.  Везде, где только возможно, все public методы Bean должны быть synchronized. Конечно, это приведет к увеличению времени выполнения synchronized методов. Если это будет основной загвоздкой, то методы, не создающие подобных проблем в критических секциях должны быть оставлены без synchronized, но учитывайте, определить такие методы не просто. Обычно эти методы невелики, (например, getCircleSize ( )) и/или принадлежат к «атомарным», то есть те, вызов которых выполняется в таком маленьком количестве кода, что изменение состояния объекта за это время не происходит. Установка подобных методов как не- synchronized может не иметь какого-либо особенного эффекта на скорости выполнения программы. Вы можете также определить все public методы Bean как synchronized и опустить ключевое слово synchronized только тогда, когда вы твердо убеждены, что это необходимо и что это принесет какие-либо плоды.
  2.  При запуске вещательного события нескольким слушателям, заинтересованным в этом событии, необходимо предположить, что слушатели могут быть добавлены или удалены при перемещении по списку.

               import javax.swing.*;

               import java.awt.*;

               import java.awt.*;

               import java.util.*;

               import java.io.*;

               import com.bruceeckel.swing.*;

               public class BangBean2 extends JPanel implements Serializable  {

                    private int xm,ym;

                    private int cSize = 20; / / Circle size

                    private String text = “Bang!”;

                    private int fontSize = 48;

                    private Color tColor = Color.red;

                    private ArrayList actionListeners = new ArrayList (  );

                    public BangBean2 (  )  {

                        addMouseListener ( new ML (  ) );

                        addMouseMotionListener ( new MM (  ) );

              }

              public synchronized int getCircleSize ( ) { return cSize;   }

              public synchronized void setCircleSize (int newSize)  {

                   cSize = newSize;

              }

              public synchronized String getBangText ( ) { return text;  }

              public synchronized void setBangText (String newText)  {

                   text = newtext;

              }

              public synchronized int getFontSize ( ) { return fontSize;   }

              public synchronized void setFontSize (int newSize)  {

                   fontSize = newSize;

              }

              public synchronized Color getTextColor ( ) { return tColor;   }

              public synchronized void setTextColor (Color newColor)  {

                   tColor = newColor;

              }

              public void paintComponent (Graphics g)   }

                   super.paintComponent (g);

                   g.setColor (Color.black);

                   g.DrawOval (xm – cSize/2, ym – cSize/2, cSize, cSize);

              }

              / / Thus is a multicast listener

              public synchronized void addActionListener (ActionListener 1 )  {

                  actionListeners.add (1);

              }

              public synchronized void removeActionListener (ActionListener 1 )  {

                  actionListeners.remove (1);

              }

              / / Notice this isn’t synchronized:

              public void notifyListeners ( )   {

                   ActionEvent a = new ActionEvent (BangBean2.this,

                          ActionEvent.ACTION_PERFORMED, null);

                   ArrayList lv = null;

                   / / Make a shallow copy of the List in case someone adds a listener while

                   / / we’re calling listeners:

                   synchronized (this)   {

                       lv = (ArrayList) actionListeners.clone ( );

                   }

              / / Call all the listener methods:

              for (int i  = 0; i < lv.size ( ); i ++)

                  ((ActionListener) lv.get (i)).actionPerformed (a);

              }

              class ML extends MouseAdapter    {

                  public void mousePressed (MouseEvent e)   {

                       Graphics g = getGraphics ( );

                        g.setColor (tColor);

                        g.setFont (new Font ( “TimesRoman”, Font.BOLD, fontSize) );

                         int width = g.getFontMetrics ( ).stringWidth (text);

                         g.drawString (text, (getSize ( ).width – width)  /2, getSize ( ).height/2);

                         g.dispose ( );

                         notifyListeners ( );

                   }

               }

              class MM extends MouseMotionAdapter    {

                  public void mouseMoved (MouseEvent e)   {

                       xm = e.getX ( );

                       ym = e.getY ( );

                        repaint ( );

                   }

               }

               public static void main (String [ ] args   {

                    BangBean2 bb = new BangBean2 ( );

                     bb.addActionListener (new ActionListener ( )  {

                  public void actionPerformed (ActionEvent e)   {

                       System.out.ptintln (“ActionEvent” + e);

                   }

               });

                bb.addActionListener (new ActionListener ( )  {

                  public void actionPerformed (ActionEvent e)   {

                       System.out.ptintln (“BangBean2 action”);

                   }

               });

                bb.addActionListener (new ActionListener ( )  {

                  public void actionPerformed (ActionEvent e)   {

                       System.out.ptintln (“More action”);

                   }

               });

                Console.run (bb, 300, 300);

         }

} / / / : ~

Что же синхронизировать? В любом случае следует учесть следующие факторы:

  1.  Изменяет ли метод значения «критических» переменных внутри объекта? Чтобы определить, является ли переменные «критическими», необходимо определить будут ли значения прочитаны или установлены другими процессами в программе. (В этом случае чтение и установка значения фактически всегда происходит через synchronized методы, так что можно их просто проверить.) В случае с paint ( ) никаких изменений нет.
  2.  Зависит ли метод от состояния этих «критических» переменных? Если synchronized метод изменяет значение той переменной, которую использует ваш метод, то вам просто необходимо также объявить ваш метод как synchronized. В связи с этим, можно видеть, что значение переменной cSize изменяется synchronized методами и, следовательно paint ( ), также должен быть synchronized. Однако в данном случае можно спросить, «А что ужасного произойдет в том случае, если cSize изменится во время paint ( )?» Когда видно, что ничего плохого. Можно решить оставить paint ( )  не synchronized во избежании излишних накладных расходов при вызове synchronized метода.
  3.  И в третьих, необходимо убедиться, является ли метод paint ( ) в базовом классе synchronized или нет. Нет! Это не решающий голос, но есть один фактор. В нашем случае, например, поля, изменяемые через synchronized методы (такие как cSize), смешиваются с оригинальным методом paint ( ) и могут в корне изменить ситуацию. Однако обратите внимание, что synchronized не наследуется, так, например, если метод является synchronized в базовом классе, то он не будет автоматически synchronized в переопределенном методе наследующего класса.

   

Задания к практическим занятиям:

1. Создайте бин. Через Beaninfo создайте поля, методы, события. Посмотрите созданные в классах бина и BeanInfo методы и поля.

2. Создайте бин с полем, значение которого будет определяться фиксированным набором значений с помощью своего  propertyEditor.

3. Создайте бин с propertyEditor, имеющим свой пользовательский интерфейс.


 

А также другие работы, которые могут Вас заинтересовать

14071. Всеволод Нестайко. Тореадори з Васюківки. Конспект уроку з української літератури 36 KB
  УРОК № 49 Тема.В. Нестайко. Тореадори з Васюківки. Мета:ознайомити учнів із новим розділом повісті; розвивати навички толерантного й аргументованого доведення своєї думки виразного читання переказу прозового твору характеризування героїв; виховувати прагнення до...
14072. Всеволод Нестайко. «Тореадори з Васюківки». Поняття про повість 36.5 KB
  УРОК № 50 Тема.В. Нестайко. Тореадори з Васюківки. Поняття про повість. Мета:ознайомити учнів з новим розділом повісті Тореадори з Васюківки допомогти усвідомити особливості жанру повісті; розвивати навички виразного читання переказу аналізу поведінки та вчин
14073. Урок. І Калинець. «Писанки» 30.5 KB
  УРОК № 52 Тема. І Калинець. Писанки. Мета: ознайомити учнів із життям та творчістю письменника допомогти сприйняти красу й оригінальність його поезій; розвивати навички виразного читання коментування ліричних творів визначення ролі метафори та порівняння у них; р
14074. Поетична вітальня. І. Калинець. Цикл «Дивосвіт»: «Стежечка», «Блискавка», «Веселка» 28 KB
  УРОК № 53 Тема. Поетична вітальня. І. Калинець. Цикл Дивосвіт: Стежечка Блискавка Веселка. Мета: ознайомити учнів з оригінальними неповторними віршами І. Калинця про природу допомогти усвідомити особливості та красу цих творів; розвивати навички виразного...
14075. Стельмах. «Химера лісового озера, або Митькозавр з Юрківки» 35 KB
  УРОК № 55 Тема. Я. Стельмах. Химера лісового озера або Митькозавр з Юрківки. Мета: ознайомити учнів із життям та творчістю письменника викликати цікавість до його пригодницьких книжок; розвивати навички виразного читання переказу аналізу прочитаного; виховувати
14076. Ярослав Стельмах. «Химера лісового озера, або Микитькозавр з Юрківки» 53 KB
  УРОК № 56 Тема. Я. Стельмах. Химера лісового озера або Микитькозавр з Юрківки. Мета:ознайомити учнів із новими розділами повісті спонукати до читання художньої літератури; розвивати навички виразного читання переказу характеристики героїв; виховувати допитливіст
14077. Ярослав Стельмах. «Химера лісового озера, або Микитькозавр з Юрківки». Урок з української літератури 28 KB
  УРОК № 57 Тема.Я. Стельмах Химера лісового озера або Микитькозавр з Юрківки. Мета:ознайомити учнів із новими пригодами двох друзів; прищеплювати інтерес і любов до читання художньої літератури; розвивати навички виразного читання уміння фантазувати передбачати
14078. Ярослав Стельмах. «Химера лісового озера...». Урок з української літератури 30 KB
  УРОК № 58 Тема.Я. Стельмах. Химера лісового озера. Мета:ознайомити учнів із кульмінацією та розв’язкою твору; розвивати навички виразного читання переказу виділення найнапруженіших епізодів у творі висловлення власної думки щодо прочитаного; виховувати почуття ...