Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Nebula » my issues with Dating Nebula's widgets
my issues with Dating Nebula's widgets [message #890164] Thu, 21 June 2012 10:47 Go to next message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 115
Registered: July 2009
Senior Member
I (and probably many other people that create SWT/JFace/Eclipse applications) have a very simple goal: provide a user-friendly editor for dates in SWT/JFace. It should allow typing and selecting from a calendar and it should also be used for editing dates in table cells. I should be easy to bind to a Date property of my model objects.

In my opinion the Nebula widgets are really cool and really easy to integrate in an application, until unfortunately in practice I encountered a few issues. In total it took me at least two work days to solve them and there is still one issue left which I didn't solve. Hopefully my post can contribute in making Nebula even better and save others some time when encountering these issues.

The most logical place to start for my requirement is the SWT DateTime widget. However we have the practical requirement that some date fields may be intentionally left blank (i.e. null). This is unsupported with this widget (https://bugs.eclipse.org/bugs/show_bug.cgi?id=178362).

I am using SWT Designer and it already supports the DateChooserCombo so logically I used this. I didn't find an IObservableValue for it, but using google I quickly found a short and simple implementation that extends WidgetValueProperty and reacts on the SWT.Modify event (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=246014).

For use in table cells I found the DateChooserComboCellEditor and it works nicely. Unfortunately it has a bug where a cell that has a null Date automatically gets the latest selected date when you start editing it even if you don't want to actually change anything. It is caused by doSetValue not allowing a null value to be set on the combo before editing starts. It can be solved by replacing "if (value instanceof Date)" by "if (value == null || value instanceof Date)". (I solved it without changing the source by extending DateChooserComboCellEditor).

DateChooserComboCellEditor also has a minor bug. When you get more experienced with editing dates, it is logical to "triple" click the right side of a cell. This is the location where the calendar button appears when the cell is being edited. When doing this quickly, the button cannot be clicked and instead cell editing stops. This problem is not present when waiting a small time after the double click. I accidentally stumbled upon the CellEditor method getDoubleClickTimeout() and overriding it to return 0 solves this issue.

Another small issue is that DateChooserComboCellEditor does not commit the cell value when pressing enter. This is easy to fix with a simple KeyListener.

Unfortunately the calendar in DateChooserCombo is absolutely not user friendly for entering years because it only has a month spinner. So when you want to use it for a birth date in the 1960's you will have to click at least 42 * 12 = 504 times. Workaround: don't use the calendar but edit the year field (possibly by using arrow up/down).

Therefore I evaluated using CDateTime instead. It looks very nice and doesn't have the problem with year selection (unless you wish to select years in other centuries) and works fine outside of table cells. The only thing I don't like about it is that it takes an unnecessary mouse movement and click to confirm the date. What I absolutely found fancy is that when setting a pattern that has no year field, the popup calendar automatically removes the possibility to select a year. (I use this for selecting a yearly period).
The first thing that struck me when using databinding is that CDateTimeObservableValue simply does not work. I solved this by making a WidgetValueProperty for it similar to that of DateChooserCombo. However it listens to SWT.Selection, I tried SWT.Modify first but this does not detect some manually typed date changes.

Unfortunately the CDateTimeCellEditor has two annoying bugs:
- It doesn't detect focus lost on the text field so that the edited value is not committed when navigating to another cell or worse: when pressing a save button. I tried fixing this by changing the source to add an extra focus listener on the actual text field, but the field also loses focus when the calendar is popped up. I tried to fix this by not stopping cell edit when isOpen() is true on the CDateTime. This seemed to work, but it does not work together with the Clear button, and in some other cases cell editing seems to stop prematurely. To avoid having to shave Yaks to fix this issue I decided to stop and use DateChooserCombo for cell editing until this issue is fixed. Perhaps it can be solved by using the same idea as the DateChooserCombo?
- When editing starts, the day part of the formatted date is selected. Expected behavior is: you can now type in another day. Actual behavior is: when you start to type, the key you pressed is entered twice when typing 1 or 2. When typing something else such as 3 nothing seems to happen. In this case, when you subsequently type a valid number (e.g. 3 again) it seems to be entered fine. Perhaps users could learn to deal with this, but it's certainly not nice. Moreover there is an extra bug: when you do it exactly like described and you commit the edited value (e.g. by editing another cell), the old date value is restored, not the value you just typed. The above problem also happens if you click to edit the month or year part before typing anything.

P.s. I used versions cdatetime 0.14.0, cwt 0.9.0, datechooser/formattedtext 1.0.0 snapshot (came with SWT designer).
Re: my issues with Dating Nebula's widgets [message #890168 is a reply to message #890164] Thu, 21 June 2012 11:02 Go to previous messageGo to next message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 115
Registered: July 2009
Senior Member
Here is the code I used to solve most of the issues I encountered:

package nl.hm.ilja.ui.databinding;

import java.util.Date;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.WidgetValueProperty;
import org.eclipse.nebula.widgets.datechooser.DateChooserCombo;
import org.eclipse.swt.SWT;

/**
 * Helper class which represents the <code>date</code> property of the
 * {@link DateChooserCombo} widget. It can be used for data binding. You can
 * obtain the {@link IObservableValue} of the <code>date</code> property with
 * this code:
 * 
 * <pre>
 * IObservableValue dateObservable = new DateChooserComboDateProperty()
 * 		.observe(dateChooserWidget);
 * </pre>
 * 
 * See also <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=246014">this
 * Eclipse feature request</a>.
 * 
 * @author Henno Vermeulen
 */
public class DateChooserComboDateProperty extends WidgetValueProperty {

	public DateChooserComboDateProperty() {
		super(SWT.Modify);
	}

	@Override
	protected Object doGetValue(Object source) {
		return ((DateChooserCombo) source).getValue();
	}

	@Override
	protected void doSetValue(Object source, Object value) {
		((DateChooserCombo) source).setValue((Date) value);
	}

	@Override
	public Object getValueType() {
		return Date.class;
	}

}


package nl.hm.ilja.ui.databinding;

import java.util.Date;

/**
 * Helper class which represents the <code>date</code> property of the
 * {@link CDateTime} widget. (Note that there does exist a
 * CDateTimeObservableValue but it did not work for me). It can be used for data
 * binding. You can obtain the {@link IObservableValue} of the <code>date</code>
 * property with this code:
 * 
 * <pre>
 * IObservableValue dateObservable = new CDateTimeDateProperty()
 * 		.observe(dateTimeWidget);
 * </pre>
 * 
 * @author Henno Vermeulen
 * @see DateChooserComboDateProperty
 */
public class CDateTimeDateProperty extends WidgetValueProperty {

	public CDateTimeDateProperty() {
		/*
		 * Note that SWT.Modify is not sufficient for CDateTime because it
		 * sometimes does not fire SWT.Modify when typing in the month.
		 * SWT.Selection works fine.
		 */
		super(SWT.Selection);
	}

	@Override
	protected Object doGetValue(Object source) {
		return ((CDateTime) source).getSelection();
	}

	@Override
	protected void doSetValue(Object source, Object value) {
		((CDateTime) source).setSelection((Date) value);
	}

	@Override
	public Object getValueType() {
		return Date.class;
	}

}


package nl.hm.ilja.ui.databinding;

import org.eclipse.nebula.widgets.datechooser.DateChooserCombo;
import org.eclipse.nebula.widgets.datechooser.DateChooserComboCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;

/**
 * Extension of {@link DateChooserComboCellEditor} which fixes two small bugs
 * (see {@link #doSetValue(Object)}, {@link #getDoubleClickTimeout()}) and
 * enhances usability by committing the value on enter (see
 * {@link #configureCommitOnEnter()}).
 * 
 * @author Henno Vermeulen
 */
public final class DateChooserComboCellEditorExtension extends
		DateChooserComboCellEditor {

	public DateChooserComboCellEditorExtension(Composite parent) {
		super(parent);
		init();
	}

	public DateChooserComboCellEditorExtension(Composite parent, int style) {
		super(parent, style);
		init();
	}

	private void init() {
		configureCommitOnEnter();
	}

	private void configureCommitOnEnter() {
		super.getCombo().addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.KEYPAD_CR || e.character == SWT.CR) {
					fireApplyEditorValue();
					deactivate();
				}
			}
		});
	}

	/**
	 * Overridden to return 0 to solve the problem that the calendar button of
	 * the {@link DateChooserCombo} cannot be clicked but instead cell editing
	 * stops if you "triple" click on the right side of the cell. With this fix
	 * you can now start cell editing and open the calendar more quickly.
	 */
	@Override
	protected int getDoubleClickTimeout() {
		return 0;
	}

	/**
	 * Overridden to allow setting null values from the model to the editor.
	 * Without this fix, a null value is replaced by the last selected date in
	 * the combo cell editor even when you do not want to change anything.
	 */
	@Override
	protected void doSetValue(Object value) {
		if (value == null) {
			super.getCombo().setValue(null);
		} else {
			super.doSetValue(value);
		}
	}

}
Re: my issues with Dating Nebula's widgets [message #890175 is a reply to message #890164] Thu, 21 June 2012 11:21 Go to previous messageGo to next message
Wim Jongman is currently offline Wim Jongman
Messages: 278
Registered: July 2009
Senior Member

