[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
|
[news.eclipse.tools] [SWT] Standalone DatePicker
|
- From: David Ryan <Oobles@xxxxxxxxxxx>
- Date: Fri, 13 Sep 2002 16:21:08 +1000
- Newsgroups: eclipse.tools
- Organization: EclipseCorner
- User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.1) Gecko/20020826
I required a DatePicker for my application and found that Konstatin had
provided some source to the list in August. His code was based on a set
of libraries that I didn't need. I've taken his code and removed all
dependencies; other than SWT. :) I've also made it Internationalised
using Calendar to work out text strings, etc. Basically, I've rewritten
a large amount of the code. Please feel free to use it where ever you like.
Only one "bug" currently. If someone can work out how to lower the Label
displaying the month and year by a few pixels, please let me know.
The code supplied is the component which needs to be added to a shell as
a popup to a text widget. What I would have like to have used is the
standard Combo box. Would it makes sense to add in a super class to
SWT's Combo that allows for any widget to be placed in the drop down?
This would be useful for situations like this.
Enjoy,
David.
/**
* DatePicker by David Ryan (oobles at hotmail dot com)
* (based on TCalendar by Konstantin Scheglov)
*
* A stand alone date picker for SWT. Can either use the default system
* locale, or be passed a specific locale.
*
* The getImage function is very basic and attempts to retrieve the <<
< > >>
* images from the current directory.
*/
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import java.util.Date;
import java.util.Calendar;
import java.util.Locale;
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
public class DatePicker
extends Composite
{
private Calendar _calendar;
private SimpleDateFormat _monthYearFormat;
private Label monthLabel;
private DatePanel datePanel;
public DatePicker(Composite parent, int style )
{
this( parent, style, null );
}
public DatePicker(Composite parent, int style, Locale locale )
{
super(parent, style);
if ( locale != null )
{
_calendar = new GregorianCalendar( locale );
_monthYearFormat = new SimpleDateFormat( "MMMM, yyyy",locale );
}
else
{
_calendar = new GregorianCalendar();
_monthYearFormat = new SimpleDateFormat( "MMMM, yyyy" );
}
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 5;
gridLayout.verticalSpacing = gridLayout.horizontalSpacing = 0;
gridLayout.marginHeight = gridLayout.marginWidth = 1;
setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
setLayout(gridLayout);
GridData gridData;
Button prevYear = new Button( this, SWT.NONE );
gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gridData.heightHint = gridData.widthHint = 20;
prevYear.setLayoutData(gridData);
prevYear.setImage(getImage("prev_year.gif"));
prevYear.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
_calendar.add( Calendar.YEAR, -1 );
updateDate();
}
});
Button prevMonth = new Button( this, SWT.NONE );
gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gridData.heightHint = gridData.widthHint = 20;
prevMonth.setLayoutData(gridData);
prevMonth.setImage(getImage("prev_month.gif"));
prevMonth.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
_calendar.add( Calendar.MONTH, -1 );
updateDate();
}
});
monthLabel = new Label(this, SWT.CENTER);
gridData = new GridData(GridData.FILL_HORIZONTAL |
GridData.VERTICAL_ALIGN_CENTER );
//gridData.grabExcessVerticalSpace = true;
gridData.heightHint = prevYear.computeSize(20, 20).y;
monthLabel.setLayoutData(gridData);
Button nextMonth = new Button( this, SWT.NONE );
gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
gridData.heightHint = gridData.widthHint = 20;
nextMonth.setLayoutData(gridData);
nextMonth.setImage( getImage("next_month.gif") );
nextMonth.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
_calendar.add( Calendar.MONTH, 1 );
updateDate();
}
});
Button nextYear = new Button( this, SWT.NONE );
gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
gridData.heightHint = gridData.widthHint = 20;
nextYear.setLayoutData(gridData);
nextYear.setImage( getImage("next_year.gif") );
nextYear.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
_calendar.add( Calendar.YEAR, 1 );
updateDate();
}
});
datePanel = new DatePanel(this, SWT.NONE);
gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
gridData.horizontalSpan = 5;
datePanel.setLayoutData(gridData);
panelChanged();
}
private Image getImage( String imageFile )
{
ImageData iData = new ImageData( this.getClass().getResourceAsStream(
imageFile ) );
ImageData iMask = iData.getTransparencyMask();
return new Image(null, iData, iMask);
}
private void updateDate()
{
datePanel.redraw();
panelChanged();
}
private void panelChanged()
{
monthLabel.setText( _monthYearFormat.format( _calendar.getTime() ));
}
private void dateSelected(boolean good)
{
Event event = new Event();
event.doit = good;
notifyListeners(SWT.Selection, event);
}
public void addSelectionListener(SelectionListener listener)
{
checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener(listener);
addListener(SWT.Selection, typedListener);
addListener(SWT.DefaultSelection, typedListener);
}
public void removeSelectionListener(SelectionListener listener)
{
checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
removeListener(SWT.Selection, listener);
removeListener(SWT.DefaultSelection, listener);
}
public Date getDate()
{
return _calendar.getTime();
}
public void setDate( Date date )
{
_calendar.setTime( date );
}
private class DatePanel
extends Canvas
{
private Display _display = Display.getCurrent();
private Calendar _panelCalendar;
private int _colSize;
private int _rowSize;
private int _maxDaysOfWeek;
private int _maxDaysOfMonth;
public DatePanel(Composite parent, int style)
{
super( parent, style | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE );
GC gc = new GC(this);
Point p = gc.stringExtent("Q");
gc.dispose();
_panelCalendar = (Calendar) _calendar.clone();
_colSize = p.x * 3;
_rowSize = (int) (p.y * 1.2);
_maxDaysOfWeek = _panelCalendar.getMaximum( Calendar.DAY_OF_WEEK );
_maxDaysOfMonth = _panelCalendar.getMaximum( Calendar.DAY_OF_MONTH );
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
onPaint(event);
}
});
addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
redraw();
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
onKeyDown(e);
}
});
addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
onMouseDown(e);
}
});
}
private void onMouseDown(MouseEvent e)
{
int day = getDayFromPoint(e.x, e.y);
if (day > 0)
{
_calendar.set( Calendar.DAY_OF_MONTH, day );
redraw();
dateSelected(true);
}
}
private int getDayFromPoint(int x, int y)
{
for (int i = 1; i <= _calendar.getActualMaximum(
Calendar.DAY_OF_MONTH ); i++)
{
Point p = getDayPoint(i);
Rectangle r = new Rectangle(p.x, p.y, _colSize, _rowSize);
if (r.contains(x, y))
return i;
}
return -1;
}
private Point getDayPoint(int day)
{
_panelCalendar.setTime( _calendar.getTime() );
_panelCalendar.set(Calendar.DAY_OF_MONTH, 1);
int first_day_of_week =
_panelCalendar.get(Calendar.DAY_OF_WEEK) - 1;
_panelCalendar.set(Calendar.DAY_OF_MONTH, day);
int day_of_week = _panelCalendar.get(Calendar.DAY_OF_WEEK);
int x = ( (day_of_week - 1) * _colSize ) + (_colSize/4);
int y = (1 + (first_day_of_week + day - 1) / _maxDaysOfWeek ) * _rowSize;
return new Point(x, y);
}
private void onPaint(PaintEvent event)
{
Rectangle rect = getClientArea();
GC gc0 = event.gc;
Image image = new Image( _display, rect.width, rect.height );
GC gc = new GC(image);
gc.setBackground( _display.getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND ) );
gc.fillRectangle(rect);
int x = 0;
int y = 0;
String dayNames[] =
_monthYearFormat.getDateFormatSymbols().getWeekdays();
for (int i = 1; i < dayNames.length; i++)
{
gc.drawText( dayNames[i].substring(0,2), x+(_colSize/4), 1 );
x += _colSize;
}
gc.setForeground( _display.getSystemColor(SWT.COLOR_BLACK));
y += _rowSize;
gc.drawLine(0, 0, rect.width, 0);
gc.drawLine(0, y - 1, rect.width, y - 1);
_panelCalendar.setTime( _calendar.getTime() );
int day = 1;
while ( day < _maxDaysOfMonth )
{
_panelCalendar.set(Calendar.DAY_OF_MONTH, day);
int day_of_week = _panelCalendar.get(Calendar.DAY_OF_WEEK);
Point p = getDayPoint(day);
if ( day == _calendar.get( Calendar.DAY_OF_MONTH ) )
{
gc.setForeground(
_display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
gc.setBackground( _display.getSystemColor(SWT.COLOR_LIST_SELECTION));
}
else
{
gc.setBackground(
_display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.setForeground( _display.getSystemColor(SWT.COLOR_BLACK));
}
gc.drawText( ""+day, p.x, p.y );
day++;
}
gc0.drawImage(image, 0, 0);
gc.dispose();
image.dispose();
}
private void onKeyDown(KeyEvent e)
{
if (e.character == SWT.ESC)
{
dateSelected(false);
return;
}
if ((e.character == ' ') || (e.character == '\r'))
{
dateSelected(true);
return;
}
Date oldDate = _calendar.getTime();
if (e.keyCode == SWT.ARROW_LEFT)
{
_calendar.add( Calendar.DATE, -1 );
}
else if (e.keyCode == SWT.ARROW_RIGHT)
{
_calendar.add( Calendar.DATE, 1 );
}
else if (e.keyCode == SWT.ARROW_UP)
{
_calendar.add( Calendar.DATE, -_maxDaysOfWeek );
}
else if (e.keyCode == SWT.ARROW_DOWN)
{
_calendar.add( Calendar.DATE, _maxDaysOfWeek );
}
else if (e.keyCode == SWT.PAGE_UP)
{
_calendar.add( Calendar.MONTH, -1 );
}
else if (e.keyCode == SWT.PAGE_DOWN)
{
_calendar.add( Calendar.MONTH, 1 );
}
if ( !_calendar.getTime().equals( oldDate ) )
{
redraw();
panelChanged();
}
}
public Point computeSize(int wHint, int hHint, boolean changed)
{
return new Point( _colSize * _maxDaysOfWeek, _rowSize *
((_maxDaysOfMonth+_maxDaysOfWeek-1)/_maxDaysOfWeek));
}
}
}