[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[news.eclipse.tools] Re: SWT Date picker

Mathias Bogaert wrote:

> I am looking for a SWT (or JFace) date picker. Does it already exist? If 
> not, are there any plans to include it in the near future?
  I have wrote it myself.
  Notice, that it uses russian strings, so...
  Well, it is not very good, but may be will usefull...

package ru.nlmk.swt.controls;
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.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 ru.nlmk.swt.SWTX;
import ru.nlmk.swt.SWTXException;
import ru.nlmk.swt.util.TImageManager;

import java.util.Calendar;
/**
 * @author Kosta
 */
public class TCalendar extends Composite {
	private int m_Year = 2002;
	private int m_Month = 7;
	private int m_Day = 10;
	private class TDatePanel extends Canvas {
		private Display m_Display = Display.getCurrent();
		private Calendar m_Calendar = Calendar.getInstance();
		private int m_ColSize;
		private int m_RowSize;
		public TDatePanel(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();
			m_ColSize = p.x * 3;
			m_RowSize = (int) (p.y * 1.2);
			//
			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) {
				m_Day = day;
				dateSelected(true);
			}
		}
		private String getDayName(int day) {
			switch (day) {
				case 1 :
					return "Ïí";
				case 2 :
					return "Âò";
				case 3 :
					return "Ñð";
				case 4 :
					return "×ò";
				case 5 :
					return "Ïò";
				case 6 :
					return "Ñá";
				case 7 :
					return "Âñ";
			}
			throw new SWTXException("Íåèçâåñòíûé íîìåð äíÿ â íåäåëå: " + day);
		}
		private int calendarDayToNormal(int day) {
			switch (day) {
				case Calendar.MONDAY :
					return 1;
				case Calendar.TUESDAY :
					return 2;
				case Calendar.WEDNESDAY :
					return 3;
				case Calendar.THURSDAY :
					return 4;
				case Calendar.FRIDAY :
					return 5;
				case Calendar.SATURDAY :
					return 6;
				case Calendar.SUNDAY :
					return 7;
			}
			return -1;
		}
		private int getDayFromPoint(int x, int y) {
			for (int i = 1; i <= 31; i++) {
				Point p = getDayPoint(i);
				Rectangle r = new Rectangle(p.x, p.y, m_ColSize, m_RowSize);
				if (r.contains(x, y))
					return i;
			}
			return -1;
		}
		private Point getDayPoint(int day) {
			m_Calendar.set(Calendar.YEAR, m_Year);
			m_Calendar.set(Calendar.MONTH, m_Month);
			m_Calendar.set(Calendar.DAY_OF_MONTH, 1);
			int first_day_of_week =
				calendarDayToNormal(m_Calendar.get(Calendar.DAY_OF_WEEK)) - 1;
			//
			m_Calendar.set(Calendar.DAY_OF_MONTH, day);
			int day_of_week =
calendarDayToNormal(m_Calendar.get(Calendar.DAY_OF_WEEK));
			int x = (day_of_week - 1) * m_ColSize;
			int y = (1 + (first_day_of_week + day - 1) / 7) * m_RowSize;
			return new Point(x, y);
		}
		private int getMaxDay() {
			m_Calendar.set(Calendar.YEAR, m_Year);
			m_Calendar.set(Calendar.MONTH, m_Month);
			int day = 28;
			for (int i = 0; i < 10; i++) {
				m_Calendar.set(Calendar.DAY_OF_MONTH, day);
				if (m_Calendar.get(Calendar.MONTH) != m_Month)
					return day - 1;
				day++;
			}
			return -1;
		}
		private void onPaint(PaintEvent event) {
			Rectangle rect = getClientArea();
			GC gc0 = event.gc;
			Image image = new Image(m_Display, rect.width, rect.height);
			GC gc = new GC(image);
			gc.setBackground(m_Display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
			gc.fillRectangle(rect);
			int x = 0;
			int y = 0;
			for (int i = 0; i < 7; i++) {
				if (i == 6)
					gc.setForeground(m_Display.getSystemColor(SWT.COLOR_RED));
				SWTX.drawTextImage(
					gc,
					getDayName(1 + i),
					SWTX.ALIGN_HORIZONTAL_CENTER | SWTX.ALIGN_VERTICAL_CENTER,
					null,
					0,
					x,
					0,
					m_ColSize,
					m_RowSize);
				x += m_ColSize;
			}
			gc.setForeground(m_Display.getSystemColor(SWT.COLOR_BLACK));
			y += m_RowSize;
			gc.drawLine(0, 0, rect.width, 0);
			gc.drawLine(0, y - 1, rect.width, y - 1);
			//
			m_Calendar.set(Calendar.YEAR, m_Year);
			m_Calendar.set(Calendar.MONTH, m_Month);
			int day = 1;
			while (true) {
				m_Calendar.set(Calendar.DAY_OF_MONTH, day);
				if (m_Calendar.get(Calendar.MONTH) != m_Month)
					break;
				int day_of_week =
calendarDayToNormal(m_Calendar.get(Calendar.DAY_OF_WEEK));
				Point p = getDayPoint(day);
				if (day == m_Day) {
					gc.setForeground(m_Display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
					gc.setBackground(m_Display.getSystemColor(SWT.COLOR_LIST_SELECTION));
				}
				else {
					gc.setBackground(m_Display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
					if (day_of_week == 7)
						gc.setForeground(m_Display.getSystemColor(SWT.COLOR_RED));
					else
						gc.setForeground(m_Display.getSystemColor(SWT.COLOR_BLACK));
				}
				SWTX.drawTextImage(
					gc,
					"" + day,
					SWTX.ALIGN_HORIZONTAL_CENTER | SWTX.ALIGN_VERTICAL_CENTER,
					null,
					0,
					p.x,
					p.y,
					m_ColSize,
					m_RowSize);
				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;
			}
			//
			int oldDay = m_Day;
			int oldMonth = m_Month;
			if (e.keyCode == SWT.ARROW_LEFT) {
				m_Day--;
			}
			if (e.keyCode == SWT.ARROW_RIGHT) {
				m_Day++;
			}
			if (e.keyCode == SWT.ARROW_UP) {
				m_Day -= 7;
				if (m_Day < 1)
					m_Day = oldDay;
			}
			if (e.keyCode == SWT.ARROW_DOWN) {
				m_Day += 7;
				if (m_Day > getMaxDay())
					m_Day = oldDay;
			}
			if (e.keyCode == SWT.PAGE_UP) {
				m_Month--;
			}
			if (e.keyCode == SWT.PAGE_DOWN) {
				m_Month++;
			}
			normalizeDay();
			if ((m_Day != oldDay) || (m_Month != oldMonth)) {
				redraw();
				if (m_Month != oldMonth)
					panelChanged();
			}
		}
		public Point computeSize(int wHint, int hHint, boolean changed) {
			return new Point(m_ColSize * 7, m_RowSize * 7);
		}
	}
	//
	private Label m_MonthLabel;
	private TDatePanel m_DatePanel;
	protected TImageManager m_ImageManager;
	//
	public TCalendar(Composite parent, int style) {
		super(parent, style);
		m_ImageManager = new TImageManager(getClass());
		//
		addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				m_ImageManager.dispose();
			}
		});
		//
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 5;
		/*gridLayout.marginHeight =
			gridLayout.marginWidth =*/
		gridLayout.verticalSpacing = gridLayout.horizontalSpacing = 0;
		gridLayout.marginHeight = gridLayout.marginWidth = 1;
		setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
		setLayout(gridLayout);
		//
		GridData gridData;
		//
		TSpeedButton prevYear = new TSpeedButton(this, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gridData.heightHint = gridData.widthHint = 20;
		prevYear.setLayoutData(gridData);
		prevYear.setImage(m_ImageManager.get("prev_year.gif"));
		prevYear.setToolTipText("Ïðåäûäóùèé ãîä");
		prevYear.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				m_Year--;
				updateDate();
			}
		});
		//
		TSpeedButton prevMonth = new TSpeedButton(this, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gridData.heightHint = gridData.widthHint = 20;
		prevMonth.setLayoutData(gridData);
		prevMonth.setImage(m_ImageManager.get("prev_month.gif"));
		prevMonth.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				m_Month--;
				updateDate();
			}
		});
		//
		m_MonthLabel = new Label(this, SWT.CENTER);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = prevYear.computeSize(20, 20).y;
		m_MonthLabel.setLayoutData(gridData);
		//
		TSpeedButton nextMonth = new TSpeedButton(this, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gridData.heightHint = gridData.widthHint = 20;
		nextMonth.setLayoutData(gridData);
		nextMonth.setImage(m_ImageManager.get("next_month.gif"));
		nextMonth.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				m_Month++;
				updateDate();
			}
		});
		//
		TSpeedButton nextYear = new TSpeedButton(this, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gridData.heightHint = gridData.widthHint = 20;
		nextYear.setLayoutData(gridData);
		nextYear.setImage(m_ImageManager.get("next_year.gif"));
		nextYear.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				m_Year++;
				updateDate();
			}
		});
		//
		m_DatePanel = new TDatePanel(this, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gridData.horizontalSpan = 5;
		m_DatePanel.setLayoutData(gridData);
		//
		panelChanged();
	}
	private void normalizeDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, m_Year);
		calendar.set(Calendar.MONTH, m_Month);
		calendar.set(Calendar.DAY_OF_MONTH, m_Day);
		m_Year = calendar.get(Calendar.YEAR);
		m_Month = calendar.get(Calendar.MONTH);
		m_Day = calendar.get(Calendar.DAY_OF_MONTH);
	}
	private void updateDate() {
		normalizeDay();
		m_DatePanel.redraw();
		panelChanged();
	}
	private String getMonthName(int month) {
		switch (month) {
			case 1 :
				return "ßíâàðü";
			case 2 :
				return "Ôåâðàëü";
			case 3 :
				return "Ìàðò";
			case 4 :
				return "Àïðåëü";
			case 5 :
				return "Ìàé";
			case 6 :
				return "Èþíü";
			case 7 :
				return "Èþëü";
			case 8 :
				return "Àâãóñò";
			case 9 :
				return "Ñåíòÿáðü";
			case 10 :
				return "Îêòÿáðü";
			case 11 :
				return "Íîÿáðü";
			case 12 :
				return "Äåêàáðü";
		}
		throw new SWTXException("Íåèçâåñòíûé íîìåð ìåñÿöà: " + month);
	}
	private void panelChanged() {
		m_MonthLabel.setText(getMonthName(m_Month + 1) + ", " + m_Year);
	}
	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 int getDay() {
		return m_Day;
	}
	public void setDay(int day) {
		m_Day = day;
		panelChanged();
		redraw();
	}
	public int getMonth() {
		return m_Month;
	}
	public void setMonth(int month) {
		m_Month = month;
		panelChanged();
		redraw();
	}
	public int getYear() {
		return m_Year;
	}
	public void setYear(int year) {
		m_Year = year;
		panelChanged();
		redraw();
	}
}