Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Chapter 2. (Introduction) Swing Mechanics. Easy for reading, Click here!

Custom Search
Chapter 2. (Introduction) Swing Mechanics. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 7/14 



Previous Page Previous Page (6/14) - Next Page (8/14) Next Page
Subpages: 1. JComponent properties, size, and positioning 
2.  Event handling and dispatching 
3. Multithreading
4. Timers
5. AppContext service
6. Inside Timers & the TimerQueue
7. JavaBeans architecture
8. Fonts, Colors, Graphics and text
9. Using the Graphics clipping area
10. Graphics debugging
11. Painting and validation
12. Focus Management
13. Keyboard input, KeyStrokes, and Actions
14. SwingUtilities

2.7    JavaBeans architecture

Since we are concerned with creating Swing applications in this book, we need to understand and appreciate the fact that every component in Swing is a JavaBean.

Note: If you are familiar with the JavaBeans component model you may want to skip to the next section.

2.7.1    The JavaBeans component model

The JavaBeans specification identifies five features that each bean is expected to provide. We will review these features here, along with the classes and mechanisms that make them possible. The first thing to do is think of a simple component, such as a button, and apply what we discuss here to this component. Second, we are assuming basic knowledge of the Java Reflection API:

"Instances of Class represent classes and interfaces in a running Java application."API

"A Method provides information about, and access to, a single method on a class or interface."API

"A Field provides information about, and dynamic access to, a single field of a class or an interface."API

2.7.2    Introspection

Introspection is the ability to discover the methods, properties, and events information of a bean. This is accomplished through use of the java.beans.Introspector class. Introspector provides static methods to generate a BeanInfo object containing all discoverable information about a specific bean. This includes information from each of a bean's superclasses, unless we specify which superclass introspection should stop at (i.e. we can specify the 'depth' of an instrospection). The following retrieves all discoverable information of a bean:

    BeanInfo myJavaBeanInfo =

      Introspector.getBeanInfo(myJavaBean);

A BeanInfo object partitions all of a bean's information into several groups, some of which are:

         A BeanDescriptor: provides general descriptive information such as a display name.

         An array of EventSetDescriptors: provides information about a set of events a bean fires. These can be used to, among other things, retrieve that bean's event listener related methods as Method instances.

         An array of MethodDescriptors: provides information about the methods of a bean that are externally accessible (this would include, for instance, all public methods). This information is used to construct a Method instance for each method.

         An array of PropertyDescriptors: provides information about each property that a bean maintains which can be accessed through get, set, and/or is methods. These objects can be used to construct Method and Class instances corresponding to that property's accessor methods and class type respectively.

2.7.3    Properties

As we discussed in section 2.1.1, beans support different types of properties. Simple properties are variables such that, when modified, a bean will do nothing. Bound and constrained properties are variables such that, when modified, a bean will send notification events to any listeners. This notification takes the form of an event object which contains the property name, the old property value, and the new property value. Whenever a bound property changes, the bean should send out a PropertyChangeEvent. Whenever a constrained property is about to change, the bean should send out a PropertyChangeEvent before the change occurs, allowing it to possibly be vetoed. Other objects can listen for these events and process them accordingly (which leads to communication).

Associated with properties are a bean's setXX()/getXX() and isXX() methods. If a setXX() method is available the associated property is said to be writeable. If a getXX() or isXX() method is available the associated property is said to be readable. An isXX() method normally corresponds to retrieval of a boolean property (occasionaly getXX() methods are used for this as well).

2.7.4    Customization

A bean's properties are exposed through its setXX()/getXX() and isXX() methods, and can be modified at run-time (or design-time). JavaBeans are commonly used in interface development environments where property sheets can be displayed for each bean allowing read/write (depending on the available accessors) property functionality.

2.7.5    Communication

Beans are designed to send events that notify all event listeners registered with that bean, when a bound or constrained property changes value. Apps are constructed by registering listeners from bean to bean. Since we can use introspection to determine event sending and receiving information about any bean, design tools can take advantage of this knowledge to allow more powerful, design-time customization. Communication is the basic glue that holds an interactive GUI together.

2.7.6    Persistency

