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

Added:
   trunk/apps/frost-0.7/lib/datechooser/
   trunk/apps/frost-0.7/lib/datechooser/mseries/
   trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/
   
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DateSelectorRB_ru.properties
   
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DefaultSpecialDayModel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/GridSelectionEvent.java
   
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateTimeValueEditor.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateValueEditor.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MMonth.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaArrowButton.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaDateEntryUI.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacArrowButton.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacDateEntryUI.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Metal/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Motif/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Windows/
   trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/basic/
   
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/basic/BasicCalendarPanelUI.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ArrowButton.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateCellEditor.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateField.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatter.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupPanel.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormConstraints.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MultiFormLayout.java
   trunk/apps/frost-0.7/lib/datechooser/mseries/utils/VFlowLayout.java
Log:
new date chooser component

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DateSelectorRB_ru.properties
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DateSelectorRB_ru.properties
  2006-03-14 07:10:06 UTC (rev 8247)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DateSelectorRB_ru.properties
  2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,17 @@
+# Resources for MDateSelector
+# Provided by Yuri Gusak
+
+# Column Headings
+Mo=\u041f\u043d
+Tu=\u0412\u0442
+We=\u0421\u0440
+Th=\u0427\u0442
+Fr=\u041f\u0442
+Sa=\u0421\u0431
+Su=\u0412\u0441
+
+# Button Labels
+Today=\u0421\u0435\u0433\u043e\u0434\u043d\u044f
+OK=OK
+Cancel=\u041e\u0442\u043c\u0435\u043d\u0430
+

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DefaultSpecialDayModel.java
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DefaultSpecialDayModel.java
   2006-03-14 07:10:06 UTC (rev 8247)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/DefaultSpecialDayModel.java
   2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,53 @@
+/*
+*   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.Calendar;
+
+import java.util.Date;
+import java.awt.Color;
+
+public class DefaultSpecialDayModel implements SpecialDayModel
+{
+
+    /**
+    *   By default no dates are special
+    *   @return false
+    */
+    public boolean isSpecialDay(Date date)
+    {
+        return false;
+    }
+
+    public Color getForeground(Date date)
+    {
+        return null;
+    }
+
+    public Color getBackground(Date date)
+    {
+        return null;
+    }
+}
+/*
+$Log: DefaultSpecialDayModel.java,v $
+Revision 1.3  2003/03/26 23:29:48  martin
+Changed email address
+
+Revision 1.2  2002/02/09 17:08:20  martin
+Removed isClickable method
+
+Revision 1.1  2002/02/09 12:54:39  martin
+Partial support for 'Special Days'
+
+*/

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/GridSelectionEvent.java
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/GridSelectionEvent.java   
    2006-03-14 07:10:06 UTC (rev 8247)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/GridSelectionEvent.java   
    2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,71 @@
+/*
+*   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.Calendar;
+
+import java.awt.Point;
+
+/**
+*   An Event class used to notify listeners that ther has been a change
+*   in the Selceted grid square
+*/
+public class GridSelectionEvent extends java.util.EventObject
+{
+    int x;
+    int y;
+    boolean quit=false;
+
+    public GridSelectionEvent(Object source, int x, int y)
+    {
+        super(source);
+        this.x=x;
+        this.y=y;
+    }
+
+    public GridSelectionEvent(Object source, Point cell)
+    {
+        super(source);
+        this.x=cell.x;
+        this.y=cell.y;
+    }
+
+    public GridSelectionEvent(Object source, boolean quit)
+    {
+        super(source);
+        this.quit=quit;
+    }
+
+    public int getX()
+    {
+        return x;
+    }
+
+    public int getY()
+    {
+        return y;
+    }
+
+    public boolean isExitEvent()
+    {
+        return quit;
+    }
+
+    public String toString()
+    {
+        String buff;
+        buff = "["+getClass().getName()+": x="+getX()+", y="+getY()+"]";
+        return buff;
+    }
+}
+

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateTimeValueEditor.java
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateTimeValueEditor.java 
    2006-03-14 07:10:06 UTC (rev 8247)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateTimeValueEditor.java 
    2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,11 @@
