384 lines
14 KiB
Java
384 lines
14 KiB
Java
|
|
/*
|
||
|
|
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||
|
|
* All rights reserved. This program and the accompanying materials
|
||
|
|
* are made available under the terms of the Declarative Engineering LLC
|
||
|
|
* verson 1 which accompanies this distribution, and is available at
|
||
|
|
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||
|
|
*/
|
||
|
|
package com.foundation.view.swt;
|
||
|
|
|
||
|
|
import org.eclipse.swt.SWT;
|
||
|
|
import org.eclipse.swt.events.SelectionEvent;
|
||
|
|
import org.eclipse.swt.events.SelectionListener;
|
||
|
|
|
||
|
|
import com.common.thread.IRunnable;
|
||
|
|
import com.foundation.view.IEventAssociation;
|
||
|
|
import com.foundation.view.SingleAssociationContainer;
|
||
|
|
import com.foundation.view.SingleResourceAssociation;
|
||
|
|
|
||
|
|
public class Spinner extends Component implements SelectionListener {
|
||
|
|
public static final int STYLE_WRAP = SWT.WRAP;
|
||
|
|
public static final int STYLE_READ_ONLY = SWT.READ_ONLY;
|
||
|
|
|
||
|
|
/** The progress' maximum resource which bounds the progress states. */
|
||
|
|
private SingleResourceAssociation maximum = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_INTEGER, false, new Integer(0));
|
||
|
|
/** The progress' minimum resource which bounds the progress states. */
|
||
|
|
private SingleResourceAssociation minimum = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_INTEGER, false, new Integer(0));
|
||
|
|
/** The progress' progress resource which defines the current progress state. */
|
||
|
|
private SingleResourceAssociation selection = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_INTEGER, true, new Integer(0));
|
||
|
|
/** The progress' progress resource which defines the increment state. */
|
||
|
|
private SingleResourceAssociation increment = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_INTEGER, false, new Integer(0));
|
||
|
|
/** The progress' progress resource which defines the page increment state. */
|
||
|
|
private SingleResourceAssociation pageIncrement = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_INTEGER, false, new Integer(0));
|
||
|
|
/** Whether the value is automatically synchronized as the user edits the value. Otherwise the field must be manually synchronized. */
|
||
|
|
private boolean autoSynchronizeSelection = false;
|
||
|
|
/** The delay used when auto synchronizing the value. A zero value means there will be no delay. The value must be on the range of [0..10,000]. */
|
||
|
|
private long autoSynchronizeSelectionDelay = 500;
|
||
|
|
/** The task that auto synchronizes the selection after a short delay. */
|
||
|
|
protected Task autoSynchronizeSelectionTask = null;
|
||
|
|
/**
|
||
|
|
* Spinner constructor.
|
||
|
|
* @param parent A composite control which will be the parent of the new instance (cannot be null).
|
||
|
|
* @param name The unique component name.
|
||
|
|
* @param style The style of control to construct.
|
||
|
|
* @see #STYLE_HORIZONTAL
|
||
|
|
* @see #STYLE_INDETERMINATE
|
||
|
|
*/
|
||
|
|
public Spinner(Container parent, String name, int style) {
|
||
|
|
super(parent, name, style);
|
||
|
|
}//Spinner()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#initializeControl(int)
|
||
|
|
*/
|
||
|
|
protected void initializeControl(int style, Object data) {
|
||
|
|
setSwtWidget(new org.eclipse.swt.widgets.Spinner(((Container) getContainer()).getSwtParent(), style));
|
||
|
|
getSwtWidget().setData(this);
|
||
|
|
}//initializeControl()//
|
||
|
|
/**
|
||
|
|
* Gets the SWT progress bar that represents this progress.
|
||
|
|
* @return The SWT progress bar providing visualization for this progress.
|
||
|
|
*/
|
||
|
|
public org.eclipse.swt.widgets.Spinner getSwtSpinner() {
|
||
|
|
return (org.eclipse.swt.widgets.Spinner) getSwtWidget();
|
||
|
|
}//getSwtSpinner()//
|
||
|
|
/**
|
||
|
|
* Sets the component maximum selection value.
|
||
|
|
* @param maximum The maximum value in the selection range.
|
||
|
|
*/
|
||
|
|
public void setMaximum(Integer maximum) {
|
||
|
|
verifyThread();
|
||
|
|
this.maximum.setDefaultValue(maximum);
|
||
|
|
}//setMaximum()//
|
||
|
|
/**
|
||
|
|
* Sets the component minimum selection value.
|
||
|
|
* @param minimum The minimum value in the progress range. This must be greater than or equal to zero.
|
||
|
|
*/
|
||
|
|
public void setMinimum(Integer minimum) {
|
||
|
|
verifyThread();
|
||
|
|
this.minimum.setDefaultValue(minimum);
|
||
|
|
}//setMinimum()//
|
||
|
|
/**
|
||
|
|
* Sets the component selection value.
|
||
|
|
* @param selection The current selection value. This must be greater than or equal to the minimum and less than or equal to the maximum.
|
||
|
|
*/
|
||
|
|
public void setSelection(Integer selection) {
|
||
|
|
verifyThread();
|
||
|
|
this.selection.setDefaultValue(selection);
|
||
|
|
}//setSelection()//
|
||
|
|
/**
|
||
|
|
* Sets the slider increment.
|
||
|
|
* @param increment The increment value for the range.
|
||
|
|
*/
|
||
|
|
public void setIncrement(Integer increment) {
|
||
|
|
verifyThread();
|
||
|
|
this.increment.setDefaultValue(increment);
|
||
|
|
}//setIncrement()//
|
||
|
|
/**
|
||
|
|
* Sets the slider page increment.
|
||
|
|
* @param pageIncrement The page increment value for the range.
|
||
|
|
*/
|
||
|
|
public void setPageIncrement(Integer pageIncrement) {
|
||
|
|
verifyThread();
|
||
|
|
this.pageIncrement.setDefaultValue(pageIncrement);
|
||
|
|
}//setIncrement()//
|
||
|
|
/**
|
||
|
|
* Sets the association container used to access the maximum value.
|
||
|
|
* @param container The maximum value association metadata.
|
||
|
|
*/
|
||
|
|
public void setMaximumAssociation(SingleAssociationContainer container) {
|
||
|
|
verifyThread();
|
||
|
|
this.maximum.setAssociations(container);
|
||
|
|
}//setMaximumAssociation()//
|
||
|
|
/**
|
||
|
|
* Sets the association container used to access the minimum value.
|
||
|
|
* @param container The minimum value association metadata.
|
||
|
|
*/
|
||
|
|
public void setMinimumAssociation(SingleAssociationContainer container) {
|
||
|
|
verifyThread();
|
||
|
|
this.minimum.setAssociations(container);
|
||
|
|
}//setMinimumAssociation()//
|
||
|
|
/**
|
||
|
|
* Sets the association container used to access the selected value.
|
||
|
|
* @param container The selected value association metadata.
|
||
|
|
*/
|
||
|
|
public void setSelectionAssociation(SingleAssociationContainer container) {
|
||
|
|
verifyThread();
|
||
|
|
this.selection.setAssociations(container);
|
||
|
|
}//setSelectionAssociation()//
|
||
|
|
/**
|
||
|
|
* Sets the association container used to access the increment size.
|
||
|
|
* @param container The increment size association metadata.
|
||
|
|
*/
|
||
|
|
public void setIncrementAssociation(SingleAssociationContainer container) {
|
||
|
|
verifyThread();
|
||
|
|
this.increment.setAssociations(container);
|
||
|
|
}//setIncrementAssociation()//
|
||
|
|
/**
|
||
|
|
* Sets the association container used to access the page increment size.
|
||
|
|
* @param container The page increment size association metadata.
|
||
|
|
*/
|
||
|
|
public void setPageIncrementAssociation(SingleAssociationContainer container) {
|
||
|
|
verifyThread();
|
||
|
|
this.pageIncrement.setAssociations(container);
|
||
|
|
}//setPageIncrementAssociation()//
|
||
|
|
/**
|
||
|
|
* Gets whether the selection will automatically synchronize.
|
||
|
|
* @return Whether the selection is automatically synchronized from the view to the model when changed, or whether it must be manually synchronized.
|
||
|
|
*/
|
||
|
|
protected boolean getAutoSynchronizeSelection() {
|
||
|
|
return autoSynchronizeSelection;
|
||
|
|
}//getAutoSynchronizeSelection()//
|
||
|
|
/**
|
||
|
|
* Sets whether the selection will automatically synchronize.
|
||
|
|
* @param autoSynchronizeSelection Whether the selection is automatically synchronized from the view to the model when changed, or whether it must be manually synchronized.
|
||
|
|
*/
|
||
|
|
public void setAutoSynchronizeSelection(boolean autoSynchronizeSelection) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(this.autoSynchronizeSelection != autoSynchronizeSelection) {
|
||
|
|
this.autoSynchronizeSelection = autoSynchronizeSelection;
|
||
|
|
}//if//
|
||
|
|
}//setAutoSynchronizeSelection()//
|
||
|
|
/**
|
||
|
|
* Gets the number of milliseconds to wait before automatically synchronizing selection changes. This must be a number between zero and ten thousand where zero synchronizes without delay.
|
||
|
|
* @return The number of milliseconds of delay when auto synchronizing the selection.
|
||
|
|
*/
|
||
|
|
protected long getAutoSynchronizeSelectionDelay() {
|
||
|
|
return autoSynchronizeSelectionDelay;
|
||
|
|
}//getAutoSynchronizeSelectionDelay()//
|
||
|
|
/**
|
||
|
|
* Sets the number of milliseconds to wait before automatically synchronizing selection changes. This must be a number between zero and ten thousand where zero synchronizes without delay.
|
||
|
|
* @param autoSynchronizeSelectionDelay The number of milliseconds of delay when auto synchronizing the selection.
|
||
|
|
*/
|
||
|
|
public void setAutoSynchronizeSelectionDelay(long autoSynchronizeSelectionDelay) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(autoSynchronizeSelectionDelay < 0) {
|
||
|
|
autoSynchronizeSelectionDelay = 0;
|
||
|
|
}//if//
|
||
|
|
else if(autoSynchronizeSelectionDelay > 10000) {
|
||
|
|
autoSynchronizeSelectionDelay = 10000;
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
if(this.autoSynchronizeSelectionDelay != autoSynchronizeSelectionDelay) {
|
||
|
|
this.autoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay;
|
||
|
|
}//if//
|
||
|
|
}//setAutoSynchronizeSelectionDelay()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewInitialize()
|
||
|
|
*/
|
||
|
|
protected void internalViewInitialize() {
|
||
|
|
getSwtSpinner().addSelectionListener(this);
|
||
|
|
maximum.initialize();
|
||
|
|
minimum.initialize();
|
||
|
|
selection.initialize();
|
||
|
|
increment.initialize();
|
||
|
|
pageIncrement.initialize();
|
||
|
|
super.internalViewInitialize();
|
||
|
|
}//internalViewInitialize()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
||
|
|
*/
|
||
|
|
protected void internalViewRelease() {
|
||
|
|
if(getSwtSpinner() != null && !getSwtSpinner().isDisposed()) {
|
||
|
|
getSwtSpinner().removeSelectionListener(this);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
synchronized(this) {
|
||
|
|
if(autoSynchronizeSelectionTask != null) {
|
||
|
|
removeTask(autoSynchronizeSelectionTask);
|
||
|
|
autoSynchronizeSelectionTask = null;
|
||
|
|
}//if//
|
||
|
|
}//synchronized//
|
||
|
|
|
||
|
|
super.internalViewRelease();
|
||
|
|
maximum.release();
|
||
|
|
minimum.release();
|
||
|
|
selection.release();
|
||
|
|
increment.release();
|
||
|
|
pageIncrement.release();
|
||
|
|
}//internalViewRelease()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewRefresh()
|
||
|
|
*/
|
||
|
|
protected void internalViewRefresh() {
|
||
|
|
super.internalViewRefresh();
|
||
|
|
internalViewRefreshMaximum();
|
||
|
|
internalViewRefreshMinimum();
|
||
|
|
internalViewRefreshSelection();
|
||
|
|
internalViewRefreshIncrement();
|
||
|
|
internalViewRefreshPageIncrement();
|
||
|
|
}//internalViewRefresh()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalViewSynchronize()
|
||
|
|
*/
|
||
|
|
protected void internalViewSynchronize() {
|
||
|
|
super.internalViewSynchronize();
|
||
|
|
|
||
|
|
if(!getAutoSynchronizeSelection()) {
|
||
|
|
selection.setValue(new Integer(getSwtSpinner().getSelection()));
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
synchronized(this) {
|
||
|
|
if(autoSynchronizeSelectionTask != null) {
|
||
|
|
removeTask(autoSynchronizeSelectionTask);
|
||
|
|
autoSynchronizeSelectionTask.execute();
|
||
|
|
}//if//
|
||
|
|
}//synchronized//
|
||
|
|
}//else if//
|
||
|
|
}//internalViewSynchronize()//
|
||
|
|
/**
|
||
|
|
* Synchronizes the selection(s) with the server.
|
||
|
|
*/
|
||
|
|
private void internalSynchronizeSelection() {
|
||
|
|
if(getAutoSynchronizeSelection()) {
|
||
|
|
if(autoSynchronizeSelectionDelay > 0) {
|
||
|
|
//Start a task to send the text to the server after a short delay.//
|
||
|
|
synchronized(this) {
|
||
|
|
final Integer selection = new Integer(getSwtSpinner().getSelection());
|
||
|
|
|
||
|
|
if(autoSynchronizeSelectionTask != null) {
|
||
|
|
removeTask(autoSynchronizeSelectionTask);
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
autoSynchronizeSelectionTask = new Task() {
|
||
|
|
boolean hasRun = false;
|
||
|
|
|
||
|
|
public void execute() {
|
||
|
|
//Make sure that this task is still valid and is not being superceeded.//
|
||
|
|
synchronized(Spinner.this) {
|
||
|
|
if((autoSynchronizeSelectionTask == this) && (!hasRun)) {
|
||
|
|
hasRun = true;
|
||
|
|
//Cleanup after the task.//
|
||
|
|
autoSynchronizeSelectionTask = null;
|
||
|
|
|
||
|
|
getEventLoop().executeAsync(new IRunnable() {
|
||
|
|
public Object run() {
|
||
|
|
Spinner.this.selection.setValue(selection);
|
||
|
|
return null;
|
||
|
|
}//run()//
|
||
|
|
});
|
||
|
|
}//if//
|
||
|
|
}//synchronized//
|
||
|
|
}//run()//
|
||
|
|
};
|
||
|
|
addTask(autoSynchronizeSelectionTask, autoSynchronizeSelectionDelay);
|
||
|
|
}//synchronized//
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
selection.setValue(new Integer(getSwtSpinner().getSelection()));
|
||
|
|
}//else//
|
||
|
|
}//if//
|
||
|
|
}//internalSynchronizeSelection()//
|
||
|
|
/**
|
||
|
|
* Refreshes the progress maximum.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshMaximum() {
|
||
|
|
if(maximum.refresh()) {
|
||
|
|
Integer value = (Integer) maximum.getValue();
|
||
|
|
|
||
|
|
getSwtSpinner().setMaximum(value.intValue());
|
||
|
|
}//if//
|
||
|
|
}//internalViewRefreshMaximum()//
|
||
|
|
/**
|
||
|
|
* Refreshes the progress maximum.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshMinimum() {
|
||
|
|
if(minimum.refresh()) {
|
||
|
|
Integer value = (Integer) minimum.getValue();
|
||
|
|
|
||
|
|
getSwtSpinner().setMinimum(value.intValue());
|
||
|
|
}//if//
|
||
|
|
}//internalViewRefreshMinimum()//
|
||
|
|
/**
|
||
|
|
* Refreshes the current selection.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshSelection() {
|
||
|
|
if(selection.refresh()) {
|
||
|
|
Integer value = (Integer) selection.getValue();
|
||
|
|
|
||
|
|
getSwtSpinner().setSelection(value.intValue());
|
||
|
|
}//if//
|
||
|
|
}//internalViewRefreshSelection()//
|
||
|
|
/**
|
||
|
|
* Refreshes the increment.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshIncrement() {
|
||
|
|
if(increment.refresh()) {
|
||
|
|
Integer value = (Integer) increment.getValue();
|
||
|
|
|
||
|
|
getSwtSpinner().setIncrement(value.intValue());
|
||
|
|
}//if//
|
||
|
|
}//internalViewRefreshIncrement()//
|
||
|
|
/**
|
||
|
|
* Refreshes the page increment.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshPageIncrement() {
|
||
|
|
if(pageIncrement.refresh()) {
|
||
|
|
Integer value = (Integer) pageIncrement.getValue();
|
||
|
|
|
||
|
|
getSwtSpinner().setPageIncrement(value.intValue());
|
||
|
|
}//if//
|
||
|
|
}//internalViewRefreshPageIncrement()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation)
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
||
|
|
if(resourceAssociation == maximum) {
|
||
|
|
internalViewRefreshMaximum();
|
||
|
|
}//if//
|
||
|
|
else if(resourceAssociation == minimum) {
|
||
|
|
internalViewRefreshMinimum();
|
||
|
|
}//else if//
|
||
|
|
else if(resourceAssociation == selection) {
|
||
|
|
internalViewRefreshSelection();
|
||
|
|
}//else if//
|
||
|
|
else if(resourceAssociation == increment) {
|
||
|
|
internalViewRefreshIncrement();
|
||
|
|
}//else if//
|
||
|
|
else if(resourceAssociation == pageIncrement) {
|
||
|
|
internalViewRefreshPageIncrement();
|
||
|
|
}//else if//
|
||
|
|
else {
|
||
|
|
super.internalOnValueChanged(resourceAssociation, flags);
|
||
|
|
}//else//
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.swt.AbstractComponent#internalOnEventFired(com.foundation.view.swt.IEventAssociation, java.lang.Object[])
|
||
|
|
*/
|
||
|
|
protected void internalOnEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
|
||
|
|
}//internalOnEventFired()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||
|
|
*/
|
||
|
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||
|
|
widgetSelected(e);
|
||
|
|
}//widgetDefaultSelected()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||
|
|
*/
|
||
|
|
public void widgetSelected(SelectionEvent e) {
|
||
|
|
//TODO: Is there some way to determine exactly what selection or deselection occured given the event object?//
|
||
|
|
internalSynchronizeSelection();
|
||
|
|
}//widgetSelected()//
|
||
|
|
}//Spinner//
|