/******************************************************************************* * Copyright (c) 2002, 2017 Innoopract Informationssysteme GmbH and others. * 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: * Innoopract Informationssysteme GmbH - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.swt.widgets; import static org.eclipse.swt.internal.widgets.MarkupUtil.isToolTipMarkupEnabledFor; import static org.eclipse.swt.internal.widgets.MarkupValidator.isValidationDisabledFor; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.lifecycle.RemoteAdapter; import org.eclipse.rap.rwt.internal.lifecycle.ReparentedControls; import org.eclipse.rap.rwt.internal.theme.ThemeAdapter; import org.eclipse.rap.rwt.internal.util.ActiveKeysUtil; import org.eclipse.rap.rwt.theme.BoxDimensions; import org.eclipse.rap.rwt.theme.ControlThemeAdapter; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.accessibility.Accessible; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.DragDetectListener; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.GestureListener; import org.eclipse.swt.events.HelpListener; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.TouchListener; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Drawable; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.internal.widgets.ControlRemoteAdapter; import org.eclipse.swt.internal.widgets.IControlAdapter; import org.eclipse.swt.internal.widgets.IDisplayAdapter; import org.eclipse.swt.internal.widgets.MarkupValidator; /** * Control is the abstract superclass of all windowed user interface classes. * <p> * <dl> * <dt><b>Styles:</b> * <dd>BORDER</dd> * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> * <dt><b>Events:</b> * <dd>FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, <!-- MouseEnter, --> * <!-- MouseExit, MouseHover, --> MouseUp, <!-- MouseMove,--> Move, <!-- Paint, --> Resize, Traverse, * <!-- DragDetect, --> MenuDetect</dd> * </dl> * </p><p> * IMPORTANT: This class is intended to be subclassed <em>only</em> * within the SWT implementation. * </p> * * @since 1.0 */ public abstract class Control extends Widget implements Drawable { private final class ControlAdapter implements IControlAdapter { @Override public Shell getShell() { return internalGetShell(); } @Override public int getTabIndex() { return tabIndex; } @Override public void setTabIndex( int index ) { if( takesFocus() ) { getRemoteAdapter().preserveTabIndex( tabIndex ); tabIndex = index; } } private boolean takesFocus() { boolean result = ( getStyle() & SWT.NO_FOCUS ) == 0; result &= Control.this.getClass() != Composite.class; result &= Control.this.getClass() != ScrolledComposite.class; result &= Control.this.getClass() != SashForm.class; return result; } @Override public Font getUserFont() { return font; } @Override public Color getUserForeground() { return foreground; } @Override public Color getUserBackground() { return background; } @Override public Image getUserBackgroundImage() { return backgroundImage; } @Override public boolean getBackgroundTransparency() { return backgroundTransparency; } @Override public boolean isPacked() { return packed; } @Override public void clearPacked() { packed = false; } @Override /* provides direct access to the internal property in order to speed up preserving */ public Rectangle getBounds() { return bounds; } @Override public void setForeground( Color color ) { foreground = color; } @Override public void setBackground( Color color ) { background = color; } @Override public void setVisible( boolean visible ) { internalSetVisible( visible ); } @Override public void setEnabled( boolean enabled ) { internalSetEnabled( enabled ); } @Override public void setToolTipText( String toolTipText ) { Control.this.toolTipText = toolTipText; } @Override public void setCursor( Cursor cursor ) { Control.this.cursor = cursor; } } private transient IControlAdapter controlAdapter; private Composite parent; private int tabIndex; private Rectangle bounds; private Object layoutData; private String toolTipText; private Menu menu; private Listener menuDisposeListener; private Color foreground; private Color background; private Image backgroundImage; private boolean backgroundTransparency; private Font font; private Cursor cursor; private BoxDimensions bufferedPadding; private transient Accessible accessible; private boolean packed; Control( Composite parent ) { // prevent instantiation from outside this package; only called by Shell // and its super-classes this.parent = parent; bounds = new Rectangle( 0, 0, 0, 0 ); tabIndex = -1; } /** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. * <p> * The style value is either one of the style constants defined in * class <code>SWT</code> which is applicable to instances of this * class, or must be built by <em>bitwise OR</em>'ing together * (that is, using the <code>int</code> "|" operator) two or more * of those <code>SWT</code> style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. * </p> * * @param parent a composite control which will be the parent of the new instance (cannot be null) * @param style the style of control to construct * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> * </ul> * * @see SWT#BORDER * @see Widget#checkSubclass * @see Widget#getStyle */ public Control( Composite parent, int style ) { super( parent, style ); this.parent = parent; controlAdapter = new ControlAdapter(); bounds = new Rectangle( 0, 0, 0, 0 ); tabIndex = -1; parent.addChild( this ); createWidget(); } void createWidget () { initState(); checkOrientation( parent ); checkMirrored(); checkBackground(); updateBackground(); } void initState() { // by default let states empty } /** * Returns the receiver's parent, which must be a <code>Composite</code> * or null when the receiver is a shell that was created with null or * a display for a parent. * * @return the receiver's parent * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Composite getParent() { checkWidget(); return parent; } Composite _getParent() { return parent; } /** * Returns the receiver's shell. For all controls other than * shells, this simply returns the control's nearest ancestor * shell. Shells return themselves, even if they are children * of other shells. * * @return the receiver's shell * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getParent */ public Shell getShell() { checkWidget(); return internalGetShell(); } Shell internalGetShell() { return parent.internalGetShell(); } /** * Returns the receiver's monitor. * * @return the receiver's monitor * * @since 1.2 */ public Monitor getMonitor() { checkWidget(); return display.getPrimaryMonitor(); } ////////////// // Visibility /** * Marks the receiver as visible if the argument is <code>true</code>, * and marks it invisible otherwise. * <p> * If one of the receiver's ancestors is not visible or some * other condition makes the receiver not visible, marking * it visible may not actually cause it to be displayed. * </p> * * @param visible the new visibility state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setVisible( boolean visible ) { checkWidget(); if( hasState( HIDDEN ) != !visible ) { preserveState( HIDDEN ); internalSetVisible( visible ); } } private void internalSetVisible( boolean visible ) { if( hasState( HIDDEN ) != !visible ) { if( visible ) { notifyListeners( SWT.Show, null ); } Control control = null; boolean fixFocus = false; if( !visible ) { control = display.getFocusControl(); fixFocus = isFocusAncestor( control ); } if( visible ) { removeState( HIDDEN ); } else { addState( HIDDEN ); } if( !visible ) { notifyListeners( SWT.Hide, null ); } if( fixFocus ) { fixFocus( control ); } } } /** * Returns <code>true</code> if the receiver is visible and all * ancestors up to and including the receiver's nearest ancestor * shell are visible. Otherwise, <code>false</code> is returned. * * @return the receiver's visibility state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getVisible */ public boolean isVisible() { checkWidget(); return getVisible() && parent.isVisible(); } /** * Returns <code>true</code> if the receiver is visible, and * <code>false</code> otherwise. * <p> * If one of the receiver's ancestors is not visible or some * other condition makes the receiver not visible, this method * may still indicate that it is considered visible even though * it may not actually be showing. * </p> * * @return the receiver's visibility state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public boolean getVisible() { checkWidget(); return !hasState( HIDDEN ); } ////////////// // Enablement /** * Enables the receiver if the argument is <code>true</code>, * and disables it otherwise. A disabled control is typically * not selectable from the user interface and draws with an * inactive or "grayed" look. * * @param enabled the new enabled state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setEnabled( boolean enabled ) { checkWidget(); if( hasState( DISABLED ) != !enabled ) { preserveState( DISABLED ); internalSetEnabled( enabled ); } } private void internalSetEnabled( boolean enabled ) { if( hasState( DISABLED ) != !enabled ) { /* * Feature in Windows. If the receiver has focus, disabling * the receiver causes no window to have focus. The fix is * to assign focus to the first ancestor window that takes * focus. If no window will take focus, set focus to the * desktop. */ Control control = null; boolean fixFocus = false; if( !enabled ) { control = display.getFocusControl(); fixFocus = isFocusAncestor( control ); } if( enabled ) { removeState( DISABLED ); } else { addState( DISABLED ); } if( fixFocus ) { fixFocus( control ); } } } /** * Returns <code>true</code> if the receiver is enabled, and * <code>false</code> otherwise. A disabled control is typically * not selectable from the user interface and draws with an * inactive or "grayed" look. * * @return the receiver's enabled state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #isEnabled */ public boolean getEnabled() { checkWidget(); return !hasState( DISABLED ); } /** * Returns <code>true</code> if the receiver is enabled and all * ancestors up to and including the receiver's nearest ancestor * shell are enabled. Otherwise, <code>false</code> is returned. * A disabled control is typically not selectable from the user * interface and draws with an inactive or "grayed" look. * * @return the receiver's enabled state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getEnabled */ public boolean isEnabled() { checkWidget(); return getEnabled() && parent.isEnabled(); } ///////// // Colors /** * Sets the receiver's background color to the color specified * by the argument, or to the default system color for the control * if the argument is null. * * @param color the new color (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBackground( Color color ) { checkWidget(); if( color != null && color.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } getRemoteAdapter().preserveBackground( background, backgroundTransparency ); background = color; updateBackground(); } /** * Returns the receiver's background color. * * @return the background color * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Color getBackground() { checkWidget(); Control control = findBackgroundControl(); if( control == null ) { control = this; } Color result = control.background; if( result == null ) { result = getControlThemeAdapter().getBackground( control ); } Shell shell = control.getShell(); control = control.parent; while( result == null && control != null ) { result = control.getBackground(); control = control == shell ? null : control.parent; } if( result == null ) { // Should never happen as the theming must prevent transparency for // shell background colors throw new IllegalStateException( "Transparent shell background color" ); } return result; } /** * Sets the receiver's background image to the image specified * by the argument, or to the default system color for the control * if the argument is null. The background image is tiled to fill * the available space. * <p> * Note: This operation is a hint and may be overridden by the platform. * For example, on Windows the background of a Button cannot be changed. * </p> * @param image the new image (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * <!-- <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li>--> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.1 */ public void setBackgroundImage( Image image ) { checkWidget(); if( image != null && image.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } if( backgroundImage != image ) { getRemoteAdapter().preserveBackgroundImage( backgroundImage ); backgroundImage = image; } } /** * Returns the receiver's background image. * * @return the background image * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.1 */ public Image getBackgroundImage() { checkWidget(); Control control = findBackgroundControl(); if( control == null ) { control = this; } return control.backgroundImage; } /** * Sets the receiver's foreground color to the color specified * by the argument, or to the default system color for the control * if the argument is null. * * @param color the new color (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setForeground( Color color ) { checkWidget(); if( color != null && color.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } getRemoteAdapter().preserveForeground( foreground ); foreground = color; } /** * Returns the foreground color that the receiver will use to draw. * * @return the receiver's foreground color * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Color getForeground() { checkWidget(); Color result = foreground; if( result == null ) { result = getControlThemeAdapter().getForeground( this ); } if( result == null ) { // Should never happen as the theming must prevent transparency for // foreground colors throw new IllegalStateException( "Transparent foreground color" ); } return result; } void updateBackgroundMode() { boolean oldState = hasState( PARENT_BACKGROUND ); checkBackground(); if( oldState != hasState( PARENT_BACKGROUND ) ) { updateBackground(); } } /* * Checks whether parent background should be applied to this control and and * sets PARENT_BACKGROUND state if so. */ // verbatim copy of SWT 3.7.0 GTK void checkBackground () { Shell shell = getShell (); if (this == shell) { return; } removeState( PARENT_BACKGROUND ); Composite composite = parent; do { int mode = composite.backgroundMode; if (mode != SWT.INHERIT_NONE) { if (mode == SWT.INHERIT_DEFAULT) { Control control = this; do { if( !control.hasState( THEME_BACKGROUND ) ) { return; } control = control.parent; } while (control != composite); } addState( PARENT_BACKGROUND ); return; } if (composite == shell) { break; } composite = composite._getParent(); } while (true); } /** * Applies the background according to PARENT_BACKGROUND state. */ private void updateBackground() { getRemoteAdapter().preserveBackground( background, backgroundTransparency ); backgroundTransparency = background == null && backgroundImage == null && hasState( PARENT_BACKGROUND ); } Control findBackgroundControl() { Control result = null; if( background != null || backgroundImage != null ) { result = this; } else if( hasState( PARENT_BACKGROUND ) ) { result = parent.findBackgroundControl(); } return result; } void checkMirrored() { if( ( style & SWT.RIGHT_TO_LEFT ) != 0 ) { style |= SWT.MIRRORED; } } ///////// // Fonts /** * Sets the font that the receiver will use to paint textual information * to the font specified by the argument, or to the default font for that * kind of control if the argument is null. * * @param font the new font (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setFont( Font font ) { checkWidget(); if( font != null && font.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } getRemoteAdapter().preserveFont( this.font ); this.font = font; } /** * Returns the font that the receiver will use to paint textual information. * * @return the receiver's font * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Font getFont() { checkWidget(); Font result = font; if( result == null ) { result = getControlThemeAdapter().getFont( this ); } return result; } ///////// // Cursors /** * Sets the receiver's cursor to the cursor specified by the * argument, or to the default cursor for that kind of control * if the argument is null. * <p> * When the mouse pointer passes over a control its appearance * is changed to match the control's cursor. * </p> * * @param cursor the new cursor (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.2 */ public void setCursor( Cursor cursor ) { checkWidget(); if( cursor != null && cursor.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } getRemoteAdapter().preserveCursor( this.cursor ); this.cursor = cursor; } /** * Returns the receiver's cursor, or null if it has not been set. * <p> * When the mouse pointer passes over a control its appearance * is changed to match the control's cursor. * </p> * * @return the receiver's cursor or <code>null</code> * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.2 */ public Cursor getCursor() { checkWidget(); return cursor; } ////////////////// // Focus handling /** * Causes the receiver to have the <em>keyboard focus</em>, * such that all keyboard events will be delivered to it. Focus * reassignment will respect applicable platform constraints. * * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #forceFocus */ public boolean setFocus() { checkWidget(); boolean result = false; if( ( style & SWT.NO_FOCUS ) == 0 ) { result = forceFocus(); } return result; } /** * Forces the receiver to have the <em>keyboard focus</em>, causing * all keyboard events to be delivered to it. * * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #setFocus */ public boolean forceFocus() { checkWidget(); // if (display.focusEvent == SWT.FocusOut) return false; Shell shell = getShell(); // was: Decorations shell = menuShell(); shell.setSavedFocus( this ); if( !isEnabled() || !isVisible() || !isActive() ) { return false; } if( isFocusControl() ) { return true; } shell.setSavedFocus( null ); setFocusControl( this ); // was: OS.SetFocus( handle ); if( isDisposed() ) { return false; } shell.setSavedFocus( this ); return isFocusControl(); } /** * Returns <code>true</code> if the receiver has the user-interface * focus, and <code>false</code> otherwise. * * @return the receiver's focus state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public boolean isFocusControl() { checkWidget(); return this == getDisplay().getFocusControl(); } boolean setSavedFocus() { return forceFocus(); } /////////////////////////////////////////////////////////////////////// // Methods to manipulate, transform and query the controls' dimensions /** * Returns a rectangle describing the receiver's size and location * relative to its parent (or its display if its parent is null), * unless the receiver is a shell. In this case, the location is * relative to the display. * * @return the receiver's bounding rectangle * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Rectangle getBounds() { checkWidget(); return new Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ); } /** * Sets the receiver's size and location to the rectangular * area specified by the argument. The <code>x</code> and * <code>y</code> fields of the rectangle are relative to * the receiver's parent (or its display if its parent is null). * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param bounds the new bounds for the receiver * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBounds( Rectangle bounds ) { checkWidget(); if( bounds == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } setBounds( bounds, true ); } /** * Sets the receiver's size and location to the rectangular * area specified by the arguments. The <code>x</code> and * <code>y</code> arguments are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the <code>x</code> * and <code>y</code> arguments are relative to the display. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param x the new x coordinate for the receiver * @param y the new y coordinate for the receiver * @param width the new width for the receiver * @param height the new height for the receiver * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBounds( int x, int y, int width, int height ) { setBounds( new Rectangle( x, y, width, height ) ); } /** * Sets the receiver's location to the point specified by * the arguments which are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @param location the new location for the receiver * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLocation( Point location ) { if( location == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } Rectangle newBounds = new Rectangle( location.x, location.y, bounds.width, bounds.height ); setBounds( newBounds ); } /** * Sets the receiver's location to the point specified by * the arguments which are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @param x the new x coordinate for the receiver * @param y the new y coordinate for the receiver * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLocation( int x, int y ) { setLocation( new Point( x, y ) ); } /** * Returns a point describing the receiver's location relative * to its parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @return the receiver's location * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point getLocation() { checkWidget(); return new Point( bounds.x, bounds.y ); } /** * Sets the receiver's size to the point specified by the argument. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause them to be * set to zero instead. * </p> * * @param size the new size for the receiver * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setSize( Point size ) { if( size == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } setBounds( new Rectangle( bounds.x, bounds.y, size.x, size.y ) ); } /** * Sets the receiver's size to the point specified by the arguments. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param width the new width for the receiver * @param height the new height for the receiver * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setSize( int width, int height ) { setSize( new Point( width, height ) ); } /** * Returns a point describing the receiver's size. The * x coordinate of the result is the width of the receiver. * The y coordinate of the result is the height of the * receiver. * * @return the receiver's size * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point getSize() { checkWidget(); return new Point( bounds.width, bounds.height ); } /** * Returns the preferred size of the receiver. * <p> * The <em>preferred size</em> of a control is the size that it would * best be displayed at. The width hint and height hint arguments * allow the caller to ask a control questions such as "Given a particular * width, how high does the control need to be to show all of the contents?" * To indicate that the caller does not wish to constrain a particular * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. * </p> * * @param wHint the width hint (can be <code>SWT.DEFAULT</code>) * @param hHint the height hint (can be <code>SWT.DEFAULT</code>) * @return the preferred size of the control * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Layout * @see #getBorderWidth * @see #getBounds * @see #getSize * @see #pack(boolean) * @see "computeTrim, getClientArea for controls that implement them" */ public Point computeSize( int wHint, int hHint ) { return computeSize( wHint, hHint, true ); } /** * Returns the preferred size of the receiver. * <p> * The <em>preferred size</em> of a control is the size that it would * best be displayed at. The width hint and height hint arguments * allow the caller to ask a control questions such as "Given a particular * width, how high does the control need to be to show all of the contents?" * To indicate that the caller does not wish to constrain a particular * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. * </p><p> * If the changed flag is <code>true</code>, it indicates that the receiver's * <em>contents</em> have changed, therefore any caches that a layout manager * containing the control may have been keeping need to be flushed. When the * control is resized, the changed flag will be <code>false</code>, so layout * manager caches can be retained. * </p> * * @param wHint the width hint (can be <code>SWT.DEFAULT</code>) * @param hHint the height hint (can be <code>SWT.DEFAULT</code>) * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise * @return the preferred size of the control. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Layout * @see #getBorderWidth * @see #getBounds * @see #getSize * @see #pack(boolean) * @see "computeTrim, getClientArea for controls that implement them" */ public Point computeSize( int wHint, int hHint, boolean changed ) { checkWidget(); int width = DEFAULT_WIDTH; int height = DEFAULT_HEIGHT; if( wHint != SWT.DEFAULT ) { width = wHint; } if( hHint != SWT.DEFAULT ) { height = hHint; } BoxDimensions border = getBorder(); width += border.left + border.right; height += border.top + border.bottom; return new Point( width, height ); } /** * Causes the receiver to be resized to its preferred size. * For a composite, this involves computing the preferred size * from its layout, if there is one. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #computeSize(int, int, boolean) */ public void pack() { checkWidget(); pack( true ); } /** * Causes the receiver to be resized to its preferred size. * For a composite, this involves computing the preferred size * from its layout, if there is one. * <p> * If the changed flag is <code>true</code>, it indicates that the receiver's * <em>contents</em> have changed, therefore any caches that a layout manager * containing the control may have been keeping need to be flushed. When the * control is resized, the changed flag will be <code>false</code>, so layout * manager caches can be retained. * </p> * * @param changed whether or not the receiver's contents have changed * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #computeSize(int, int, boolean) */ public void pack( boolean changed ) { checkWidget(); setSize( computeSize( SWT.DEFAULT, SWT.DEFAULT, changed ) ); packed = true; } /** * Returns the receiver's border width. * Note: When the theming defines different border widths for the four edges, this method returns * the maximum border width. * * @return the border width * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public int getBorderWidth() { checkWidget(); BoxDimensions border = getBorder(); int max1 = Math.max( border.left, border.right ); int max2 = Math.max( border.top, border.bottom ); return Math.max( max1, max2 ); } BoxDimensions getBorder() { return getControlThemeAdapter().getBorder( this ); } BoxDimensions getPadding() { if( bufferedPadding == null ) { bufferedPadding = getControlThemeAdapter().getPadding( this ); } return bufferedPadding; } private ControlThemeAdapter getControlThemeAdapter() { return getAdapter( ControlThemeAdapter.class ); } /** * Returns a point which is the result of converting the * argument, which is specified in display relative coordinates, * to coordinates relative to the receiver. * <p> * @param x the x coordinate to be translated * @param y the y coordinate to be translated * @return the translated coordinates * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toControl( int x, int y ) { checkWidget(); return getDisplay().map( null, this, x, y ); } /** * Returns a point which is the result of converting the * argument, which is specified in display relative coordinates, * to coordinates relative to the receiver. * <p> * @param point the point to be translated (must not be null) * @return the translated coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toControl( Point point ) { checkWidget(); if( point == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } return toControl( point.x, point.y ); } /** * Returns a point which is the result of converting the * argument, which is specified in coordinates relative to * the receiver, to display relative coordinates. * <p> * @param x the x coordinate to be translated * @param y the y coordinate to be translated * @return the translated coordinates * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toDisplay( int x, int y ) { checkWidget(); return getDisplay().map( this, null, x, y ); } /** * Returns a point which is the result of converting the * argument, which is specified in coordinates relative to * the receiver, to display relative coordinates. * <p> * @param point the point to be translated (must not be null) * @return the translated coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toDisplay( Point point ) { checkWidget(); if( point == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } return toDisplay( point.x, point.y ); } /////////////////////////// // Layout related methods /** * Returns layout data which is associated with the receiver. * * @return the receiver's layout data * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Object getLayoutData() { checkWidget(); return layoutData; } /** * Sets the layout data associated with the receiver to the argument. * * @param layoutData the new layout data for the receiver. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLayoutData( Object layoutData ) { checkWidget(); this.layoutData = layoutData; } @SuppressWarnings( "unused" ) void markLayout( boolean changed, boolean all ) { /* Do nothing */ } @SuppressWarnings( "unused" ) void updateLayout( boolean resize, boolean all ) { /* Do nothing */ } ///////////////////// // ToolTip operations /** * Sets the receiver's tool tip text to the argument, which * may be null indicating that no tool tip text should be shown. * * @param toolTipText the new tool tip text (or null) * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setToolTipText( String toolTipText ) { checkWidget(); if( toolTipText != null && isToolTipMarkupEnabledFor( this ) && !isValidationDisabledFor( this ) ) { MarkupValidator.getInstance().validate( toolTipText ); } getRemoteAdapter().preserveToolTipText( this.toolTipText ); this.toolTipText = toolTipText; } /** * Returns the receiver's tool tip text, or null if it has * not been set. * * @return the receiver's tool tip text * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public String getToolTipText() { checkWidget(); return toolTipText; } /////////////////// // Menu operations /** * Sets the receiver's pop up menu to the argument. * All controls may optionally have a pop up * menu that is displayed when the user requests one for * the control. The sequence of key strokes, button presses * and/or button releases that are used to request a pop up * menu is platform specific. * <p> * Note: Disposing of a control that has a pop up menu will * dispose of the menu. To avoid this behavior, set the * menu to null before the control is disposed. * </p> * * @param menu the new pop up menu * * @exception IllegalArgumentException <ul> * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li> * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li> * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setMenu( Menu menu ) { checkWidget(); if( this.menu != menu ) { if( menu != null ) { if( menu.isDisposed() ) { SWT.error( SWT.ERROR_INVALID_ARGUMENT ); } if( ( menu.getStyle() & SWT.POP_UP ) == 0 ) { SWT.error( SWT.ERROR_MENU_NOT_POP_UP ); } if( menu.getParent() != getShell() ) { SWT.error( SWT.ERROR_INVALID_PARENT ); } } removeMenuDisposeListener(); _setMenu( menu ); addMenuDisposeListener(); } } /** * Returns the receiver's pop up menu if it has one, or null * if it does not. All controls may optionally have a pop up * menu that is displayed when the user requests one for * the control. The sequence of key strokes, button presses * and/or button releases that are used to request a pop up * menu is platform specific. * * @return the receiver's menu * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Menu getMenu() { checkWidget(); return menu; } /////////// // Z-Order /** * Moves the receiver above the specified control in the * drawing order. If the argument is null, then the receiver * is moved to the top of the drawing order. The control at * the top of the drawing order will not be covered by other * controls even if they occupy intersecting areas. * * @param control the sibling control (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Control#moveBelow * @see Composite#getChildren */ public void moveAbove( Control control ) { checkWidget(); if( control != null && control.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } if( this instanceof Shell ) { // TODO: add support for Shell reordering } else if( control == null || control.parent == parent && control != this ) { parent.moveAbove( this, control ); } } /** * Moves the receiver below the specified control in the * drawing order. If the argument is null, then the receiver * is moved to the bottom of the drawing order. The control at * the bottom of the drawing order will be covered by all other * controls which occupy intersecting areas. * * @param control the sibling control (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Control#moveAbove * @see Composite#getChildren */ public void moveBelow( Control control ) { checkWidget(); if( control != null && control.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } if( this instanceof Shell ) { // TODO: add support for Shell reordering } else if( control == null || control.parent == parent && control != this ) { parent.moveBelow( this, control ); } } @Override @SuppressWarnings("unchecked") public <T> T getAdapter( Class<T> adapter ) { T result = null; if( adapter == IControlAdapter.class ) { if( controlAdapter == null ) { controlAdapter = new ControlAdapter(); } result = ( T )controlAdapter; } else if( adapter == ControlThemeAdapter.class ) { result = ( T )super.getAdapter( ThemeAdapter.class ); } else { result = super.getAdapter( adapter ); } return result; } @Override RemoteAdapter createRemoteAdapter( Widget parent, String id ) { ControlRemoteAdapter remoteAdapter = new ControlRemoteAdapter( id ); remoteAdapter.setParent( parent ); return remoteAdapter; } ////////////////////////////////// // Methods to add/remove listener /** * Adds the listener to the collection of listeners who will * be notified when the control is moved or resized, by sending * it one of the messages defined in the <code>ControlListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see ControlListener * @see #removeControlListener */ public void addControlListener( ControlListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.Move, typedListener ); addListener( SWT.Resize, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when the control is moved or resized. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see ControlListener * @see #addControlListener */ public void removeControlListener( ControlListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.Move, listener ); removeListener( SWT.Resize, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when mouse buttons are pressed and released, by sending * it one of the messages defined in the <code>MouseListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseListener * @see #removeMouseListener * * @since 1.1 */ public void addMouseListener( MouseListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.MouseDown, typedListener ); addListener( SWT.MouseUp, typedListener ); addListener( SWT.MouseDoubleClick, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when mouse buttons are pressed and released. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseListener * @see #addMouseListener * * @since 1.1 */ public void removeMouseListener( MouseListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.MouseDown, listener ); removeListener( SWT.MouseUp, listener ); removeListener( SWT.MouseDoubleClick, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when keys are pressed and released on the system keyboard, by sending * it one of the messages defined in the <code>KeyListener</code> * interface. * <!-- * TODO [rh] investigate whether this statements is true in RWT as well * <p> * When a key listener is added to a control, the control * will take part in widget traversal. By default, all * traversal keys (such as the tab key and so on) are * delivered to the control. In order for a control to take * part in traversal, it should listen for traversal events. * Otherwise, the user can traverse into a control but not * out. Note that native controls such as table and tree * implement key traversal in the operating system. It is * not necessary to add traversal listeners for these controls, * unless you want to override the default traversal. * </p> * --> * <!-- RAP specific --> * <p> * <strong>Note:</strong> the key events in RWT are not meant for * general purpose. * </p> * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see KeyListener * @see #removeKeyListener * * @since 1.2 */ public void addKeyListener( KeyListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.KeyUp, typedListener ); addListener( SWT.KeyDown, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when keys are pressed and released on the system keyboard. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see KeyListener * @see #addKeyListener * * @since 1.2 */ public void removeKeyListener( KeyListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.KeyUp, listener ); removeListener( SWT.KeyDown, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when traversal events occur, by sending it * one of the messages defined in the <code>TraverseListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TraverseListener * @see #removeTraverseListener * * @since 1.2 */ public void addTraverseListener( TraverseListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.Traverse, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when traversal events occur. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TraverseListener * @see #addTraverseListener * * @since 1.2 */ public void removeTraverseListener( TraverseListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.Traverse, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when the control gains or loses focus, by sending * it one of the messages defined in the <code>FocusListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see FocusListener * @see #removeFocusListener */ public void addFocusListener( FocusListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.FocusIn, typedListener ); addListener( SWT.FocusOut, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when the control gains or loses focus. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see FocusListener * @see #addFocusListener */ public void removeFocusListener( FocusListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.FocusIn, listener ); removeListener( SWT.FocusOut, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when help events are generated for the control, * by sending it one of the messages defined in the * <code>HelpListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see HelpListener * @see #removeHelpListener * @since 1.3 */ public void addHelpListener( HelpListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.Help, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when the help events are generated for the control. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see HelpListener * @see #addHelpListener * @since 1.3 */ public void removeHelpListener( HelpListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.Help, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when a drag gesture occurs, by sending it * one of the messages defined in the <code>DragDetectListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #removeDragDetectListener * * @since 1.3 */ public void addDragDetectListener( DragDetectListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.DragDetect, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when a drag gesture occurs. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #addDragDetectListener * * @since 1.3 */ public void removeDragDetectListener( DragDetectListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.DragDetect, listener ); } /** * Adds the listener to the collection of listeners who will * be notified when the platform-specific context menu trigger * has occurred, by sending it one of the messages defined in * the <code>MenuDetectListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that * created the receiver</li> * </ul> * * @see MenuDetectListener * @see #removeMenuDetectListener * * @since 1.3 */ public void addMenuDetectListener( MenuDetectListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } TypedListener typedListener = new TypedListener( listener ); addListener( SWT.MenuDetect, typedListener ); } /** * Removes the listener from the collection of listeners who will * be notified when the platform-specific context menu trigger has * occurred. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MenuDetectListener * @see #addMenuDetectListener * * @since 1.3 */ public void removeMenuDetectListener( MenuDetectListener listener ) { checkWidget(); if( listener == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } removeListener( SWT.MenuDetect, listener ); } /** * Requests that this control and all of its ancestors be repositioned * their layouts at the earliest opportunity. This should be invoked after * modifying the control in order to inform any dependent layouts of * the change. * <p> * The control will not be repositioned synchronously. This method is * fast-running and only marks the control for future participation in * a deferred layout. * <p> * Invoking this method multiple times before the layout occurs is an * inexpensive no-op. * * @since 3.1 */ public void requestLayout() { getShell().layout( new Control[] { this }, SWT.DEFER ); } //////////////// // drawing (Note that we can't really force a redraw. This is just a // fake for event notifications that come on OS systems with redraws) /** * If the argument is <code>false</code>, causes subsequent drawing * operations in the receiver to be ignored. No drawing of any kind * can occur in the receiver until the flag is set to true. * Graphics operations that occurred while the flag was * <code>false</code> are lost. When the flag is set to <code>true</code>, * the entire widget is marked as needing to be redrawn. Nested calls * to this method are stacked. * <p> * Note: This operation is a hint and may not be supported on some * platforms or for some widgets. * </p> * <p> * Note: With RAP we can't really force a redraw. This is just a * fake to enable event notifications that come on OS systems * with redraws. * </p> * * @param redraw the new redraw state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setRedraw( boolean redraw ) { checkWidget(); internalSetRedraw( redraw ); } /** * Causes the entire bounds of the receiver to be marked * as needing to be redrawn. * * <p> * Note: With RAP we can't really force a redraw. This is just a * fake to enable event notifications that come on OS systems * with redraws. * </p> * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void redraw() { checkWidget(); internalSetRedraw( true ); } /** * Causes the rectangular area of the receiver specified by * the arguments to be marked as needing to be redrawn. * The next time a paint request is processed, that area of * the receiver will be painted, including the background. * If the <code>all</code> flag is <code>true</code>, any * children of the receiver which intersect with the specified * area will also paint their intersecting areas. If the * <code>all</code> flag is <code>false</code>, the children * will not be painted. * * @param x the x coordinate of the area to draw * @param y the y coordinate of the area to draw * @param width the width of the area to draw * @param height the height of the area to draw * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #update() * @see PaintListener * @see SWT#NO_BACKGROUND * @see SWT#NO_REDRAW_RESIZE * @see SWT#NO_MERGE_PAINTS * @see SWT#DOUBLE_BUFFERED * @since 1.3 */ // * @see SWT#Paint public void redraw( int x, int y, int width, int height, boolean all ) { checkWidget(); if( width > 0 && height > 0 ) { internalSetRedraw( true, x, y, width, height ); } } void internalSetRedraw( boolean redraw ) { display.redrawControl( this, redraw ); } @SuppressWarnings( "unused" ) void internalSetRedraw( boolean redraw, int x, int y, int width, int height ) { display.redrawControl( this, redraw ); } /** * Forces all outstanding paint requests for the widget * to be processed before this method returns. If there * are no outstanding paint request, this method does * nothing. * <p> * Note: This method does not cause a redraw. * </p> * * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.3 */ public void update() { checkWidget(); } /** * Changes the parent of the widget to be the one provided if * the underlying operating system supports this feature. * Returns <code>true</code> if the parent is successfully changed. * * @param parent the new parent for the control. * @return <code>true</code> if the parent is changed and <code>false</code> otherwise. * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.3 */ public boolean setParent( Composite parent ) { checkWidget(); if( parent == null ) { error( SWT.ERROR_NULL_ARGUMENT ); } if( parent.isDisposed() ) { error( SWT.ERROR_INVALID_ARGUMENT ); } if( !isReparentable() ) { return false; } if( this.parent != parent ) { releaseParent(); Shell newShell = parent.getShell(); Shell oldShell = getShell(); Decorations newDecorations = parent.menuShell(); Decorations oldDecorations = menuShell(); if( oldShell != newShell || oldDecorations != newDecorations ) { fixChildren( newShell, oldShell, newDecorations, oldDecorations ); } getRemoteAdapter().preserveParent( this.parent ); ReparentedControls.add( this ); this.parent = parent; parent.addChild( this ); } return true; } /** * Returns <code>true</code> if the underlying operating * system supports this reparenting, otherwise <code>false</code> * * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code> * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.3 */ public boolean isReparentable() { checkWidget(); return true; } /** * Sets the orientation of the receiver, which must be one * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>. * * @param orientation new orientation style * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.4 */ public void setOrientation( int orientation ) { checkWidget(); int flags = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT; if( ( orientation & flags ) == 0 || ( orientation & flags ) == flags ) { return; } getRemoteAdapter().preserveOrientation( style & flags ); style &= ~SWT.MIRRORED; style &= ~flags; style |= orientation & flags; updateOrientation(); checkMirrored(); } /** * Returns the orientation of the receiver, which will be one of the * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>. * * @return the orientation style * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.4 */ public int getOrientation() { checkWidget(); return style & ( SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT ); } void updateOrientation() { // subclasses may override } //////////////// // Accessibility /** * Returns the accessible object for the receiver. * <p> * If this is the first time this object is requested, * then the object is created and returned. The object * returned by getAccessible() does not need to be disposed. * </p> * * @return the accessible object * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Accessible#addAccessibleListener * @see Accessible#addAccessibleControlListener * * @since 1.4 */ public Accessible getAccessible() { checkWidget(); if( accessible == null ) { accessible = Accessible.internal_new_Accessible( this ); } return accessible; } //////////////////// // Touch and Gesture /** * Adds the listener to the collection of listeners who will * be notified when gesture events are generated for the control, * by sending it one of the messages defined in the * <code>GestureListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see GestureListener * @see #removeGestureListener * * @since 1.4 */ public void addGestureListener( GestureListener listener ) { checkWidget(); } /** * Removes the listener from the collection of listeners who will * be notified when gesture events are generated for the control. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see GestureListener * @see #addGestureListener * * @since 1.4 */ public void removeGestureListener( GestureListener listener ) { checkWidget(); } /** * Adds the listener to the collection of listeners who will * be notified when touch events occur, by sending it * one of the messages defined in the <code>TouchListener</code> * interface. * <p> * NOTE: You must also call <code>setTouchEnabled</code> to notify the * windowing toolkit that you want touch events to be generated. * </p> * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TouchListener * @see #removeTouchListener * * @since 1.4 */ public void addTouchListener( TouchListener listener ) { checkWidget(); } /** * Removes the listener from the collection of listeners who will * be notified when touch events occur. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TouchListener * @see #addTouchListener * * @since 1.4 */ public void removeTouchListener( TouchListener listener ) { checkWidget(); } /** * Sets whether the receiver should accept touch events. By default, a Control does not accept * touch events. No error or exception is thrown if the underlying hardware does not support touch * input. * * @param enabled the new touch-enabled state * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * * @since 1.4 */ public void setTouchEnabled( boolean enabled ) { checkWidget(); } /** * Returns <code>true</code> if this control is receiving OS-level touch events, * otherwise <code>false</code> * <p> * Note that this method will return false if the current platform does not support touch-based * input. If this method does return true, gesture events will not be sent to the control. * * @return <code>true</code> if the widget is currently receiving touch events; <code>false</code> * otherwise. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 1.4 */ public boolean getTouchEnabled() { checkWidget(); return false; } @Override public void setData( String key, Object value ) { if( RWT.TOOLTIP_MARKUP_ENABLED.equals( key ) && isToolTipMarkupEnabledFor( this ) ) { // MARKUP_ENABLED cannot be changed once it is set return; } if( RWT.ACTIVE_KEYS.equals( key ) ) { if( value != null && !( value instanceof String[] ) ) { String mesg = "Illegal value for RWT.ACTIVE_KEYS in data, must be a string array"; throw new IllegalArgumentException( mesg ); } ActiveKeysUtil.preserveActiveKeys( this ); } if( RWT.CANCEL_KEYS.equals( key ) ) { if( value != null && !( value instanceof String[] ) ) { String mesg = "Illegal value for RWT.CANCEL_KEYS in data, must be a string array"; throw new IllegalArgumentException( mesg ); } ActiveKeysUtil.preserveCancelKeys( this ); } if( RWT.CUSTOM_VARIANT.equals( key ) ) { bufferedPadding = null; } super.setData( key, value ); } //////////// // Disposal @Override void releaseParent() { if( parent != null ) { parent.removeChild( this ); } } @Override void releaseWidget() { if( menu != null ) { removeMenuDisposeListener(); menu.dispose(); menu = null; } Shell shell = internalGetShell(); if( display.getFocusControl() == this ) { Control focusControl = parent; while( focusControl != null && focusControl.isInDispose() ) { focusControl = focusControl.getParent(); } if( focusControl != null && focusControl.internalGetShell() != shell ) { focusControl = null; } setFocusControl( focusControl ); } if( shell.getSavedFocus() == this ) { shell.setSavedFocus( null ); } internalSetRedraw( false ); if( accessible != null ) { accessible.internal_dispose_Accessible(); } accessible = null; super.releaseWidget(); } ///////////// // Tab order boolean isTabGroup() { Control[] tabList = parent._getTabList(); if( tabList != null ) { for( int i = 0; i < tabList.length; i++ ) { if( tabList[ i ] == this ) { return true; } } } return false; } //////////////////////////////// // Helping methods for setBounds void setBounds( Rectangle bounds, boolean updateMode ) { Point oldLocation = getLocation(); Point oldSize = getSize(); _setBounds( new Rectangle( bounds.x, bounds.y, bounds.width, bounds.height ) ); if( updateMode ) { updateMode(); } clearPacked( oldSize ); notifyMove( oldLocation ); notifyResize( oldSize ); } void _setBounds( Rectangle rectangle ) { getRemoteAdapter().preserveBounds( bounds ); bounds = rectangle; bounds.width = Math.max( 0, bounds.width ); bounds.height = Math.max( 0, bounds.height ); } private void _setMenu( Menu menu ) { getRemoteAdapter().preserveMenu( this.menu ); this.menu = menu; } void updateMode() { // subclasses may override } private void clearPacked( Point oldSize ) { if( !oldSize.equals( getSize() ) ) { packed = false; } } void notifyResize( Point oldSize ) { if( !oldSize.equals( getSize() ) ) { notifyListeners( SWT.Resize, new Event() ); } } void notifyMove( Point oldLocation ) { if( !oldLocation.equals( getLocation() ) ) { notifyListeners( SWT.Move, new Event() ); } } //////////////////////// // Focus helping methods private void setFocusControl( Control control ) { if( control != null ) { display.setActiveShell( control.getShell() ); } // focus IDisplayAdapter displayAdapter = display.getAdapter( IDisplayAdapter.class ); displayAdapter.setFocusControl( control, true ); // active if( control != null ) { Shell shell = control.getShell(); shell.setActiveControl( control ); } } Control[] getPath() { int count = 0; Shell shell = getShell(); Control control = this; while( control != shell ) { count++; control = control.parent; } control = this; Control[] result = new Control[ count ]; while( control != shell ) { result[ --count ] = control; control = control.parent; } return result; } // Copied from SWT/win32 as is @SuppressWarnings("all") boolean isFocusAncestor (Control control) { while (control != null && control != this && !(control instanceof Shell)) { control = control.parent; } return control == this; } // Copied from SWT/win32 as is void fixFocus ( Control focusControl) { Shell shell = getShell (); Control control = this; while (control != shell && (control = control.parent) != null) { if (control.setFixedFocus ()) { return; } } shell.setSavedFocus (focusControl); // OS.SetFocus (0); // Replacement for OS.setFocus( 0 ) IDisplayAdapter displayAdapter = display.getAdapter( IDisplayAdapter.class ); displayAdapter.setFocusControl( null, true ); } // Copied from SWT/win32 as is boolean setFixedFocus () { if ((style & SWT.NO_FOCUS) != 0) { return false; } return forceFocus (); } boolean isActive() { Shell shell = getShell(); boolean result = shell.getEnabled(); Shell[] allShells = getDisplay().getShells(); int bits = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL; int shellIndex = allShells.length; for( int i = 0; i < allShells.length && result; i++ ) { if( allShells[ i ] == shell ) { shellIndex = i; } if( ( allShells[ i ].style & bits ) != 0 && shellIndex < i ) { result = false; } } return result; } Decorations menuShell() { return parent.menuShell(); } void fixChildren( Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations ) { oldShell.fixShell( newShell, this ); oldDecorations.fixDecorations( newDecorations, this ); } private void preserveState( int flag ) { if( ( flag & DISABLED ) != 0 ) { getRemoteAdapter().preserveEnabled( !hasState( DISABLED ) ); } if( ( flag & HIDDEN ) != 0 ) { getRemoteAdapter().preserveVisible( !hasState( HIDDEN ) ); } } private void addMenuDisposeListener() { if( menu != null ) { if( menuDisposeListener == null ) { menuDisposeListener = new Listener() { @Override public void handleEvent( Event event ) { _setMenu( null ); } }; } menu.addListener( SWT.Dispose, menuDisposeListener ); } } private void removeMenuDisposeListener() { if( menu != null ) { menu.removeListener( SWT.Dispose, menuDisposeListener ); } } private ControlRemoteAdapter getRemoteAdapter() { return ( ControlRemoteAdapter )getAdapter( RemoteAdapter.class ); } }