+package mseries.Calendar;
+
+import java.text.*;
+
+public class MDateTimeValueEditor extends MDateValueEditor
+{
+    public MDateTimeValueEditor()
+    {
+        df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+    }
+}

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateValueEditor.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateValueEditor.java 
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MDateValueEditor.java 
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,119 @@
+/*
+*   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.Calendar;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.beans.*;
+import java.util.*;
+import java.text.*;
+
+public class MDateValueEditor implements PropertyEditor
+{
+
+    protected Date value; // The thing being edited
+    protected DateFormat df;
+    protected PropertyChangeSupport listeners = new 
PropertyChangeSupport(this);
+
+    public MDateValueEditor()
+    {
+        df = DateFormat.getDateInstance(DateFormat.LONG);
+    }
+
+    public String getJavaInitializationString()
+    {
+        String buff;
+        buff = "new java.util.Date("+value.getTime()+")";
+        return buff;
+    }
+
+    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()
+    {
+        String val=null;
+        val = df.format(value);
+        return val;
+    }
+
+    public void setAsText(String s)
+    {
+        Date old=value;
+        try
+        {
+            value = df.parse(s);
+            listeners.firePropertyChange(null, null, null);
+        }
+        catch(ParseException e)
+        {
+            value = old;
+        }
+    }
+
+    public void setValue(Object object)
+    {
+        if (object != null)
+        {
+            value = (Date)object;
+        }
+    }
+
+    public Object getValue()
+    {
+        return value;
+    }
+
+    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/Calendar/MMonth.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MMonth.java   
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/Calendar/MMonth.java   
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,493 @@
+/*
+*   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.Calendar;
+
+import java.awt.*;
+import java.util.*;
+
+/**
+ *   The business end of the DateSelector component. This class maintains the 
state of the
+ *   the component
+ */
+public class MMonth
+{
+
+    private Calendar today;
+    private Calendar currentDate;     // As passed in,
+    private Point currentPoint;       // The point in the model/table
+    // of the current date
+    private int calMonth;     // The month of the current calendar
+    private Calendar startOfMonth;  // The 1st of the month
+    private Calendar date;          // Working date
+    protected Vector listeners = new Vector();
+
+    private Calendar minC;          // Minimum value allowed
+    private Calendar maxC;          // Maximum value allowed
+
+    private Toolkit tk;
+
+    int offset;
+    int firstDay = 1;
+    private Date minDate;
+    private Date maxDate;
+
+    public MMonth(Date min, Date max)
+    {
+        this.minDate=min;
+        this.maxDate=max;
+        init();
+    }
+    public MMonth()
+    {
+        init();
+    }
+    private void init()
+    {
+        today = Calendar.getInstance();
+        today.setTime(new Date());
+
+        currentDate = Calendar.getInstance();
+        currentDate.setTime(new Date());
+        startOfMonth = Calendar.getInstance();
+        minC = Calendar.getInstance();
+        maxC = Calendar.getInstance();
+        currentPoint = new Point(0, 0);
+        tk = Toolkit.getDefaultToolkit();
+
+        if(minDate==null)
+        {
+            minC.set(1900, 0, 1, 0, 0, 0);
+        }
+        else
+        {
+            minC.setTime(minDate);
+        }
+
+        if(maxDate==null)
+        {
+        maxC.set(2037, 11, 31, 23, 59, 59);
+        }
+        else
+        {
+            maxC.setTime(maxDate);
+        }
+
+
+        setFirstDay(Calendar.SUNDAY);
+    }
+
+    /**
+     *   The first column on the calendar grid shows the dates for
+     *   the day passed here.
+     *   @param first a day constant from java.util.Calendar such as 
Calendar.SUNDAY
+     */
+    public void setFirstDay(int first)
+    {
+        if (first < Calendar.SUNDAY || first > Calendar.SATURDAY)
+        {
+            return;
+        }
+        this.firstDay = first;
+        try
+        {
+            setDate(getCurrentDate());
+        }
+        catch (MDateOutOfRangeException ex)
+        {
+        }
+        notifyListeners(new MMonthEvent(this, MMonthEvent.NEW_FIRST_DAY, 
currentDate));
+    }
+
+    /**
+     *   @return the first day on display
+     */
+    public int getFirstDay()
+    {
+        return firstDay;
+    }
+
+
+    /**
+     *   Sets the date and preserves the time that the model previously has
+     *   @param inDate the new value whose Hour, Minute and Second elements are
+     *   ignored
+     */
+    protected void setDMY(Date inDate) throws MDateOutOfRangeException
+    {
+        int h = currentDate.get(Calendar.HOUR_OF_DAY);
+        int m = currentDate.get(Calendar.MINUTE);
+        int s = currentDate.get(Calendar.SECOND);
+
+        Calendar newC = Calendar.getInstance();
+        newC.setTime(inDate);
+        newC.set(Calendar.HOUR_OF_DAY, h);
+        newC.set(Calendar.MINUTE, m);
+        newC.set(Calendar.SECOND, s);
+        setDate(newC.getTime());
+    }
+
+    public void setDate(Date inDate) throws MDateOutOfRangeException
+    {
+        long currentInMillis = 0;
+        long startInMillis = 0;
+
+        if (compDates(inDate, minC) < 0 || compDates(inDate, maxC) > 0)
+        //if (inDate.before(minC.getTime()) || inDate.after(maxC.getTime()))
+        {
+            throw new MDateOutOfRangeException(inDate);
+        }
+
+        currentDate.setTime(inDate);
+
+        currentInMillis = inDate.getTime();
+
+        calMonth = currentDate.get(Calendar.MONTH);
+
+        startOfMonth.setTime(inDate);
+        startOfMonth.set(Calendar.DAY_OF_MONTH, 1); // First of month
+
+        int startDay = startOfMonth.get(Calendar.DAY_OF_WEEK);
+
+        // Calculate the first date to appear on the top line
+        // of the calendar
+        int x = firstDay - startDay;
+        if (x > 0) x = x - 7;
+//System.out.println("first="+firstDay+", StartDay="+startDay+", x="+x);
+        startOfMonth.add(Calendar.DATE, x);
+//System.out.println("S="+startOfMonth.getTime());
+        startInMillis = startOfMonth.getTime().getTime();
+
+        /* Now calculate the cell of the current date, there are 86,400,000
+        *  milliseconds in a day
+        */
+        Double daysD = new Double(((currentInMillis - startInMillis) / 
86400000d) + 0.5d);
+        int daysI = daysD.intValue(); // #days from start of calendar
+        if (startInMillis < 0 && currentInMillis > 0)
+        {
+            daysI++;
+        }
+        int row = Math.abs(daysI / 7);
+        int col = daysI - row * 7;
+
+        currentPoint.x = col;
+        currentPoint.y = row;
+
+        // Fire MMonthEvent as all data has changed
+        notifyListeners(new MMonthEvent(this, MMonthEvent.NEW_MONTH, 
currentDate));
+    }
+
+    /** Sets the earliest possible date for the calendar
+     *   @param min the earliest possible date
+     */
+    public void setMinimum(Date min)
+    {
+        if(compDates(min, maxC)<0)
+        {
+             minC.setTime(min);
+            notifyListeners(new MMonthEvent(this, MMonthEvent.NEW_MIN, minC));
+        }
+    }
+
+    /** Returns the earliest possible date the model can be set to
+     *   @return earliest date
+     */
+    public Date getMinimum()
+    {
+        return minC.getTime();
+    }
+
+    /** Sets the latest possible date for the calendar
+     *   @param max the latest possible date
+     */
+    public void setMaximum(Date max)
+    {
+        if(compDates(max, minC)>0)
+        {
+            maxC.setTime(max);
+            notifyListeners(new MMonthEvent(this, MMonthEvent.NEW_MAX, maxC));
+        }
+    }
+
+    /** Returns the latest possible date the model can be set to
+     *   @return latest date
+     */
+    public Date getMaximum()
+    {
+        return maxC.getTime();
+    }
+
+    /** Adds a number of months to the minimum date
+     *   @param increment the number of months to add
+     */
+    public void addToMin(int increment) throws MDateOutOfRangeException
+    {
+        addToM(increment);
+    }
+
+    private void addToM(int increment) throws MDateOutOfRangeException
+    {
+        Calendar currVal = (Calendar) minC.clone();
+        int day = currentDate.get(Calendar.DAY_OF_MONTH);
+        int hour = currentDate.get(Calendar.HOUR_OF_DAY);
+        int minute = currentDate.get(Calendar.MINUTE);
+        int second = currentDate.get(Calendar.SECOND);
+
+
+        currVal.add(Calendar.MONTH, increment);
+        currVal.set(Calendar.DAY_OF_MONTH, day);
+        currVal.set(Calendar.HOUR_OF_DAY, hour);
+        currVal.set(Calendar.MINUTE, minute);
+        currVal.set(Calendar.SECOND, second);
+
+        int day2 = currVal.get(Calendar.DAY_OF_MONTH);
+        //  If the dates are the same do nothing
+        if (compDates(currVal, currentDate) == 0)
+        {
+            return;
+        }
+
+        /*  Detect if we have skipped a month which occurs when the current 
date is 31 and the
+        *   following month has only 30 days (or less)
+        */
+        if (day != day2)
+        {
+            currVal.set(Calendar.DAY_OF_MONTH, 1);
+            currVal.add(Calendar.DAY_OF_MONTH, -1);
+        }
+        setDate(currVal.getTime());
+    }
+
+    /**
+     *    Returns the current date in the calendar. This gets set as
+     *    the calendar is clicked on
+     *    @return the currently selected date
+     */
+    public Date getCurrentDate()
+    {
+        return currentDate.getTime();
+    }
+
+    public Point getCurrentPoint()
+    {
+        return currentPoint;
+    }
+
+    /**
+     *    Sets the current date in the model
+     */
+    public void setCurrentDate(int row, int col) throws 
MDateOutOfRangeException
+    {
+        Calendar value = (Calendar) getValueAt(row, col);
+
+        if (compDates(value, minC) < 0|| compDates(value, maxC) >0)
+        {
+            tk.beep();
+            throw new MDateOutOfRangeException(value.getTime());
+        }
+        else
+        {
+            currentDate = value;
+            currentPoint.x = col;
+            currentPoint.y = row;
+            notifyListeners(new MMonthEvent(this, MMonthEvent.NEW_DATE, 
currentDate));
+
+        }
+
+    }
+
+    /**
+     *    returns the month index of the current calendar
+     */
+    public int getMonth()
+    {
+        return calMonth;
+    }
+
+    public int getColumnCount()
+    {
+        return 7;
+    }
+
+    public int getRowCount()
+    {
+        return 6;
+    }
+
+    /**
+     *   calculates the date in a particular cell based on the date at 0,0
+     *   (the start of the displayed calendar) and the cell being returned
+     */
+    public Object getValueAt(int r, int c)
+    {
+        offset = r * 7 + c;
+        date = (Calendar) startOfMonth.clone();
+        date.add(Calendar.DATE, offset);
+
+        return date;
+    }
+
+    protected Date getAsDate(int r, int c)
+    {
+        Calendar cal = (Calendar) getValueAt(r, c);
+        return cal.getTime();
+    }
+
+    /** Registers the listeners of the table changes
+     *   @param listener - MMonthListener
+     */
+    public void addMMonthListener(MMonthListener listener)
+    {
+        listeners.addElement(listener);
+
+    }
+
+    /** Removes the listener from the registered list
+     *   of listeners
+     *   @param listener - MMonthListener
+     */
+    public void removeMMonthListener(MMonthListener listener)
+    {
+        listeners.removeElement(listener);
+
+    }
+
+    /** Notifies registered listeners of a change to the data model
+     *   @param event - a MMonthEvent describing the change
+     */
+    private void notifyListeners(MMonthEvent event)
+    {
+        // Pass these events on to the registered listener
+
+        Vector list = (Vector) listeners.clone();
+        for (int i = 0; i < list.size(); i++)
+        {
+            MMonthListener l = (MMonthListener) listeners.elementAt(i);
+            l.dataChanged(event);
+        }
+    }
+
+    public boolean isInRange(Date date)
+    {
+        Calendar c=Calendar.getInstance();
+        c.setTime(date);
+        return isInRange(c);
+    }
+    public boolean isInRange(Calendar date)
+    {
+        return compDates(date, minC)>=0 && compDates(date, maxC)<=0;
+    }
+
+    public void exitEvent()
+    {
+        notifyListeners(new MMonthEvent(this, MMonthEvent.SELECTED, 
currentDate));
+    }
+
+    public void lostFocus()
+    {
+        notifyListeners(new MMonthEvent(this, MMonthEvent.EXITED, 
currentDate));
+    }
+
+    public boolean isCellEditable(int r, int c)
+    {
+        return false;
+    }
+
+    /**
+     *   Compares the Day, Month and Year in the Calendar objects passed in
+     *   @return 0 if the D, M and Y are the same in d2 and d1, < 0 if d1 is
+     *   before d2, > 0 if d1 is after d2
+     */
+    private static int compDates(Calendar d1, Calendar d2)
+    {
+        int day1 = d1.get(Calendar.DATE);
+        int month1 = d1.get(Calendar.MONTH);
+        int year1 = d1.get(Calendar.YEAR);
+        int day2 = d2.get(Calendar.DATE);
+        int month2 = d2.get(Calendar.MONTH);
+        int year2 = d2.get(Calendar.YEAR);
+
+
+        if (year1 != year2)
+            return year1 - year2;
+        if (month1 != month2)
+            return month1 - month2;
+        if (day1 != day2)
+            return day1 - day2;
+
+        return 0;
+    }
+
+    protected static int compDates(Date d1, Calendar c2)
+    {
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime((Date) d1.clone());
+        return compDates(c1, c2);
+    }
+
+    public boolean isCurrentDate(int d, int w)
+    {
+        Calendar date = (Calendar) getValueAt(d, w);
+        return (compDates(date, today) == 0);
+    }
+}
+
+/*
+$Log: MMonth.java,v $
+Revision 1.17  2003/10/11 10:28:46  martin
+*** empty log message ***
+
+Revision 1.16  2003/10/04 09:41:40  martin
+*** empty log message ***
+
+Revision 1.15  2003/06/20 21:55:32  martin
+*** empty log message ***
+
+Revision 1.14  2003/04/01 19:42:23  martin
+Fixed DST problem
+
+Revision 1.13  2003/03/31 20:35:39  martin
+no message
+
+Revision 1.12  2003/03/26 23:29:48  martin
+Changed email address
+
+Revision 1.11  2002/08/20 21:38:06  martin
+no message
+
+Revision 1.10  2002/08/20 20:53:07  martin
+no message
+
+Revision 1.9  2002/07/21 16:24:39  martin
+no message
+
+Revision 1.8  2002/06/07 21:53:03  martin
+Fixed bugs introduced in earlier fixes
+
+Revision 1.7  2002/06/06 21:13:46  martin
+Fixed bug with changing the year
+
+Revision 1.6  2002/05/31 18:51:33  martin
+no message
+
+Revision 1.5  2002/05/31 17:20:53  martin
+Added support for incrementing dates when current date is the last of the month
+
+Revision 1.4  2002/02/09 12:54:39  martin
+Partial support for 'Special Days'
+
+Revision 1.3  2002/02/03 12:49:08  martin
+Added support for curret date highlighted in different colour
+
+*/

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaArrowButton.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaArrowButton.java 
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaArrowButton.java 
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,119 @@
+/*
+*   Copyright (c) 2003 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.
+*
+*   Created on Jan 15, 2003 at 7:36:31 PM by martin
+*   Commited on $Date: 2003/04/10 19:03:56 $
+*/
+package mseries.plaf.Aqua;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class AquaArrowButton extends JButton
+{
+    int direction;
+
+    public AquaArrowButton(int dir)
+    {
+        super();
+        setDirection(dir);
+        setRequestFocusEnabled(false);
+        setIcon(new Triangle(dir, 4));
+    }
+
+    public int getDirection()
+    {
+        return direction;
+    }
+
+    public void setDirection(int dir)
+    {
+        direction = dir;
+    }
+
+    class Triangle implements Icon
+    {
+        int size = 6;
+        int dir = NORTH;
+
+        public Triangle(int dir, int size)
+        {
+            this.dir = dir;
+            this.size = size;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y)
+        {
+            Color oldColor = g.getColor();
+            int mid, i, j;
+
+            j = 0;
+            size = Math.max(size, 2);
+            mid = size / 2;
+
+            g.translate(x, y);
+
+            g.setColor(UIManager.getColor("textText"));
+            switch (dir)
+            {
+                case NORTH:
+                    for (i = 0; i < size; i++)
+                    {
+                        g.drawLine(mid - i, i, mid + i, i);
+                    }
+
+                    break;
+                case SOUTH:
+
+
+                    j = 0;
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(mid - i, j, mid + i, j);
+                        j++;
+                    }
+                    break;
+                case WEST:
+                    for (i = 0; i < size; i++)
+                    {
+                        g.drawLine(i, mid - i, i, mid + i);
+                    }
+
+                    break;
+                case EAST:
+
+
+                    j = 0;
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(j, mid - i, j, mid + i);
+                        j++;
+                    }
+                    break;
+            }
+            g.translate(-x, -y);
+            g.setColor(oldColor);
+        }
+
+        public int getIconWidth()
+        {
+            return size;
+        }
+
+        public int getIconHeight()
+        {
+            return size;
+        }
+    }
+}

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaDateEntryUI.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaDateEntryUI.java 
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Aqua/AquaDateEntryUI.java 
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,63 @@
+/*
+*   Copyright (c) 2003 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.
+*
+*   Created on Jan 14, 2003 at 7:40:42 PM by martin
+*   Commited on $Date: 2003/04/10 19:03:56 $
+*/
+package mseries.plaf.Aqua;
+
+import mseries.plaf.Mac.MacArrowButton;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+
+public class AquaDateEntryUI extends mseries.plaf.basic.BasicDateEntryUI
+{
+    public AquaDateEntryUI()
+    {
+        super();
+    }
+
+    /**
+    *    This method is called by the UIManager to get an instance of
+    *    this class and must be overridden in subclasses.
+    */
+    public static ComponentUI createUI(JComponent x)
+    {
+        return new AquaDateEntryUI();
+    }
+
+    public void configureDisplay(JComponent display)
+    {
+        display.setBorder(UIManager.getBorder("TextField.border"));
+        display.setPreferredSize(new Dimension(75, 21));
+    }
+
+    public void uninstallUI(JComponent c)
+    {
+        super.uninstallUI(c);
+        dateEntry.setBorder(null);
+    }
+
+    protected void configureBorder(JComponent c)
+    {
+    }
+
+    protected JButton createArrowButton()
+    {
+        JButton x=new MacArrowButton(SwingConstants.SOUTH);
+        return x;
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacArrowButton.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacArrowButton.java   
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacArrowButton.java   
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,119 @@
+/*
+*   Copyright (c) 2003 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.
+*
+*   Created on Jan 15, 2003 at 7:36:31 PM by martin
+*   Commited on $Date: 2003/03/26 23:29:49 $
+*/
+package mseries.plaf.Mac;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class MacArrowButton extends JButton
+{
+    int direction;
+
+    public MacArrowButton(int dir)
+    {
+        super();
+        setDirection(dir);
+        setRequestFocusEnabled(false);
+        setIcon(new Triangle(dir, 4));
+    }
+
+    public int getDirection()
+    {
+        return direction;
+    }
+
+    public void setDirection(int dir)
+    {
+        direction = dir;
+    }
+
+    class Triangle implements Icon
+    {
+        int size = 6;
+        int dir = NORTH;
+
+        public Triangle(int dir, int size)
+        {
+            this.dir = dir;
+            this.size = size;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y)
+        {
+            Color oldColor = g.getColor();
+            int mid, i, j;
+
+            j = 0;
+            size = Math.max(size, 2);
+            mid = size / 2;
+
+            g.translate(x, y);
+
+            g.setColor(UIManager.getColor("textText"));
+            switch (dir)
+            {
+                case NORTH:
+                    for (i = 0; i < size; i++)
+                    {
+                        g.drawLine(mid - i, i, mid + i, i);
+                    }
+
+                    break;
+                case SOUTH:
+
+
+                    j = 0;
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(mid - i, j, mid + i, j);
+                        j++;
+                    }
+                    break;
+                case WEST:
+                    for (i = 0; i < size; i++)
+                    {
+                        g.drawLine(i, mid - i, i, mid + i);
+                    }
+
+                    break;
+                case EAST:
+
+
+                    j = 0;
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(j, mid - i, j, mid + i);
+                        j++;
+                    }
+                    break;
+            }
+            g.translate(-x, -y);
+            g.setColor(oldColor);
+        }
+
+        public int getIconWidth()
+        {
+            return size;
+        }
+
+        public int getIconHeight()
+        {
+            return size;
+        }
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacDateEntryUI.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacDateEntryUI.java   
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/Mac/MacDateEntryUI.java   
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,61 @@
+/*
+*   Copyright (c) 2003 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.
+*
+*   Created on Jan 14, 2003 at 7:40:42 PM by martin
+*   Commited on $Date: 2003/03/26 23:29:49 $
+*/
+package mseries.plaf.Mac;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+
+public class MacDateEntryUI extends mseries.plaf.basic.BasicDateEntryUI
+{
+    public MacDateEntryUI()
+    {
+        super();
+    }
+
+    /**
+    *    This method is called by the UIManager to get an instance of
+    *    this class and must be overridden in subclasses.
+    */
+    public static ComponentUI createUI(JComponent x)
+    {
+        return new MacDateEntryUI();
+    }
+
+    public void configureDisplay(JComponent display)
+    {
+        display.setBorder(UIManager.getBorder("TextField.border"));
+        display.setPreferredSize(new Dimension(75, 21));
+    }
+
+    public void uninstallUI(JComponent c)
+    {
+        super.uninstallUI(c);
+        dateEntry.setBorder(null);
+    }
+
+    protected void configureBorder(JComponent c)
+    {
+    }
+
+    protected JButton createArrowButton()
+    {
+        JButton x=new MacArrowButton(SwingConstants.SOUTH);
+        return x;
+    }
+}

Added: 
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/basic/BasicCalendarPanelUI.java
===================================================================
--- 
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/basic/BasicCalendarPanelUI.java
   2006-03-14 07:10:06 UTC (rev 8247)
+++ 
trunk/apps/frost-0.7/lib/datechooser/mseries/plaf/basic/BasicCalendarPanelUI.java
   2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,513 @@
+/*
+*   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.plaf.basic;
+
+import mseries.Calendar.CalendarPanel;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ *   The BASIC look and feel UIDelegate for the CalendarPanel. It is envisaged
+ *   that this is subclasses to provide something more acceptable. A Windows
+ *   and Metal one are provided.
+
+ *    A Look and Feel delegate for the CalenderPanel. This version renders the
+ *    selected date with a raised border and dashed focus indicator. TAB moves
+ *    around the calendar, Shift-Tab jumps out to the next component. The arrow
+ *    keys move around the panel stopping (i.e. not rolling over) at the ends.
+ */
+public class BasicCalendarPanelUI extends ComponentUI
+{
+    protected Color background = UIManager.getColor("control");
+    protected Color foreground = UIManager.getColor("Button.foreground");
+    protected Color selectedBackground = UIManager.getColor("controlShadow");
+    protected Color selectedForeground = 
UIManager.getColor("Button.foreground");
+
+    protected CalendarPanel calendarPanel;
+
+    protected KeyListener keyHandler;
+    protected MouseListener mouseHandler;
+    protected FocusListener focusHandler;
+
+    protected int cellWidth, cellHeight;
+    protected int DAYS, WEEKS;
+    protected Font font;
+    private Toolkit tk = Toolkit.getDefaultToolkit();
+
+    /**
+     *    Inner class to handle presses of the arrow keys
+     */
+    protected class ArrowKeyAction implements ActionListener
+    {
+        private boolean horizontal;
+        private int inc;
+        private Point selected;
+        private Point first;
+        private Point last;
+
+        public ArrowKeyAction(int inc, boolean horizontal)
+        {
+            this.inc = inc;
+            this.horizontal = horizontal;
+        }
+
+        public void actionPerformed(ActionEvent e)
+        {
+            doAction(e);
+        }
+
+        private void doAction(ActionEvent e)
+        {
+            selected = calendarPanel.getSelectedCell();
+            int x = selected.x;
+            int y = selected.y;
+            first = calendarPanel.firstCell;
+            last = calendarPanel.lastCell;
+
+            if (horizontal)
+            {
+                int left = (selected.y == first.y) ? first.x : 0;
+                int right = (selected.y == last.y) ? last.x : DAYS - 1;
+                selected.x += inc;
+                selected.x = Math.min(Math.max(selected.x, left), right);
+            }
+            else
+            {
+                int top = (selected.x < first.x) ? first.y + 1 : 0;
+                int bottom = (selected.x > last.x) ? last.y - 1 : last.y;
+                selected.y += inc;
+                selected.y = Math.min(Math.max(selected.y, top), bottom);
+            }
+            if (calendarPanel.isInRange(selected.y, selected.x))
+            {
+                calendarPanel.setSelectedCell(selected);
+                calendarPanel.notifyListeners();
+            }
+            else
+            {
+                selected.x = x;
+                selected.y = y;
+                tk.beep();
+            }
+        }
+    }
+
+    /**
+     *    This method is called by the UIManager to get an instance of
+     *    this class and must be overridden in subclasses.
+     */
+    public static ComponentUI createUI(JComponent x)
+    {
+        return new BasicCalendarPanelUI();
+    }
+
+    /*
+    *    Called by the UIManager to install the UI of the component
+    */
+    public void installUI(JComponent c)
+    {
+        calendarPanel = (CalendarPanel)c;
+        installDefaults();
+        installListeners();
+    }
+
+    public void uninstallUI(JComponent c)
+    {
+        uninstallDefaults();
+        uninstallListeners();
+    }
+
+    protected void installDefaults()
+    {
+        DAYS = calendarPanel.DAYS;
+        WEEKS = calendarPanel.WEEKS;
+    }
+
+    protected void uninstallDefaults()
+    {
+    };
+
+
+
+    protected void installListeners()
+    {
+        if ((keyHandler = createKeyHandler()) != null)
+        {
+            calendarPanel.addKeyListener(keyHandler);
+        }
+
+        if ((mouseHandler = createMouseHandler()) != null)
+        {
+            calendarPanel.addMouseListener(mouseHandler);
+        }
+
+        if ((focusHandler = createFocusHandler()) != null)
+        {
+            calendarPanel.addFocusListener(focusHandler);
+        }
+
+        installKeyboardActions();
+    }
+
+    private void installKeyboardActions()
+    {
+        calendarPanel.registerKeyboardAction(new ArrowKeyAction(-1, true), 
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), JComponent.WHEN_FOCUSED);
+        calendarPanel.registerKeyboardAction(new ArrowKeyAction(1, true), 
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), JComponent.WHEN_FOCUSED);
+        calendarPanel.registerKeyboardAction(new ArrowKeyAction(-1, false), 
KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), JComponent.WHEN_FOCUSED);
+        calendarPanel.registerKeyboardAction(new ArrowKeyAction(1, false), 
KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), JComponent.WHEN_FOCUSED);
+    }
+
+    protected void uninstallListeners()
+    {
+        if (keyHandler != null)
+        {
+            calendarPanel.removeKeyListener(keyHandler);
+        }
+
+        if (mouseHandler != null)
+        {
+            calendarPanel.removeMouseListener(mouseHandler);
+        }
+
+        if (focusHandler != null)
+        {
+            calendarPanel.removeFocusListener(focusHandler);
+        }
+    }
+
+    public void update(Graphics g, JComponent c)
+    {
+        paint(g, c);
+    }
+
+    public void paint(Graphics g, JComponent c)
+    {
+        cellWidth = getCellSize().width;
+        cellHeight = getCellSize().height;
+
+        doPaint(g, c);
+    }
+
+    private void doPaint(Graphics g, JComponent c)
+    {
+        String legend;
+        boolean selectCell;
+        int day;
+        Point thisCell = calendarPanel.getSelectedCell();
+
+        background = c.getBackground();
+        foreground = c.getForeground();
+
+        font = c.getFont();
+
+/*
+        if(isOpaque())
+        {
+            g.setColor(background);
+            g.fillRect(0, 0, cellWidth, cellHeight);
+        }
+*/
+
+        for (int d = 0; d < WEEKS; d++)
+        {
+            for (int w = 0; w < DAYS; w++)
+            {
+                selectCell = false;
+                if (thisCell.x == w && thisCell.y == d)
+                {
+                    selectCell = true;
+                }
+
+                if (!calendarPanel.isInMonth(d, w))
+                {
+                    legend = null;
+                    background = calendarPanel.getBackground();
+                    foreground = calendarPanel.getForeground();
+                }
+                else
+                {
+                    day = calendarPanel.getLegendFor(d, w);
+                    if (day == 1)
+                        calendarPanel.firstCell.x = w;
+                    legend = Integer.toString(day);
+                    calendarPanel.lastCell.x = w;
+                    calendarPanel.lastCell.y = d;
+
+                    background = calendarPanel.getBackground(d, w);
+                    foreground = calendarPanel.getForeground(d, w);
+                }
+
+                g.translate(cellWidth * w, cellHeight * d);
+
+
+                drawSelectedEffect(g, selectCell);
+                if (legend != null)
+                    drawLegend(g, legend);
+
+                drawFocusedEffect(g, calendarPanel.hasFocus() && selectCell, 
selectCell);
+
+                g.translate(-(cellWidth * w), -(cellHeight * d));
+            }
+        }
+    }
+
+    /*
+    *    This is where we would draw/remove borders, focus highlights,
+    *    colours etc. Override this method in a subclass to render the
+    *    selected date.
+    */
+    protected void drawSelectedEffect(Graphics g, boolean selected)
+    {
+        int width, height;
+
+        width = getCellSize().width;
+        height = getCellSize().height;
+
+        if (isOpaque())
+        {
+            g.setColor(background);
+            g.fillRect(0, 0, width, height);
+        }
+
+        if (selected)
+        {
+            g.setColor(SystemColor.controlDkShadow);
+            // Draw Raised Border TOP-LEFT
+            g.drawRoundRect(0, 0, width-1, height-1, 2, 2);
+            /*
+            g.drawLine(0, 0, width, 0);
+            g.drawLine(0, 0, 0, height);
+
+            // BOTTOM-RIGHT
+            g.drawLine(0, height - 1, width - 1, height - 1);
+            g.drawLine(width - 1, height - 1, width - 1, 0);
+            */
+        }
+    }
+
+    /**
+     *   This is where the legend, the day is drawn
+     */
+    public void drawLegend(Graphics g, String legend)
+    {
+        int x,y;
+        FontMetrics fm;
+        int strWidth = 0;
+        int strHeight = 0;
+        int width, height;
+
+        width = getCellSize().width;
+        height = getCellSize().height;
+
+        g.setFont(calendarPanel.getFont());
+        fm = g.getFontMetrics();
+        strWidth = fm.stringWidth(legend);
+        strHeight = fm.getHeight();
+        x = width - strWidth - 4;
+        y = ((height - strHeight) / 2) + strHeight - 4;
+
+        g.setColor(foreground);
+        g.drawString(legend, x, y);
+    }
+
+    /**
+     *    Draws the dashed rectangle around the number in the cell which is 
selected
+     *    when the calendar panel has focus. Over ride this method in a 
subclass
+     *    to change the appearance.
+     */
+    protected void drawFocusedEffect(Graphics g, boolean focused, boolean 
selected)
+    {
+/*
+        int width, height;
+
+        width = getCellSize().width;
+        height = getCellSize().height;
+        if (focused)
+        {
+            g.setColor(foreground);
+            g.drawLine(3, height-5, width-3, height-5);
+            //drawDashedRect(g, 3, , width-5, height-5);
+        }
+*/
+    }
+
+    /**
+     *    Creates the mouse listener for the panel.
+     */
+    protected MouseListener createMouseHandler()
+    {
+
+        return new MouseAdapter()
+        {
+            int x, y;
+
+            public void mousePressed(MouseEvent e)
+            {
+                x = e.getX() / cellWidth;
+                y = e.getY() / cellHeight;
+                if (calendarPanel.isInMonth(y, x) && 
calendarPanel.isInRange(y, x))
+                {
+                    calendarPanel.setSelectedCell(x, y);
+                    /*
+                    *    Only repaint if the click is in a legitimate cell
+                    */
+                    if (calendarPanel.hasFocus())
+                    {
+                        // Already go the focus so a simple repaint will do
+                        calendarPanel.repaint();
+                    }
+                    else
+                    {
+                        /*
+                        *    First click to get the focus, repaint is done by 
the
+                        *    processFocusEvent method
+                        */
+                        calendarPanel.requestFocus();
+                    }
+                    calendarPanel.notifyListeners();
+                }
+            }
+        };
+    }
+
+
+    /**
+     *    KeyHandler factory method, this implementation handles the push
+     *    of the TAB and SHIFT-TAB key
+     *    @return a KeyListener Object
+     */
+    protected KeyListener createKeyHandler()
+    {
+        return new KeyAdapter()
+        {
+            public void keyPressed(KeyEvent e)
+            {
+                int key = e.getKeyCode();
+                int modifiers = e.getModifiers();
+                if (key == KeyEvent.VK_TAB)
+                {
+                    // Manage tabbing around the Button Panel
+                    int inc = (modifiers == InputEvent.SHIFT_MASK) ? -1 : 1;
+                    moveToNextCell(inc, true);
+                    calendarPanel.notifyListeners();
+                    e.consume();
+                }
+                calendarPanel.repaint();
+            }
+        };
+    }
+
+    protected FocusListener createFocusHandler()
+    {
+        return new FocusAdapter()
+        {
+            public void focusGained(FocusEvent e)
+            {
+                doFocus();
+            }
+
+            public void focusLost(FocusEvent e)
+            {
+                doFocus();
+            }
+
+            private void doFocus()
+            {
+                calendarPanel.repaint();
+            }
+        };
+    }
+
+    protected Dimension getCellSize()
+    {
+        return calendarPanel.getCellSize();
+    }
+
+    /**
+     *    Calculates the next cell that contains a valid date and therefore
+     *    can be selected
+     *    @param inc minus -1 moves back one day, +1 forward wrapping around at
+     *    both the start and end of the month
+     *    @param roll true if the selection rols to the next row at the end
+     */
+    protected void moveToNextCell(int inc, boolean roll)
+    {
+        move(inc, roll);
+    }
+
+    private void move(int inc, boolean roll)
+    {
+        Point firstCell = calendarPanel.firstCell;
+        Point lastCell = calendarPanel.lastCell;
+        Point selectedCell = (Point)(calendarPanel.getSelectedCell()).clone();
+        /*
+        *    First check the boundaries
+        */
+        if (inc > 0 && selectedCell.equals(lastCell))
+        {
+            calendarPanel.setSelectedCell(firstCell);
+            return;
+        }
+        if (inc < 0 && selectedCell.equals(firstCell))
+        {
+            calendarPanel.setSelectedCell(lastCell);
+            return;
+        }
+        /*
+        *    Now move within the calendar, rolling around at the end/start
+        *    of each row
+        */
+        selectedCell.x += inc;
+
+        if (selectedCell.x == DAYS)
+        {
+            selectedCell.x = 0;
+            selectedCell.y++;
+
+        }
+        else if (selectedCell.x < 0)
+        {
+            selectedCell.x = DAYS - 1;
+            selectedCell.y--;
+        }
+
+        if (selectedCell.y == WEEKS)
+        {
+            selectedCell.y = 0;
+        }
+        else if (selectedCell.y < 0)
+        {
+            selectedCell.y = WEEKS - 1;
+        }
+        if (calendarPanel.isInRange(selectedCell.y, selectedCell.x))
+        {
+            calendarPanel.setSelectedCell(selectedCell);
+        }
+        else
+        {
+            tk.beep();
+        }
+    }
+
+    public boolean isOpaque()
+    {
+        return !calendarPanel.hasImage();
+    }
+}
+
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ArrowButton.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ArrowButton.java    
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/ArrowButton.java    
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,199 @@
+/*
+*   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.*;
+
+
+/**
+ *   An arrow button with no border, until the mouse rolls over when the L&F 
border is drawn
+ */
+public class ArrowButton extends JButton implements SwingConstants
+{
+    int direction;
+
+    public ArrowButton(int dir)
+    {
+        super();
+        setDirection(dir);
+        setRequestFocusEnabled(false);
+        //setRolloverEnabled(true);
+    }
+
+    public int getDirection()
+    {
+        return direction;
+    }
+
+    public void setDirection(int dir)
+    {
+        direction = dir;
+    }
+
+
+    public void paint(Graphics g)
+    {
+        int w, h, size;
+        boolean isEnabled;
+        Color origColor;
+
+        h = getSize().height;
+        setMinimumSize(new Dimension(h, h));
+        setPreferredSize(new Dimension(h, h));
+        w = getSize().width;
+        isEnabled = isEnabled();
+        origColor = g.getColor();
+        g.setColor(getBackground());
+        g.fillRect(0, 0, w, h);
+
+        // Draw the arrow
+        size = Math.min((h - 4) / 3, (w - 4) / 3);
+        size = Math.max(size, 2);
+        paintTriangle(g, (w - size) / 2, (h - size) / 2, size, direction, 
isEnabled);
+
+        // Reset the Graphics back to it's original settings
+        g.setColor(origColor);
+
+        paintBorder(g);
+    }
+
+    public void paintTriangle(Graphics g, int x, int y, int size,
+                              int direction, boolean isEnabled)
+    {
+        Color oldColor = g.getColor();
+        int mid, i, j;
+
+        j = 0;
+        size = Math.max(size, 2);
+        mid = size / 2;
+
+        g.translate(x, y);
+
+        g.setColor(isEnabled() ? UIManager.getColor("Button.foreground") :
+                UIManager.getColor("controlShadow"));
+        switch (direction)
+        {
+            case NORTH:
+                for (i = 0; i < size; i++)
+                {
+                    g.drawLine(mid - i, i, mid + i, i);
+                }
+                if (!isEnabled)
+                {
+                    g.setColor(UIManager.getColor("controlLtHighlight"));
+                    g.drawLine(mid - i + 2, i, mid + i, i);
+                }
+                break;
+            case SOUTH:
+                if (!isEnabled)
+                {
+                    g.translate(1, 1);
+                    g.setColor(UIManager.getColor("controlLtHighlight"));
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(mid - i, j, mid + i, j);
+                        j++;
+                    }
+                    g.translate(-1, -1);
+                    g.setColor(UIManager.getColor("controlShadow"));
+                }
+
+                j = 0;
+                for (i = size - 1; i >= 0; i--)
+                {
+                    g.drawLine(mid - i, j, mid + i, j);
+                    j++;
+                }
+                break;
+            case WEST:
+                for (i = 0; i < size; i++)
+                {
+                    g.drawLine(i, mid - i, i, mid + i);
+                }
+                if (!isEnabled)
+                {
+                    g.setColor(UIManager.getColor("controlLtHighlight"));
+                    g.drawLine(i, mid - i + 2, i, mid + i);
+                }
+                break;
+            case EAST:
+                if (!isEnabled)
+                {
+                    g.translate(1, 1);
+                    g.setColor(UIManager.getColor("controlLtHighlight"));
+                    for (i = size - 1; i >= 0; i--)
+                    {
+                        g.drawLine(j, mid - i, j, mid + i);
+                        j++;
+                    }
+                    g.translate(-1, -1);
+                    g.setColor(UIManager.getColor("controlShadow"));
+                }
+
+                j = 0;
+                for (i = size - 1; i >= 0; i--)
+                {
+                    g.drawLine(j, mid - i, j, mid + i);
+                    j++;
+                }
+                break;
+        }
+        g.translate(-x, -y);
+        g.setColor(oldColor);
+    }
+
+    public boolean isFocusable()
+    {
+        return false;
+    }
+
+    public boolean isFocusPainted()
+    {
+        return false;
+    }
+
+    public void setEnabled(boolean enabled)
+    {
+        if (!enabled)
+        {
+            getModel().setRollover(false);
+        }
+        super.setEnabled(enabled);
+    }
+}
+
+// $Log: ArrowButton.java,v $
+// Revision 1.4  2003/03/26 23:29:49  martin
+// Changed email address
+//
+// Revision 1.3  2003/01/18 16:53:53  martin
+// *** empty log message ***
+//
+// Revision 1.2  2003/01/07 22:15:55  martin
+// *** empty log message ***
+//
+// Revision 1.1  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/MDateCellEditor.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateCellEditor.java        
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateCellEditor.java        
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,107 @@
+/*
+*   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 mseries.Calendar.*;
+import java.awt.*;
+import java.util.*;
+import java.text.*;
+import javax.swing.*;
+import javax.swing.table.*;
+
+/**
+*   A simple example of MDateEntryField used as a table cell editor and table
+*   cell renderer. It implements both interfaces but the same instance can
+*   not be used as both the renderer and the editor. It is safest to use two
+*   instances for each cell. As a renderer all the component gives is the
+*   date formatting and the button which when clicked invokes the editor which
+*   looks the same. A simple date formatting textfield would work equally well
+*   as the renderer as Swing itself replaces the renderer with the editor when
+*   the cell is clicked and vice-versa when editing is finished.
+*/
+public class MDateCellEditor extends AbstractCellEditor implements 
TableCellEditor, TableCellRenderer
+{
+    public MDateEntryField comp=new MDateEntryField();
+    Date date;
+
+    /**
+     * Constructs the editor using the date formatter passed.
+     * @param formatter a DateFormat object to use for displaying the date
+     */
+    public MDateCellEditor(DateFormat formatter)
+    {
+        comp=new MDateEntryField(formatter);
+        comp.setBorder(null);
+        configureEditor();
+    }
+
+
+    public MDateCellEditor(String format)
+    {
+        this(new SimpleDateFormat(format));
+    }
+    /**
+    *   This method makes the component an editor
+    */
+    public Component getTableCellEditorComponent(JTable table, Object value, 
boolean isSelected, int row, int column)
+    {
+        comp.setValue((Date)value);
+        return comp;
+    }
+
+    /**
+    *   This method makes the component a renderer
+    */
+    public Component getTableCellRendererComponent(JTable table, Object value, 
boolean isSelected, boolean hasFocus, int row, int column)
+    {
+        comp.setValue((Date)value);
+        return comp;
+    }
+
+    public Object getCellEditorValue()
+    {
+        try
+        {
+            date=comp.getValue();
+        }
+        catch (ParseException e)
+        {
+            date=new Date();
+        }
+        return date;
+    }
+
+    /**
+    *   This method can be used to configure the MDateEntryField that is used
+    *   as the cell editor component. In the constructor this method is called
+    *   <i>after</i> the format is set and after border is nullified. Thus it
+    *   is best to only configure a constrainst object here and use it to
+    *   configure the editing field.
+    *   @see mseries.ui.MDateEntryField
+    *   @see mseries.Calendar.MDateSelectorConstraints
+    */
+    protected void configureEditor()
+    {
+    }
+
+    /**
+    *   Passes the constraints object to the field that does the editing.
+    *   @param c a constraints object that can configure the pull down
+    */
+    public void setConstraints(MDateSelectorConstraints c)
+    {
+        comp.setConstraints(c);
+    }
+}

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateField.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateField.java     
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateField.java     
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,457 @@
+/*
+*   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 mseries.Calendar.MDateSelector;
+import mseries.Calendar.MDateSelectorConstraints;
+import mseries.Calendar.MDefaultPullDownConstraints;
+
+import javax.swing.*;
+import javax.swing.text.DateFormatter;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * Date entry widget with built in Formatter/Parser and Calendar popup to
+ * facilitate input. The earliest and latest possible values may be set using
+ * the setMinimum and setMaximum methods, this causes the calendar popup to
+ * allow date within the range to be selected. Dates outside of the range may
+ * be entered by typing directly into the field.
+ *
+ * @author     Martin Newstead
+ */
+public class MDateField extends JFormattedTextField
+{
+    private Date minDate = null;
+    private Date maxDate = null;
+//    private Date date = null;
+
+    /**
+     *   The MDateFormatter trys to parse the user input in SHORT, MEDIUM and 
LONG
+     *   formats for the default locale. If the text field is not enterable or 
less
+     *   flexibility is needed then this would be done differently
+     */
+    /** @deprecated */
+    public mseries.ui.MDateFormat df = MDateFormatter.getInstance();
+    ResourceBundle rb;
+    MouseListener mouseListener;
+    MDateSelectorConstraints c = new MDefaultPullDownConstraints();
+
+    private boolean hasPopup = false;
+    private int h;
+    private int m;
+    private int s;
+    private int ms;
+
+
+    public MDateField(DateFormat df)
+    {
+        super(new DateFormatter(df));
+        init();
+    }
+    /**
+     * @param  text the display field size
+     * @deprecated
+     */
+    public MDateField(int text)
+    {
+        super();
+        init();
+    }
+
+    /**
+     * Default Constructor
+     *
+     *
+     */
+    public MDateField()
+    {
+        super(new Date());
+        init();
+    }
+
+    protected void init()
+    {
+        super.setValue(new Date());
+        try
+        {
+            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, new 
Locale("en", "GB"));
+            maxDate = df.parse("31/12/2037");
+            minDate = df.parse("1/1/1970");
+        }
+        catch (ParseException e)
+        {
+        }
+    }
+
+    /**
+     *   Tells the component what date formatter to use for parsing and 
formatting
+     *   the user input.
+     *   @param df the date formatter
+     *   @deprecated format should be set when the object is instantiated by 
passing an instance of DateFormat, NB this
+     *   method does nothing
+     */
+    public void setDateFormatter(MDateFormat df)
+    {
+        //this.df = df;
+        //setValue(date);
+    }
+
+
+
+    /**
+     * Returns the date formatter
+     * @param x not used, only inplace to allow the same method name as the 
depreicated method
+     * @return the date formatter
+     */
+    public AbstractFormatter getDateFormatter(Object x)
+    {
+        return getFormatter();
+    }
+    /*
+    *   @deprecated Use DateFormat getDateFormatter() to get a formatter
+    */
+    public MDateFormat getDateFormatter()
+    {
+        return df;
+    }
+
+    public boolean hasPopup()
+    {
+        return this.hasPopup;
+    }
+
+    /**
+     *   Sets the constraints object that contains the parameters used to 
configure the
+     *   pull down calendar
+     *   @param c the constraints object
+     *   @see #getConstraints
+     */
+    public void setConstraints(MDateSelectorConstraints c)
+    {
+        this.c = c;
+    }
+
+    /**
+     *   Gets the constraints object that contains the parameters used to 
configure the
+     *   pull down calendar
+     *   @see #setConstraints
+     */
+    public MDateSelectorConstraints getConstraints()
+    {
+        return this.c;
+    }
+
+    /**
+     * @param  hasPopup
+     */
+    public void setPopup(boolean hasPopup)
+    {
+        pSetPopup(hasPopup);
+    }
+
+    private void pSetPopup(boolean hasPopup)
+    {
+        /* Already has a popup and we want one */
+        if (hasPopup && this.hasPopup)
+        {
+            return;
+        }
+        /* Don't want a popup and haven't got one */
+        if (!hasPopup && !this.hasPopup)
+        {
+            return;
+        }
+        /* Don't want a popup but it has one */
+        if (!hasPopup && this.hasPopup)
+        {
+            removeMouseListener(mouseListener);
+            this.hasPopup = false;
+        }
+
+        /* User can right click on the textfield to get a date popup */
+        mouseListener = new MouseAdapter()
+        {
+            public void mouseReleased(MouseEvent e)
+            {
+                if (e.isPopupTrigger())
+                {
+                    doPopup(e.getPoint());
+                }
+            }
+
+            public void mousePressed(MouseEvent e)
+            {
+                if (e.isPopupTrigger())
+                {
+                    doPopup(e.getPoint());
+                }
+            }
+
+            private void doPopup(Point p)
+            {
+                MDateSelector popup;
+                popup = new MDateSelector(minDate, maxDate);
+                popup.setConstraints(c);
+
+                //if (minDate != null)
+                //    popup.setMinimum(minDate);
+                //if (maxDate != null)
+                //    popup.setMaximum(maxDate);
+
+                p.x += getBounds(null).x;
+                p.y += getBounds(null).y;
+                popup.show(getParent(), p, getValue(null));
+
+                setValue(popup.getValue());
+                popup = null;
+                requestFocus();
+
+            }
+        };
+        addMouseListener(mouseListener);
+        this.hasPopup = hasPopup;
+    }
+
+    /** 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)
+    {
+        minDate = 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)
+    {
+        maxDate = date;
+    }
+
+    /**
+     * Returns the earliest date
+     *
+     */
+    public Date getMinimum()
+    {
+        return minDate;
+    }
+
+    /**
+     * @return The latest date
+     *
+     */
+    public Date getMaximum()
+    {
+        return maxDate;
+    }
+
+    /**
+     * @return the value of the field
+     * date formatter
+     */
+    public Date getValue(Date defaultValue)
+    {
+        String v=getText();
+        AbstractFormatter f=getFormatter();
+        Date date=null;
+        try
+        {
+            date = (Date)f.stringToValue(v);
+            //Date date = (Date)super.getValue();//df.parse(getText());
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(date);
+            cal.set(Calendar.HOUR_OF_DAY, h);
+            cal.set(Calendar.MINUTE, m);
+            cal.set(Calendar.SECOND, s);
+            cal.set(Calendar.MILLISECOND, ms);
+            //setValue(cal.getTime());
+            return cal.getTime();
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+
+    }
+
+    /**
+     *   @return the value of the field
+     *   @param defaultValue the value to be returned if a parseException 
occurs, useful
+     *   if there is no value in the field as "" is not parsable
+     */
+    //public Date getValue(Date defaultValue)
+    //{
+    //    //try
+    //    //{
+    //    //    return (Date)super.getValue();
+    //    //}
+    //    //catch (ParseException e)
+    //    //{
+    //    //    return defaultValue;
+    //    //}
+    //    Date d=(Date)super.getValue();
+    //    return (d==null) ? defaultValue : d;
+    //}
+
+    /**
+     * @param  date
+     */
+    public void setValue(Date date)
+    {
+        Calendar cal = Calendar.getInstance();
+        if (date != null)
+        {
+            cal.setTime(date);
+            h = cal.get(Calendar.HOUR_OF_DAY);
+            m = cal.get(Calendar.MINUTE);
+            s = cal.get(Calendar.SECOND);
+            ms = cal.get(Calendar.MILLISECOND);
+        }
+//        this.date = date;
+        //setText(date == null ? "" : df.format(date));
+        super.setValue(date);
+    }
+
+    /**
+     * @param  args
+     */
+//    public static void main(String args[])
+//    {
+//        /*  The date entry field, this variable and the frame need to be 
final because main()
+//        *   is static and they are used in the inner class that is the 
action listener for
+//        *   the button
+//        */
+//        final MDateField endDate = new MDateField(20);
+//        final JFrame myFrame = new JFrame("My Frame");
+//endDate.setEnabled(false);
+//
+//        /* This date formatter is used simply to parse the strings for max 
and min values */
+//        DateFormat dF = DateFormat.getDateInstance(DateFormat.SHORT);
+//         try
+//        {
+//            
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+//            
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
+//            /*  Correct format for locale en_GB ! Setting the maximum and 
minimum is
+//            *   optional, defaults are provided.
+//            */
+//            endDate.setPopup(true);
+//            endDate.setMinimum(dF.parse("1/1/1970"));
+//            endDate.setMaximum(dF.parse("30/06/2030"));
+//         }
+//        catch (Exception e)
+//        {
+//           e.printStackTrace();
+//         }
+//
+//
+//        JButton dateButton = new JButton("Select");
+//
+//        dateButton.addActionListener(new ActionListener()
+//        {
+//            public void actionPerformed(ActionEvent e)
+//            {
+//                MDateSelector popup;
+//                popup = new MDateSelector();
+//
+//                /* endDate is the name of my custom text field for date 
input */
+//                popup.setMinimum(endDate.getMinimum());
+//                popup.setMaximum(endDate.getMaximum());
+//                //popup.setImageFile("d:\\temp\\MBackground.gif");
+//                //popup.setFirstDay(Calendar.SATURDAY);
+//
+//                /*  Get the position of the text field and use this for the 
position of the popup,
+//                *   the MDateSelector uses these coordinates relative to the 
component passed as
+//                *   the parent (endDate)
+//                */
+//                Point p=endDate.getBounds().getLocation();
+//
+//                try
+//                {
+//                    /*  1st arg is the component to position the popup 
relative to
+//                    *   2nd is the position relative to the component in 1
+//                    *   3rd is the initial value, null for the default 
(today)
+//                    */
+//                    popup.show(endDate, p, endDate.getValue(null));
+//
+//                    /*  Set the value in the text field once the popup has 
been dismissed */
+//                    endDate.setValue(popup.getValue());
+//                }
+//                catch(Exception ex)
+//                {
+//                    ex.printStackTrace();
+//                }
+//                popup=null;
+//            }
+//
+//        });
+//
+//        myFrame.getContentPane().setLayout(new FlowLayout());
+//        myFrame.getContentPane().add(endDate);
+//        myFrame.getContentPane().add(dateButton);
+//JTextField tf=new JTextField("hello");
+//tf.setEnabled(false);
+//        myFrame.getContentPane().add(tf);
+//
+//        myFrame.addWindowListener(new WindowAdapter() {
+//            public void windowClosing(WindowEvent e) {
+//                System.exit(0);
+//            }
+//        });
+//        myFrame.pack();
+//        myFrame.show();
+//    }
+}
+
+// $Log: MDateField.java,v $
+// Revision 1.12  2004/08/29 17:11:09  martin
+// *** empty log message ***
+//
+// Revision 1.11  2004/03/07 18:57:36  martin
+// *** empty log message ***
+//
+// Revision 1.10  2004/03/05 23:25:00  martin
+// *** empty log message ***
+//
+// Revision 1.9  2003/10/04 09:47:39  martin
+// *** empty log message ***
+//
+// Revision 1.8  2003/06/20 21:55:26  martin
+// *** empty log message ***
+//
+// Revision 1.7  2003/03/26 23:29:50  martin
+// Changed email address
+//
+// Revision 1.6  2002/05/15 17:36:45  martin
+// Added call to setText to echo the parsed date to the display
+//
+// Revision 1.5  2002/03/06 22:08:22  martin
+// Fixed format problem with default value
+//
+// Revision 1.4  2002/02/17 17:24:16  martin
+// Commented out main(String[])
+//
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatter.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatter.java 
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MDateFormatter.java 
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,199 @@
+/*
+*   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.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.util.Date;
+
+public class MDateFormatter  implements MDateFormat
+{
+    private DateFormat shortFormatter = 
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+    private DateFormat mediumFormatter = 
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
+    private DateFormat longFormatter = 
DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT);
+
+    private DateFormat shortDFormatter = 
DateFormat.getDateInstance(DateFormat.SHORT);
+    private DateFormat mediumDFormatter = 
DateFormat.getDateInstance(DateFormat.MEDIUM);
+    private DateFormat longDFormatter = 
DateFormat.getDateInstance(DateFormat.LONG);
+
+    private static DateFormat formatter;
+    private static MDateFormatter thisFormatter;
+
+    private MDateFormatter()
+    {
+        formatter = DateFormat.getDateInstance(DateFormat.SHORT);
+        formatter.setLenient(false);
+
+        shortFormatter.setLenient(false);
+        mediumFormatter.setLenient(false);
+        longFormatter.setLenient(false);
+
+        shortDFormatter.setLenient(false);
+        mediumDFormatter.setLenient(false);
+        longDFormatter.setLenient(false);
+    }
+
+
+    /**
+    *   Singleton constructor, there is no public constructor for this class
+    */
+    public static MDateFormat getInstance()
+    {
+        if (thisFormatter == null)
+        {
+             thisFormatter= new MDateFormatter();
+        }
+        return thisFormatter;
+    }
+
+
+    /**
+    *    Returns the date formatted for display in the form of a String.
+    *    The format is defined in the constructor of the class.
+    */
+    public String format(Date date)
+    {
+        String formattedDate="";
+        try
+        {
+            formattedDate = formatter.format(date);
+        }
+        catch (NullPointerException npe)
+        {
+            System.out.println(npe.toString());
+        }
+        return formattedDate;
+    }
+
+    public StringBuffer format(Date date, StringBuffer appendTo, FieldPosition 
pos)
+    {
+        return formatter.format(date, appendTo, pos);
+    }
+
+   /**
+    *  Applies the formatters to parse the input string and attempts
+    *  to translate it into a valid date. Valid dates with the last two digits 
less
+    *  than the value of Constants.CENTURY_VALUE are parsed to the 21st 
Century,
+    *  greater than the constant value are the 20th Century.
+    */
+
+    public Date parse(String text) throws ParseException
+    {
+        String inputText=new String(text);
+        Date date;
+
+        try
+        {
+            date = dateTimeParse(inputText);
+        }
+        catch (ParseException pe)
+        {
+            // Date/Time didn't work so try date only
+            date = dateParse(inputText);
+            // date works so add default time and retry
+            inputText+=" 00:00:00";
+            date=dateTimeParse(inputText);
+        }
+
+        return date;
+    }
+
+
+    /** Uses Date formatters to parse the input text
+    *   @param text - the string to be parsed
+    */
+    public Date dateParse(String text) throws ParseException
+    {
+        Date date=new Date();
+        try
+        {
+            date=longDFormatter.parse(text);
+
+        }
+        catch (ParseException le)
+        {
+            try
+            {
+                 date=mediumDFormatter.parse(text);
+            }
+            catch (ParseException me)
+            {
+                try
+                {
+                    date=shortDFormatter.parse(text);
+                }
+                catch (ParseException se)
+                {
+                    throw se;
+                }
+            }
+        }
+
+        return date;
+    }
+    /** Uses DateTime formatters to parse the input text
+    *   @param text - the string to be parsed
+    */
+    public Date dateTimeParse(String text) throws ParseException
+    {
+        Date date=new Date();
+        try
+        {
+            date=longFormatter.parse(text);
+
+        }
+        catch (ParseException le)
+        {
+            try
+            {
+                 date=mediumFormatter.parse(text);
+            }
+            catch (ParseException me)
+            {
+                try
+                {
+                    date=shortFormatter.parse(text);
+                }
+                catch (ParseException se)
+                {
+                    throw se;
+                }
+            }
+        }
+        return date;
+    }
+
+    public static void main(String args[])
+    {
+        Date d=new Date();
+
+        MDateFormat df=null;
+
+        try
+        {
+            df = MDateFormatter.getInstance();
+            System.out.println(df.parse(args[0]));
+        }
+        catch(ParseException pe)
+        {
+            System.out.println(pe);
+
+        }
+
+        System.out.println(df.format(d));
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupPanel.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupPanel.java    
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/ui/MPopupPanel.java    
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,164 @@
+/*
+*   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.*;
+import java.io.*;
+import javax.swing.*;
+
+public class MPopupPanel extends JPanel implements MPopup, Serializable
+{
+    int desiredLocationX,desiredLocationY;
+    boolean isVisible=false;
+    boolean hasShadow=false;
+    Component invoker;
+    Component firstComp=null;
+
+    public MPopupPanel() 
+    {
+        super();
+        setLayout(new BorderLayout());
+        setDoubleBuffered(true);
+        this.setOpaque(true);
+    }
+
+    public void addComponent(Component aComponent,Object constraints) 
+    {
+        this.add(aComponent,constraints);
+        if (firstComp==null) 
+        {
+            firstComp=aComponent;
+        }
+    }
+
+    public void setShadow(boolean hasShadow)
+    {
+        if (hasShadow)
+        {
+            this.add(new Shadow(SwingUtilities.HORIZONTAL), 
BorderLayout.SOUTH);
+            this.add(new Shadow(SwingUtilities.VERTICAL), BorderLayout.EAST);
+        }
+        this.hasShadow=hasShadow;
+    }
+
+    public boolean isShadow()
+    {
+        return hasShadow;
+    }
+
+    public void removeComponent(Component c) 
+    {
+        this.remove(c);
+    }
+
+    public void requestFocus()
+    {
+        firstComp.requestFocus();
+    }
+
+    public void update(Graphics g) 
+    {
+        paint(g);
+    }
+    
+    public void pack() 
+    {
+        setSize(getPreferredSize());
+    }
+
+    public void setParent(Component invoker)
+    {
+        this.invoker=invoker;
+    }
+
+    private void showPanel(Component invoker) 
+    {
+        Container parent = ScreenUtilities.getParentWindow(invoker);
+
+        Point p = 
ScreenUtilities.convertScreenLocationToParent(parent,desiredLocationX,desiredLocationY);
+
+        this.setLocation(p.x,p.y);
+        if(parent instanceof JLayeredPane) 
+        {
+            ((JLayeredPane)parent).add(this,JLayeredPane.POPUP_LAYER,0);
+        } 
+        else
+        {
+            parent.add(this);
+        }
+
+        this.isVisible=true;
+    }
+
+    public void setVisible(boolean show) 
+    {
+        if (show)
+        {
+            showPanel(invoker);
+        }
+        else
+        {
+            hidePanel();
+        }
+    }
+
+    private void hidePanel()
+    {
+        Container parent = getParent();
+        Rectangle r = this.getBounds();
+        if(parent != null)
+        {
+            parent.remove(this);
+        }
+        parent.repaint(r.x,r.y,r.width,r.height);
+        this.isVisible=false;
+    }
+
+    public void setLocationOnScreen(int x,int y) 
+    {
+        Container parent = getParent();
+        if(parent != null) 
+        {
+            Point p = 
ScreenUtilities.convertScreenLocationToParent(parent,x,y);
+            this.setLocation(p.x,p.y);
+        } 
+        else 
+        {
+            desiredLocationX = x;
+            desiredLocationY = y;
+        }
+    }
+
+    public boolean isVisible()
+    {
+        return this.isVisible;
+    }
+
+    public int getWeight()
+    {
+        return MPopup.LIGHT;
+    }
+
+    public boolean isLightweight()
+    {
+        return true;
+    }
+
+    public boolean isOpaque()
+    {
+        return false;
+    }
+}
+

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormConstraints.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormConstraints.java     
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/FormConstraints.java     
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,174 @@
+/*
+*   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.*;
+
+/**
+ * The <code>FormConstraints</code> class specifies constraints
+ * for components that are laid out using the
+ * <code>FormLayout</code> class.
+ *
+ * @see mseries.utils.FormLayout
+ */
+public class FormConstraints implements Cloneable, java.io.Serializable
+{
+
+
+    /**
+    * Specify that this component is to be placed next to the previously added
+    * component (<code>gridx</code>, <code>gridy</code>).
+    * @see      mseries.utils.FormConstraints#gridx
+    * @see      mseries.utils.FormConstraints#gridy
+    */
+    public static final int RELATIVE = -1;
+
+    /** Put the component in the center of its display area.  */
+    public static final int CENTER = 10;
+
+    /** Put the component at the top of its display area, centered 
horizontally. */
+    public static final int NORTH = 11;
+
+    /** Put the component at the top-right corner of its display area. */
+    public static final int NORTHEAST = 12;
+
+    /** Put the component on the right side of its display area, centered 
vertically. */
+    public static final int EAST = 13;
+
+    /** Put the component at the bottom-right corner of its display area. */
+    public static final int SOUTHEAST = 14;
+
+    /** Put the component at the bottom of its display area, centered 
horizontally. */
+    public static final int SOUTH = 15;
+
+    /** Put the component at the bottom-left corner of its display area. */
+    public static final int SOUTHWEST = 16;
+
+    /** Put the component on the left side of its display area, centered 
vertically. */
+    public static final int WEST = 17;
+
+    /** Put the component at the top-left corner of its display area. */
+    public static final int NORTHWEST = 18;
+
+    /**
+    *   A component that spans columns will be drawn at its preferred size if 
there is
+    *   enough remaining space in the container.
+    */
+    public boolean spansColumns;
+    /**
+    *   Speifies the border around the component, this is usually left to the 
default
+    *   value
+    */
+    public Insets insets;
+    /**
+    * Specifies the cell at the left of the component's display area,
+    * where the leftmost cell has <code>gridx=0</code>. The value
+    * <code>RELATIVE</code> specifies that the component be placed just
+    * to the right of the component that was added to the container just
+    * before this component was added.
+    * <p>
+    * The default value is <code>RELATIVE</code>.
+    * gridx should be a non-negative value.
+    * @serial
+    * @see #clone()
+    * @see mseries.utils.FormConstraints#gridy
+    */
+    public int gridx;
+    /**
+    * Specifies the cell at the top of the component's display area,
+    * where the topmost cell has <code>gridy=0</code>. The value
+    * <code>RELATIVE</code> specifies that the component be placed just
+    * below the component that was added to the container just before
+    * this component was added.
+    * <p>
+    * The default value is <code>RELATIVE</code>.
+    * gridy should be a non-negative value.
+    * @serial
+    * @see #clone()
+    * @see mseries.utils.FormConstraints#gridx
+    */
+    public int gridy;
+
+    /**
+    * This field is used when the component is smaller than its display
+    * area. It determines where, within the display area, to place the
+    * component. Possible values are <code>CENTER</code>,
+    * <code>NORTH</code>, <code>NORTHEAST</code>, <code>EAST</code>,
+    * <code>SOUTHEAST</code>, <code>SOUTH</code>, <code>SOUTHWEST</code>,
+    * <code>WEST</code>, and <code>NORTHWEST</code>.
+    * The default value is <code>CENTER</code>.
+    * @serial
+    * @see #clone()
+    */
+    public int anchor;
+
+
+    int cellWidth;
+    int cellHeight;
+
+    int tempX;
+    int tempY;
+    /**
+     * Set this to true of the components is not to take part in column width 
calculations, it will fill the column
+     * which is wht widht of the widest component in the column
+     */
+    public boolean fill;
+
+    /**
+    * Creates a <code>FormConstraint</code> object with
+    * all of its fields set to their default value.
+    */
+    public FormConstraints ()
+    {
+        gridx = RELATIVE;
+        gridy = RELATIVE;
+
+        anchor = WEST;
+
+        insets = new Insets(4, 4, 4, 4);
+        spansColumns=false;
+        fill=false;
+    }
+
+
+    /**
+    * Creates a copy of this form constraint.
+    * @return     a copy of this form constraint
+    */
+    public Object clone ()
+    {
+        try
+        {
+            FormConstraints c = (FormConstraints)super.clone();
+            c.insets = (Insets)insets.clone();
+            return c;
+        }
+        catch (CloneNotSupportedException e)
+        {
+            // this shouldn't happen, since we are Cloneable
+            throw new InternalError();
+        }
+    }
+}
+// $Log: FormConstraints.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/MultiFormLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MultiFormLayout.java     
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/MultiFormLayout.java     
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,213 @@
+/*
+*   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.io.*;
+import java.util.*;
+/**
+*   A layout manager that is aware of the type children that have been added 
to it. If the
+*   children are containers that have <code>mseries.utils.FormLayout</code> 
this layout
+*   manager will try to ensure that each column remains vertically aligned 
with the others
+*   giving the effect of continuous vertical columns. Importantly the effect 
is retained when
+*   the container is resized. See the image, notice the field labels have been 
truncated as the
+*   container has been shrunk. The children have borders labelled TopPanel & 
BottomPanel, both
+*   children are containers with FormLayout.
+
+*   In other words each column in one child will have the same
+*   width as the corresponding column in the other child components.
+*<p>
+*Usage:
+*<pre>
+*       JPanel p = new JPanel();
+*       p.setLayout(new MultiFormLayout());
+*       p.add(<i>panel1</i>);
+*       p.add(<i>panel2</i>);
+*</pre>
+*<p>
+*   where <i>panel1</i> and <i>panel2</i> are JPanels that have a FormLayout. 
Since the
+*   MulitFormLayout gathers the charateristics of each of its child panels as 
they are added
+*   to the containers, they must be complete before they are added, i.e. the 
application must have
+*   first added all the components to each FormLayout container <i>before</i> 
the FormLayout
+*   container is added to the MulitFormLayout container.
+*<p>
+*   There will be occasions when some child components should not participate 
in the scheme
+*   described above. This will occur when the components layout manager is not 
FormLayout
+*   or, if it is FormLayout, when the component is added with the 
NONPARTICIPANT constraint.
+*   @see mseries.utils.FormLayout
+*/
+public class MultiFormLayout extends VFlowLayout implements Serializable
+{
+
+
+    ArrayList children;     // List of the FormLayout panels in the Box 
(java.awt.Component)
+
+    int[] actualWidth;
+    int[] colWidth;
+    int width=0;
+    int height=0;
+    int minHeight=0;
+    int cols=0;
+
+    /**
+    *   Pass this constant as a constraint when adding a FormLayout container 
to the
+    *   MultiFormLayout container if the FormLayout container is not to 
participate with
+    *   other FormLayouts in the MulitFormLayout.
+    */
+    public static final Integer NONPARTICIPANT=new Integer(1);
+    /**
+    *   Pass this constant as a constraint when adding a FormLayout container 
to the
+    *   MultiFormLayout container if the FormLayout container is to 
participate with
+    *   other FormLayouts in the MulitFormLayout. This is the default if no 
constraints
+    *   are passed when adding components to the container.
+    */
+    public static final Integer PARTICIPANT=new Integer(2);
+
+    /**
+    *   This constructor simply delegates to MultiFormLayout(), it remains for 
backward
+    *   compatibility with previous versions
+    *   @param target the thing being layed out (not used)
+    */
+    public MultiFormLayout(Container target)
+    {
+        this();
+    }
+
+    /**
+    *   The preferred constructor
+    */
+    public MultiFormLayout()
+    {
+        children = new ArrayList();
+        colWidth = new int[FormLayout.MAXGRIDSIZE];
+        actualWidth = new int[FormLayout.MAXGRIDSIZE];
+    }
+
+    /**
+    *   Not used by this component
+    *   @throws a runtime exception if it gets called.
+    */
+    public void addLayoutComponent(Component comp)
+    {
+        throw new RuntimeException("Not used");
+    }
+
+    /**
+    *   Add the components to the layout manager, the container will call this 
method, not
+    *   the application code. In it we measure the width of each column, 
providing the component
+    *   is a Container with a FormLayout, and add some struts to each 
component representing the
+    *   preferred widths of the columns. The largest preferred width of each 
column is used. The
+    *   FormLayouts themselves actually manage the widths of their columns but 
the struts that
+    *   are added ensure that their calculations yield the same values giving 
the same column
+    *   widths when the container is resized.
+    */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+        Container container;
+        FormLayout fl;
+        LayoutManager lm;
+        FormLayoutInfo info;
+        int x, y;
+
+        if ((constraints instanceof Integer) && 
((Integer)constraints).equals(NONPARTICIPANT))
+        {
+            // Can ignore components that do not wish to participate
+            return;
+        }
+        if (comp instanceof Container)
+        {
+            lm = ((Container)comp).getLayout();
+            if (lm instanceof FormLayout)
+            {
+                fl = (FormLayout)lm;
+                children.add(comp);
+                info=fl.getInfo();
+                info.calculateLayoutInfo((Container)comp);
+            }
+            else
+            {
+                // Only manage FormLayout containers
+                return;
+            }
+        }
+        int size=children.size();
+        if (size == 1)
+        {
+            /*  Do not need to worry about the 'other' panels if there aren't 
any !
+            */
+            return;
+        }
+
+        /*
+        *   Loop through the other components in the box and update the 
colWidths array, we
+        *   need to make each column as wide as it is in each component
+        */
+        minHeight=0;
+        height=0;
+        for (y=0; y<size; y++)
+        {
+            width=0;
+            lm = ((Container)children.get(y)).getLayout();
+            fl = (FormLayout)lm;
+            info = fl.getInfo();
+            for (x=0; x<info.width; x++)
+            {
+                 colWidth[x]=Math.max(colWidth[x], info.colWidth[x]);
+                 width+=colWidth[x];
+            }
+            height+=info.height;
+            minHeight+=info.getMinimumSize().height;
+
+            cols=Math.max(cols, info.width);
+
+        }
+        /*  Add struts to each component to ensure they have the same width
+        */
+        for (y=0; y<size; y++)
+        {
+            container = (Container)children.get(y);
+            lm = container.getLayout();
+            fl = (FormLayout)lm;
+            info = fl.getInfo();
+            FormConstraints c= new FormConstraints();
+            c.gridy=info.height;
+            for (x=0; x<cols; x++)
+            {
+                c.gridx=x;
+                container.add(new FormStrut(colWidth[x]), c);
+            }
+        }
+    }
+
+    /**
+    *   Allow the BoxLayout to lay out the container as usual
+    */
+    public void layoutContainer(Container parent)
+    {
+        super.layoutContainer(parent);
+    }
+}
+// $Log: MultiFormLayout.java,v $
+// Revision 1.4  2003/03/26 23:29:51  martin
+// Changed email address
+//
+// Revision 1.3  2002/11/03 10:56:22  martin
+// *** empty log message ***
+//
+// Revision 1.2  2002/11/03 10:55:40  martin
+// *** empty log message ***
+//
+// Revision 1.1  2002/11/03 10:29:05  martin
+// Added header comment
+//
\ No newline at end of file