Hi Slow,

Thank you for using the Nebula widgets and taking the time to write such an elaborate post. We appreciate that.

To begin, make sure you use the latest version of the widgets. Version numbers do not say much because we currently do not bump them. What is important is the build qualifier. The current build qualifier is: 20120619hhss [1] [2] which means that they have been build just a few days ago. Rebuild automatically happens when new code is committed [3].

We have two streams of development [4]: Release and Incubation. Release widgets are stable supported widgets. Incubation widgets are new widgets or widgets without a dedicated maintainer.

If you are looking for something to use in your production environment, pick from the Release widgets first.

Then about the bugs. Please file a bug against any of these widgets for the problems you want to have resolved [5]. Since you seem to be doing some code, it is a better idea to provide the patch to us instead of (or in addition to) subclassing. Providing patches (and associated tests) is the best way to get your requests in on a short time basis.

If you have some time on your hands and want to support the Nebula project by helping us maintain one or more widgets, please open bugs and add patches. If you do this on a regular basis then you can become a committer for the project. (Being an Eclipse committer looks very good on your resume. (trust me, I know that for a fact.))

Best Regards,

Wim


[1] http://ftp.halifax.rwth-aachen.de/eclipse/technology/nebula/snapshot/plugins/
[2] http://ftp.halifax.rwth-aachen.de/eclipse/technology/nebula/incubation/snapshot/plugins/
[3] http://git.eclipse.org/c/nebula/org.eclipse.nebula.git
[4] http://eclipse.org/nebula/
[5] https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Nebula
Re: my issues with Dating Nebula's widgets [message #890206 is a reply to message #890175] Thu, 21 June 2012 12:57 Go to previous message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 115
Registered: July 2009
Senior Member
Thank you for these download links, I was having some trouble with the download site that tries to install it inside my Eclipse (I admit I was a bit inpatient and was only interested in having the jars in my workspace so I googled up an alternative download link).

Thank you, currently I seem to have solved/worked around the issues I was having so I can continue my other work. I'm not sure yet if I would like to become a contributor but I will soon make tickets for the issues I found.
Previous Topic:Analog clock is shown despite CLOCK_DISCRETE being set
Next Topic:Gantt Chart dependencies as straight lines
Goto Forum:
  


Current Time: Mon Sep 22 06:24:01 GMT 2014

Powered by FUDForum. Page generated in 0.04750 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software