Java tutorial
/****************************************************************************** * Copyright (c) 2007 g-Eclipse consortium * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Initial development of the original code was made for * project g-Eclipse founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributor(s): * Mariusz Wojtysiak - initial API and implementation * *****************************************************************************/ package eu.geclipse.ui.widgets; import java.lang.reflect.InvocationTargetException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DateTime; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import eu.geclipse.core.reporting.IProblem; import eu.geclipse.core.reporting.ISolution; import eu.geclipse.core.reporting.ProblemException; import eu.geclipse.ui.internal.Activator; /** * Widgets, which allow to edit date and time */ public class DateTimeText { /** * Widget style */ public enum Style { /** * Edit only date */ DATE, /** * Edit both date and time */ DATETIME } private static Image image; protected Style style; protected Button calendarButton; private Text text; private Composite topComposite; private boolean allowEmpty; /** * @param parent * @param style * @param allowEmpty if false, then {@link DateTimeText#getDate()} throw an exception for empty date */ public DateTimeText(final Composite parent, final Style style, final boolean allowEmpty) { super(); this.style = style; this.allowEmpty = allowEmpty; this.topComposite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(2, false); layout.horizontalSpacing = 0; layout.marginWidth = 0; layout.marginTop = 0; layout.marginBottom = 0; layout.verticalSpacing = 0; layout.marginHeight = 0; layout.marginWidth = 0; this.topComposite.setLayout(layout); createText(this.topComposite); createButton(this.topComposite); } /** * @param date date which will be shown in widget */ public void setDate(final Date date) { String valueString = ""; //$NON-NLS-1$ if (date != null) { valueString = getFormatter(this.style).format(date); } this.text.setText(valueString); } /** * @return Date entered in control, or null if allowEmpty is true and entered date is empty * @throws ProblemException thrown when user entered date in wrong format * @see eu.geclipse.ui.dialogs.ProblemDialog#openProblem(Shell, String, String, Throwable) */ public Date getDate() throws ProblemException { Date date = null; try { date = internalGetDate(); } catch (ParseException exception) { ProblemException problemExc = new ProblemException( "eu.geclipse.problem.widget.DateTimeText.WrongFormat", //$NON-NLS-1$ exception, Activator.PLUGIN_ID); IProblem problem = problemExc.getProblem(); problem.addSolution(createUseCalendarSolution()); problem.addSolution("eu.geclipse.solution.widget.DateTimeText.UseCorrectFormat", //$NON-NLS-1$ String.format(Messages.getString("DateTimeText.solutionEnterDateInCorrectFormat"), //$NON-NLS-1$ getValidDateFormat())); if (this.allowEmpty) { problem.addSolution("eu.geclipse.solution.widget.DateTimeText.DeleteValue", //$NON-NLS-1$ null); } throw problemExc; } return date; } /** * @return String containing format in which date should be entered. */ public String getValidDateFormat() { String validFormat = null; try { validFormat = ((SimpleDateFormat) getFormatter(this.style)).toLocalizedPattern(); } catch (ClassCastException exception) { // getFormatter() may return formatter other than SimpleDateFormat for rare localizations. // see java-doc for class DateFormat for details } return validFormat; } private DateFormat getFormatter(final Style forStyle) { DateFormat formatter = null; switch (forStyle) { case DATE: formatter = DateFormat.getDateInstance(); break; case DATETIME: default: formatter = DateFormat.getDateTimeInstance(); break; } formatter.setLenient(true); return formatter; } private void createText(final Composite parent) { this.text = new Text(parent, SWT.SINGLE | SWT.BORDER); GridData gridData = new GridData(); gridData.widthHint = getWidthHint(); this.text.setLayoutData(gridData); } private int getWidthHint() { int width = SWT.DEFAULT; switch (this.style) { case DATE: width = SWT.DEFAULT; break; case DATETIME: default: width = 110; break; } return width; } private Date internalGetDate() throws ParseException { Date date = null; DateFormat formatter = getFormatter(this.style); String dateString = this.text.getText(); if (!this.allowEmpty || dateString.length() > 0) { try { date = formatter.parse(dateString); } catch (ParseException exception) { // if declared parser doesn't work for entered data, try to use other // parsers (maybe user omitted some date parts)? date = parseOtherFormats(dateString); if (date == null) { throw exception; } } } return date; } private Date parseOtherFormats(final String dateString) { Date date = null; // formatters ordered since most detailed DateFormat[] formatters = new DateFormat[] { DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM), DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT), DateFormat.getDateInstance() }; for (int index = 0; index < formatters.length && date == null; index++) { try { date = formatters[index].parse(dateString); } catch (ParseException exception) { // ignore exception } } return date; } private void createButton(final Composite parent) { this.calendarButton = new Button(parent, SWT.PUSH); this.calendarButton.setImage(getImage()); this.calendarButton.addSelectionListener(new SelectionAdapter() { /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(final SelectionEvent e) { openCalendarDialog(); } }); } private Image getImage() { if (DateTimeText.image == null) { ImageDescriptor imageDescriptor = Activator.getDefault().getImageRegistry().getDescriptor("calendar"); //$NON-NLS-1$ DateTimeText.image = imageDescriptor.createImage(); } return DateTimeText.image; } /** * @return shell, on which control is placed */ public Shell getShell() { return this.topComposite.getShell(); } /** * Opens popup dialog with calendar to easy selecting date and time */ public void openCalendarDialog() { DateTimeDialog dialog = new DateTimeDialog(getShell()); dialog.open(); } private class DateTimeDialog extends PopupDialog { private DateTime dateControl; private DateTime timeControl; protected DateTimeDialog(final Shell parentShell) { super(parentShell, PopupDialog.INFOPOPUP_SHELLSTYLE, true, false, false, false, null, null); } private void setDate(final Date date) { if (date != null) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); this.dateControl.setYear(calendar.get(Calendar.YEAR)); this.dateControl.setMonth(calendar.get(Calendar.MONTH)); this.dateControl.setDay(calendar.get(Calendar.DAY_OF_MONTH)); if (this.timeControl != null) { this.timeControl.setHours(calendar.get(Calendar.HOUR_OF_DAY)); this.timeControl.setMinutes(calendar.get(Calendar.MINUTE)); this.timeControl.setSeconds(calendar.get(Calendar.SECOND)); } } } private Date getDate() { Calendar calendar = Calendar.getInstance(); calendar.set(this.dateControl.getYear(), this.dateControl.getMonth(), this.dateControl.getDay(), this.timeControl == null ? 0 : this.timeControl.getHours(), this.timeControl == null ? 0 : this.timeControl.getMinutes(), this.timeControl == null ? 0 : this.timeControl.getSeconds()); return calendar.getTime(); } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createDialogArea(final Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(2, true)); createCalendar(composite); if (DateTimeText.this.style == Style.DATETIME) { createHour(composite); } createButtons(composite); try { setDate(DateTimeText.this.getDate()); } catch (ProblemException exception) { // ignore exception } return composite; } private void createButtons(final Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; composite.setLayout(layout); GridData gridData = new GridData(); gridData.horizontalAlignment = SWT.RIGHT; gridData.horizontalSpan = 2; composite.setLayoutData(gridData); createOkButton(composite); createCancelButton(composite); } private void createCalendar(final Composite parent) { this.dateControl = new DateTime(parent, SWT.CALENDAR); GridData layoutData = new GridData(); layoutData.horizontalSpan = 2; this.dateControl.setLayoutData(layoutData); } private void createHour(final Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText(Messages.getString("DateTimeText.labelHour")); //$NON-NLS-1$ GridData gridData = new GridData(); gridData.horizontalAlignment = SWT.END; label.setLayoutData(gridData); this.timeControl = new DateTime(parent, SWT.TIME); gridData = new GridData(); gridData.horizontalAlignment = SWT.RIGHT; this.timeControl.setLayoutData(gridData); } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.Dialog#getInitialLocation(org.eclipse.swt.graphics.Point) */ @Override protected Point getInitialLocation(final Point initialSize) { return Display.getCurrent().map(DateTimeText.this.calendarButton.getParent(), null, DateTimeText.this.calendarButton.getLocation()); } private void createOkButton(final Composite parent) { Button button = new Button(parent, SWT.PUSH | SWT.FLAT); button.setText(IDialogConstants.OK_LABEL); GridData gridData = new GridData(); gridData.horizontalAlignment = SWT.RIGHT; gridData.widthHint = IDialogConstants.BUTTON_WIDTH; button.setLayoutData(gridData); getShell().setDefaultButton(button); button.addSelectionListener(new SelectionAdapter() { /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(final SelectionEvent e) { closeWithSave(); } }); } private void createCancelButton(final Composite parent) { Button button = new Button(parent, SWT.PUSH | SWT.FLAT); button.setText(IDialogConstants.CANCEL_LABEL); GridData gridData = new GridData(); gridData.horizontalAlignment = SWT.RIGHT; gridData.widthHint = IDialogConstants.BUTTON_WIDTH; button.setLayoutData(gridData); button.addSelectionListener(new SelectionAdapter() { /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(final SelectionEvent e) { close(); } }); } protected void closeWithSave() { DateTimeText.this.setDate(getDate()); close(); } } /** * @param enabled true if widget should allow editing, false if should work in readonly mode */ public void setEnabled(final boolean enabled) { this.text.setEnabled(enabled); this.calendarButton.setEnabled(enabled); } /** * @return @see org.eclipse.swt.widgets.Text#setFocus() */ public boolean setFocus() { return this.text.setFocus(); } private ISolution createUseCalendarSolution() { return new ISolution() { public String getDescription() { return Messages.getString("DateTimeText.solutionUseButton"); //$NON-NLS-1$ } public String getID() { return null; } public boolean isActive() { return true; } public void solve() throws InvocationTargetException { openCalendarDialog(); } }; } }