Added: trunk/apps/frost-0.7/lib/datechooser/mseries/utils/VFlowLayout.java
===================================================================
--- trunk/apps/frost-0.7/lib/datechooser/mseries/utils/VFlowLayout.java 
2006-03-14 07:10:06 UTC (rev 8247)
+++ trunk/apps/frost-0.7/lib/datechooser/mseries/utils/VFlowLayout.java 
2006-03-14 14:03:34 UTC (rev 8248)
@@ -0,0 +1,133 @@
+package mseries.utils;
+
+import java.awt.*;
+import java.io.*;
+/**
+*   A Simple layout manager that will stack components vertically as they are 
added. When 
+*   there is excess space, the components are not assigned it so they all 
remain to the 
+*   top of the container. The components stretch horizontally to width of the 
container
+*/
+public class VFlowLayout implements LayoutManager2, Serializable
+{
+
+
+    Dimension layoutSize=null;
+
+    public Dimension preferredLayoutSize(Container parent) 
+    {
+        return getLayoutSize(parent);
+    }
+
+    public Dimension minimumLayoutSize(Container parent) 
+    {
+        return getLayoutSize(parent);
+    }
+
+    public Dimension maximumLayoutSize(Container parent) 
+    {
+        return parent.getSize();
+    }
+
+    /**
+    *   Lays out the container by stacking the components in one vertical 
column.
+    *   Stretches each component to the width of the container, does not 
stretch 
+    *   or shrink the components vertically.
+    */
+    public void layoutContainer(Container parent) 
+    {
+        Component components[] = parent.getComponents();
+        Component comp;
+        Insets insets = parent.getInsets();
+        Rectangle r = new Rectangle();
+        Dimension size=parent.getSize();
+
+        r.width=size.width-insets.left-insets.right;
+        r.x=insets.left;
+
+        int compCount=components.length;
+        for (int i=0; i < compCount; i++)
+        {
+            comp = components[i];
+            r.height=comp.getPreferredSize().height;
+
+            r.y+=insets.top;
+
+            comp.setBounds(r);
+
+            // Prepare the tally for the next component
+            r.y+=r.height;
+            r.y+=insets.bottom;
+        }
+    }
+
+    /**
+    *   Total up the height of each component in the container plus the insets 
of
+    *   the container itself. Width is width of the container
+    */
+    protected Dimension calculateLayoutSize(Container parent)
+    {
+        Component components[] = parent.getComponents();
+        Component comp;
+        Insets insets = parent.getInsets();
+        int width=0;
+        int height=0;
+
+        int compCount=components.length;
+        for (int i=0; i < compCount; i++)
+        {
+            comp = components[i];
+
+            height+=comp.getPreferredSize().height+insets.top+insets.bottom;
+            width=Math.max(width, 
comp.getPreferredSize().width+insets.left+insets.right);
+        }
+        return new Dimension (width, height);
+    }
+
+    /** 
+    *   The layout size is not changed by this layout manager so we can cache 
the
+    *   the dimensions. This method only recalculates them if the cache is 
null which
+    *   may happen by the invalidateLayout method.
+    */
+    protected Dimension getLayoutSize(Container parent)
+    {
+        if (layoutSize==null)
+        {
+            layoutSize=calculateLayoutSize(parent);
+        }
+        return layoutSize;
+    }
+
+    /** Not used by this class */
+    public void addLayoutComponent(String name, Component comp) 
+    {
+        throw new RuntimeException("Not used by this class");
+    }
+
+    /** Not used by this class */
+    public void removeLayoutComponent(Component comp)
+    {
+        throw new RuntimeException("Not used by this class");
+    }
+
+    public synchronized float getLayoutAlignmentY(Container target) 
+    {
+        return 0.0f;
+    }
+
+    public synchronized float getLayoutAlignmentX(Container target) 
+    {
+        return 0.0f;
+    }
+
+    public synchronized void invalidateLayout(Container target) 
+    {
+        layoutSize=null;
+    }
+
+    /** 
+    *   Not currently used but likely to be overridden in subclasses 
+    */
+    public void addLayoutComponent(Component comp, Object constraints) 
+    {
+    }
+}


Reply via email to