All JavaBeans must implement the Serializable interface (directly or indirectly) to allow serialization of their state into persistent storage (storage that exists beyond program termination). All objects are saved except those declared transient. (Note that JComponent directly implements this interface.)

Classes which need special processing during serialization need to implement the following private methods:

    private void writeObject(java.io.ObjectOutputStreamout) and

    private void readObject(java.io.ObjectInputStream in )

These methods are called to write or read an instance of this class to a stream. Note that the default serialization mechanism will be invoked to serialize all sub-classes because these are private methods. (Refer to the API documentation or Java tutorial for more information about serialization.)

Note: As of the first release of Java 2, JComponent implements readObject() and writeObject() as private. All subclasses need to implement these methods if special processing is desired. Currently long-term persistance is not recommended and is subject to change in future releases. However, there is nothing wrong with implementing Short-term persistance (e.g. for RMI, misc. data transfer, etc.).

Classes that intend to take comple control of their serialization and deserialization should, instead, implement the Externalizable interface.

Two methods are defined in the Externalizable interface:

    public void writeExternal(ObjectOutput out)

    public void readExternal(ObjectInput in)

These methods will be invoked when writeObject() and readObject() (discussed above) are invoked to handle any serialization/deserialization.

2.7.7    A simple Swing-based JavaBean

The following code demonstrates how to build a Swing-based JavaBean with simple, bound, constrained, and 'change' properties.

The code: BakedBean.java

see \Chapter1\1

import javax.swing.*;

import javax.swing.event.*;

import java.beans.*;

import java.awt.*;

import java.io.*;

public class BakedBean extends JComponent implements Externalizable

{

  // Property names (only needed for bound or constrained properties)

  public static final String BEAN_VALUE = "Value";

  public static final String BEAN_COLOR = "Color";

  // Properties

  private Font m_beanFont;           // simple

  private Dimension m_beanDimension; // simple

  private int m_beanValue;           // bound

  private Color m_beanColor;         // constrained

  private String m_beanString;       // change

  // Manages all PropertyChangeListeners

  protected SwingPropertyChangeSupport m_supporter =

    new SwingPropertyChangeSupport(this);

  // Manages all VetoableChangeListeners

  protected VetoableChangeSupport m_vetoer =

    new VetoableChangeSupport(this);

  // Only one ChangeEvent is needed since the event's only

  // state is the source property.  The source of events generated

  // is always "this". You'll see this in lots of Swing source.

  protected transient ChangeEvent m_changeEvent = null;

  // This can manage all types of listeners, as long as we set

  // up the fireXX methods to correctly look through this list.

  // This makes you appreciate the XXSupport classes.

  protected EventListenerList m_listenerList =

    new EventListenerList();

  public BakedBean() {

    m_beanFont = new Font("SanSerif", Font.BOLD | Font.ITALIC, 12);

    m_beanDimension = new Dimension(150,100);

    m_beanValue = 0;

    m_beanColor = Color.black;

    m_beanString = "BakedBean #";

  }

  public void paintComponent(Graphics g) {

    super.paintComponent(g);

    g.setColor(m_beanColor);

    g.setFont(m_beanFont);

    g.drawString(m_beanString + m_beanValue,30,30);

  }

  public void setBeanFont(Font font) {

    m_beanFont = font;

  }

  public Font getBeanFont() {

    return m_beanFont;

  }

  public void setBeanValue(int newValue) {

    int oldValue = m_beanValue;

    m_beanValue = newValue;

    // Notify all PropertyChangeListeners

    m_supporter.firePropertyChange(BEAN_VALUE,

      new Integer(oldValue), new Integer(newValue));

  }

  public int getBeanValue() {

    return m_beanValue;

  }

  public void setBeanColor(Color newColor)

   throws PropertyVetoException {

    Color oldColor = m_beanColor;

    // Notify all VetoableChangeListeners before making change

    // ...exception will be thrown here if there is a veto

    // ...if not we continue on and make the change

    m_vetoer.fireVetoableChange(BEAN_COLOR, oldColor, newColor);

    m_beanColor = newColor;

    m_supporter.firePropertyChange(BEAN_COLOR, oldColor, newColor);

  }

  public Color getBeanColor() {

    return m_beanColor;

  }

  public void setBeanString(String newString) {

    m_beanString = newString;

    // Notify all ChangeListeners

    fireStateChanged();

  }

