/*******************************************************************************
* Copyright (c) 2013 Pivotal Software, Inc.
* 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
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springsource.ide.eclipse.commons.livexp.core;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.progress.UIJob;
/**
* This class should be used instead of ValueListener when the code it
* wants to execute upon receiving a 'gotValue' event is required
* to run in the UIThread (i.e. typically this is code that needs to
* update or read widgets in the UI).
*/
public abstract class UIValueListener<T> implements ValueListener<T> {
private class NotifyingJob extends UIJob {
LiveExpression<T> exp;
public NotifyingJob(LiveExpression<T> exp) {
super("Notifying Job");
this.exp = exp;
setSystem(true);
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
uiGotValue(exp, exp.getValue());
return Status.OK_STATUS;
}
}
private NotifyingJob job = null;
/**
* This method is final. Implement 'uiGotValue' instead.
*/
public final void gotValue(final LiveExpression<T> exp, final T value) {
if (Display.getCurrent() == null) {
NotifyingJob job = this.job;
if (job == null || job.exp != exp) {
job = new NotifyingJob(exp);
this.job = job;
}
job.schedule();
} else {
uiGotValue(exp, value);
}
}
/**
* Subclasses should implement. This method will always be called in the UIThread.
*/
protected abstract void uiGotValue(LiveExpression<T> exp, T value);
/**
* A Lambda-friendly way to creat {@link UIValueListener}
*/
public static <T> UIValueListener<T> from(ValueListener<T> l) {
return new UIValueListener<T>() {
@Override
protected void uiGotValue(LiveExpression<T> exp, T value) {
l.gotValue(exp, value);
}
};
}
}