Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* 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:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
package at.spardat.xma.page;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.SortedMap;
import java.util.TreeMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import at.spardat.xma.appshell.AppShell;
import at.spardat.xma.boot.component.IDialog;
import at.spardat.xma.component.ComponentClient;
import at.spardat.xma.component.EmbeddableComponent;
import at.spardat.xma.mdl.UIDelegateClient;
import at.spardat.xma.mdl.list.ListUIDelegateClient;
import at.spardat.xma.mdl.simple.SimpleUIDelegateClient;
/**
* This Class is the base class of all dialog Pages.
* It implements the main livecycle protocoll for the dialog
* and the handling of the corresponding SWT-Shell.
*
* @author s2877
*
*/
public abstract class DialogPage extends PageClient implements IDialogPage {
/**
* The SWT-shell for the dialog.
*/
Shell shell;
/**
* SWT-Style for the Shell.
*/
int style;
/** optional parent shell */
Shell parentShell;
/**
* Flag indicating if the Dialog was finished with a save operation.
* true means ok
* false means the Dialog is still running or was canceld.
*/
boolean exitStatus;
/**
* The StatusBar of the Dialog.
*/
protected StatusBar statusBar;
/** The SWT-Composite serving as parent for the StatusBar*/
protected Composite statusBarComposite;
/**
* The Widget which currently has the focus.
*/
private Control focusControl;
/**
* An ordered list of validation errors. Keys are Widget-objects (the
* widgets that are in error), values are Strings describing the error.
* The entries are ordered by the tab order of the widgets.
*/
private SortedMap validationErrors_ = new TreeMap(new TabOrderComparator());
/**
* An ordered list of warnings. Keys are Widget-objects,
* values are Strings describing the error.
* The entries are ordered by the tab order of the widgets.
*/
private SortedMap warnings;
/**
* An ordered list of infos. Keys are Widget-objects,
* values are Strings describing the error.
* The entries are ordered by the tab order of the widgets.
*/
private SortedMap infos;
// /**
// * An ordered list of errors set by application code. Keys are Widget-objects (the
// * widgets that are in error), values are Strings describing the error.
// * The entries are ordered by the tab order of the widgets.
// */
// private SortedMap appErrors_ = new TreeMap(new TabOrderComparator());
/**
* Flag indicating that stateChandedBase() has to be called once more.
*/
private boolean rerunStateChanched=false;
/**
* Initializes a DialogPage inside a given Component.
*
* @param component the Component containing the DialogPage.
* @param style The SWT-Style for the Shell of the DialogPage.
* @param stateless indicating if this page is stateless on the server.
* @throws IllegalArgumentException if component is null.
*/
public DialogPage(ComponentClient component, boolean stateless, int style) {
super(component,stateless);
if (component == null) throw new IllegalArgumentException("Component must not be null");
this.style=style;
}
/**
* Initializes a DialogPage inside a given Component.
*
* @param component the Component containing the DialogPage.
* @param parentShell the Shell which shall be the parent of the Shell of the DialogPage.
* @param style The SWT-Style for the Shell of the DialogPage.
* @param stateless indicating if this page is stateless on the server.
* @throws IllegalArgumentException if component is null.
*/
public DialogPage(ComponentClient component, Shell parentShell, boolean stateless, int style) {
super(component,stateless);
if (component == null) throw new IllegalArgumentException("Component must not be null");
this.parentShell=parentShell;
this.style=style;
}
/**
* Initializes a DialogPage inside the same Component as the parent PageClient.
*
* @param parent the PageClient calling this DialogPage.
* @param stateless indicating if this page is stateless on the server.
* @param style The SWT-Style for the Shell of the DialogPage.
*/
public DialogPage(PageClient parent, boolean stateless, int style) {
super(parent,stateless);
this.style=style;
}
/**
* Get the DialogPage of this Page.
*
* @return this.
*/
public IDialog getDialog() {
if(dialog!=null) return dialog;
else return this;
}
/**
* Get the SWT-Shell of the DialogPage. For DialogPages the corresponding
* SWT-Composite of the DialogPage is a Shell and will be returned.
*
* @return the SWT-Shell containing the widgets of this DialogPage.
*/
public Shell getShell() {
if(dialog!=null) return dialog.getShell();
else return shell;
}
// /**
// * Gets the StatusBar of this DialogPage.
// *
// * @return the SatusBar of the Dialog
// */
// public StatusBar getStatusBar() {
// return statusBar;
// }
/**
* Sets the focus to the given control.
* @param control the Control to set the focus to.
*/
public void setFocus(final Control control) {
boolean success = control.setFocus();
if(!success) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
if (!control.isDisposed()) control.setFocus();
}
});
}
}
/**
* Gets the Control on the DialogPage or a Subpage of it, which currently
* has the focus.
* @return the Control with the focus.
*/
public Control getFocusControl() {
return focusControl;
}
/**
* Sets the Control on the DialogPage of a Subpage of it, which currently
* has the focus. The Control must allready have the focus. No SWT-Method will
* be called. This method is reserverd for the runtime to keep track of the focus.
* Do not call it directly!
* @param control the Control with the focus.
*/
public void setFocusControl(Control control) {
focusControl=control;
}
public Composite createComposite(Composite parentComp) {
// if(dialog==null) {
// shell = new Shell((Shell)parentComp,style);
// composite = shell;
// } else {
composite = new Composite(parentComp, SWT.NONE);
// }
composite.setData(this);
return composite;
}
/**
* Creates the Widgets of the PageClient and all Subpages by calling
* {@link #createWidgets()} on the PageClient and all Subpages.
*/
public void initGUI() {
if(!hasModels()) {
createModels();
}
if(dialog==null) {
if(shell==null||shell.isDisposed()) {
if(parentShell!=null) {
shell = new Shell(parentShell, style);
} else if(parent!=null) {
shell = new Shell(parent.getDialog().getShell(), style);
} else {
shell = new Shell(getComponent().getDisplay(), style);
}
}
shell.setData(this);
FormLayout layout = new FormLayout();
shell.setLayout(layout);
DialogEventAdapter adapter = new DialogEventAdapter(this);
shell.addShellListener(adapter);
shell.addDisposeListener(adapter);
// shell.addKeyListener(new KeyListener() {
// public void keyPressed(KeyEvent e) {
// if(((e.stateMask & (SWT.CONTROL|SWT.SHIFT))!=0) && e.keyCode == 'D') {
// printData();
// }
// }
// public void keyReleased(KeyEvent e) {}
// });
FormData data;
if ( doCreateStatusBar() ) {
statusBarComposite = new Composite(shell, SWT.NONE);
statusBarComposite.setLayout(new FormLayout());
data = new FormData();
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
data.bottom = new FormAttachment(100, 0);
statusBarComposite.setLayoutData(data);
statusBar = new StatusBar(statusBarComposite, SWT.NONE);
data = new FormData();
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
data.top = new FormAttachment(0, 0);
data.bottom = new FormAttachment(100, 0);
statusBar.setLayoutData(data);
}
composite = new Composite(shell,SWT.NONE);
data = new FormData();
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
data.top = new FormAttachment(0, 0);
data.bottom = doCreateStatusBar()
? new FormAttachment(statusBarComposite,0,SWT.DEFAULT)
: new FormAttachment(100, 0);
composite.setLayoutData(data);
}
super.initGUI();
attachUI();
handleDialogPageIcon();
}
/**
* Toggles if the status bar will be displayed or not.
* @return false to hide the status bar
*/
protected boolean doCreateStatusBar() {
return true;
}
/**
* Method called to start the DialogPage.
* The Dialog will be shown and executed.
* For modal dialogs invoke() blocks until the Dialog is closed.
* For nonmodal dialogs invoke() returns imediately.
*
* @return true if a nonmodal dialog is started successfully or
* a modal dialog is closed via the ok-, save- or a similar button.
* false if a modal dialog is canceld.
*/
public boolean invoke() {
initGUI();
enterBase();
stateChangedBase();
updateErrorStatus(focusControl);
shell.open();
setEventsEnabled(true);
if((shell.getStyle() & (SWT.PRIMARY_MODAL|SWT.APPLICATION_MODAL|SWT.SYSTEM_MODAL)) != 0) {
eventLoop();
return exitStatus;
}
return true;
}
/**
* Execute the eventLoop and dispach all Events. Every modal SWT-Shell has its
* own eventLoop which is implemented here.
*/
private void eventLoop() {
Display display = shell.getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Notify the PageClient and all Subpages of a possible Change in the PageModels
* by calling {@link #determineState()} and {@link #stateChanged()} on the PageClient
* and all Subpages. My be repeated by calling {@link #setRerunStateChanched()}.
*/
public void stateChangedBase() {
do {
rerunStateChanched=false;
super.stateChangedBase();
} while(rerunStateChanched);
}
/**
* Requests another call to {@link #determineState()} and {@link #stateChanged()} if called within one of
* these methods. It has no effect if called outside these methods.
* @since 1.7.0
*/
public void setRerunStateChanched() {
rerunStateChanched=true;
}
/**
* Eventhandler called by SWT every time, the Shell is tried to be closed.
* This Method calls {@link #close()} which my decide if the Shell will actually be closed.
* It the Shell is not closed, {@link #stateChanged()} is called.
*
* @param event the SWT-Event that happended.
*/
void shellClosed(ShellEvent event) {
try{
setEventsEnabled(false);
try {
event.doit = close();
} catch (Exception exc) {
showException(exc);
}
if(event.doit) {
exitStatus=false;
leaveBase();
removeWidgetsBase();
notifyClose();
} else {
stateChangedBase();
}
} finally {
if(getWidgets()!=null) setEventsEnabled(true);
}
}
/**
* Closes the dialog with exitStatus true.
*
*/
public void closeOK() {
if (dialog == null || dialog == this) {
exitStatus=true;
leaveBase();
removeWidgetsBase();
getShell().dispose();
} else if (dialog instanceof AppShell) {
AppShell appShell = (AppShell)dialog;
appShell.closeTasks(this);
} else if (dialog != null) {
dialog.closeOK();
}
notifyClose();
}
/**
* Closes the dialog with exitStatus false.
*
*/
public void closeCancel() {
if (dialog == null || dialog == this) {
exitStatus=false;
leaveBase();
removeWidgetsBase();
getShell().dispose();
} else if (dialog instanceof AppShell) {
AppShell appShell = (AppShell)dialog;
appShell.closeTasks(this);
} else if (dialog != null) {
dialog.closeCancel();
}
notifyClose();
}
/**
* Sends the closeEvent of the component, if this page is the main page
* of an embeddable component. Automatically called by shellClosed(), closeOK(), closeCancel()
*/
private void notifyClose() {
ComponentClient comp = getComponent();
if(comp instanceof EmbeddableComponent) {
if(((EmbeddableComponent)comp).getMainPage()==this) {
comp.notifyClosed();
}
}
}
/**
* Eventhandler called by SWT when the Shell is disposed.
*
* @param event the SWT-Event that happended.
*/
void widgetDisposed(DisposeEvent event) {
// removeWidgetsBase(); moved to close,closeOK,closeCancel
}
/**
* Notify the PageClient and all Subpages, that the Widgets are disposed
* by calling {@link #removeWidgets()} on all Subpages and the PageClient.
*/
public void removeWidgetsBase() {
super.removeWidgetsBase();
statusBar=null;
statusBarComposite=null;
focusControl=null;
}
/**
* This method will be called every time the Shell is tried to be closed.
* It is intended to be implemented by the application programmer if he
* wants to react on this event. The application programmer my decide if
* the shell will actually be closed.
*
* @return true means it is ok to close the Shell
* false means do not close the Shell
*/
protected boolean close() {
return true;
}
/**
* Indicates if the dialog is shown to the user. Use this method to
* determine if a modeless dialog is open or closed.
*
* @return true if the dialog is visible to the user.
*/
public boolean isVisible() {
return shell!=null && shell.isVisible();
}
/**
* Returns the exitStatus of the DialogPage.
*/
public boolean getExitstatus() {
return exitStatus;
}
/**
* Returns the internationalized title of this dialog.
* The title is read form the properties file.
*/
public String getDialogTitle() {
Locale locale = getComponent().getSession().getContext().getLocale();
ResourceBundle messages = ResourceBundle.getBundle(getComponent().getClass().getName(),locale);
String className = getClass().getName();
className=className.substring(className.lastIndexOf('.')+1);
return messages.getString(className);
}
/**
* Returns the number of Errors in this dialog including its subpages.
* This is the count of widgets with errors.
*/
public int getErrorCount () {
if(dialog!=null) return dialog.getErrorCount();
else return validationErrors_.size();
}
/**
* Removes a validation error for a particular widget. This method
* is for internal use only. Calling it causes undefined behaviour!
*
* @param widget the widget where to clear the error state.
*/
public void clearValidationErrorImpl (Widget widget) {
if(dialog!=null) ((IDialogPage)dialog).clearValidationErrorImpl(widget);
else errorsRemove(widget,0);
}
/**
* Sets a validation error for a particular widget. This method
* is for internal use only. Calling it causes undefined behaviour!
*
* @param widget the widget where the error occured
* @param errorText indicates the error
*/
public void setValidationErrorImpl (Widget widget,String errorText) {
if(dialog!=null) ((IDialogPage)dialog).setValidationErrorImpl(widget,errorText);
else errorsPut(widget,errorText,0);
}
/**
* Determines if a validation error currently exists for a given widget.
* Note that validation is disabled automatically for readonly widgets, so
* readonly widgets never have validation errors.
* @param widget to search for validation errors
* @return true if the validator reported an error for the given widget. false otherwise.
*/
public boolean hasValidationError(Widget widget) {
if(dialog!=null) {
return ((IDialogPage)dialog).hasValidationError(widget);
} else {
String[] list = (String[]) validationErrors_.get(widget);
return list!=null&&list[0]!=null;
}
}
/**
* Returns some error text. If there is an error
* for the provided control, this is returned. Otherwise the
* error for the widget next in tab order is returned. If one control
* contains a validation error and an error set via {@link #setError(Widget, String)},
* the validation error is returned.
*
* @param control the UI control (SWT widget) whose error is most wanted.
* @return null, if there are no validation errors. Otherwise, a
* String is returned following the algorithm described
* above.
*/
private String getError (Widget control) {
if (validationErrors_.size() == 0) return null;
String[] list;
SortedMap tail = validationErrors_.tailMap(control);
if(tail.size()>0) {
list = (String[])tail.values().iterator().next();
} else {
list = (String[])validationErrors_.values().iterator().next();
}
if(list[0]!=null) return list[0];
else return list[1];
}
/**
* Updates the error message in the StatusBar. If there are more then one
* error, the error belonging to the widget which currently owns the focus
* is displayed. If there is no error on the PageClient, the error message is cleared.
*
* @param current the Widget which currently owns the focus.
*/
public void updateErrorStatus(Widget current) {
if ( statusBar == null )
return;
String error = getError(current);
if (error != null) {
statusBar.setError(error);
} else {
String warning = getWarning(current);
if(warning!=null) {
statusBar.setWarning(warning);
} else {
String info = getInfo(current);
if(info!=null) {
statusBar.setInfo(info);
} else {
statusBar.clear();
}
}
}
statusBar.message.setToolTipText(getStatusMessages(current));
}
/**
* Stores an error
* @param widget the widget where the error occured
* @param error the errortext to display
* @param type 0=validationError, 1=appError
*/
private void errorsPut(Widget widget,String error,int type) {
String[] list = (String[]) validationErrors_.get(widget);
if(list==null) {
list=new String[2];
validationErrors_.put(widget,list);
}
list[type]=error;
if(widget!=null) {
Object delegate = widget.getData();
if(delegate instanceof UIDelegateClient) ((UIDelegateClient)delegate).setErrorColor(true);
}
}
/**
* Removes an error
* @param widget the widget where the error occured
* @param type 0=validationError, 1=appError
*/
private void errorsRemove(Widget widget, int type) {
String[] list = (String[]) validationErrors_.get(widget);
if(list!=null) {
list[type]=null;
if(list[0]==null&&list[1]==null) {
validationErrors_.remove(widget);
if(widget!=null) {
Object delegate = widget.getData();
if(delegate instanceof UIDelegateClient) ((UIDelegateClient)delegate).setErrorColor(false);
}
}
} else { // color must be set even if error state does not change
if(widget!=null && !widget.isDisposed()) { // maybe the widget changed from editable to not editable
Object delegate = widget.getData();
if(delegate instanceof UIDelegateClient) ((UIDelegateClient)delegate).setErrorColor(false);
}
}
}
/**
* Removes the error for the given widget.
*
* @param widget the widget where to clear the error state.
*/
public void clearError (Widget widget) {
if(dialog!=null) dialog.clearError(widget);
else errorsRemove(widget,1);
}
/**
* Sets an error for the given widget. The error is shown in the status line.
* Only one error can be shown at a time. The precedence rules are:
* 1) the validation error of the widget owning the focus
* 2) the error of the widget owning the focus set with this method
* 3) the error of the next widget in the tab order containing an error
* 4) the error set for the null-widget.
*
* @param widget the widget where the error occured. Null is allowd if the error can not
* be associated with a widget.
* @param errorText indicates the error
*/
public void setError (Widget widget,String errorText) {
if(dialog!=null) dialog.setError(widget,errorText);
else errorsPut(widget,errorText,1);
}
/**
* Resets all widgets containing values with validation errors to their
* last known valid value from the model.
*/
public void overrideErrorsFromModel() {
ArrayList errors = new ArrayList(validationErrors_.keySet());
for(Iterator it=errors.iterator();it.hasNext();) {
Widget widget = (Widget)it.next();
Object delegate = widget.getData();
if(delegate instanceof SimpleUIDelegateClient) {
((SimpleUIDelegateClient)delegate).resetWidgetFromModel();
} else if(delegate instanceof ListUIDelegateClient) {
((ListUIDelegateClient)delegate).resetWidgetFromModel();
}
}
}
/**
* Sets an warning for the given widget. The warning is shown in the status line,
* if currently no error has to be shown.
* Only one error or warning can be shown at a time. The precedence rules are:
* 1) any error of any widget (see {@link #setError(Widget, String)}
* 2) the warning of the widget owning the focus
* 3) the warning of the next widget in the tab order containing a warning
* 4) the warning set for the null-widget.
*
* @param widget the widget the warning is associated with. Null is allowed.
* @param warningText indicates the warning
*/
public void setWarning(Widget widget,String warningText) {
if(dialog!=null) {
((IDialogPage)dialog).setWarning(widget,warningText);
} else {
if(warnings==null) { warnings = new TreeMap(new TabOrderComparator()); }
warnings.put(widget, warningText);
}
}
/**
* Removes the warning for the given widget.
*
* @param widget the widget where to clear the warning.
*/
public void clearWarning(Widget widget) {
if(dialog!=null) {
((IDialogPage)dialog).clearWarning(widget);
} else if(warnings!=null) {
warnings.remove(widget);
}
}
/**
* Returns a warning text. If there is a warning associated
* to the provided control, this is returned. Otherwise the
* warning for the widget next in tab order is returned.
*
* @param control the UI control (SWT widget) whose warning is most wanted.
* @return null, if there are no warnings. Otherwise, a
* String is returned following the algorithm described
* above.
*/
private String getWarning (Widget control) {
if (warnings==null || warnings.size() == 0) return null;
SortedMap tail = warnings.tailMap(control);
if(tail.size()>0) {
return (String)tail.values().iterator().next();
} else {
return (String)warnings.values().iterator().next();
}
}
/**
* Sets an info for the given widget. The info is shown in the status line,
* if currently no error or warning has to be shown.
* Only one error, warning or info can be shown at a time. The precedence rules are:
* 1) any error or warning of any widget (see {@link #setWarning(Widget, String)}
* 2) the info of the widget owning the focus
* 3) the info of the next widget in the tab order containing a warning
* 4) the info set for the null-widget.
*
* @param widget the widget the info is associated with. Null is allowed.
* @param infoText indicates the info
*/
public void setInfo(Widget widget,String infoText) {
if(dialog!=null) {
((IDialogPage)dialog).setInfo(widget,infoText);
} else {
if(infos==null) { infos = new TreeMap(new TabOrderComparator()); }
infos.put(widget, infoText);
}
}
/**
* Removes the info for the given widget.
*
* @param widget the widget where to clear the info.
*/
public void clearInfo(Widget widget) {
if(dialog!=null) {
((IDialogPage)dialog).clearInfo(widget);
} else if(infos!=null) {
infos.remove(widget);
}
}
/**
* Returns an info text. If there is a info associated
* to the provided control, this is returned. Otherwise the
* info for the widget next in tab order is returned.
*
* @param control the UI control (SWT widget) whose info is most wanted.
* @return null, if there are no infos. Otherwise, a
* String is returned following the algorithm described
* above.
*/
private String getInfo (Widget control) {
if (infos==null || infos.size() == 0) return null;
SortedMap tail = infos.tailMap(control);
if(tail.size()>0) {
return (String)tail.values().iterator().next();
} else {
return (String)infos.values().iterator().next();
}
}
/**
* Returns all validation errors, errors, warnings and infos of
* the dialog seperated by newlines. The order is the same as
* the precedence order for the status bar.
* @param current the control witch currently has the focus.
*/
private String getStatusMessages(Widget current) {
StringBuffer messages = new StringBuffer();
// errors
SortedMap tail = validationErrors_.tailMap(current);
for(Iterator it=tail.values().iterator();it.hasNext();) {
String[] errors = (String[]) it.next();
if(errors[0]!=null) messages.append(errors[0]+"\n");
if(errors[1]!=null) messages.append(errors[1]+"\n");
}
SortedMap head = validationErrors_.headMap(current);
for(Iterator it=head.values().iterator();it.hasNext();) {
String[] errors = (String[]) it.next();
if(errors[0]!=null) messages.append(errors[0]+"\n");
if(errors[1]!=null) messages.append(errors[1]+"\n");
}
// warnings
if(warnings!=null) {
tail = warnings.tailMap(current);
for(Iterator it=tail.values().iterator();it.hasNext();) {
messages.append(it.next()+"\n");
}
head = warnings.headMap(current);
for(Iterator it=head.values().iterator();it.hasNext();) {
messages.append(it.next()+"\n");
}
}
// infos
if(infos!=null) {
tail = infos.tailMap(current);
for(Iterator it=tail.values().iterator();it.hasNext();) {
messages.append(it.next()+"\n");
}
head = infos.headMap(current);
for(Iterator it=head.values().iterator();it.hasNext();) {
messages.append(it.next()+"\n");
}
}
// remove last "\n".
if(messages.length()>0) {
messages.delete(messages.length()-1, messages.length());
}
return messages.toString();
}
/**
* Centers this DialogPabe on the screen. If more than one monitor is used,
* the dialog is centered on the primary monitor.
*/
public void centerShell() {
centerShell(getShell());
}
/**
* Centers the given shell on the screen. If more than one monitor is used,
* the shell is centered on the primary monitor.
*/
public static void centerShell(Shell shell) {
centerShell(null,shell);
}
/**
* Centers the given shell on the parent shell.
*
* If the parent shell is null, the shell is centered on the display.
*
* If more than one monitor is used, the shell is centered on the
* primary monitor.
*/
public static void centerShell(Shell parentShell, Shell shell) {
Rectangle parentRect;
Rectangle splashRect = shell.getBounds();
if (parentShell == null) {
parentRect = shell.getDisplay().getPrimaryMonitor().getBounds();
} else {
parentRect = parentShell.getBounds();
}
int x = parentRect.x + (parentRect.width - splashRect.width) / 2;
int y = parentRect.y + (parentRect.height - splashRect.height) / 2;
shell.setLocation(x, y);
}
/**
* Comparator class used to order SWT-Components by their
* tab order in this dialog.
* @author s2877
*/
class TabOrderComparator implements Comparator {
/**
* Determines wich of the both controls comes first in the tab
* order of this dialog.
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return -1 if o1 comes first in tab order, 1 if o2 comes
* first in tab order, 0 if o1 and o2 are identical.
* if both controls are not defined in the tab order,
* they are sorted by their respective hashValues.
* @throws ClassCastException if the arguments are not SWT-Controls.
*/
public int compare(Object o1, Object o2) {
if(o1==o2) return 0;
if(o1==null) return 1;
if(o2==null) return -1;
Widget first = firstTab(composite,(Widget)o1,(Widget)o2);
if(first==o1) return -1;
if(first==o2) return 1;
// no defined tab-order -> sort by hashCode
int h1=o1.hashCode();
int h2=o2.hashCode();
if(h1
h2) return 1;
// identical hashCode -> consider equal
return 0;
}
/**
* Returns that control given in the parameters which is found first in
* the tab order of the given composite or one of its subcomposits.
* @param comp the composite where to search for the controls
* @param c1, c2 the controls to deside which comes first in tab order
* @return the control of the parameters which is found first in the tab order
* or null if none of them is found.
*/
private Widget firstTab(Composite comp,Widget c1, Widget c2) {
Control[] conts = comp.getTabList();
for(int i=0;i