Archive for September, 2006

Developing Java Beans When an object is saved,

Saturday, September 30th, 2006

Developing Java Beans When an object is saved, its internal data members are saved along with any other objects that it refers to. The resulting serialized data contains information about the types and classes of the objects, as well as their values. There is enough information stored to be able to reconstruct the objects with their values at a later time, including any references to other objects. In some cases, one object can be referenced by more than one other object. The serialization mechanism keeps track of objects efficiently so that if multiple references to an object exist, the object is only stored once. This is important when the objects are reconstructed from the serialized data, ensuring that there is only one new instance of the object that is referenced by others. Let’s look at an example. import java.io.*; class WidgetA implements Serializable{ protected int val; public WidgetA() { } public void setValue(int value) { val = value; } public int getValue() { return val; } } class WidgetB implements Serializable { protected int val; protected WidgetA AA; public WidgetB(WidgetA a) { AA = a; } public void setValue(int value) { val = value; } public int getValue() { return val; } } class Container implements Serializable { protected int val; protected WidgetA a1; protected WidgetB b1; public Container() { a1 = new WidgetA(); b1 = new WidgetB(a1); } page 75

Developing Java Beans 5.2.1 Static Data Members Static

Saturday, September 30th, 2006

Developing Java Beans 5.2.1 Static Data Members Static data members are not serialized automatically. Only the data associated with a specific instance of the class is serialized. If you want to serialize data stored in a static variable, you’ll have to provide class-specific serialization. We’ll look at the technique for doing so a little later. Data members that are marked as static final are considered to be part of the class definition, so they don’t have to be saved during serialization. In fact, it would be impossible to set their values during deserialization, since they are marked as final. 5.2.2 Transient Data Members Some data members may not be a part of the persistent state of the object. Classes may define data members for use as scratch variables, or to make some other part of their processing easier. It may be unnecessary, or even inappropriate, to serialize these data members. For instance, you might include some data members to keep run-time statistics on your object. These statistics may, for example, keep track of how many times a particular property is accessed. This is not the kind of data you want to serialize since it is not part of the persistent state of the object you wouldn’t want to restore that information when the object is reconstructed. These data members should be marked with the transient modifier. The standard object serialization mechanism will not save and restore data members that are marked as transient. It is also necessary to use the transient modifier on data members that are instances of classes that are not serializable. As I mentioned above, a java.io.NotSerializableException will be thrown when an attempt is made to save or restore an instance of a class that is not serializable. If this happens, the serialization process won’t complete. However, it’s not as simple as marking a data member as transient. After all, this data may represent all or part of the state of the object. We’ll examine this problem more closely a little later when we look at how the GenericButtonAdapter from an earlier chapter interacts with the serialization process. 5.2.3 Implementing Serialization Let’s look at the following example: public class SimpleExample implements java.io.Serializable { protected int anInteger; protected float aFloat; protected java.awt.Button aButton; public SimpleExample() { } } The class SimpleExample contains three data members. The first two, anInteger and aFloat, are primitive data types. As we discussed earlier, all primitive data types are automatically serializable. The data member called aButton is an instance of type java.awt.Button. This is a subclass of java.awt.Component, which itself implements java.io.Serializable. So the SimpleExampleclass can be serialized without doing anything more than declaring that it implements the java.io.Serializable interface. page 74

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans The next applet, SimpleReader, simply reads the serialized button object from file Saver.tmp and adds it to the applet. When this applet is run, the button appears with the properties that were established in the first example. You’ll have to take it for granted that this applet creates the same display (Figure 5.2) as the previous one, SimpleSaver. The code for SimpleReader is shown next: import java.applet.*; import java.awt.*; import java.io.*; public class SimpleReader extends Applet { public void init() { try { FileInputStream f = new FileInputStream(”Saver.tmp”); ObjectInput s = new ObjectInputStream(f); Button b =(Button)s.readObject(); add(b); } catch (Exception e) { System.out.println(e); } } } While the model used for serialization is very simple, it has some drawbacks. First, it’s not as simple as marking serializable classes with the Serializable interface. It is possible common, in fact for an object that can’t be serialized to implement Serializable (either directly or by inheritance). Ultimately, serialization has to do with the data members of the class, not the methods it contains; after all, Serializable is an empty interface and doesn’t require you to implement any methods. A class is serializable if, and only if, it has no members that aren’t serializable specifically: no non-static, non-transient members. By default, static and transient members are ignored when an object is serialized. Generally speaking, classes that belong to the standard Java distribution are serializable unless serializing an object of that class would be a security risk. The problem is that there are many standard classes that would present security risks if serialized for example, a FileInputStream can’t be serialized, because when it is deserialized at a later time (and possibly on a different machine), you have an object that references some file handle that may no longer be meaningful, or that may point to a different file than it did originally. You should make it a practice to check the class of any data members you add to a serializable class to make sure that those data members can be serialized also. Don’t make any assumptions; just look it up in the documentation. Stating that a class implements Serializable is essentially a promise that the class can be successfully saved and restored using the serialization mechanism. The problem is that any subclass of that class automatically implements Serializable via inheritance, even if it adds some nonserializable members. Java throws a NotSerializableException (from the java.io package) if you try to save or restore a non-serializable object. This probably isn’t what you want to happen. When you are writing Beans (or any class that you may want to serialize), you have to think carefully about what the class contains, and you also have to think about how the class will be used. As we’ll see, you can redesign almost any class so that it is serializable, but this redesign may have implications for the interface between your class and the rest of the world. Ultimately, that’s the trick with object serialization. It’s not as simple as marking a few classes Serializable; it has real implications for how you write code. page 73
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans some circumstances it requires very little extra programming effort to implement persistence, but it can often require extra work and careful planning. 5.1 Object Serialization The java.io package provides a streaming mechanism for serializing the persistent state of objects. Any type of input or output stream can be used, which allows persistence streams to be stored on a variety of storage mediums. The most common form of this is a file stream, using an instance of class java.io.FileOutputStream to save the data and class java.io.FileInputStream to restore it. Serialization can be broken down into streams and components. The stream is responsible for saving and restoring objects and primitive data types such as int and float. The components of serialization are those objects and data members that are saved and restored. The stream controls the process of saving objects by requesting that those objects write their own contents, and must contain enough information to reconstruct the object. The new instance should be of the same class or data type and should contain the same internal data values. The object stream contains the methods for saving or restoring objects and primitive data types. The java.io package defines two interfaces for this purpose. The java.io.ObjectOutput interface, which is implemented by objects that can save other objects to the stream; and the java.io.ObjectInput interface, which is implemented by objects that can restore other objects from the stream. The java.io.ObjectOutputStream and java.io.ObjectInputStream classes implement the java.io.ObjectOutput and java.io.ObjectInput interfaces, respectively. These classes provide methods for saving and restoring objects, as well as for saving and restoring the primitive data types. Here are two code snippets that show how these classes are used: // save a string and a double to the stream String str = “Sample”; double d = 3.14; FileOutputStream f = new FileOutputStream(”Beans.tmp”); ObjectOutputStream s = new ObjectOutputStream(f); s.writeObject(str); s.writeDouble(d); s.flush(); // restore the string and double FileInputStream f = new FileInputStream(”Beans.tmp”); ObjectInputStream s = new ObjectInputStream(f); String str = (String)s.readObject(); double d = s.readDouble(); In the first example we create an instance of the java.lang.String class and an instance of the primitive type double. Next we create an instance of java.io.FileOutputStream, and use it to create an instance of java.io.ObjectOutputStream. We then call the writeObject() method on the stream to save the string object, and call the writeDouble() method to save the double. Lastly, we call flush() to commit everything in the stream to the file. The second example reconstructs the objects from the file. An instance of java.io.FileInputStream is created and used to create an instance of java.io.ObjectInputStream. Next, the readObject() method is called on the stream to restore the string. Because the readObject() method does not distinguish between classes, the returned object must be cast to the appropriate type. Next, we call the readDouble() method to restore the value of the double. What’s not clear from the example is that there’s no call to the constructor (explicit or implicit) of an object being read back from the stream. page 71
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans The Java object serialization mechanism requests that an object read or write its own state. In order to handle these requests an object must implement either the java.io.Serializable interface or the java.io.Externalizable interface. 5.2 The java.io.Serializable Interface Objects that implement the java.io.Serializable interface can have their state saved and restored. This state includes data from all of the classes in the object’s class hierarchy. So an object need not worry about the serialization of data from superclasses, as this is handled automatically. The Serializable interface has no methods. It is used as a marker, indicating that the class is serializable. All subclasses of a class that implements this interface will also be serializable. So it is not necessary to declare that a class implements java.io.Serializable if one of its superclasses has already done so. The object serialization mechanism analyzes objects that implement java.io.Serializable, looking for data members to save or restore. By default, all non-static and non-transient data members will be serialized. Let’s take a look at a simple example. We create an applet that contains a single instance of java.awt.Button, which is serializable. The button’s Label property is set by specifying it as a parameter of the constructor. In this case the string Beans Book is used. We also set the button’s Font property, using a bold 36-point font. After adding the button to the applet, we serialize the button to file Saver.tmp. Figure 5.2 shows the applet, and its code is shown here: import java.applet.*; import java.awt.*; import java.io.*; public class SimpleSaver extends Applet { public void init() { Button b = new Button(”Beans Book”); b.setFont(new Font(”System”, Font.BOLD, 36)); add(b); try { FileOutputStream f = new FileOutputStream(”Saver.tmp”); ObjectOutput s = new ObjectOutputStream(f); s.writeObject(b); s.flush(); } catch (Exception e) { System.out.println(e); } } } Figure 5.2. An applet that saves and restores itself page 72
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans them, while the other monitors those changes and updates its own Value property in response. Figure 4.5 shows an example. Figure 4.5. An applet using a constrained property If you continue to press the increment button, the labels will eventually have values of 20. If you try to increment again, the Constrainer object vetoes the change. The result is that the Value properties of both labels remain at 20. The same is true if you decrement the Value properties to 10. If you continue decrementing, the Constrainer object again vetoes the change and the Value properties remain at 10. Chapter 5. Persistence Most components maintain information that defines their appearance and behavior. This information is known as the state of the object. Some of this information is represented by the object’s properties. For instance, the font or color properties of a visual component are usually considered to be part of that object’s state. The Thermometer class that we’ve been discussing in previous chapters has a MinimumTemperature property that is part of its state. There may also be internal data used by an object that is not exposed as properties, but plays a part in defining the behavior of the object nevertheless. An applet or application may use one or more components, and these components will be configured to exhibit specific behavior. When the application is loaded, these components should automatically exhibit the prescribed behavior. This means that the state information of all of the components, as well as the application or applet itself, must be saved on a persistent storage medium so that it can be used to recreate the overall application state at run-time. Figure 5.1 shows that some portion of an application will be saved to, and subsequently restored from, persistent storage. An important aspect of application state is the definition of the components themselves: the persistent state of an application includes a description of the components being used, as well as their collective state. Figure 5.1. Saving and restoring components The JavaBeans architecture uses the Java object serialization mechanisms for persistence. These mechanisms are designed to make it very easy for simple Beans to implement persistence, while at the same time providing the flexibility needed by more complex Beans. We’ll see shortly that under page 70
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans public void handleDecrement(ActionEvent evt) { // get the current value and subtract 1 int val = primaryLabel.getValue() - 1; // try to set the new value try { primaryLabel.setValue(val); } catch (PropertyVetoException e) { } } // handle the increment button push public void handleIncrement(ActionEvent evt) { // get the current value and add 1 int val = primaryLabel.getValue() + 1; // try to set the new value try { primaryLabel.setValue(val); } catch (PropertyVetoException e) { } } } When the decrement button is pressed, the handleDecrement() method gets called. The Value property of the primary NumberLabel object is retrieved and its value is decremented and stored locally. Then handleDecrement() attempts to set the Value property to this new value. The PropertyVetoException must be caught in case the change is vetoed. When the increment button is pressed, the handleIncrement() method does the same thing, except that the value is incremented instead. When the applet’s init() method is called, the buttons and labels are added first. Next, the instance of the Constrainer class is registered as a listener for VetoableChange events from the primary NumberLabel object, and the other NumberLabel object (mirrorLabel) is registered to listen for PropertyChange events. The button adapter is set up to route action events, and the two labels are initialized with two different values. Figure 4.4 shows what the applet looks like when it first starts up. The components are labeled with the variable names to show where they appear on the applet. Figure 4.4. An applet using a constrained property: initial state When the decrement (<<) and increment (>>) buttons are pressed, both labels update together. Press the buttons and watch how these two labels stay in sync by setting the Value property of one of page 69
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans // the decrement button protected

Saturday, September 30th, 2006

Developing Java Beans // the decrement button protected Button decButton = new Button(”<<"); // the increment button protected Button incButton = new Button(">>”); // the constrained label protected NumberLabel primaryLabel = new NumberLabel(”*****”); // the label that mirrors the primary label protected NumberLabel mirrorLabel = new NumberLabel(”*****”); // the constraining object protected Constrainer cnstr = new Constrainer(); // the constructor public ExampleApplet4() { } // the applet init public void init() { // add the user interface elements add(decButton); add(incButton); add(primaryLabel); add(mirrorLabel); // register the constrainer with the primary label primaryLabel.addVetoableChangeListener(cnstr); // register the mirroring label with the primary labelprimaryLabel.addPropertyChangeListener(mirrorLabel); // setup the button adapter try { adapter = new GenericButtonAdapter(this); adapter.registerActionEventHandler(decButton, “handleDecrement”); adapter.registerActionEventHandler(incButton, “handleIncrement”); } catch (NoSuchMethodException e) {} catch (ClassNotFoundException e) { } // start the labels at different values try { primaryLabel.setValue(15); mirrorLabel.setValue(5); } catch (PropertyVetoException e) { } } // handle the decrement button push page 68
Note: If you are looking for good and high quality web space to host and run your java application check Vision java hosting services

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans The NumberLabel class extends java.awt.Label, a class for creating a static text field. NumberLabel implements the java.beans.PropertyChangeListener interface because we will use one instance of the NumberLabel class to monitor the Value property of another. Since NumberLabel supports a property named Value that is both bound and constrained, we use an instance of java.beans.PropertyChangeSupport as well as an instance of VetoableChangeSupport. The implementation of the methods addPropertyChangeListener(), removePropertyChangeListener(), addVetoableChangeListener(), and removeVetoable- ChangeListener() all defer to their respective support objects. Since the Value property is read/write, we implement a getValue() method as well as a setValue() method. The latter declares that it can throw the java.beans.PropertyVetoException because the Value property is constrained as well as bound. The setValue() method first instructs the support object to fire a VetoableChangeEvent for the Value property by calling the fireVetoableChange() method. If the event is not vetoed, SetValue() stores the new value, updates the label’s text, and repaints. Finally, the other support object is instructed to fire a PropertyChangeEvent by invoking the firePropertyChange() method. The NumberLabel class also implements the propertyChange() method to handle property changes from other objects. In this example, we know that a NumberLabel listens for property changes only from the other instance of NumberLabel. We can therefore take a shortcut and simply have the NumberLabel set its own Value property based on the new value of the PropertyChangeEvent that it received. This is guaranteed to keep our two labels in sync. Of course, we first check to make sure that it was the Value property that changed, and that we haven’t received a notification about some other property. Now let’s take a look at the code for the Constrainer class: class Constrainer implements VetoableChangeListener { // handle the vetoable change event public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { // we constrain the value to between 10 and 20 Integer val = (Integer)evt.getNewValue(); if (val.intValue() < 10 || val.intValue() > 20) { throw new PropertyVetoException(”Bad Value”, evt); } } } The Constrainer class vetoes any property changes that attempt to change the Value property of a NumberLabel object to a value below 10 or above 20. The vetoableChange() method examines the new value and rejects it if it does not meet the criteria. Now we can create an applet that ties all this together. The applet uses an instance of the class BeansBook.util.GenericButtonAdapter to route action events that occur when the two buttons are pressed. Here’s what the code looks like: public class ExampleApplet4 extends Applet { // the button adapter for handling button action events protected GenericButtonAdapter adapter; page 67
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans Let’s take a look at the code for the NumberLabel class first: import java.applet.*; import java.awt.*; import java.awt.event.*; import java.beans.*; import BeansBook.util.*; // the NumberLabel classclass NumberLabel extends Label implements PropertyChangeListener { // the support object for bound listenersprotected PropertyChangeSupport boundSupport; // the support object for constrained listeners protected VetoableChangeSupport vetoSupport; // the implementation of the Value property protected int theValue = 15; // constructor public NumberLabel(String text) { // call the super class super(text); // construct the support objects boundSupport = new PropertyChangeSupport(this); vetoSupport = new VetoableChangeSupport(this); } // add a bound property listenerpublic void addPropertyChangeListener(PropertyChangeListener l) { // defer to the support object boundSupport.addPropertyChangeListener(l); } // remove a bound property listenerpublic void removePropertyChangeListener(PropertyChangeListener l) { page 65
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services