Author: bback
Date: 2006-03-14 14:05:14 +0000 (Tue, 14 Mar 2006)
New Revision: 8249

Added:
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/DefaultSpinnerModel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/IconPanel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ImagePanel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeEvent.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeListener.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryField.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryFieldBeanInfo.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormat.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatEditor.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateSpinnerModel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MImagePanel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopup.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupDialog.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupWindow.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MSimpleDateFormat.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/RollOverButton.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ScreenUtilities.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/Shadow.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ShadowImage.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/SpinnerModel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormCellLayout.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormLayout.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormStrut.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MComboBoxLayout.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MSpinnerLayout.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/SafeCalendarUtils.java
Log:
new date chooser component

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/DefaultSpinnerModel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/DefaultSpinnerModel.java    
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/DefaultSpinnerModel.java    
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,69 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+import javax.swing.event.*;
+
+public class DefaultSpinnerModel implements SpinnerModel
+{
+    String val="";
+    EventListenerList listenerList = new EventListenerList();
+
+    public Object getValue()
+    {
+        return val;
+    }
+
+    public void setValue(Object v)
+    {
+    }
+
+    public void setStep(int step)
+    {
+    }
+
+    public Object getNextValue()
+    {
+        return val;
+    }
+
+    public Object getPreviousValue()
+    {
+        return val;
+    }
+    public void addChangeListener(ChangeListener l)
+    {
+        listenerList.add(ChangeListener.class, l);
+    }
+    public void removeChangeListener(ChangeListener l)
+    {
+        listenerList.remove(ChangeListener.class, l);
+    }
+    protected void notifyListeners()
+    {
+        ChangeEvent event;
+        // Guaranteed to return a non-null array
+        Object[] listeners = 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)
+            {
+                event = new ChangeEvent(this);
+                ((ChangeListener)listeners[i+1]).stateChanged(event);
+            }
+        }
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/IconPanel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/IconPanel.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/IconPanel.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,258 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+
+package mseries.ui;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+public class IconPanel extends JPanel
+{
+
+    // Placement constants
+
+    /**
+     * Place the image in the top left position
+     */
+    public static final int NORTH_WEST    = 1;
+    /**
+     * Place the image in the top centre position
+     */
+    public static final int NORTH         = 2;
+    /**
+     * Place the image in the top right position
+     */
+    public static final int NORTH_EAST    = 3;
+    /**
+     * Place the image in the centre right position
+     */
+    public static final int EAST          = 4;
+    /**
+     * Place the image in the bottom right position
+     */
+    public static final int SOUTH_EAST    = 5;
+    /**
+     * Place the image in the bottom centre position
+     */
+    public static final int SOUTH         = 6;
+    /**
+     * Place the image in the bottom left position
+     */
+    public static final int SOUTH_WEST    = 7;
+    /**
+     * Place the image in the centre left position
+     */
+    public static final int WEST          = 8;
+    /**
+     * Place the image in the centre position
+     */
+    public static final int CENTER        = 9;
+    /**
+     * Fill the panel with multiple copies of the image
+     */
+    public static final int TILED         = 10;
+    /**
+     * Fill the panel with a single scaled copy of the image (only
+     * avaliable if the icon is an ImageIcon)
+     */
+    public static final int STRETCHED     = 11;
+
+    protected int placement               = 1;
+    protected Color background;
+    protected Icon icon                   = null;
+
+    /**
+     * Construct a panel with no icon set
+     */
+    public IconPanel()
+    {
+        super();
+        background = super.getBackground();
+    }
+
+    /**
+     * Construct a panel with the specified icon in the top left position
+     * @param icon the icon for the panel background
+     */
+    public IconPanel(Icon icon)
+    {
+        this.icon = icon;
+        background = super.getBackground();
+    }
+
+
+    /**
+     * Construct a panel with the specified icon in specified position
+     * @param icon the icon for the panel background
+     * @param placement the position of the image in the panel
+     */
+    public IconPanel(Icon icon, int placement)
+    {
+        this.icon = icon;
+        setPlacement(placement);
+        background = super.getBackground();
+    }
+
+    /**
+     * Set the image placement attribute
+     * @param placement the position of the image in the panel
+     */
+    public void setPlacement(int placement)
+    {
+        if (placement < 1 || placement > 11)
+        {
+            throw new IllegalArgumentException("Placement value is not valid");
+        }
+
+        this.placement = placement;
+    }
+
+    /**
+     * Set the icon attribute
+     * @param icon the icon for the panel background
+     */
+    public void setIcon(Icon icon)
+    {
+        this.icon = icon;
+    }
+
+    /**
+     * Set the background colour for the panel
+     * @param background the background colour
+     */
+    public void setBackground(Color background)
+    {
+        super.setBackground(background);
+        this.background = background;
+    }
+
+    /**
+     * Get the current placement value
+     * @return the placement value
+     */
+    public int getPlacement()
+    {
+        return placement;
+    }
+
+    /**
+     * Get the current icon
+     * @return the current icon
+     */
+    public Icon getIcon()
+    {
+        return icon;
+    }
+
+    /**
+     * Paint the component
+     * @param g the graphics instance
+     */
+    protected void paintComponent(Graphics g)
+    {
+        Dimension size=getSize();
+        int w=getSize().width;
+        int h=getSize().height;
+        int x=0;
+        int y=0;
+
+        if (g==null)
+        {
+            return;
+        }
+
+        g.setColor(background);
+        g.fillRect(x,y,w,h);
+
+        if (icon==null)
+        {
+            return;
+        }
+
+        if (placement == NORTH_WEST)
+        {
+            x = 0;
+            y = 0;
+        } else if (placement == NORTH)
+        {
+            x = (w - icon.getIconWidth()) / 2;
+            y = 0;
+        } else if (placement == NORTH_EAST)
+        {
+            x = w - icon.getIconWidth();
+            y = 0;
+        } else if (placement == EAST)
+        {
+            x = w - icon.getIconWidth();
+            y = (h - icon.getIconHeight()) / 2;
+        } else if (placement == SOUTH_EAST)
+        {
+            x = w - icon.getIconWidth();
+            y = h - icon.getIconHeight();
+        } else if (placement == SOUTH)
+        {
+            x = (w - icon.getIconWidth()) / 2;
+            y = h - icon.getIconHeight();
+        } else if (placement == SOUTH_WEST)
+        {
+            x = 0;
+            y = h - icon.getIconHeight();
+        } else if (placement == WEST)
+        {
+            x = 0;
+            y = (h - icon.getIconHeight()) / 2;
+        } else if (placement == CENTER)
+        {
+            x = (w - icon.getIconWidth()) / 2;
+            y = (h - icon.getIconHeight()) / 2;
+        } else if (placement == TILED)
+        {
+            x = 0;
+            while (x < w)
+            {
+                y = 0;
+                while (y < h)
+                {
+                    if (icon != null)
+                    {
+                        icon.paintIcon(this, g, x, y);
+                    }
+                    y = y + icon.getIconHeight();
+                }
+                x = x + icon.getIconWidth();
+            }
+        } else if (placement == STRETCHED)
+        {
+            if (icon instanceof ImageIcon)
+            {
+                g.drawImage(((ImageIcon)icon).getImage(),0,0,w,h,this);
+            }
+            else
+            {
+                System.out.println("Can only stretch ImageIcons");
+                icon.paintIcon(this, g, 0, 0);
+            }
+        }
+
+        if (placement != TILED && placement != STRETCHED)
+        {
+            icon.paintIcon(this, g, x, y);
+        }
+
+        return;
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ImagePanel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ImagePanel.java     
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ImagePanel.java     
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,71 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+
+package mseries.ui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.net.URL;
+
+/**
+*   An Image panel that provides a component showing an image on its 
background. It allows
+*   an image to be placed on the IconPanel
+*
+*/
+public class ImagePanel extends IconPanel
+{
+
+    URL imageURL;
+
+    public ImagePanel()
+    {
+        super();
+        Color background=UIManager.getColor("ImagePanel.background");
+        if (background==null)
+        {
+            background=Color.white;
+        }
+        setBackground(background);
+    }
+
+
+    /**
+     * Construct a panel with the specified image
+     * @param imageURL the URL of the image to be used in the background
+     */
+    public ImagePanel(URL imageURL)
+    {
+        this();
+        setImageURL(imageURL);
+    }
+
+    public URL getImageURL()
+    {
+        return imageURL;
+    }
+
+    public void setImageURL(URL imageURL)
+    {
+        this.imageURL = imageURL;
+        try
+        {
+            setIcon(new ImageIcon(imageURL));
+        }
+        catch(Throwable t)
+        {
+        }
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeEvent.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeEvent.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeEvent.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,50 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+/** An Event class used to notify listeners that there has been a change
+*   in the MMonth data model
+*/
+public class MChangeEvent extends java.util.EventObject
+{
+    private Object value;
+    private int type;
+
+    /** The value has changed */
+    public final static int CHANGE=0;
+    public final static int EXIT=1;
+    /** The pull down has been 'pulled down' */
+    public final static int PULLDOWN_OPENED=2;
+    /** The pull down has been closed */
+    public final static int PULLDOWN_CLOSED=3;
+
+    public MChangeEvent(Object source, Object newValue, int type)
+    {
+        super(source);
+        this.value = newValue;
+        this.type=type;
+    }
+
+    public int getType()
+    {
+        return this.type;
+    }
+
+    public Object getValue()
+    {
+        return this.value;
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeListener.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeListener.java        
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MChangeListener.java        
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,21 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+import java.util.EventListener;
+
+public interface MChangeListener extends EventListener
+{
+    public void valueChanged(MChangeEvent event);
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryField.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryField.java        
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryField.java        
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,776 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import mseries.Calendar.MDateSelectorConstraints;
+import mseries.Calendar.MDefaultPullDownConstraints;
+import mseries.Calendar.MFieldListener;
+import mseries.utils.SafeCalendarUtils;
+
+import javax.swing.*;
+import javax.swing.event.EventListenerList;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.TextUI;
+import java.awt.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.logging.Logger;
+
+/**
+ *   Date entry component which looks like a combobox, when the button is 
pushed a calendar
+ *   drops down for selection of the date. Uses a JFormattedTextField as the 
display component
+ */
+public class MDateEntryField extends JComponent implements FocusListener
+{
+    private static final String uiClassID = "DateEntryUI";
+    protected MDateField display;
+    private boolean todayButton = false;
+    private boolean hasBorder = true;
+    private boolean nullOnEmpty = false;
+    private Logger logger=Logger.getLogger("mseries");
+
+    protected EventListenerList listenerList = new EventListenerList();
+
+    MDateSelectorConstraints panelConstraints = new 
MDefaultPullDownConstraints();
+
+    /**
+     *   Creates a MDateEntryField with default SHORT DateFormatter
+     */
+    public MDateEntryField()
+    {
+        this(DateFormat.getDateInstance(DateFormat.SHORT));
+    }
+
+    /**
+     * Creates a MDateEntryField with the formatter passed
+     * @param df the date formatter to use in the display and for parsing the 
value
+     * in the JFormattedTextField
+     */
+    public MDateEntryField(DateFormat df)
+    {
+        super();
+        display = new MDateField(df)
+        {
+            public void setUI(TextUI ui)
+            {
+                super.setUI(ui);
+                setBorder(null);
+            }
+        };
+        setValue(new Date());
+        display.addFocusListener(this);
+        updateUI();
+    }
+    /**
+     *   Creates a MDateEntryField
+     *   @param size the size of the display part of the component
+     *   @deprecated simply delegates to MDateEntryField()
+     */
+    public MDateEntryField(int size)
+    {
+        this();
+    }
+
+    /**
+     *   Returns the textfield that handles the date editing. Used by the 
UIDelegates
+     */
+    public MDateField getDisplay()
+    {
+        return display;
+    }
+
+    public void updateUI()
+    {
+        setUI(registerUIDelegate());
+    }
+
+    /**
+     * Delegates to the same method in the JFormattedTextField
+     * @return the focus lost behaviour
+     */
+    public int getFocusLostBehavior()
+    {
+        return display.getFocusLostBehavior();
+    }
+
+    /**
+     * Delegates to the same method in the JFormattedTextField
+     * @param b focus lost behaviour
+     */
+    public void setFocusLostBehavior(int b)
+    {
+        display.setFocusLostBehavior(b);
+    }
+    /**
+     *   Used to automatically install the UIDelagate for Windows & Metal Look 
& Feels. Any
+     *   other Look & Feel will get the basic look and feel unless a 
UIDelegate is provided
+     *   and set in the look and feel class.
+     *   @see #getUIClassID
+     */
+    protected ComponentUI registerUIDelegate()
+    {
+        ComponentUI compUI = (ComponentUI) UIManager.get(uiClassID);
+        if (compUI == null)
+        {
+            String uiDelegateClassName = "mseries.plaf.basic.BasicDateEntryUI";
+            String lafName = UIManager.getLookAndFeel().getID();
+            lafName=SafeCalendarUtils.squeeze(lafName);
+            /*
+            *   There is no UI Delegate for this component so try to install
+            *   one of the defaults
+            */
+            //if (lafName.equals("Windows"))
+            //{
+            //    uiDelegateClassName = "mseries.plaf." + lafName + "." + 
lafName + "DateEntryUI";
+            //}
+            //if (lafName.equals("Metal"))
+            //{
+            //    uiDelegateClassName = "mseries.plaf." + lafName + "." + 
lafName + "DateEntryUI";
+            //}
+            //if (lafName.equals("Motif"))
+            //{
+            //    uiDelegateClassName = "mseries.plaf." + lafName + "." + 
lafName + "DateEntryUI";
+            //}
+            //if (lafName.equals("Mac"))
+            //{
+            //    uiDelegateClassName = "mseries.plaf." + lafName + "." + 
lafName + "DateEntryUI";
+            //}
+            //if (lafName.equals("Aqua"))
+            //{
+            //    uiDelegateClassName = "mseries.plaf." + lafName + "." + 
lafName + "DateEntryUI";
+            //}
+            //UIManager.put(uiClassID, uiDelegateClassName);
+
+            uiDelegateClassName = "mseries.plaf." + lafName + "." + lafName + 
"DateEntryUI";
+            try
+            {
+                compUI = (ComponentUI) 
(Class.forName(uiDelegateClassName)).newInstance();
+            }
+            catch (Exception e)
+            {
+                logger.info("Class "+uiDelegateClassName+" not found, using 
default");
+                uiDelegateClassName = "mseries.plaf.basic.BasicDateEntryUI";
+                try
+                {
+                    compUI = (ComponentUI) 
(Class.forName(uiDelegateClassName)).newInstance();
+                }
+                catch (Exception e1)
+                {
+                    System.out.println(e1);
+                }
+            }
+        }
+        return compUI;
+    }
+
+    /**
+     *   This method gives the UI Manager a constant to use to look up in the 
UI Defaults table
+     *   to find the class name of the UI Delegate for the installed L&F.
+     *   @return string "DateEntryUI"
+     */
+    public String getUIClassID()
+    {
+        return uiClassID;
+    }
+
+
+    /**
+     *   @return the nullOnEmpty attribute
+     */
+    public boolean getNullOnEmpty()
+    {
+        return this.nullOnEmpty;
+    }
+
+    /**
+     *   If set to true the getValue method will return null when the text 
field is empty,
+     *   otherwise a ParseException is thrown since "" is not a valid date. 
Default is false.
+     *   @param nullOnEmpty set to true if a null is required when the 
textfield is empty
+     */
+    public void setNullOnEmpty(boolean nullOnEmpty)
+    {
+        this.nullOnEmpty = nullOnEmpty;
+    }
+
+    /**
+     *   @return the current value of the field
+     *   The value of the entry field, no parsing is performed, use getValue() 
to get a Date
+     */
+    public String getText()
+    {
+        return display.getText();
+    }
+
+    /**
+     *   This method does not do anything, the implementation is empty and it 
only
+     *   present to make the component a JavaBean
+     */
+    public void setText(String text)
+    {
+    }
+
+    /**
+     * Gets the name attribute which is delegated to the textfield used as the 
display component
+     * @return the name
+     */
+    public String getName()
+    {
+        return display.getName();
+    }
+
+    /**
+     * Sets the name attribute which is delegated to the textfield used as the 
display component
+     * @param name the name attribute
+     */
+    public void setName(String name)
+    {
+        display.setName(name);
+    }
+
+    /**
+     *   @return the current value of the field
+     *   @exception ParseException if it is not a valid date
+     */
+    public Date getValue() throws ParseException
+    {
+        Date ret=null;
+        if (nullOnEmpty && display.getText().equals(""))
+        {
+            ret = null;
+        }
+        else
+        {
+            display.commitEdit();
+            ret = (Date)display.getValue();
+        }
+        return ret;
+    }
+
+    /**
+     *   Sets the current value in the field, parsed using the current date 
formatter
+     *   @param newValue the new value
+     */
+    public void setValue(Date newValue)
+    {
+        display.setValue(newValue);
+    }
+
+    /**
+     *   Tells the component what date formatter to use for parsing and 
formatting
+     *   the user input.
+     *   @param df the date formatter
+     *   @deprecated use setFormatter(DateFormat)
+     */
+    public void setDateFormatter(MDateFormat df)
+    {
+        display.setDateFormatter(df);
+    }
+
+    /**
+     * @deprecated
+     */
+    public MDateFormat getDateFormatter()
+    {
+        return display.getDateFormatter();
+    }
+
+
+    //public void setDateFormatter(DateFormat df)
+    //{
+    //    display.setDateFormatter(df);
+    //}
+
+    public JFormattedTextField.AbstractFormatter getDateFormatter(Object x)
+    {
+        return display.getDateFormatter(x);
+    }
+
+    /** Sets the earliest value that may be selected for this field when
+     *   the poup calendar in invoked. The default is 1 January 1900
+     *   @param date the ealiest date
+     */
+    public void setMinimum(Date date)
+    {
+        display.setMinimum(date);
+    }
+
+    /** Sets the latest value that may be selected for this field when
+     *   the poup calendar in invoked. The default is 31 December 2037
+     *   @param date the latest date
+     */
+    public void setMaximum(Date date)
+    {
+        display.setMaximum(date);
+    }
+
+    public Date getMinimum()
+    {
+        return display.getMinimum();
+    }
+
+    public Date getMaximum()
+    {
+        return display.getMaximum();
+    }
+
+    /**
+     *   @return true if a border will be drawn
+     */
+    public boolean hasBorder()
+    {
+        return hasBorder;
+    }
+
+    /**
+     *   causes a border to be drawn around the component
+     *   @param border true is a border is to be drawn (default=true)
+     */
+    public void drawBorder(boolean border)
+    {
+        hasBorder = border;
+    }
+
+    /**
+     *   Returns the font that the editor part (the textfield) uses
+     *   @return the font for the date display
+     */
+    public Font getFont()
+    {
+        return display.getFont();
+    }
+
+    public void setFont(Font font)
+    {
+        display.setFont(font);
+    }
+
+    /**
+     *   @return the date fields editable property
+     */
+    public boolean isEnabled()
+    {
+        return display.isEnabled();
+    }
+
+    /**
+     *   Sets the date entry field editable or not, the button can still be 
used
+     *   to allow date selection.
+     *   @param editable <I>true</I> if the field can be typed into
+     */
+    public void setEditable(boolean editable)
+    {
+        display.setEditable(editable);
+    }
+
+    /**
+     *   @return the date fields editable property
+     */
+    public boolean isEditable()
+    {
+        return display.isEditable();
+    }
+
+    public void setInputVerifier(InputVerifier inputVerifier)
+    {
+        display.setInputVerifier(inputVerifier);
+        //this.inputVerifier=inputVerifier;
+    }
+
+    public InputVerifier getInputVerifier()
+    {
+        return display.getInputVerifier();
+    }
+
+    /**
+     *   Sets the constraints object that contains the parameters used to 
configure the
+     *   pull down calendar. Constraints include the visual aspects of the 
pull down such
+     *   as the colours, including the colours of the month and date changer, 
if the look and
+     *   feel permits it.
+     *   @param c the constraints object
+     *   @see #getConstraints
+     */
+    public void setConstraints(MDateSelectorConstraints c)
+    {
+        this.panelConstraints = c;
+    }
+
+    /**
+     *   Gets the constraints object that contains the parameters used to 
configure the
+     *   pull down calendar
+     *   @see #getConstraints
+     */
+    public MDateSelectorConstraints getConstraints()
+    {
+        return this.panelConstraints;
+    }
+
+    public void setToolTipText(String text)
+    {
+        display.setToolTipText(text);
+    }
+
+    public String getToolTipText()
+    {
+        return display.getToolTipText();
+    }
+
+    /**
+     *   This method is public as an implementation side effect, <b>do not 
override or call
+     *   it directly</b>
+     */
+    public void opened()
+    {
+        display.removeFocusListener(this);
+
+    }
+
+    /**
+     *   This method is public as an implementation side effect, <b>do not 
override or call
+     *   it directly</b>
+     */
+    public void closed()
+    {
+        display.addFocusListener(this);
+
+    }
+
+    /*
+    *   These private variables are concerned with managing the focus on the 
compound
+    *   component.
+    */
+    private int last = FocusEvent.FOCUS_LOST;
+
+    /**
+     *   This method is public as an implementation side effect, <b>do not 
override or call
+     *   it directly</b>
+     */
+    public void focusLost(FocusEvent e)
+    {
+        notifyListeners(e);
+    }
+
+    /**
+     *   Set focus on the receiving component if isRequestFocusEnabled returns 
true
+     */
+    public void requestFocus()
+    {
+            display.requestFocus();
+    }
+    /**
+     *   This method is public as an implementation side effect, <b>do not 
override or call
+     *   it directly</b>
+     */
+    public void focusGained(FocusEvent e)
+    {
+        notifyListeners(e);
+    }
+
+    /** Registers the listeners of the field changes. The event is fired when 
the component
+     *   gets and loses focus.
+     *   @param listener - MFieldListener
+     *   @see #removeMFieldListener
+     */
+    public void addMFieldListener(MFieldListener listener)
+    {
+        listenerList.add(MFieldListener.class, listener);
+    }
+
+    /** Removes the listener from the registered list
+     *   of listeners
+     *   @param listener - MFieldListener
+     */
+    public void removeMFieldListener(MFieldListener listener)
+    {
+        listenerList.remove(MFieldListener.class, listener);
+    }
+
+    public void notifyListeners(FocusEvent e)
+    {
+        int type = e.getID();
+
+        if (last != type)
+        {
+
+            Object[] listeners = 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] == MFieldListener.class)
+                {
+                    MFieldListener l = (MFieldListener) listeners[i + 1];
+                    if (type == FocusEvent.FOCUS_GAINED)
+                    {
+                        l.fieldEntered(new FocusEvent(this, type));
+                    }
+                    else
+                    {
+
+                        l.fieldExited(new FocusEvent(this, type));
+                    }
+                }
+            }
+            last = type;
+        }
+    }
+
+    /** Registers the listeners of the field changes. Fired when the user 
changes a value
+     *   in the dropped down calendar
+     *   @param listener - MMonthListener
+     */
+    public void addMChangeListener(MChangeListener listener)
+    {
+        listenerList.add(MChangeListener.class, listener);
+    }
+
+    /** Removes the listener from the registered list
+     *   of listeners
+     *   @param listener - MMonthListener
+     */
+    public void removeMChangeListener(MChangeListener listener)
+    {
+        listenerList.remove(MChangeListener.class, listener);
+    }
+
+    /**
+     *   Causes the MChangeEvents to be fired. This is called by the L&F 
Delegate
+     *   and should not be overloaded or called directly.
+     */
+    public void notifyListeners(int type)
+    {
+        // Pass these events on to the registered listener
+        MChangeEvent event;
+        Date date;
+        try
+        {
+            date = getValue();
+        }
+        catch (ParseException e)
+        {
+            date = null;
+        }
+        event = new MChangeEvent(this, date, type);
+
+
+        Object[] listeners = 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] == MChangeListener.class)
+            {
+                ((MChangeListener) listeners[i + 1]).valueChanged(event);
+            }
+        }
+    }
+
+    /**
+     *   The pull down can be configured with a button at the bottom to 
quickly select the
+     *   current date. The label is translated using the ResourceBundle given 
in the contraints
+     *   object passed in the setConstraints() method (or the default which is 
false), by default
+     *   the popup closes when the button is pushed, this behaviour can be 
changed by setting the
+     *   closeOnToday attribute.
+     *   @param show set this to true if the button is required.
+     *   @see mseries.Calendar.MDateSelectorConstraints
+     */
+    public void setShowTodayButton(boolean show)
+    {
+        setShowTodayButton(show, true);
+    }
+
+    /**
+     *   Does this field have a today button when the pull down is shown ?
+     *   @return true if a 'today' button is displayed.
+     *   @see #setShowTodayButton
+     */
+    public boolean getShowTodayButton()
+    {
+        return todayButton;
+    }
+
+    private boolean closeOnToday = true;
+
+    /**
+     *   The pull down can be configured with a button at the bottom to 
quickly select the
+     *   current date. The label is translated using the ResourceBundle given 
in the contraints
+     *   object passed in the setConstraints() method (or the default which is 
false).
+     *   @param show set this to true if the button is required.
+     *   @param close the popup closes when close is true (default)
+     *   @see mseries.Calendar.MDateSelectorConstraints
+     */
+    public void setShowTodayButton(boolean show, boolean close)
+    {
+        this.todayButton = show;
+        this.closeOnToday = close;
+    }
+
+    /**
+     *   @return the close on today attribute
+     */
+    public boolean getCloseOnToday()
+    {
+        return this.closeOnToday;
+    }
+}
+
+class ShortFormatter implements MDateFormat
+{
+
+    DateFormat formatter;
+
+    public ShortFormatter()
+    {
+        formatter = DateFormat.getDateInstance(DateFormat.SHORT);
+    }
+
+    public StringBuffer format(Date d, StringBuffer appendTo, FieldPosition 
pos)
+    {
+        return formatter.format(d, appendTo, pos);
+    }
+
+    public String format(Date d)
+    {
+        return formatter.format(d);
+    }
+
+    public Date parse(String s) throws ParseException
+    {
+        return formatter.parse(s);
+    }
+}
+
+// $Log: MDateEntryField.java,v $
+// Revision 1.31  2004/09/06 19:27:15  martin
+// added support for nullOnEmpty
+//
+// Revision 1.30  2004/05/21 19:30:59  martin
+// *** empty log message ***
+//
+// Revision 1.29  2004/05/05 22:26:13  martin
+// *** empty log message ***
+//
+// Revision 1.28  2004/03/21 09:55:16  martin
+// *** empty log message ***
+//
+// Revision 1.27  2004/03/07 17:11:06  martin
+// *** empty log message ***
+//
+// Revision 1.26  2004/03/05 23:25:00  martin
+// *** empty log message ***
+//
+// Revision 1.25  2003/10/02 20:28:38  martin
+// *** empty log message ***
+//
+// Revision 1.24  2003/09/25 18:36:11  martin
+// no message
+//
+// Revision 1.23  2003/04/10 19:04:38  martin
+// *** empty log message ***
+//
+// Revision 1.22  2003/03/26 23:29:50  martin
+// Changed email address
+//
+// Revision 1.21  2003/03/24 19:45:07  martin
+// Latest 1.4 version
+//
+// Revision 1.19  2003/03/11 22:35:15  martin
+// Upgraded to Java 1.4 on 11/03/03
+//
+// Revision 1.18  2003/01/18 16:40:09  martin
+// *** empty log message ***
+//
+// Revision 1.17  2003/01/15 21:47:34  martin
+// *** empty log message ***
+//
+// Revision 1.16  2003/01/08 20:47:19  martin
+// Overrode setInputVerifier method and delegate to display
+//
+// Revision 1.15  2002/12/21 23:03:25  martin
+// *** empty log message ***
+//
+// Revision 1.14  2002/12/21 22:53:16  martin
+// *** empty log message ***
+//
+// Revision 1.13  2002/12/15 17:44:16  martin
+// *** empty log message ***
+//
+// Revision 1.12  2002/06/13 19:25:24  martin
+// Added closeOnToday button support
+//
+// Revision 1.11  2002/06/09 13:59:45  martin
+// Adjusted Javadoc comment
+//
+// Revision 1.10  2002/06/09 13:58:51  martin
+// Adjusted Javadoc comment
+//
+// Revision 1.9  2002/06/09 13:53:44  martin
+// Adjusted Javadoc comment
+//
+// Revision 1.8  2002/06/09 13:48:05  martin
+// Added 'Today' button
+//
+// Revision 1.7  2002/04/19 20:41:40  martin
+// Make the default date format locale sensitive and SHORT
+//
+// Revision 1.6  2002/03/03 09:49:38  martin
+// Changed listener list to javax.swing.event.ListenerList
+//
+// Revision 1.5  2002/02/19 20:28:44  martin
+// Ensure that the MFieldEvents have the correct source
+//
+// $Log: MDateEntryField.java,v $
+// Revision 1.31  2004/09/06 19:27:15  martin
+// added support for nullOnEmpty
+//
+// Revision 1.30  2004/05/21 19:30:59  martin
+// *** empty log message ***
+//
+// Revision 1.29  2004/05/05 22:26:13  martin
+// *** empty log message ***
+//
+// Revision 1.28  2004/03/21 09:55:16  martin
+// *** empty log message ***
+//
+// Revision 1.27  2004/03/07 17:11:06  martin
+// *** empty log message ***
+//
+// Revision 1.26  2004/03/05 23:25:00  martin
+// *** empty log message ***
+//
+// Revision 1.25  2003/10/02 20:28:38  martin
+// *** empty log message ***
+//
+// Revision 1.24  2003/09/25 18:36:11  martin
+// no message
+//
+// Revision 1.23  2003/04/10 19:04:38  martin
+// *** empty log message ***
+//
+// Revision 1.22  2003/03/26 23:29:50  martin
+// Changed email address
+//
+// Revision 1.21  2003/03/24 19:45:07  martin
+// Latest 1.4 version
+//
+// Revision 1.19  2003/03/11 22:35:15  martin
+// Upgraded to Java 1.4 on 11/03/03
+//
+// Revision 1.4.2.1  2002/02/24 10:46:47  martin
+// Focus Events have correct source. Field does not grab focus
+//

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryFieldBeanInfo.java
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryFieldBeanInfo.java    
    2006-03-14 14:03:34 UTC (rev 8248)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateEntryFieldBeanInfo.java    
    2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,138 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.beans.*;
+
+import mseries.Calendar.*;
+
+/**
+*   Bean Info class for MDateSelectorPanel. Not all attributes are editable in 
the
+*   beanbox but most are.
+*/
+public class MDateEntryFieldBeanInfo extends SimpleBeanInfo
+{
+    Class mdsClass = MDateEntryField.class;
+
+/*
+    public Image getIcon(int kind)
+    {
+        Image image = null;
+
+        if (kind == BeanInfo.ICON_COLOR_16x16)
+        {
+            image = loadImage("calicon16.gif");
+        }
+        else if (kind == BeanInfo.ICON_COLOR_32x32)
+        {
+            image = loadImage("calicon32.gif");
+        }
+        return image;
+    }
+*/
+
+    public EventSetDescriptor[] getEventSetDescriptors()
+    {
+        EventSetDescriptor entered=null;
+        EventSetDescriptor changed=null;
+        try
+        {
+            String[] methods= {"fieldEntered", "fieldExited"};
+            entered = new EventSetDescriptor(mdsClass,
+                                            "mField",
+                                            
mseries.Calendar.MFieldListener.class,
+                                            methods,
+                                            "addMFieldListener",
+                                            "removeMFieldListener");
+            changed = new EventSetDescriptor(mdsClass,
+                                           "mChange",
+                                           mseries.ui.MChangeListener.class,
+                                           "valueChanged");
+
+        }
+        catch (IntrospectionException e)
+        {
+        }
+        EventSetDescriptor[] events = {entered, changed};
+        return events;
+    }
+
+    public PropertyDescriptor[] getPropertyDescriptors()
+    {
+        try
+        {
+            PropertyDescriptor
+                date = new PropertyDescriptor("value", mdsClass),
+                format = new PropertyDescriptor("dateFormatter", mdsClass);
+/*
+                text = new PropertyDescriptor("text", mdsClass);
+                foreground = new PropertyDescriptor("foreground", mdsClass),
+                background = new PropertyDescriptor("background", mdsClass),
+                db = new PropertyDescriptor("doubleBuffered", mdsClass),
+                opaque = new PropertyDescriptor("opaque", mdsClass),
+                autoscrolls = new PropertyDescriptor("autoscrolls", mdsClass),
+                alx = new PropertyDescriptor("alignmentX", mdsClass),
+                aly = new PropertyDescriptor("alignmentY", mdsClass),
+                dgo = new PropertyDescriptor("debugGraphicsOptions", mdsClass),
+                rfe = new PropertyDescriptor("requestFocusEnabled", mdsClass),
+                ps = new PropertyDescriptor("preferredSize", mdsClass),
+                maxS = new PropertyDescriptor("maximumSize", mdsClass),
+                minS = new PropertyDescriptor("minimumSize", mdsClass),
+                b = new PropertyDescriptor("border", mdsClass),
+                max = new PropertyDescriptor("maximum", mdsClass),
+                min = new PropertyDescriptor("minimum", mdsClass),
+                tl = new PropertyDescriptor("textLocalizer", mdsClass),
+                nfc = new PropertyDescriptor("nextFocusableComponent", 
mdsClass),
+                fd = new PropertyDescriptor("firstDay", mdsClass),
+                font = new PropertyDescriptor("font", mdsClass);
+
+
+            ps.setHidden(true);
+            maxS.setHidden(true);
+            minS.setHidden(true);
+            b.setHidden(true);
+            db.setHidden(true);
+            opaque.setHidden(true);
+            autoscrolls.setHidden(true);
+            alx.setHidden(true);
+            aly.setHidden(true);
+            dgo.setHidden(true);
+            rfe.setHidden(true);
+            nfc.setHidden(true);
+*/
+
+            date.setPropertyEditorClass(MDateValueEditor.class);
+            format.setPropertyEditorClass(MDateFormatEditor.class);
+/*
+            max.setPropertyEditorClass(MDateValueEditor.class);
+            min.setPropertyEditorClass(MDateValueEditor.class);
+            fd.setPropertyEditorClass(MFirstDayEditor.class);
+            tl.setPropertyEditorClass(MTextLocaliserEditor.class);
+            min.setShortDescription("Minimum Value");
+            max.setShortDescription("Maximum Value");
+*/
+            date.setShortDescription("Current Value");
+            format.setShortDescription("Date Format");
+
+            PropertyDescriptor[] pd = {date, format};
+            return pd;
+        }
+        catch (IntrospectionException e)
+        {
+            System.out.println("Exception is "+e.getMessage());
+            return super.getPropertyDescriptors();
+        }
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormat.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormat.java    
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormat.java    
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,35 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.text.ParseException;
+import java.text.FieldPosition;
+import java.util.Date;
+
+/**
+*   A simple interface to define format and parse methods, this may be simply 
implemented by
+*   a subclass of java.text.DateFormat or something more sophisticated such as
+*   mseries.ui.MDateFormatter
+*   @see mseries.ui.MDateFormatter
+*/
+public interface MDateFormat
+{
+    public StringBuffer format(Date d, StringBuffer appendTo, FieldPosition 
pos);
+
+    public String format(Date d);
+
+    public Date parse(String s) throws ParseException;
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatEditor.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatEditor.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatEditor.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,103 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+import java.awt.event.TextEvent;
+import java.awt.event.TextListener;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.beans.PropertyEditor;
+
+public class MDateFormatEditor implements PropertyEditor
+{
+
+    protected String value; // The thing being edited
+    protected PropertyChangeSupport listeners = new 
PropertyChangeSupport(this);
+
+    public MDateFormatEditor()
+    {
+    }
+
+    public String getJavaInitializationString()
+    {
+        return "new mseries.ui.MSimpleDateFormat(\""+value.toString()+"\")";
+    }
+
+    public boolean isPaintable()
+    {
+        return false;
+    }
+
+    public void paintValue(Graphics g, Rectangle r)
+    {
+        g.setClip(r);
+        g.drawString(getAsText(), r.x+5, r.y+15);
+    }
+
+    public Component getCustomEditor()
+    {
+        final TextField t = new TextField(getAsText(), 20);
+
+        t.addTextListener(new TextListener() {
+            public void textValueChanged(TextEvent e)
+            {
+                setAsText(t.getText());
+            }
+        });
+        return t;
+    }
+
+    public String getAsText()
+    {
+        return value;
+    }
+
+    public void setAsText(String s)
+    {
+        value = s;
+        listeners.firePropertyChange("dateFormatter", null, null);
+    }
+
+    public void setValue(Object object)
+    {
+        value = object.toString();
+    }
+
+    public Object getValue()
+    {
+        return new MSimpleDateFormat(value.toString());
+    }
+
+    public String[] getTags()
+    {
+        return null;
+    }
+
+    public boolean supportsCustomEditor()
+    {
+        return true;
+    }
+
+    public void addPropertyChangeListener(PropertyChangeListener l)
+    {
+        listeners.addPropertyChangeListener(l);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener l)
+    {
+        listeners.removePropertyChangeListener(l);
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateSpinnerModel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateSpinnerModel.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateSpinnerModel.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,329 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+*   Spinner model to manage a range of dates. This one is a little special in 
that in allows
+*   each part (month, day, year etc) of a date to be spun independantly. In 
other words
+*   the step is variable .The value is always a Date but the step changes 
usually by the
+*   editor according to where the user places the cursor.
+*/
+public class MDateSpinnerModel extends DefaultSpinnerModel
+{
+    private int step;
+    //private Date value;
+    private Calendar m_calendar=Calendar.getInstance();
+
+    private Date maxDate, minDate;
+
+    private DateFormat df;
+    private static final int UP=1;
+    private static final int DOWN=-1;
+
+    /**
+    *   Constructor.
+    *   @param start the initial value
+    *   @param max the maximum value allowed
+    *   @param min the minimum value allowed
+    */
+    public MDateSpinnerModel(Date start, Comparable max, Comparable min)
+    {
+        setMaximum(max);
+        setMinimum(min);
+        setValue(start);
+    }
+
+    /**
+    *   Constructor with default minimum and maximum values (1/1/1970 and 
31/12/2037 respectively)
+    *   @param start the initial value
+    */
+    public MDateSpinnerModel(Date start)
+    {
+        try
+        {
+            df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("en", 
"GB"));
+            maxDate=df.parse("31/12/2037");
+            minDate=df.parse("1/1/1970");
+        }
+        catch(Exception e)
+        {
+        }
+        setValue(start);
+    }
+
+    /**
+    *   Defualt constructor initialised to todays date and default maximum and 
minimum
+    */
+    public MDateSpinnerModel()
+    {
+        this(new Date());
+    }
+
+    /**
+    *   Sets the step which is a constant from java.text.DateFormat
+    *   @param step the step value
+    */
+    public void setStep(int step)
+    {
+        this.step=step;
+    }
+
+    /**
+    *   @return the step value
+    */
+    private int getStep()
+    {
+        return step;
+    }
+    /**
+    *   Returns the current value of the field
+    *   @return the current value of the field
+    */
+    public Object getValue()
+    {
+        return m_calendar.getTime();
+    }
+
+    /**
+    *   Sets a new value in the model
+    *   @param newValue the new value
+    */
+    public void setValue(Object newValue)
+    {
+        Date x = (Date)newValue;
+        if (!x.before(minDate) && !x.after(maxDate))
+        {
+            m_calendar.setTime(x);
+            notifyListeners();
+        }
+    }
+
+    /**
+    *   Sets the maximum allowed value in the model
+    *   @param max the maximum value
+    */
+    public void setMaximum(Comparable max)
+    {
+        if (max instanceof java.util.Date)
+        {
+            maxDate=(Date)max;
+        }
+        Date d = (Date)getValue();
+        if (d.after(maxDate))
+        {
+            setValue(maxDate);
+        }
+    }
+
+    /**
+    *   Returns the maximum value
+    *   @return the maximum value
+    */
+    public Comparable getMaximum()
+    {
+        return maxDate;
+    }
+
+    /**
+    *   Sets the minimum allowed value in the model
+    *   @param min the minimum value
+    */
+    public void setMinimum(Comparable min)
+    {
+        if (min instanceof java.util.Date)
+        {
+            minDate=(Date)min;
+        }
+        Date d = (Date)getValue();
+        if (d.before(minDate))
+        {
+            setValue(minDate);
+        }
+    }
+
+    /**
+    *   Returns the minimum value
+    *   @return the minimum value
+    */
+    public Comparable getMinimum()
+    {
+        return minDate;
+    }
+
+    /**
+    *   Advance and return the next value in the sequence according to the 
step value and
+    *   maximum
+    *   @return the next value
+    */
+    public Object getNextValue()
+    {
+        Date d = (Date)changeValue(getStep(), UP);
+
+        if (!d.after(maxDate))
+        {
+            setValue(d);
+        }
+        return getValue();
+    }
+
+    /**
+    *   Advance and return the previous value in the sequence according to the 
step value and
+    *   minimum
+    *   @return the previous value
+    */
+    public Object getPreviousValue()
+    {
+        Date d = (Date)changeValue(getStep(), DOWN);
+
+        if (!d.before(minDate))
+        {
+            setValue(d);
+        }
+        return getValue();
+    }
+
+    private Object changeValue(int step, int dir)
+    {
+        Calendar cal=(Calendar)m_calendar.clone();
+        Date m_lastDate=cal.getTime();
+        int d=cal.get(Calendar.DAY_OF_MONTH);
+        cal.set(Calendar.DAY_OF_MONTH, 1);
+
+        boolean dateSet = true;
+
+        switch (step)
+        {
+
+            case DateFormat.AM_PM_FIELD:
+                // If the time is AM, add 12 hours, if it is PM subtract 12 
hours
+                int ampm=cal.get(Calendar.AM_PM);
+                int mult= (ampm==Calendar.AM) ? 12 : -12;
+
+                cal.set(Calendar.HOUR,
+                               cal.get(Calendar.HOUR) + mult);
+
+                break;
+
+            case DateFormat.DATE_FIELD:
+
+            case DateFormat.DAY_OF_WEEK_FIELD:
+
+            case DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD:
+
+            case DateFormat.DAY_OF_YEAR_FIELD:
+                cal.set(Calendar.DAY_OF_YEAR,
+                               cal.get(Calendar.DAY_OF_YEAR)
+                               + dir);
+                break;
+
+            case DateFormat.ERA_FIELD:
+                dateSet = false;
+
+                break;
+
+            case DateFormat.HOUR0_FIELD:
+
+            case DateFormat.HOUR1_FIELD:
+
+            case DateFormat.HOUR_OF_DAY0_FIELD:
+
+            case DateFormat.HOUR_OF_DAY1_FIELD:
+
+                cal.set(Calendar.HOUR,
+                               cal.get(Calendar.HOUR)
+                               + dir);
+                break;
+
+            case DateFormat.MILLISECOND_FIELD:
+                cal.set(Calendar.MILLISECOND,
+                               cal.get(Calendar.MILLISECOND)
+                               + dir);
+                break;
+
+            case DateFormat.MINUTE_FIELD:
+                cal.set(Calendar.MINUTE,
+                               cal.get(Calendar.MINUTE)
+                               + dir);
+
+                break;
+
+            case DateFormat.MONTH_FIELD:
+                cal.set(Calendar.MONTH,
+                               cal.get(Calendar.MONTH)
+                               + dir);
+                int max=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+                cal.set(Calendar.DAY_OF_MONTH, d > max ? max : d);
+
+                m_lastDate = cal.getTime();
+
+                break;
+
+            case DateFormat.SECOND_FIELD:
+                cal.set(Calendar.SECOND,
+                               cal.get(Calendar.SECOND)
+                               + dir);
+
+                break;
+
+            case DateFormat.WEEK_OF_MONTH_FIELD:
+                cal.set(Calendar.WEEK_OF_MONTH,
+                               cal.get(Calendar.WEEK_OF_MONTH)
+                               + dir);
+
+                break;
+
+            case DateFormat.WEEK_OF_YEAR_FIELD:
+                cal.set(Calendar.WEEK_OF_MONTH,
+                               cal.get(Calendar.WEEK_OF_MONTH)
+                               + dir);
+
+                break;
+
+            case DateFormat.YEAR_FIELD:
+                cal.set(Calendar.YEAR,
+                               cal.get(Calendar.YEAR)
+                               + dir);
+
+                break;
+
+            default:
+                dateSet = false;
+        }
+
+        if (dateSet)
+        {
+            m_lastDate = cal.getTime();
+        }
+        return m_lastDate;
+    }
+}
+// $Log: MDateSpinnerModel.java,v $
+// Revision 1.8  2003/08/22 21:52:45  martin
+// no message
+//
+// Revision 1.7  2003/08/22 20:38:28  martin
+// no message
+//
+// Revision 1.5  2003/03/26 23:29:50  martin
+// Changed email address
+//
+// Revision 1.4  2002/08/17 19:55:54  martin
+// Added CVS log tag
+//

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MImagePanel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MImagePanel.java    
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MImagePanel.java    
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,124 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+import java.io.*;
+import java.net.*;
+
+/**
+*   A simple subclass of JPanel that provides a background image
+*/
+public class MImagePanel extends javax.swing.JPanel
+{
+    URL imageURL;
+
+    String file="";
+    File f;
+    Image img;
+
+    public MImagePanel(LayoutManager layout)
+    {
+        super(layout);
+    }
+
+    protected void paintComponent(Graphics g)
+    {
+        if (g==null)
+            return;
+
+        if (!file.equals(""))
+        {
+            img = loadImage(this);
+            g.drawImage(img, 0, 0, this);
+            return;
+        }
+        super.paintComponent(g);
+        return;
+    }
+
+    protected Image loadImage(Component comp)
+    {
+        Image i=null;
+
+        i = comp.getToolkit().getImage(imageURL);
+        MediaTracker m = new MediaTracker(comp);
+        m.addImage(i, 0);
+        try
+        {
+            m.waitForAll();
+        }
+        catch(InterruptedException ee)
+        {
+        }
+        return i;
+    }
+
+    public void setImageURL(URL imageURL)
+    {
+        this.imageURL=imageURL;
+    }
+
+    public void setImageFile(String file)
+    {
+        f = new File(file);
+        if (f.exists())
+        {
+            this.file=file;
+            try
+            {
+                imageURL=new URL("file:///"+file);
+            }
+            catch(MalformedURLException e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public String getImageFile()
+    {
+        return file;
+    }
+
+    public boolean hasImage()
+    {
+        return (!file.equals(""));
+    }
+
+/* Uncomment for unit testing
+
+    public static void main(String[] argv)
+    {
+        MImagePanel panel = new MImagePanel(new FlowLayout());
+        panel.setImageFile(argv[0]);
+        panel.add(new javax.swing.JButton("OK"));
+        panel.add(new javax.swing.JButton("OK"));
+        panel.add(new javax.swing.JButton("OK"));
+        panel.add(new javax.swing.JButton("OK"));
+
+        javax.swing.JFrame f = new javax.swing.JFrame("Panel Test");
+
+        f.getContentPane().setLayout(new FlowLayout());
+
+        f.getContentPane().add(panel);
+
+        f.pack();
+        f.show();
+    }
+*/
+
+
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopup.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopup.java 2006-03-14 
14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopup.java 2006-03-14 
14:05:14 UTC (rev 8249)
@@ -0,0 +1,80 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*   Reaped from javax.swing.JPopupMenu
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+/**
+* The following interface describes what a popup should implement.
+* We do this because Popup Calendar uses popup that can be windows or
+* panels.
+*/
+public interface MPopup
+{
+    /** Lightweight popup type (JPanel) */
+    public static final int LIGHT=0;
+    /** Mediumweight popup type (Panel) not yet implemented */
+    public static final int MEDIUM=1;
+    /** Heavyweight popup type (JWindow) */
+    public static final int HEAVY=2;
+
+    public void addComponent(Component aComponent,Object constraints);
+    public void removeComponent(Component c);
+    public void pack();
+    public void setParent(Component invoker);
+    public void setVisible(boolean visible);
+    public boolean isVisible();
+    public void setLocationOnScreen(int x,int y);
+    public void requestFocus();
+    public int getWeight();
+    public void setShadow(boolean hasShadow);
+    public boolean isShadow();
+}
+/* $Log: MPopup.java,v $
+/* Revision 1.9  2003/10/04 09:47:39  martin
+/* *** empty log message ***
+/*
+/* Revision 1.8  2003/03/26 23:29:50  martin
+/* Changed email address
+/*
+/* Revision 1.7  2002/01/31 21:31:28  martin
+/* no message
+/*
+/* Revision 1.6  2002/01/31 21:20:04  martin
+/* 131
+/*
+/* Revision 1.5  2002/01/31 21:14:50  martin
+/* 131
+/*
+/* Revision 1.4  2002/01/22 20:38:15  martin
+/* Tiny change
+/*
+/* Revision 1.3  2001/11/21 21:18:43  martin
+/* removed controlMs
+/*
+/* Revision 1.2  2001/11/21 21:17:44  martin
+/* Added Revision 1.6  2002/01/31 21:20:04  martin
+/* Added 131
+/* Added
+/* Added Revision 1.5  2002/01/31 21:14:50  martin
+/* Added 131
+/* Added
+/* Added Revision 1.4  2002/01/22 20:38:15  martin
+/* Added Tiny change
+/* Added
+/* Added Revision 1.3  2001/11/21 21:18:43  martin
+/* Added removed controlMs
+/* Added
+/* */

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupDialog.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupDialog.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupDialog.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,149 @@
+/*
+*   Author Martin Newstead (mseries at brundell.fsnet.co.uk).  All Rights 
Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*
+*   Reaped from javax.swing.JPopupMenu with thanks
+*/
+package mseries.ui;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+  /**
+   * A class used to popup a window.
+   * <p>
+   * <strong>Warning:</strong>
+   * Serialized objects of this class will not be compatible with
+   * future Swing releases.  The current serialization support is appropriate
+   * for short term storage or RMI between applications running the same
+   * version of Swing.  A future release of Swing will provide support for
+   * long term persistence.
+   */
+  public class MPopupDialog extends JDialog implements MPopup, FocusListener, 
Serializable
+  {
+    int saveX,saveY;
+    boolean  firstShow = true;
+    boolean isVisible=false;
+    boolean hasShadow=false;
+    Component firstComp=null;
+
+    JButton a;
+
+    public MPopupDialog(Frame owner)
+    {
+           super(owner);
+        init();
+    }
+
+    public MPopupDialog(Dialog owner)
+    {
+        super(owner);
+        init();
+    }
+
+    public MPopupDialog()
+    {
+        init();
+    }
+
+    private void init()
+    {
+        addFocusListener(this);
+        setUndecorated(true);
+    }
+    public void focusGained(FocusEvent e)
+    {
+        firstComp.requestFocus();
+        dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_ACTIVATED));
+    }
+
+    public void focusLost(FocusEvent e)
+    {
+    }
+
+    public void update(Graphics g)
+    {
+      paint(g);
+    }
+
+    public void setParent(Component invoker)
+    {
+    }
+
+    public void setLocationOnScreen(int x,int y)
+    {
+      this.setLocation(x,y);
+    }
+
+    public void addComponent(Component aComponent,Object constraints)
+    {
+        this.getContentPane().add(aComponent,constraints);
+        if (firstComp == null)
+        {
+            firstComp=aComponent;
+        }
+    }
+
+    public void removeComponent(Component c)
+    {
+      this.getContentPane().remove(c);
+    }
+
+    public void setBorder(Border border)
+    {
+    }
+
+    public int getWeight()
+    {
+        return MPopup.HEAVY;
+    }
+
+    public void setShadow(boolean hasShadow)
+    {
+    }
+
+    /**
+    *   Heavy weight panels can not be opaque and therefore a shadow can not be
+    *   transparant.
+    */
+    public boolean isShadow()
+    {
+        return hasShadow;
+    }
+
+    public void setVisible(boolean visible)
+    {
+        super.setVisible(visible);
+        if (visible)
+        {
+            toFront();
+        }
+    }
+}
+/* $Log: MPopupDialog.java,v $
+/* Revision 1.5  2003/03/26 23:29:50  martin
+/* Changed email address
+/*
+/* Revision 1.4  2003/03/24 19:45:07  martin
+/* Latest 1.4 version
+/*
+/* Revision 1.2  2003/03/11 22:35:16  martin
+/* Upgraded to Java 1.4 on 11/03/03
+/*
+/* Revision 1.1.2.1  2002/01/31 22:47:15  martin
+/* New  for Java 1.4
+/*
+*/
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupWindow.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupWindow.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupWindow.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,135 @@
+/*
+*   Author Martin Newstead (mseries at brundell.fsnet.co.uk).  All Rights 
Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*
+*   Reaped from javax.swing.JPopupMenu with thanks
+*/
+package mseries.ui;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+  /**
+   * A class used to popup a window.
+   * <p>
+   * <strong>Warning:</strong>
+   * Serialized objects of this class will not be compatible with
+   * future Swing releases.  The current serialization support is appropriate
+   * for short term storage or RMI between applications running the same
+   * version of Swing.  A future release of Swing will provide support for
+   * long term persistence.
+   */
+  public class MPopupWindow extends JWindow implements MPopup, FocusListener, 
Serializable
+  {
+    int saveX,saveY;
+    boolean  firstShow = true;
+    boolean isVisible=false;
+    boolean hasShadow=false;
+    Component firstComp=null;
+
+    JButton a;
+
+    public MPopupWindow(Window owner)
+    {
+           super(owner);
+        addFocusListener(this);
+    }
+
+    public MPopupWindow()
+    {
+        addFocusListener(this);
+    }
+
+    public void focusGained(FocusEvent e)
+    {
+        dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_ACTIVATED));
+        firstComp.requestFocus();
+    }
+
+    public void focusLost(FocusEvent e)
+    {
+    }
+
+    public void update(Graphics g)
+    {
+      paint(g);
+    }
+
+    public void setParent(Component invoker)
+    {
+    }
+
+    public void setLocationOnScreen(int x,int y)
+    {
+      this.setLocation(x,y);
+    }
+
+    public void addComponent(Component aComponent,Object constraints)
+    {
+        this.getContentPane().add(aComponent,constraints);
+        if (firstComp == null)
+        {
+            firstComp=aComponent;
+        }
+    }
+
+    public void removeComponent(Component c)
+    {
+      this.getContentPane().remove(c);
+    }
+
+    public void setBorder(Border border){}
+
+    public int getWeight()
+    {
+        return MPopup.HEAVY;
+    }
+
+    public void setShadow(boolean hasShadow)
+    {
+    }
+
+    /**
+    *   Heavy weight panels can not be opaque and therefore a shadow can not be
+    *   transparant.
+    */
+    public boolean isShadow()
+    {
+        return hasShadow;
+    }
+
+    public void setVisible(boolean visible)
+    {
+        super.setVisible(visible);
+        if (visible)
+        {
+            toFront();
+        }
+    }
+}
+/* $Log: MPopupWindow.java,v $
+/* Revision 1.6  2003/03/26 23:29:50  martin
+/* Changed email address
+/*
+/* Revision 1.5  2002/01/30 21:45:05  martin
+/* Fixed Focus problem
+/*
+/* Revision 1.4  2002/01/22 21:35:21  martin
+/* Provided new constructor to pass owner
+/*
+/* Revision 1.3  2002/01/15 20:01:27  martin
+/* Over rode setVisible(boolean) from Window
+/* */
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MSimpleDateFormat.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MSimpleDateFormat.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MSimpleDateFormat.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,55 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+import java.text.*;
+import java.util.*;
+
+/**
+*   Simple implementation of MDateFormat to allow a date formatter to be 
quickly built
+*   by simply applying a format as a String
+*/
+
+public class MSimpleDateFormat extends SimpleDateFormat implements MDateFormat
+{
+        public MSimpleDateFormat()
+        {
+            super();
+            setLenient(false);
+        }
+
+        public MSimpleDateFormat(String pattern)
+        {
+            super(pattern);
+            setLenient(false);
+        }
+
+        public MSimpleDateFormat(String pattern, DateFormatSymbols formatData)
+        {
+            super(pattern, formatData);
+            setLenient(false);
+        }
+
+        public MSimpleDateFormat(String pattern, Locale loc)
+        {
+            super(pattern, loc);
+            setLenient(false);
+        }
+
+        public String toString()
+        {
+             return toPattern();
+        }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/RollOverButton.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/RollOverButton.java 
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/RollOverButton.java 
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,56 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+
+
+/**
+ *   An arrow button with no border, until the mouse rolls over when the L&F 
border is drawn
+ */
+public class RollOverButton extends ArrowButton
+{
+    int direction;
+
+    public RollOverButton(int dir)
+    {
+        super(dir);
+        setRolloverEnabled(true);
+    }
+
+    protected void paintBorder(Graphics g)
+    {
+        setBorderPainted(getModel().isRollover());
+        super.paintBorder(g);
+    }
+
+}
+
+// $Log: RollOverButton.java,v $
+// Revision 1.5  2003/03/26 23:29:50  martin
+// Changed email address
+//
+// Revision 1.4  2002/12/21 22:53:16  martin
+// *** empty log message ***
+//
+// Revision 1.3  2002/07/21 16:25:20  martin
+// no message
+//
+// Revision 1.2  2002/06/18 21:32:55  martin
+// no message
+//
+// Revision 1.1  2002/06/16 21:46:43  martin
+// new file
+//

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ScreenUtilities.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ScreenUtilities.java        
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ScreenUtilities.java        
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,150 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import javax.swing.*;
+
+public class ScreenUtilities
+{
+
+
+    /**
+    *   Finds the parent container (Window, JRootPane) of the component. This 
is useful
+    *   for drawing components in the container since all co-ords are reltive 
to the component
+    *   and not its parent
+    *   @param c the component
+    *   @return its parent
+    */
+    public static Container getParentWindow(Component c)
+    {
+        Container parent = null;
+        if (c != null)
+        {
+            parent = c.getParent();
+        }
+
+        for(Container p = parent; p != null; p = p.getParent())
+        {
+            if(p instanceof JRootPane)
+            {
+                    if(p.getParent() instanceof JInternalFrame)
+                {
+                        continue;
+                }
+
+                parent = ((JRootPane)p).getLayeredPane();
+                for(p = parent.getParent(); p != null && (!(p instanceof 
java.awt.Window));
+                p = p.getParent());
+                break;
+            }
+            else if(p instanceof Window)
+            {
+                parent = p;
+                break;
+            }
+        }
+        return parent;
+    }
+
+    /**
+    *   Given a point ona screen this method calculates the absolute point in 
the
+    *   parent container (Frame)
+    */
+    public static Point convertScreenLocationToParent(Container parent,int 
x,int y)
+    {
+        Window parentWindow = null;
+        for(Container p = parent; p != null; p = p.getParent())
+        {
+            if(p instanceof Window)
+            {
+                parentWindow = (Window)p;
+                break;
+            }
+        }
+        if(parentWindow != null)
+        {
+            Point p = new Point(x,y);
+            SwingUtilities.convertPointFromScreen(p,parent);
+            return p;
+        }
+        else
+        {
+            throw new Error("convertScreenLocationToParent: no window ancestor 
found");
+        }
+    }
+
+    /**
+    *   @return a Dialog that is the first one in the hierarchy
+    *   containing the component passed component
+    */
+    public static Dialog getParentDialog(Component child)
+    {
+        Dialog parentWindow = null;
+        for(Container p = child.getParent(); p != null; p = p.getParent())
+        {
+            if(p instanceof Dialog)
+            {
+                parentWindow = (Dialog)p;
+                break;
+            }
+        }
+        return parentWindow;
+    }
+
+    /**
+    *   @return a Frame that is the first one in the hierarchy
+    *   containing the component passed component
+    */
+    public static Frame getParentFrame(Component child)
+    {
+        Frame parentWindow = null;
+        for(Container p = child.getParent(); p != null; p = p.getParent())
+        {
+            if(p instanceof Frame)
+            {
+                parentWindow = (Frame)p;
+                break;
+            }
+        }
+        return parentWindow;
+    }
+
+    /**
+    *   @return a set of KeyStrokes for traversal of custom components
+    */
+    public static HashSet getDefaultFocusTraversalKeys(int id)
+    {
+        HashSet keys=new HashSet();
+
+        switch (id)
+        {
+            case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 
InputEvent.CTRL_MASK));
+                break;
+            case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 
InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK));
+                break;
+        }
+        return keys;
+
+    }
+}
+/*
+$:Log$
+*/

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/Shadow.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/Shadow.java 2006-03-14 
14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/Shadow.java 2006-03-14 
14:05:14 UTC (rev 8249)
@@ -0,0 +1,112 @@
+/*
+*   Copyright (c) 2000 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary
+*   that makes use of this code and that some acknowedgement is given. 
Comments,
+*   questions and requests for change will be welcomed.
+*/
+package mseries.ui;
+
+import java.awt.*;
+import javax.swing.*;
+
+/**
+*   A simple GUI component that displays a semi transparent strip. It is either
+*   HORIZONATAL or VERTICAL and alwats four pixels wide.
+*/
+public class Shadow extends JComponent
+{
+    int shadowWidth=6;
+    int orientation;
+    /**
+    *   Constructor. Use SwingUtilities.HORIZONTAL or SwingUtilities.VERTICAL 
to
+    *   specify the orientation
+    */
+    public Shadow(int orientation)
+    {
+        this.orientation=orientation;
+    }
+
+    public void paintComponent(Graphics g)
+    {
+
+        int width=getSize().width;
+        int height=getSize().height;
+
+        g.setColor(Color.black);
+
+        if (orientation==SwingUtilities.HORIZONTAL)
+        {
+            for (int i=width; i>shadowWidth; i-=shadowWidth)
+            {
+                g.drawLine(i,1,i,1);
+                g.drawLine(i,3,i,3);
+                g.drawLine(i,5,i,5);
+
+                g.drawLine(i-1,0,i-1,0);
+                g.drawLine(i-1,2,i-1,2);
+                g.drawLine(i-1,4,i-1,4);
+
+                g.drawLine(i-2,1,i-2,1);
+                g.drawLine(i-2,3,i-2,3);
+                g.drawLine(i-2,5,i-2,5);
+
+                g.drawLine(i-3,0,i-3,0);
+                g.drawLine(i-3,2,i-3,2);
+                g.drawLine(i-3,4,i-3,4);
+
+                g.drawLine(i-4,1,i-4,1);
+                g.drawLine(i-4,3,i-4,3);
+                g.drawLine(i-4,5,i-4,5);
+
+                g.drawLine(i-5,0,i-5,0);
+                g.drawLine(i-5,2,i-5,2);
+                g.drawLine(i-5,4,i-5,4);
+
+            }
+        }
+        else
+        {
+            for (int i=height; i>shadowWidth; i-=shadowWidth)
+            {
+                g.drawLine(1,i,1,i);
+                g.drawLine(3,i,3,i);
+                g.drawLine(5,i,5,i);
+
+                g.drawLine(0,i-1,0, i-1);
+                g.drawLine(2,i-1,2,i-1);
+                g.drawLine(4,i-1,4,i-1);
+
+                g.drawLine(1,i-2,1,i-2);
+                g.drawLine(3,i-2,3,i-2);
+                g.drawLine(5,i-2,5,i-2);
+
+                g.drawLine(0,i-3,0, i-3);
+                g.drawLine(2,i-3,2, i-3);
+                g.drawLine(4,i-3,4, i-3);
+
+                g.drawLine(1,i-4,1,i-4);
+                g.drawLine(3,i-4,3,i-4);
+                g.drawLine(5,i-4,5,i-4);
+
+                g.drawLine(0,i-5,0, i-5);
+                g.drawLine(2,i-5,2, i-5);
+                g.drawLine(4,i-5,4, i-5);
+            }
+
+        }
+    }
+
+    public Dimension getPreferredSize()
+    {
+        return new Dimension(shadowWidth, shadowWidth);
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ShadowImage.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ShadowImage.java    
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ShadowImage.java    
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,181 @@
+package mseries.ui;
+
+import java.awt.*;
+
+import javax.swing.*;
+
+public class ShadowImage implements Icon
+{
+    protected BumpBuffer    buffer;
+    int width, height, orientation;
+
+    public ShadowImage(int orientation)
+    {
+        this.orientation=orientation;
+
+        if (buffer == null)
+        {
+            createBuffer();
+        }
+    }
+
+    protected void createBuffer()
+    {
+        buffer = new BumpBuffer();
+    }
+
+    public void setArea(int w, int h)
+    {
+        this.width=width;
+        this.height=height;
+    }
+
+
+    /*
+    *   Paints the texture on the texture area, repeating (tiling) as often as 
it needs
+    *   to fill the area.
+    */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+        int bufferWidth = buffer.getImageSize().width;
+        int bufferHeight = buffer.getImageSize().height;
+        int w = getIconWidth();
+        int h = getIconHeight();
+
+
+        if (orientation==SwingUtilities.VERTICAL)
+        {
+            for (int i=height; i>bufferWidth; i-=bufferWidth)
+            {
+                g.drawImage(buffer.getImage(), x, i,  w,  h,  null);
+            }
+        }
+        else
+        {
+            for (int i=width; i>bufferWidth; i-=bufferWidth)
+            {
+                g.drawImage(buffer.getImage(), i, y, i + w, y + h, null);
+            }
+        }
+
+    }
+
+    public int getIconWidth()
+    {
+        return width;
+    }
+
+    public int getIconHeight()
+    {
+        return height;
+    }
+
+}
+
+/**
+ * One instance of the texture image. Each image is 64x64. Different colours 
and different
+ * orientation make a different image. This class is capable of drawing the 
ArmatureImage
+ * in any colours and etiher horizontal and vertical.
+ */
+class BumpBuffer
+{
+    static Frame        frame;
+    static Component    component;
+
+    static final int    IMAGE_SIZE = 6;
+    static Dimension    imageSize = new Dimension(IMAGE_SIZE, IMAGE_SIZE);
+
+    transient Image     image;
+    Color               topColor;
+    Color               backColor;
+    boolean             horizontal = true;
+
+    public BumpBuffer()
+    {
+
+        createComponent();
+
+        image = getComponent().createImage(IMAGE_SIZE, IMAGE_SIZE);
+
+        fillBumpBuffer();
+    }
+
+
+    public Image getImage()
+    {
+        if (image == null)
+        {
+            image = getComponent().createImage(IMAGE_SIZE, IMAGE_SIZE);
+
+            fillBumpBuffer();
+        }
+
+        return image;
+    }
+
+    public Dimension getImageSize()
+    {
+        return imageSize;
+    }
+
+    /**
+     *  The texture is drawn in this method, a graphic could be retrieved and 
drawn or simply
+     *  a texture using lines
+     */
+    protected void fillBumpBuffer()
+    {
+        Graphics    g = image.getGraphics();
+
+
+        g.setColor(Color.black);
+
+                g.drawLine(0,0,0,0);
+                g.drawLine(0,2,0,2);
+                g.drawLine(0,4,0,4);
+
+                g.drawLine(1,1,1,1);
+                g.drawLine(1,3,1,3);
+                g.drawLine(1,5,1,5);
+
+                g.drawLine(2,0,2,0);
+                g.drawLine(2,2,2,2);
+                g.drawLine(2,4,2,4);
+
+                g.drawLine(3,0,3,0);
+                g.drawLine(3,2,3,2);
+                g.drawLine(3,4,3,4);
+
+                g.drawLine(4,1,4,1);
+                g.drawLine(4,3,4,3);
+                g.drawLine(4,5,4,5);
+
+                g.drawLine(5,0,5,0);
+                g.drawLine(5,2,5,2);
+                g.drawLine(5,4,5,4);
+
+
+        g.dispose();
+    }
+
+    protected Component getComponent()
+    {
+        return component;
+    }
+
+    protected void createComponent()
+    {
+        if (frame == null)
+        {
+            frame = new Frame("bufferCreator");
+        }
+
+        if (component == null)
+        {
+            component = new Canvas();
+
+            frame.add(component, BorderLayout.CENTER);
+        }
+
+        frame.addNotify();
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/SpinnerModel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/SpinnerModel.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/SpinnerModel.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,54 @@
+/* 140
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.ui;
+import javax.swing.event.*;
+
+/**
+*   The SpinnerModel interface represents a sequence of values. Each value can 
only be accessed
+*   using the getValue(), getNextValue() or getPreviousValue() methods. Random 
access is not
+*   allowed. The set of values in the sequence is unbounded though 
implementations are at liberty
+*   to impose bounds. The step is the amount which the current value will 
change when the next or
+*   previous values are requested.
+*<P>
+*   A Spinner model is usually rendered in the Spinner by a SpinnerEditor 
which is aware of the
+*   actual data types encapsuated in any particular model. The model notifies 
the editor of changes
+*   by firing ChangeEvents.
+*   @see mseries.ui.SpinnerEditor
+*/
+public interface SpinnerModel
+{
+    /** Returns the current value */
+    public Object getValue();
+
+    /** Sets a value in the model which may or may not be in the sequence */
+    public void setValue(Object v);
+    /** Sets the step size to indicate how far getNextValue and 
getPreviousValue should
+    *   move in the set.
+    */
+    public void setStep(int step);
+    /**
+    *   Advances to and returns the next value in the sequence depending on 
the step size
+    */
+    public Object getNextValue();
+    /**
+    *   Advances to and returns the previous value in the sequence depending 
on the step size
+    */
+    public Object getPreviousValue();
+
+    /** ChangeEvents are fired to registered listeners when the current value 
is changed
+    */
+    public void addChangeListener(ChangeListener x);
+    public void removeChangeListener(ChangeListener x);
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormCellLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormCellLayout.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormCellLayout.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,148 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.utils;
+
+import java.util.*;
+import java.awt.*;
+
+/**
+*   A layout manager that lays out a container in one, horizonatal row. The 
resizing and placement
+*   policies are inherited from FormLayout. Components are added to their 
container using
+*   FormConstraints and this layout manager then ignores many of the values !. 
The intention is that
+*   it is easy for the application programmer to use this layout manager, it 
does not allow
+*   anything that could not be achieved with careful use of FormLayout. It is 
designed to be used
+*   to manage a small group of components that should ideally be placed in the 
same cell in a
+*   FormLayout. The image below shows a FormLayout with superimposed grid 
lines, the cell (1,1)
+*   contains 3 components, two JTextFields and a JLabel.
+*<p>
+* <img src="doc-files/FormCell.gif" ALIGN=center HSPACE=10 VSPACE=7>
+*<p>
+*   This cell contains a JPanel that has a FormCellLayout, the FormLayout 
automatically calculates
+*   the insets for its child components, the left most component gets zero 
left insets, the right
+*   most one zero right insets, all components get zero top and bottom insets. 
These values can
+*   not be over ridden by the application program so the FormCellLayout may 
not be the most
+*   appropriate Layout Manager to use outside of a FormLayout. (Remember the 
cell itself has insets)
+*<p>
+*   As components are added to the container, their x coordinate is 
automatically calculated, the
+*   first component to be added gets gridx=0, the next 1 etc. The gridy value 
is always zero as this
+*   layout manager can deal with only one row.
+*<p>
+*   The following code shows the usage of the FormCellLayout to produce the 
effects shown in the
+*   sample image above:
+*<pre>
+*
+*          public JPanel makeUOMPanel()
+*          {
+*              JPanel p = new JPanel();
+*              p.setLayout(new FormCellLayout());
+*
+*              FormConstraints c =new FormConstraints();
+*
+*              JTextField t1= new JTextField(5);
+*              c.anchor=FormConstraints.WEST;
+*              p.add(t1, c);
+*
+*              c.anchor=FormConstraints.EAST;
+*              JLabel l2=new JLabel("Printer");
+*              p.add(l2, c);
+*
+*              JTextField t2= new JTextField(5);
+*              c.anchor=FormConstraints.WEST;
+*              p.add(t2, c);
+*
+*              return p;
+*          }
+*</pre>
+*   The complete panel is added to the FormLayout with the following lines of 
code
+*<pre>
+*          JPanel ip=makeUOMPanel();
+*
+*          c.gridx=FormConstraints.RELATIVE;
+*          c.anchor=FormConstraints.WEST;
+*          c.spansColumns=true;
+*          p.add(ip, c);
+*</pre>
+*<hr>
+*   @see mseries.utils.FormLayout
+*
+*/
+public class FormCellLayout extends FormLayout
+{
+
+
+    /**
+    * Lays out the specified container using this form layout.
+    * This method reshapes components in the specified container in
+    * order to satisfy the contraints of this <code>FormLayout</code>
+    * object.
+    * <p>
+    * Most applications do not call this method directly.
+    * @param parent the container in which to do the layout.
+    * @see java.awt.Container
+    * @see java.awt.Container#doLayout
+    */
+    public void layoutContainer(Container parent)
+    {
+        resetConstraints();
+        super.layoutContainer(parent);
+    }
+
+    int nextX=0;
+    /**
+    * Adds the specified component to the layout, using the specified
+    * constraint object.
+    * @param      comp         the component to be added.
+    * @param      constraints  an object that determines how
+    *                              the component is added to the layout.
+    */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+        FormConstraints c;
+        if (constraints instanceof FormConstraints)
+        {
+            c= (FormConstraints)constraints;
+            c.gridy=0;
+            c.gridx=nextX++;
+            c.spansColumns=false;
+            c.insets.top=0;
+            c.insets.bottom=0;
+            setConstraints(comp, c);
+        }
+        else if (constraints != null)
+        {
+            throw new IllegalArgumentException("cannot add to layout: 
constraint must be a FormConstraint");
+        }
+    }
+
+    protected void resetConstraints()
+    {
+        int top = comptable.size()-1;
+        FormConstraints c;
+        Enumeration e = comptable.elements();
+        while(e.hasMoreElements())
+        {
+            c=(FormConstraints)e.nextElement();
+
+            if (c.gridx==0)
+            {
+                c.insets.left=0;
+            }
+            else if(c.gridx==top)
+            {
+                c.insets.right=0;
+            }
+        }
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormLayout.java  
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormLayout.java  
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,916 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.utils;
+
+import java.awt.*;
+import java.util.*;
+
+
+/**
+ * The <code>FormLayout</code> class is a flexible layout
+ * manager that aligns components vertically and horizontally,
+ * without requiring that the components be of the same size.
+ * Each <code>FormLayout</code> object maintains a dynamic
+ * rectangular grid of cells, with each component occupying
+ * one cell, called its <em>display area</em>.
+ * <p>
+ * Each component managed by a form layout is associated
+ * with an instance of
+ * {@link FormConstraints}
+ * that specifies how the component is laid out within its display area.
+ * <p>
+ * How a <code>FormLayout</code> object places a set of components
+ * depends on the <code>FormConstraints</code> object associated
+ * with each component, and on the minimum size
+ * and the preferred size of the components' containers.
+ * <p>
+ * To use a form layout effectively, you must customize one or more
+ * of the <code>FormConstraints</code> objects that are associated
+ * with its components. You customize a <code>FormConstraints</code>
+ * object by setting one or more of its instance variables:
+ * <p>
+ * <dl>
+ * <dt>{@link FormConstraints#gridx},
+ * {@link FormConstraints#gridy}
+ * <dd>Specifies the cell at the upper left of the component's display area,
+ * where the upper-left-most cell has address
+ * <code>gridx&nbsp;=&nbsp;0</code>,
+ * <code>gridy&nbsp;=&nbsp;0</code>.
+ * Use <code>FormConstraints.RELATIVE</code> (the default value)
+ * to specify that the component be just placed
+ * just to the right of (for <code>gridx</code>)
+ * or just below (for <code>gridy</code>)
+ * the component that was added to the container
+ * just before this component was added.
+ * <dt>{@link FormConstraints#insets}
+ * <dd>Specifies the component's external padding, the minimum
+ * amount of space between the component and the edges of its display area. 
This is defaulted to
+ * four pixels on each side.
+ * <dt>{@link FormConstraints#anchor}
+ * <dd>Used when the component is smaller than its display area
+ * to determine where (within the display area) to place the component.
+ * Valid values are
+ * <code>FormConstraints.CENTER</code> (the default),
+ * <code>FormConstraints.NORTH</code>,
+ * <code>FormConstraints.NORTHEAST</code>,
+ * <code>FormConstraints.EAST</code>,
+ * <code>FormConstraints.SOUTHEAST</code>,
+ * <code>FormConstraints.SOUTH</code>,
+ * <code>FormConstraints.SOUTHWEST</code>,
+ * <code>FormConstraints.WEST</code>, and
+ * <code>FormConstraints.NORTHWEST</code>.
+ * <dt>{@link FormConstraints#spansColumns}
+ * <dd>Specifies the component can span across column boundaries and the 
preferred width
+ * width will be used if the container (not the column) is wide enough
+ * </dl>
+ * <p>
+ * The following figure shows 16 components
+ * managed by a form layout:
+ * <p>
+ * <img src="doc-files/FormPanel.gif"
+ * ALIGN=center HSPACE=10 VSPACE=7>
+ *<hr>
+ * <p>
+ * Here is the code that implements the example shown above, the creation of 
the components
+ * and setting of the border have been omitted.
+ * <p>
+ *<pre>
+ *
+ *        JPanel pnlWeight = new JPanel();
+ *
+ *        pnlWeight.setLayout(new FormLayout());
+ *
+ *
+ *        FormConstraints constraints = new  FormConstraints();
+ *        constraints.gridx       = 0;
+ *        constraints.gridy       = 0;
+ *
+ *        // Gross Weight
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        pnlWeight.add(lblGrossWeightMand,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(tfGrossWeight,constraints);
+ *
+ *        // UOM2
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(lblUOM2,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(cmbUOM2,constraints);
+ *
+ *        // Net Weight
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx       = 0;
+ *        constraints.gridy++;
+ *        pnlWeight.add(lblNetWeightMand,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(tfNetWeight,constraints);
+ *
+ *        // UOM 3
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(lblUOM3,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(cmbUOM3,constraints);
+ *
+ *
+ *        // Tare Weight
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx       = 0;
+ *        constraints.gridy++;
+ *        pnlWeight.add(lblTareWeight,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(tfTareWeight,constraints);
+ *
+ *        // UOM 4
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(lblUOM4,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(cmbUOM4,constraints);
+ *
+ *        // Average Weight
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx       = 0;
+ *        constraints.gridy++;
+ *        pnlWeight.add(lblAverageWeight,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(tfAverageWeight,constraints);
+ *
+ *
+ *        // UOM 5
+ *        constraints.anchor      = FormConstraints.EAST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(lblUOM5,constraints);
+ *
+ *        constraints.anchor      = FormConstraints.WEST;
+ *        constraints.gridx++;
+ *        pnlWeight.add(cmbUOM5,constraints);
+ *
+ *
+ *
+ *</pre>
+ * <hr>
+ * @see       mseries.utils.FormConstraints
+ */
+
+public class FormLayout implements LayoutManager2, java.io.Serializable
+{
+
+    /**
+    * The maximum number of grid positions (both horizontally and
+    * vertically) that can be laid out by the form layout. Current value is 20
+    */
+    protected static final int MAXGRIDSIZE = 20;
+
+    /** The smallest size (width) to make a component in each cell */
+    protected static final int MINWIDTH=35;
+    /** The smallest size (height) to make a component in each cell */
+    protected static final int MINHEIGHT=17;
+    /**
+    * This hashtable maintains the association between
+    * a component and its gridbox constraints.
+    * The Keys in comptable are the components and the
+    * values are the instances of FormConstraints.
+    *
+    * @serial
+    * @see mseries.utils.FormConstraints
+    */
+    protected Hashtable comptable;
+    /**
+    * This field holds a gridbox constraints instance
+    * containing the default values, so if a component
+    * does not have gridbox constraints associated with
+    * it, then the component will be assigned a
+    * copy of the <code>defaultConstraints</code>.
+    *
+    * @serial
+    * @see #getConstraints(Component)
+    * @see #setConstraints(Component, FormConstraints)
+    * @see #lookupConstraints(Component)
+    */
+    protected FormConstraints defaultConstraints;
+
+    /**
+    *   One FormLayoutInfo object is maintained for the layout manager that 
contains the working
+    *   attributes for the whole layout.
+    */
+    protected FormLayoutInfo info=null;
+
+    /**
+    * Creates a form layout manager.
+    */
+    public FormLayout()
+    {
+        comptable = new Hashtable();
+        defaultConstraints = new FormConstraints();
+        info = new FormLayoutInfo(this);
+    }
+
+    /**
+    *   @return the info object used by this instance of the layout manager
+    */
+    public FormLayoutInfo getInfo()
+    {
+        return info;
+    }
+
+    /**
+    * Adds the specified component with the specified name to the layout.
+    * @param      name         the name of the component.
+    * @param      comp         the component to be added.
+    */
+    public void addLayoutComponent(String name, Component comp)
+    {
+    }
+
+    /**
+    * Adds the specified component to the layout, using the specified
+    * constraint object.
+    * @param      comp         the component to be added.
+    * @param      constraints  an object that determines how
+    *                              the component is added to the layout.
+    */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+        if (constraints instanceof FormConstraints)
+        {
+            setConstraints(comp, (FormConstraints)constraints);
+        }
+        else if (constraints != null)
+        {
+            throw new IllegalArgumentException("cannot add to layout: 
constraint must be a FormConstraint");
+        }
+    }
+    /**
+    * Removes the specified component from this layout.
+    * <p>
+    * Most applications do not call this method directly.
+    * @param    comp   the component to be removed.
+    * @see      java.awt.Container#remove(java.awt.Component)
+    * @see      java.awt.Container#removeAll()
+    */
+    public void removeLayoutComponent(Component comp)
+    {
+        removeConstraints(comp);
+    }
+    /**
+    * Sets the constraints for the specified component in this layout.
+    * @param       comp the component to be modified.
+    * @param       constraints the constraints to be applied.
+    */
+    public void setConstraints(Component comp, FormConstraints constraints)
+    {
+        comptable.put(comp, constraints.clone());
+    }
+
+    /**
+    * Removes the constraints for the specified component in this layout
+    * @param       comp the component to be modified.
+    */
+    private void removeConstraints(Component comp)
+    {
+        comptable.remove(comp);
+    }
+
+    /**
+    * Gets the constraints for the specified component.  A copy of
+    * the actual <code>FormConstraints</code> object is returned.
+    * @param       comp the component to be queried.
+    * @return      the constraint for the specified component in this
+    *                  form layout; a copy of the actual constraint
+    *                  object is returned.
+    */
+    public FormConstraints getConstraints(Component comp)
+    {
+        FormConstraints constraints = (FormConstraints)comptable.get(comp);
+        if (constraints == null)
+        {
+            setConstraints(comp, defaultConstraints);
+            constraints = (FormConstraints)comptable.get(comp);
+        }
+        return (FormConstraints)constraints.clone();
+    }
+
+    /**
+    * Retrieves the constraints for the specified component.
+    * The return value is not a copy, but is the actual
+    * <code>FormConstraints</code> object used by the layout mechanism.
+    * @param       comp the component to be queried
+    * @return      the contraints for the specified component.
+    */
+    protected FormConstraints lookupConstraints(Component comp)
+    {
+        FormConstraints constraints = (FormConstraints)comptable.get(comp);
+        if (constraints == null)
+        {
+            setConstraints(comp, defaultConstraints);
+            constraints = (FormConstraints)comptable.get(comp);
+        }
+        return constraints;
+    }
+
+    /**
+    *   Passes a new info objet to the component, used when the container is 
participating
+    *   in a GridBoxLayout.
+    */
+    void installFormInfo(FormLayoutInfo info)
+    {
+        this.info=info;
+    }
+
+    /**
+    * Lays out the specified container using this form layout.
+    * This method reshapes components in the specified container in
+    * order to satisfy the contraints of this <code>FormLayout</code>
+    * object.
+    * <p>
+    * Most applications do not call this method directly.
+    * @param parent the container in which to do the layout.
+    * @see java.awt.Container
+    * @see java.awt.Container#doLayout
+    */
+    public void layoutContainer(Container parent)
+    {
+        calculateGridSize(parent, parent.getSize());
+        setComponentBounds(parent);
+    }
+
+    /**
+    *   Calculates the location and size of each component in the container, 
according to the
+    *   in built rules and the constraints of each component this is the job 
of the layout manager.
+    */
+    protected void calculateGridSize(Container parent, Dimension size)
+    {
+        Component comp;
+        Component components[];
+        FormConstraints constraints;
+        Insets insets = parent.getInsets();
+
+        int x, y;
+        int adjW=0;
+
+        info.calculateLayoutInfo(parent);
+
+        adjW=0;
+
+        int spare, rem, quot;
+        spare=rem=quot=0;
+        int w=info.getActualWidth();
+        w = w + insets.left + insets.right;
+
+        spare = w - size.width;
+        do
+        {
+            /*  Attempt to resize the columns (& rows) by calculating the 
amount that should
+            *   be removed from each column. Initially we can remove from 
every column as we
+            *   assume the preferred width is larger than the minimum width 
and that the preferred
+            *   width can be displayed. As columns are shrunk to their 
minimums space can not be
+            *   removed from them so the excess space is saved and further 
passes are done to
+            *   remove it from those columns that have not yet reached their 
minimum. Do this
+            *   until all space has been removed from the columns or until all 
columns are as
+            *   small as the layout manager allows i.e. the minimum (MINWIDTH)
+            */
+            if (spare > 0)
+            {
+                /*  The parent is smaller than our panel some shrinking
+                *   takes place, divide the shortage up equally among all 
columns
+                */
+                quot = spare / info.getColsNotAtMin();
+                rem = spare % info.getColsNotAtMin();
+                quot+=(rem >0) ? 1 : 0;
+                adjW+= quot;
+            }
+
+            components = parent.getComponents();
+            x=y=-1; // Start at -1 so we can increment the co-ords in the loop
+
+            for (int compindex = 0 ; compindex < components.length ; 
compindex++)
+            {
+                comp = components[compindex];
+                if (!comp.isVisible())
+                {
+                    continue;
+                }
+
+                constraints = lookupConstraints(comp);
+                x=(constraints.gridx==FormConstraints.RELATIVE) ? x+1 : 
constraints.gridx;
+                y=(constraints.gridy==FormConstraints.RELATIVE) ? y+1 : 
constraints.gridy;
+                constraints.tempX=x;
+                constraints.tempY=y;
+
+                /*  If we can make the column narrower then we will calculate 
a new value
+                *   if it makes the column reach its minimum we record the 
amount which
+                *   could not be removed so we can remove it from somewhere 
else later
+                */
+                if(!info.atMin[x])
+                {
+                    int newWidth=info.colWidth[x]-adjW;
+                    info.actualWidth[x]=Math.max(/*info.minWidth[x]*/MINWIDTH, 
newWidth);
+                    if (MINWIDTH > newWidth)
+                    {
+                        info.atMin[x]=true;
+                    }
+                }
+            } // Component loop
+
+            /*  Lets see how wide we managed to make the components and 
calculate if it is
+            *   still larger parent container, it may be since some components 
may have been
+            *   set to the minimum so there is still some space to remove.
+            */
+            w=info.getActualWidth();
+            w = w + insets.left + insets.right;
+
+            spare = w - size.width;
+            /*  In the while test below we use info.width instead of zero to 
account for
+            *   integer division which may mean the spare space is not 
actually zero but
+            *   too small to worry about
+            */
+        }
+        while (spare > info.width && info.getColsNotAtMin()>0);
+    }
+
+    /**
+    *   Set the bounds on the components based on the values calculated in the 
calculateGridSize
+    *   method
+    */
+    protected void setComponentBounds(Container parent)
+    {
+        Component comp;
+        Component components[];
+
+        Rectangle r = new Rectangle();
+        FormConstraints constraints;
+        Insets insets = parent.getInsets();
+
+        int i;
+        int x, y, marginH, marginV;
+
+
+        components = parent.getComponents();
+        x=y=-1; // Start at -1 so we can increment the co-ords in the loop
+
+        for (int compindex = 0 ; compindex < components.length ; compindex++)
+        {
+            comp = components[compindex];
+            if (!comp.isVisible())
+            {
+                continue;
+            }
+            constraints = lookupConstraints(comp);
+            x=(constraints.gridx==FormConstraints.RELATIVE) ? x+1 : 
constraints.gridx;
+            y=(constraints.gridy==FormConstraints.RELATIVE) ? y+1 : 
constraints.gridy;
+            constraints.tempX=x;
+            constraints.tempY=y;
+
+            marginH=constraints.insets.left+constraints.insets.right;
+            marginV=constraints.insets.top+constraints.insets.bottom;
+
+            /*  Set the width of the component based on the column width just 
calculated.
+            */
+            int pWidth=comp.getPreferredSize().width;
+            if (constraints.spansColumns)
+            {
+                int w=0;
+                for(i=x ; i < info.width; i++)
+                {
+                    w+=info.actualWidth[i];
+                }
+                r.width=Math.min(pWidth, w-marginH);
+            }
+            else if(constraints.fill)
+            {
+                r.width=info.actualWidth[x]-marginH;
+            }
+            else
+            {
+                r.width=Math.min(pWidth, info.actualWidth[x]-marginH);
+            }
+
+            constraints.cellWidth=info.actualWidth[x]-marginH;
+
+            /*  Calculate the height but do not let it go smaller than the 
minimum */
+            int pHeight=comp.getPreferredSize().height;
+            int newHeight=info.rowHeight[y];
+            info.actualHeight[y]=Math.max(MINHEIGHT, newHeight);
+
+            r.height=Math.min(pHeight, info.actualHeight[y]-marginV);
+            constraints.cellHeight=info.actualHeight[y]-marginV;
+
+
+            /*  Now calculate the placement, this demands that the Lefth Hand 
components have
+            *   been added before the ones on their right
+            */
+            r.x=insets.left;
+            r.y=insets.top;
+
+            // Sum all column widths that are to the left of the target cell
+            for (i=0; i<constraints.tempX; i++)
+            {
+                r.x+=info.actualWidth[i];
+            }
+
+            // Sum all row heights that are above the target cell
+            for (i=0; i<constraints.tempY; i++)
+            {
+                r.y+=info.rowHeight[i];
+            }
+
+            applyGravity(constraints, r);
+            comp.setBounds(r);
+
+        } // Component loop
+    }
+
+    /**
+    *   Relocates the component inside its cell according to the anchor 
constraint
+    *   @param constraints the FormConstraints for the cell
+    *   @param r the rectangle speifying the bounds of the cell
+    */
+    protected void applyGravity(FormConstraints constraints, Rectangle r)
+    {
+        r.x+=constraints.insets.left;
+        r.y+=constraints.insets.top;
+
+        int diffx=0;
+        if (r.width < constraints.cellWidth)
+        {
+            diffx=constraints.cellWidth-r.width;
+        }
+
+        int diffy=0;
+        if (r.height < constraints.cellHeight)
+        {
+            diffy=constraints.cellHeight-r.height;
+        }
+
+        switch (constraints.anchor)
+        {
+            case GridBagConstraints.CENTER:
+                r.x += diffx/2;
+                r.y += diffy/2;
+                break;
+            case FormConstraints.NORTH:
+                r.x+=diffx/2;
+                break;
+            case FormConstraints.SOUTH:
+                r.x += diffx/2;
+                r.y += diffy;
+                break;
+            case FormConstraints.EAST:
+                r.x+=diffx;
+                r.y+=diffy/2;
+            case FormConstraints.WEST:
+                r.y+=diffy/2;
+                break;
+            case FormConstraints.NORTHEAST:
+                r.x+=diffx;
+                break;
+            case FormConstraints.SOUTHWEST:
+                r.y+=diffy;
+                break;
+            case FormConstraints.SOUTHEAST:
+                r.y+=diffy;
+                r.x+=diffx;
+                break;
+            case FormConstraints.NORTHWEST:
+            default:
+                break;
+        }
+    }
+    /**
+    * Determines the preferred size of the <code>target</code>
+    * container using this form layout.
+    * <p>
+    * Most applications do not call this method directly.
+    * @param     parent   the container in which to do the layout.
+    * @see       java.awt.Container#getPreferredSize
+    */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+        info.calculateLayoutInfo(parent);
+        Insets insets=parent.getInsets();
+        Dimension d=info.getPreferredSize();
+        d.width = d.width + insets.left + insets.right;
+        d.height= d.height + insets.top + insets.bottom;
+        return d;
+    }
+
+    /**
+    * Determines the minimum size of the <code>target</code> container
+    * using this form layout.
+    * <p>
+    * Most applications do not call this method directly.
+    * @param     parent   the container in which to do the layout.
+    * @see       java.awt.Container#doLayout
+    */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+        info.calculateLayoutInfo(parent);
+        Insets insets=parent.getInsets();
+        Dimension d=info.getMinimumSize();
+        d.width = d.width + insets.left + insets.right;
+        d.height= d.height + insets.top + insets.bottom;
+        return d;
+    }
+    /**
+    * Returns the maximum dimensions for this layout given the components
+    * in the specified target container.
+    * @param target the component which needs to be laid out
+    * @see Container
+    * @see #minimumLayoutSize(Container)
+    * @see #preferredLayoutSize(Container)
+    */
+    public Dimension maximumLayoutSize(Container target)
+    {
+        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+
+    /**
+    * Returns the alignment along the x axis.  This specifies how
+    * the component would like to be aligned relative to other
+    * components.  The value should be a number between 0 and 1
+    * where 0 represents alignment along the origin, 1 is aligned
+    * the furthest away from the origin, 0.5 is centered, etc.
+    */
+    public float getLayoutAlignmentX(Container parent)
+    {
+        return 0.5f;
+    }
+
+    /**
+    * Returns the alignment along the y axis.  This specifies how
+    * the component would like to be aligned relative to other
+    * components.  The value should be a number between 0 and 1
+    * where 0 represents alignment along the origin, 1 is aligned
+    * the furthest away from the origin, 0.5 is centered, etc.
+    */
+    public float getLayoutAlignmentY(Container parent)
+    {
+        return 0.5f;
+    }
+
+    /**
+    * Invalidates the layout, indicating that if the layout manager
+    * has cached information it should be discarded.
+    */
+    public void invalidateLayout(Container target)
+    {
+    }
+}
+
+/**
+*   Helper class for FormLayout that holds working values for the container 
being layed out using
+*   FormLayout. As the container is resized the values in here are 
recalculated by the method
+*   calculateLayoutInfo
+*/
+class FormLayoutInfo implements java.io.Serializable
+{
+    public static final String REVISION_ID =  "$Id: FormLayout.java,v 1.3 
2003/03/26 23:29:51 martin Exp $";
+    public static final String REVISION_TAG = "$Name:  $";
+
+    int colsNotAtMin;   //  The number of columns that can get shrunk
+    boolean atMin[];    //  Can the column at [x] get shrunk
+    int width, height;  //  Number of cells horizontally, vertically
+
+    int colWidth[];     //  Preferred Width of each column, large preferred 
width of each component
+                        //  in the column
+    int rowHeight[];    //  Preferred Height of each column is the largest 
minimum height of each
+                        //  component in the row
+
+
+    int minWidth[];     //  The minimum width of each column is the largest 
minimum width of each
+                        //  component in the column
+    int minHeight[];    //  The minimum height of each rowis the largest 
minimum height of each
+                        //  component in the column
+
+    int actualWidth[];  //  The width that each column is set to at any moment 
in time
+    int actualHeight[]; //  The height that each row is set to at any moment 
in time
+    boolean doneStatic=false;
+    FormLayout master;
+
+    FormLayoutInfo (FormLayout master)
+    {
+        this.master=master;
+        colWidth = new int[FormLayout.MAXGRIDSIZE];
+        rowHeight = new int[FormLayout.MAXGRIDSIZE];
+
+        actualWidth = new int[FormLayout.MAXGRIDSIZE];
+        actualHeight = new int[FormLayout.MAXGRIDSIZE];
+
+        minWidth = new int[FormLayout.MAXGRIDSIZE];
+        minHeight = new int[FormLayout.MAXGRIDSIZE];
+        width=height=0;
+        atMin=new boolean[FormLayout.MAXGRIDSIZE];
+
+        Arrays.fill(atMin, false);
+        colsNotAtMin=width;
+    }
+
+    /**
+    *   Calculates some static information about the columns and rows in the 
container based
+    *   on the components that have been added. The FormLayoutInfo object is 
populated once
+    *   since the components do not change but some attributes are reset if 
necessary
+    */
+    void calculateLayoutInfo(Container parent)
+    {
+        synchronized (parent.getTreeLock())
+        {
+            Arrays.fill(atMin, false);
+            setStaticLayoutInfo(parent.getComponents());
+        }
+    }
+
+
+    void setStaticLayoutInfo(Component[] components)
+    {
+        Insets compInsets;
+        Component comp;
+        FormConstraints constraints;
+        Dimension dp, dm;
+        int curX, curY;
+
+        curX=curY=-1;
+        for (int compindex = 0 ; compindex < components.length ; compindex++)
+        {
+            comp = components[compindex];
+            if (!comp.isVisible())
+            {
+                continue;
+            }
+
+            constraints = master.lookupConstraints(comp);
+
+            curX=(constraints.gridx==FormConstraints.RELATIVE) ? curX+1 : 
constraints.gridx;
+            curY=(constraints.gridy==FormConstraints.RELATIVE) ? curY+1 : 
constraints.gridy;
+            constraints.tempX=curX;
+            constraints.tempY=curY;
+
+            compInsets=constraints.insets;
+
+            // Number of columns & rows
+            width=Math.max(curX+1, width);
+            height=Math.max(curY+1, height);
+
+            if (!constraints.spansColumns)
+            {
+                dp = comp.getPreferredSize();
+            }
+            else
+            {
+                int h=comp.getPreferredSize().height;
+                dp = new Dimension(FormLayout.MINWIDTH, h);
+            }
+            /*  Preferred size of each column, the size of the largest 
component in
+            *   the column/row
+            */
+            colWidth[curX]=Math.max(colWidth[curX],
+                                            
dp.width+compInsets.left+compInsets.right);
+            rowHeight[curY]=Math.max(rowHeight[curY],
+                                            
dp.height+compInsets.top+compInsets.bottom);
+
+            dm = comp.getMinimumSize();
+            /*  Minimum size of each column, the size of the largest component 
in
+            *   the column/row
+            */
+            minWidth[curX]=Math.max(minWidth[curX],
+                                            
dm.width+compInsets.left+compInsets.right);
+            minHeight[curY]=Math.max(minHeight[curY],
+                                            
dm.height+compInsets.top+compInsets.bottom);
+            actualWidth[curX]=colWidth[curX];
+            actualHeight[curX]=rowHeight[curX];
+
+            colsNotAtMin=width;
+        } // Component Loop
+    }
+
+    public String toString()
+    {
+        String ret = "["+this.getClass().getName()+ ": \n" +
+            "  width="+width+", height="+height+", \n";
+        ret+="  Preferred Widths \n";
+        for (int i=0; i<width; i++)
+        {
+            ret+="    ["+i+"] = "+colWidth[i]+"\n";
+        }
+        ret+="  Preferred Heights \n";
+        for (int i=0; i<height; i++)
+        {
+            ret+="    ["+i+"] = "+rowHeight[i]+"\n";
+        }
+
+        ret+="  Minimum Widths \n";
+        for (int i=0; i<width; i++)
+        {
+            ret+="    ["+i+"] = "+minWidth[i]+"\n";
+        }
+        ret+="  Minimum Heights \n";
+        for (int i=0; i<height; i++)
+        {
+            ret+="    ["+i+"] = "+minHeight[i]+"\n";
+        }
+
+        return ret;
+    }
+
+
+    Dimension getMinimumSize()
+    {
+        int i;
+        int t=0;
+        Dimension d=new Dimension(1,1);
+        for(i = 0; i < width; i++)
+        {
+            t += minWidth[i];
+        }
+        d.width=t;
+
+        t = 0;
+        for(i = 0; i < height; i++)
+        {
+            t += minHeight[i];
+        }
+        d.height=t;
+        return d;
+    }
+
+    Dimension getPreferredSize()
+    {
+        int i;
+        int t=0;
+        Dimension d=new Dimension(1,1);
+        for(i = 0; i < width; i++)
+        {
+            t += colWidth[i];
+        }
+        d.width=t;
+
+        t = 0;
+        for(i = 0; i < height; i++)
+        {
+            t += rowHeight[i];
+        }
+        d.height=t;
+        return d;
+    }
+
+    int getColsNotAtMin()
+    {
+        int i;
+        int t=0;
+        for(i = 0; i < width; i++)
+        {
+            t += (atMin[i]) ? 0 : 1;
+        }
+        return t;
+    }
+
+    int getActualWidth()
+    {
+        int i;
+        int t=0;
+        for(i = 0; i < width; i++)
+        {
+            t += actualWidth[i];
+        }
+        return t;
+    }
+}
+
+// $Log: FormLayout.java,v $
+// Revision 1.3  2003/03/26 23:29:51  martin
+// Changed email address
+//
+// Revision 1.2  2002/12/29 18:26:07  martin
+// *** empty log message ***
+//
+// Revision 1.1  2002/11/03 10:29:05  martin
+// Added header comment
+//
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormStrut.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormStrut.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormStrut.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,79 @@
+/*
+*   Copyright (c) 2002 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.utils;
+
+import java.awt.*;
+
+/**
+ *   Simple non visual component that is used to coerce a layout manager into 
setting columns
+ *   and rows to a certain size. It is used by mseries.utils.FormLayout in 
particular. The
+ *   component has preferred width and height so that layout managers will 
involve it in
+ *   calculations but it has no implementation in its paint method so it will 
never be seen.
+ */
+public class FormStrut extends Component
+{
+    /** The size of the strut */
+    public Dimension size;
+
+    /**
+     *   Create a strut with specified width and zero height
+     *   @param w the preferred width of the strut
+     */
+    public FormStrut(int w)
+    {
+        this(new Dimension(w, 0));
+    }
+
+    /**
+     *   Create a strut with specified width and height
+     *   @param w the preferred width of the strut
+     *   @param h the preferred height of the strut
+     */
+    public FormStrut(int w, int h)
+    {
+        this(new Dimension(w, h));
+    }
+
+    /**
+     *   Create a strut with specified width and height
+     *   @param d the preferred dimension of the strut
+     */
+    public FormStrut(Dimension d)
+    {
+        this.size = d;
+    }
+
+    public Dimension getPreferredSize()
+    {
+        return size;
+    }
+
+    public Dimension getMinimumSize()
+    {
+        return new Dimension(0, 0);
+    }
+
+    public void paint(Graphics g)
+    {
+    }
+}
+
+// $Log: FormStrut.java,v $
+// Revision 1.2  2003/03/26 23:29:51  martin
+// Changed email address
+//
+// Revision 1.1  2002/11/03 10:29:05  martin
+// Added header comment
+//

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MComboBoxLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MComboBoxLayout.java     
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MComboBoxLayout.java     
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,95 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+/**
+*   Layout manager for a comobox style display with
+*   the arrow button to the right and the editor to the left.
+*
+*/
+package mseries.utils;
+import java.awt.*;
+
+public class MComboBoxLayout implements LayoutManager
+{
+    public void addLayoutComponent(String name, Component comp) {}
+
+    public void removeLayoutComponent(Component comp) {}
+
+    private Component display, pushButton;
+    Insets insets;
+    private int width, height;
+
+    public Dimension preferredLayoutSize(Container parent)
+    {
+        display = parent.getComponent(0);
+        Dimension d = new Dimension(display.getPreferredSize().width+20, 
display.getPreferredSize().height);
+        return d;
+    }
+
+    public Dimension minimumLayoutSize(Container parent)
+    {
+        display = parent.getComponent(0);
+        Dimension d = new Dimension(display.getMinimumSize().width+20, 
display.getMinimumSize().height);
+        return d;
+    }
+
+    public void layoutContainer(Container parent)
+    {
+        int n = parent.getComponentCount();
+        if (n>0)
+        {
+            display = parent.getComponent(0);
+        }
+        if (n>1)
+        {
+            pushButton=parent.getComponent(1);
+        }
+
+        width = parent.getSize().width;
+        height = parent.getSize().height;
+        insets = parent.getInsets();
+
+        Rectangle cvb;
+
+        if (pushButton != null)
+        {
+            int buttonSize = height - (insets.top + insets.bottom);
+            pushButton.setBounds(width - (insets.right + buttonSize),
+                                   insets.top,
+                                   buttonSize, buttonSize);
+        }
+        if (display != null)
+        {
+            cvb = rectangleForCurrentValue();
+            display.setBounds(cvb);
+        }
+    }
+
+    /**
+    * Returns the area that is reserved for drawing the currently selected 
item.
+    */
+    protected Rectangle rectangleForCurrentValue()
+    {
+        int buttonSize=0;
+        if ( pushButton != null )
+        {
+            buttonSize = pushButton.getSize().width;
+        }
+        Rectangle r= new Rectangle(insets.left, insets.top,
+                            width - (insets.left + insets.right + buttonSize),
+                            height - (insets.top + insets.bottom));
+        return r;
+    }
+
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MSpinnerLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MSpinnerLayout.java      
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MSpinnerLayout.java      
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,142 @@
+/*
+*   Copyright (c) 2001 Martin Newstead (mseries at brundell.fsnet.co.uk).  All 
Rights Reserved.
+*   Reaped from javax.swing.JPopupMenu
+*
+*   The author makes no representations or warranties about the suitability of 
the
+*   software, either express or implied, including but not limited to the
+*   implied warranties of merchantability, fitness for a particular
+*   purpose, or non-infringement. The author shall not be liable for any 
damages
+*   suffered by licensee as a result of using, modifying or distributing
+*   this software or its derivatives.
+*
+*   The author requests that he be notified of any application, applet, or 
other binary that
+*   makes use of this code and that some acknowedgement is given. Comments, 
questions and
+*   requests for change will be welcomed.
+*/
+package mseries.utils;
+import java.awt.*;
+/**
+*   Layout manager for a spinner type display.
+*   Divides the space into three, add the textfield first, then the top right 
component
+*   then the bottom right. The image shows buttons on the right hand side 
which is the
+*   most likely usage but <i>any</i> component could be added.
+*<PRE>
+*         <img src="MSpinnerLayout.jpg"/>
+*</PRE>
+*   The right hand components get resized to be twice as wide as the are high, 
and they will always
+*   occupy the full height of the component as assigned by the parent layout 
manager
+*
+*/
+public class MSpinnerLayout implements LayoutManager
+{
+    private Component display, up, down;
+    int width, height;
+    Insets insets;
+
+    public void addLayoutComponent(String name, Component comp) {}
+
+    public void removeLayoutComponent(Component comp) {}
+
+    public Dimension preferredLayoutSize(Container parent)
+    {
+        synchronized (parent.getTreeLock())
+        {
+            display = parent.getComponent(0);
+            Dimension d = new Dimension(display.getPreferredSize().width+20,
+                                    display.getPreferredSize().height);
+            return d;
+        }
+    }
+
+    public Dimension minimumLayoutSize(Container parent)
+    {
+
+        synchronized (parent.getTreeLock())
+        {
+            display = parent.getComponent(0);
+
+/*
+            Dimension d = new Dimension(display.getMinimumSize().width+50,
+                                        display.getMinimumSize().height);
+*/
+            Dimension d = new Dimension(50, 22);
+            return d;
+        }
+    }
+
+    public void layoutContainer(Container parent)
+    {
+        synchronized (parent.getTreeLock())
+        {
+            insets = parent.getInsets();
+            width = parent.getWidth();
+            height = parent.getHeight();
+
+            Rectangle cvb;
+
+            int ncomponents = parent.getComponentCount();
+
+            display = parent.getComponent(0);
+            if (ncomponents > 1)
+                up = parent.getComponent(1);
+            if (ncomponents > 2)
+                down = parent.getComponent(2);
+
+            int buttonWidth = height - (insets.right + insets.left);
+            int buttonHeight = (height-(insets.top + insets.bottom))/2;
+
+            if (up != null)
+            {
+
+                up.setBounds(width - (insets.right + buttonWidth),
+                                        insets.top,
+                                    buttonWidth, buttonHeight);
+            }
+            if (down != null)
+            {
+                down.setBounds(width - (insets.right + buttonWidth),
+                                    buttonHeight+insets.top,
+                                    buttonWidth, buttonHeight);
+            }
+            if (display != null)
+            {
+                cvb = rectangleForCurrentValue();
+                display.setBounds(cvb);
+            }
+        }
+    }
+
+    /**
+    * Returns the area that is reserved for drawing the currently selected 
item.
+    */
+    protected Rectangle rectangleForCurrentValue()
+    {
+        int buttonSize=0;
+        if ( up != null )
+        {
+            buttonSize = up.getWidth();
+        }
+        return new Rectangle(insets.left, insets.top,
+                             width - (insets.left + insets.right + buttonSize),
+                             height - (insets.top + insets.bottom));
+    }
+
+
+/*
+    public static void main(String[] argv)
+    {
+        javax.swing.JPanel p=new javax.swing.JPanel();
+        javax.swing.JFrame f = new javax.swing.JFrame();
+
+        f.getContentPane().setLayout(new MSpinnerLayout());
+
+        f.getContentPane().add(new javax.swing.JButton("Java"));
+        f.getContentPane().add(new javax.swing.JTextField("Hello"));
+        f.getContentPane().add(new javax.swing.JButton("World"));
+
+
+        f.pack();
+        f.show();
+    }
+*/
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/SafeCalendarUtils.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/SafeCalendarUtils.java   
2006-03-14 14:03:34 UTC (rev 8248)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/SafeCalendarUtils.java   
2006-03-14 14:05:14 UTC (rev 8249)
@@ -0,0 +1,59 @@
+package mseries.utils;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * Class created to "work-around" an apparent bug with 
sun.util.BuddhistCalendar (hardcoded to be returned
+ * by Calendar.getInstance() calls for the Thai locale (language)).  The bug 
causes the Calendar date to become incorrect
+ * (e.g. 1998 + 5 years becomes 1460) whenever a .add(...) call forces a year 
change.
+ *
+ * @author  S. Ruman
+ * @version 1.0
+ * @see java.util.Calendar
+ */
+
+public class SafeCalendarUtils
+{
+    public static String squeeze(String input)
+    {
+        StringBuffer insb=new StringBuffer(input);
+        StringBuffer outsb=new StringBuffer(input.length());
+        for (int i=0; i<insb.length(); i++)
+        {
+            if (insb.charAt(i)!=' ')
+            {
+                outsb.append(insb.charAt(i));
+            }
+        }
+        return new String(outsb);
+    }
+    /**
+     Creates a temporary GregorianCalendar, sets its time, uses it for the 
addition, and then sets the modified
+     time to the passed in Calendar.
+     Note:  This convenience performs a .add(...) call (as opposed to a 
.roll(...) call) on the Calendar.
+     @param cal     The calendar to be modified by adding the <i>amount</i> of 
<i>field</i> to it
+     @param field   A constant from the Calendar class (DAY, MONTH, etc.)
+     @param amount  The amount of <i>field</i> to add to the calendar.
+     */
+    public static final void doSafeAddition(Calendar cal, int field, int 
amount)
+    {
+        if (cal == null)
+            return;
+
+        // sun.util.BuddhistCalendar inherits from GregorianCalendar, so an 
instanceof doesn't work and
+        // a security access exception occurs if sun.util.BuddhistCalendar is 
mentioned by name (unfortunately, this forces
+        // brittleness if there are "legitimate" GregorianCalendar 
sub-classes, but no choice)
+        if (!cal.getClass().equals(GregorianCalendar.class))
+        {           // Creating GregorianCalendar's is relatively expensive
+            GregorianCalendar gc = new GregorianCalendar();
+            gc.setTime(cal.getTime());
+
+            gc.add(field, amount);
+
+            cal.setTime(gc.getTime());
+        }
+        else
+            cal.add(field, amount);
+    }
+}
\ No newline at end of file


Reply via email to