Forum Stats

  • 3,724,396 Users
  • 2,244,747 Discussions
  • 7,850,993 Comments

Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Problem with JavaBean constrained property

User_9NOLC
User_9NOLC Member Posts: 2 Blue Ribbon

This isn't really an Enterprise JavaBeans question, but I couldn't find a JavaBeans topic. Please feel free to reassign this to a more appropriate forum if it's appropriate.

I've been struggling to have a complete solution to my JavaBeans constrained property example. The idea (an application that I found years ago, but I don't remember where I found it) is that a BarChart bean (actually, more like a temperature gauge) is listening to property changes from an IntBox bean (Intbox is a very simple class that inherits from JFormattedTextField, that provides a "value" property from the JFormattedTextField class). There is a application class ColorBarApp that provides the main method, sets up a JFrame and its contents to display the BarChart and the IntBox. I've managed to get things working, except that it should, when the user enters a value outside the percentage range of the BarChart, and the BarChart vetoes that change, I believe that the underlying JFormattedTextField should produce an "undo" event that changes the contents of the text field back to its former value. I can't seem to achieve that final, complete result. What am I missing? 


Here's the ColorBarApp.java file:


[code=Java]

package javaBeans;


import java.awt.BorderLayout;

import java.awt.Rectangle;

import java.awt.event.ComponentAdapter;

import java.awt.event.ComponentEvent;


import javax.swing.JFrame;

import javax.swing.JPanel;


/**

 *  The ColorBar Applet Bean contains two beans: IntBox and BarChart.

 *

 *  @author Bryan J. Higgs, 8 April, 2000

 */

public class ColorBarApp extends JFrame

{

 /**

  * Main entry point

  */

 public static void main(String[] args) 

 {

  ColorBarApp frame = new ColorBarApp();

  frame.setDefaultLookAndFeelDecorated(true);

  frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

  frame.setVisible(true);

 }


 /**

  *  Constructor

  */

 public ColorBarApp()

 {

  setSize(300, 250);

  setTitle("Color Bar Frame");


  // Initialize the beans

  m_intBox.setEditable(true);


  JPanel contentPane = (JPanel) getContentPane();

  contentPane.setLayout(new BorderLayout());


  JPanel panel = new JPanel();

  panel.add(m_barChart);


  contentPane.add(panel, BorderLayout.CENTER);

  contentPane.add(m_intBox, BorderLayout.SOUTH);


  // Set the BarChart to listen for IntegerBox property change events for the

  // IntegerBox "value" property.

  m_intBox.addPropertyChangeListener("value", m_barChart);

 }


 //// Private Data ////

 private BarChart  m_barChart = new BarChart();

 private IntBox   m_intBox  = new IntBox();

}

[/code]


The BarChart.java file:


[code=Java]

package javaBeans;


import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;


import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import java.beans.VetoableChangeListener;

import java.beans.VetoableChangeSupport;

import java.beans.PropertyVetoException;


import javax.swing.BorderFactory;

import javax.swing.JPanel;


/**

 * A BarChart JavaBean class.

 *

 * @author Bryan J. Higgs, 12 March, 2000

 */

public class BarChart extends JPanel 

           implements PropertyChangeListener,

                 VetoableChangeListener

{

 /**

  * Constructs a BarChart instance

  */

 public BarChart()

 {

  setPreferredSize( new Dimension(m_barWidth, m_barHeight) );

  setBorder( BorderFactory.createLineBorder(m_borderColor, m_borderWidth) );

   

  addVetoableChangeListener("percent", this);

 }


 //// Setter/Getter methods ////


 /**

  * Sets the percent for bar display.

  */

 public void setPercent(int newPercent)

          throws PropertyVetoException // Now, this setter can be vetoed

 {

  int oldPercent = getPercent();

   

  // If it's out of range, veto it

  if (newPercent < 0 || newPercent > 100)

  {

   System.out.println("BarChart setPercent() vetoing the percent value");

   PropertyChangeEvent event = new PropertyChangeEvent(this, "value", 

                             new Integer(oldPercent), 

                             new Integer(newPercent));

   throw new PropertyVetoException("Value out of range!", event);

  }

    

  // Otherwise, change its value

  m_percent = newPercent;

   

  // Ensure the GUI updates

  System.out.println("Repainting...");

  repaint();

 }


 /**

  * Gets the percent for bar display.

  */

 public int getPercent()

 {

  return m_percent;

 }


 public Dimension getPreferredSize()

 {

  return new Dimension(m_barWidth, m_barHeight);

 }


 /**

  *  Allow other objects to register interest in my constrained properties (percent)

  */

  public void addVetoableChangeListener(String propertyName, 

                     VetoableChangeListener listener)

  {

   if (m_vcs == null)

    m_vcs = new VetoableChangeSupport(this);

   System.out.println("Listening for vetoable changes in property '" + propertyName + "'");

   m_vcs.addVetoableChangeListener(propertyName, listener);

  }


  /**

  *  Allow other objects to remove interest in my constrained properties

  */

  public void removeVetoableChangeListener(String propertyName, 

                      VetoableChangeListener listener)

  {

    m_vcs.removeVetoableChangeListener(propertyName, listener);

  }

     

 // Respond to a property change event for the property

 // "value" by updating my value to a new value.

 public void propertyChange(PropertyChangeEvent event)

 {

  // If the property changed is "value", use it to try

  // to update the percent property (which is subject to constraints)

  String propertyName = event.getPropertyName();

  if (propertyName.equals("value"))

  {

   Number newValue = (Number)(event.getNewValue());

   if (newValue != null)

   {

    int value = newValue.intValue();

    System.out.println("Property '" + propertyName + "': changing to " + value);

     

    // Change the percent property (subject to constraints)

    try

    {

     setPercent(value);

    }

    catch (PropertyVetoException pve)

    {

     try

     {

      // defer to the support handler to handle change property values back

      System.out.println("Firing Vetoable Change for 'value'...");

      Integer oldValue = new Integer(m_percent);

      m_vcs.fireVetoableChange("value", oldValue, newValue);

     }

     catch (PropertyVetoException e) 

     {

      System.out.println("fireVetoableChange rethrew PropertyVetoException...");

      // Do nothing when the fireVetoableChange method re-throws the PropertyVetoException

     }

    }

   }

   else

   {

     

    System.out.println("Property '" + propertyName + "' change to " + event.getNewValue());

    // We don't care about other properties here

    // so do nothing

   }

  }

 }


 // Respond to a vetoable property change event for the 

 // property "value" by checking the new value for validity

 // If it's not valid, a PropertyVetoException is thrown.

 // (We leave it to the propertyChange() method above to

 // actually change the value.)

 public void vetoableChange(PropertyChangeEvent event)

   throws PropertyVetoException

 {

  String propertyName = event.getPropertyName();

  if ( propertyName.equals("value") )

  {

   int newPercent = ((Integer)event.getNewValue()).intValue();

   System.out.println("Checking property change '" + propertyName + "' for potential veto...");

   if (newPercent < 0 || newPercent > 100)

   {

    System.out.println("Vetoing!");

    throw new PropertyVetoException("No way, Jose!", event);

   }

   else

   {

    System.out.println("Not vetoed!");

   }

  }

  else

  {

   // We don't expect, or care, about other properties, here

  }

 }


 /**

  * Paints the BarChart using the specified Graphics.

  */

 public void paintComponent(Graphics g)

 {

  super.paintComponent(g);

  System.out.println( "Painting for new value of " + m_percent );

  System.out.println( "Width: " + getWidth() + " Height: " + getHeight() );

   

  // Paint the background color for the bar

  setBackground(m_floodColor);

    

   // Paint the part of the bar that represents the percentage

  g.setColor(m_fillColor);

  int y = (getHeight() * (100 - m_percent) / 100);

  int width = getWidth();

  int height = getHeight() * m_percent / 100;

  System.out.println("Filling Rectangle at [" + 0 + ", " + y + "] Width: " + width + " Height: " + height);

  System.out.println("m_barWidth = " + m_barWidth);

  g.fillRect(0, y, width, height);

 }


 //// Private data ////


 // The Vetoable Change Support object for constrained properties

 protected VetoableChangeSupport m_vcs;

  

 private int   m_percent = 0;

 private Color  m_floodColor = Color.cyan;

 private Color  m_fillColor = Color.red;

 private Color  m_borderColor = Color.black;

 private int   m_barWidth = 25;

 private int   m_barHeight = 150;

 private int   m_borderWidth = 2;

}

[/code]


and the IntBox.java file:


[code=Java]

package javaBeans;


import java.beans.PropertyChangeListener;

import java.beans.PropertyChangeSupport;

import java.beans.VetoableChangeListener;

import java.beans.VetoableChangeSupport;

import java.text.NumberFormat;


import javax.swing.JFormattedTextField;

import javax.swing.JTextField;


import java.beans.PropertyVetoException;


/**

*  An IntBox Bean is a JFormattedTextField that only accepts positive integers.

*

*  @author Bryan J. Higgs, 8 April, 2000

*/

public class IntBox extends JFormattedTextField

{

 /**

 *  Default constructor.

 */

 public IntBox()

 {

  super(NumberFormat.getIntegerInstance()); // Ensure the contents are integer

 }

}

[/code]


They work, except that, when the user enters an invalid value (like 200), while the BarChart does not change its display (as expected), the IntBox does not revert to its old value. Any suggestions on how I can make this work property would be much appreciated.


Thanks!

Answers

Sign In or Register to comment.