  public String getBeanString() {

    return m_beanString;

  }

  public void setPreferredSize(Dimension dim) {

    m_beanDimension = dim;

  }

  public Dimension getPreferredSize() {

    return m_beanDimension;

  }

  public void setMinimumSize(Dimension dim) {

    m_beanDimension = dim;

  }

  public Dimension getMinimumSize() {

    return m_beanDimension;

  }

  public void addPropertyChangeListener(

   PropertyChangeListener l) {

    m_supporter.addPropertyChangeListener(l);

  }

  public void removePropertyChangeListener(

   PropertyChangeListener l) {

    m_supporter.removePropertyChangeListener(l);

  }

  public void addVetoableChangeListener(

   VetoableChangeListener l) {

    m_vetoer.addVetoableChangeListener(l);

  }

  public void removeVetoableChangeListener(

   VetoableChangeListener l) {

    m_vetoer.removeVetoableChangeListener(l);

  }

  // Remember that EventListenerList is an array of

  // key/value pairs:

  //   key = XXListener class reference

  //   value = XXListener instance

  public void addChangeListener(ChangeListener l) {

    m_listenerList.add(ChangeListener.class, l);

  }

  public void removeChangeListener(ChangeListener l) {

    m_listenerList.remove(ChangeListener.class, l);

  }

  // This is typical EventListenerList dispatching code.

  // You'll see this in lots of Swing source.

  protected void fireStateChanged() {

    Object[] listeners = m_listenerList.getListenerList();

    // Process the listeners last to first, notifying

    // those that are interested in this event

    for (int i = listeners.length-2; i>=0; i-=2) {

      if (listeners[i]==ChangeListener.class) {

       if (m_changeEvent == null)

         m_changeEvent = new ChangeEvent(this);

         ((ChangeListener)listeners[i+1]).stateChanged(m_changeEvent);

      }          

    }

  }

  public void writeExternal(ObjectOutput out) throws IOException {

    out.writeObject(m_beanFont);

    out.writeObject(m_beanDimension);

    out.writeInt(m_beanValue);

    out.writeObject(m_beanColor);

    out.writeObject(m_beanString);

  }

  public void readExternal(ObjectInput in)

   throws IOException, ClassNotFoundException {

    setBeanFont((Font)in.readObject());

    setPreferredSize((Dimension)in.readObject());

    // Use preferred size for minimum size..

    setMinimumSize(getPreferredSize());

    setBeanValue(in.readInt());

    try {

      setBeanColor((Color)in.readObject());

    }

    catch (PropertyVetoException pve) {

      System.out.println("Color change vetoed..");

    }

    setBeanString((String)in.readObject());

  }

  public static void main(String[] args) {

    JFrame frame = new JFrame("BakedBean");

    frame.getContentPane().add(new BakedBean());

    frame.setVisible(true);

    frame.pack();

  }

}

BakedBean has a visual representation (not a requirement for a bean). It has properties: m_beanValue, m_beanColor, m_beanFont, m_beanDimension, and m_beanString. It supports persistency by implementing the Externalizable interface and implementing the writeExternal() and readExternal() methods to control its own serialization (note that the order in which data is written and read match). BakedBean supports customization through its setXX() and getXX() methods, and it supports communication by allowing the registration of PropertyChangeListeners, VetoableChangeListeners, and ChangeListeners. And, without having to do anything special, it supports introspection.

Attaching a main method to display BakedBean in a frame does not get in the way of any JavaBeans functionality. Figure 2.1 shows BakedBean when executed as an application.

Figure 2.1 BakedBean in our custom JavaBeans property editor

<<file figure2-1.gif>>

In chapter 18 (section 18.9) we construct a full-featured JavaBeans property editing environment. Figure 2.2 shows a BakedBean instance in this environment. The BakedBean shown has had its m_beanDimension, m_beanColor, and m_beanValue properties modified with our property editor and was then serialized to disk. What figure 2.2 really shows is an instance of that BakedBean after it had been deserialized (loaded from disk). Note that any Swing component can be created, modified, serialized, and deserialized using this environment because they are all JavaBeans compliant!

Figure 2.2 BakedBean in our custom JavaBeans property editor

<<file figure2-2.gif>>



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy