org.eclipse.swt.widgets.Decorations.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.swt.widgets.Decorations.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2015 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 org.eclipse.rap.rwt.internal.lifecycle.ProcessActionRunner;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.internal.widgets.MenuHolder;

/**
 * <p>This class was introduced to be API compatible with SWT and does only
 * provide those methods that are absolutely necessary to serve this purpose.
 * </p>
 */
public class Decorations extends Canvas {

    private Menu menuBar;
    private MenuHolder menuHolder;
    private DisposeListener menuBarDisposeListener;
    private Image image;
    private Image[] images;
    private String text;
    private Button defaultButton;
    private Button saveDefault;
    private Listener defaultButtonFocusListener;
    private Control savedFocus;

    Decorations(Composite parent) {
        // prevent instantiation from outside this package
        super(parent);
        images = new Image[0];
        text = "";
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getAdapter(Class<T> adapter) {
        if (adapter == MenuHolder.class) {
            if (menuHolder == null) {
                menuHolder = new MenuHolder();
            }
            return (T) menuHolder;
        }
        return super.getAdapter(adapter);
    }

    /**
     * Sets the receiver's images to the argument, which may
     * be an empty array. Images are typically displayed by the
     * window manager when the instance is marked as iconified,
     * and may also be displayed somewhere in the trim when the
     * instance is in normal or maximized states. Depending where
     * the icon is displayed, the platform chooses the icon with
     * the "best" attributes. It is expected that the array will
     * contain the same icon rendered at different sizes, with
     * different depth and transparency attributes.
     *
     * @param images the new image array
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
     *    <li>ERROR_INVALID_ARGUMENT - if one of the images is null or 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.3
     */
    public void setImages(Image[] images) {
        checkWidget();
        if (images == null) {
            error(SWT.ERROR_INVALID_ARGUMENT);
        }
        for (int i = 0; i < images.length; i++) {
            if (images[i] == null) {
                error(SWT.ERROR_INVALID_ARGUMENT);
            }
        }
        this.images = images;
    }

    /**
     * Returns the receiver's images if they had previously been
     * set using <code>setImages()</code>. Images are typically
     * displayed by the window manager when the instance is
     * marked as iconified, and may also be displayed somewhere
     * in the trim when the instance is in normal or maximized
     * states. Depending where the icon is displayed, the platform
     * chooses the icon with the "best" attributes.  It is expected
     * that the array will contain the same icon rendered at different
     * sizes, with different depth and transparency attributes.
     *
     * <p>
     * Note: This method will return an empty array if called before
     * <code>setImages()</code> is called. It does not provide
     * access to a window manager provided, "default" image
     * even if one exists.
     * </p>
     *
     * @return the images
     *
     * @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 Image[] getImages() {
        checkWidget();
        return images;
    }

    /**
     * Sets the receiver's image to the argument, which may
     * be null. The image is typically displayed by the window
     * manager when the instance is marked as iconified, and
     * may also be displayed somewhere in the trim when the
     * instance is in normal or maximized states.
     *
     * @param image the new image (or null)
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_INVALID_ARGUMENT - if the image 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 setImage(Image image) {
        checkWidget();
        this.image = image;
    }

    /**
     * Returns the receiver's image if it had previously been
     * set using <code>setImage()</code>. The image is typically
     * displayed by the window manager when the instance is
     * marked as iconified, and may also be displayed somewhere
     * in the trim when the instance is in normal or maximized
     * states.
     * <p>
     * Note: This method will return null if called before
     * <code>setImage()</code> is called. It does not provide
     * access to a window manager provided, "default" image
     * even if one exists.
     * </p>
     *
     * @return the 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>
     */
    public Image getImage() {
        checkWidget();
        return image;
    }

    /**
     * Sets the receiver's text, which is the string that the
     * window manager will typically display as the receiver's
     * <em>title</em>, to the argument, which must not be null.
     *
     * @param text the new text
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_NULL_ARGUMENT - if the text 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>
     * @since 2.2
     */
    public void setText(String text) {
        checkWidget();
        if (text == null) {
            error(SWT.ERROR_NULL_ARGUMENT);
        }
        this.text = text;
    }

    /**
     * Returns the receiver's text, which is the string that the
     * window manager will typically display as the receiver's
     * <em>title</em>. If the text has not previously been set,
     * returns an empty string.
     *
     * @return the 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>
     * @since 2.2
     */
    public String getText() {
        checkWidget();
        return text;
    }

    /**
     * Sets the receiver's menu bar to the argument, which
     * may be null.
     *
     * @param menuBar the new menu bar
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
     *    <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</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 setMenuBar(Menu menuBar) {
        checkWidget();
        if (this.menuBar != menuBar) {
            if (menuBar != null) {
                if (menuBar.isDisposed()) {
                    SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                }
                if (menuBar.getParent() != this) {
                    SWT.error(SWT.ERROR_INVALID_PARENT);
                }
                if ((menuBar.getStyle() & SWT.BAR) == 0) {
                    SWT.error(SWT.ERROR_MENU_NOT_BAR);
                }
            }
            removeMenuBarDisposeListener();
            this.menuBar = menuBar;
            addMenuBarDisposeListener();
        }
    }

    /**
     * Returns the receiver's menu bar if one had previously
     * been set, otherwise returns null.
     *
     * @return the menu bar 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 Menu getMenuBar() {
        checkWidget();
        return menuBar;
    }

    @Override
    public boolean isReparentable() {
        checkWidget();
        return false;
    }

    /**
     * If the argument is not null, sets the receiver's default
     * button to the argument, and if the argument is null, sets
     * the receiver's default button to the first button which
     * was set as the receiver's default button (called the
     * <em>saved default button</em>). If no default button had
     * previously been set, or the saved default button was
     * disposed, the receiver's default button will be set to
     * null.
     * <p>
     * The default button is the button that is selected when
     * the receiver is active and the user presses ENTER.
     * </p>
     *
     * @param button the new default button
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_INVALID_ARGUMENT - if the button has been disposed</li>
     *    <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</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 2.2
     */
    public void setDefaultButton(Button button) {
        checkWidget();
        if (button != null) {
            if (button.isDisposed()) {
                error(SWT.ERROR_INVALID_ARGUMENT);
            }
            if (button.getShell() != this) {
                error(SWT.ERROR_INVALID_PARENT);
            }
        }
        setDefaultButton(button, true);
    }

    /**
     * Returns the receiver's default button if one had
     * previously been set, otherwise returns null.
     *
     * @return the default button 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>
     *
     * @see Shell#setDefaultButton(Button)
     * @since 2.2
     */
    public Button getDefaultButton() {
        checkWidget();
        Button result = null;
        if (defaultButton != null && !defaultButton.isDisposed()) {
            result = defaultButton;
        }
        return result;
    }

    void updateDefaultButton(final Control focusControl, final boolean set) {
        if (isPushButton(focusControl)) {
            ProcessActionRunner.add(new Runnable() {
                @Override
                public void run() {
                    Button defaultButton = (Button) focusControl;
                    updateDefaultButtonFocusListener(defaultButton, set);
                    setDefaultButton(set ? defaultButton : null, false);
                }
            });
        }
    }

    void setDefaultButton(Button button, boolean save) {
        if (button == null) {
            if (defaultButton == saveDefault) {
                if (save) {
                    saveDefault = null;
                }
                return;
            }
        } else {
            if ((button.getStyle() & SWT.PUSH) == 0) {
                return;
            }
            if (button == defaultButton) {
                if (save) {
                    saveDefault = defaultButton;
                }
                return;
            }
        }
        if (defaultButton != null && !defaultButton.isDisposed()) {
            defaultButton.setDefault(false);
        }
        defaultButton = button;
        if (defaultButton == null) {
            defaultButton = saveDefault;
        }
        if (defaultButton != null && !defaultButton.isDisposed()) {
            defaultButton.setDefault(true);
        }
        if (save) {
            saveDefault = defaultButton;
        }
        if (saveDefault != null && saveDefault.isDisposed()) {
            saveDefault = null;
        }
    }

    final void setSavedFocus(Control control) {
        savedFocus = control;
    }

    final Control getSavedFocus() {
        return savedFocus;
    }

    final void saveFocus() {
        Control control = display.getFocusControl();
        if (control != null && control != this && this == control.getShell()) {
            setSavedFocus(control);
        }
    }

    final boolean restoreFocus() {
        if (savedFocus != null && savedFocus.isDisposed()) {
            savedFocus = null;
        }
        boolean result = false;
        if (savedFocus != null && savedFocus.setSavedFocus()) {
            result = true;
        }
        return result;
    }

    @Override
    String getNameText() {
        return getText();
    }

    static int checkStyle(int style) {
        int result = style;
        if ((result & SWT.NO_TRIM) != 0) {
            int trim = (SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.BORDER);
            result &= ~trim;
        }
        if ((result & ( /* SWT.MENU | */ SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
            result |= SWT.TITLE;
        }
        if ((result & (SWT.MIN | SWT.MAX)) != 0) {
            result |= SWT.CLOSE;
        }
        return result;
    }

    @Override
    final void releaseWidget() {
        removeMenuBarDisposeListener();
        super.releaseWidget();
    }

    @Override
    Decorations menuShell() {
        return this;
    }

    void fixDecorations(Decorations newDecorations, Control control) {
        if (newDecorations != this) {
            if (control == savedFocus) {
                savedFocus = null;
            }
            if (control == defaultButton) {
                defaultButton = null;
            }
            if (control == saveDefault) {
                saveDefault = null;
            }
        }
    }

    private void addMenuBarDisposeListener() {
        if (menuBar != null) {
            if (menuBarDisposeListener == null) {
                menuBarDisposeListener = new DisposeListener() {
                    @Override
                    public void widgetDisposed(DisposeEvent event) {
                        Decorations.this.menuBar = null;
                    }
                };
            }
            menuBar.addDisposeListener(menuBarDisposeListener);
        }
    }

    private void removeMenuBarDisposeListener() {
        if (menuBar != null) {
            menuBar.removeDisposeListener(menuBarDisposeListener);
        }
    }

    private static boolean isPushButton(Control control) {
        return control instanceof Button && (control.style & SWT.PUSH) != 0;
    }

    private void updateDefaultButtonFocusListener(Button defaultButton, boolean set) {
        if (!defaultButton.isDisposed()) {
            if (set) {
                defaultButton.addListener(SWT.FocusOut, getDefaultButtonFocusListener());
            } else {
                defaultButton.removeListener(SWT.FocusOut, getDefaultButtonFocusListener());
            }
        }
    }

    private Listener getDefaultButtonFocusListener() {
        if (defaultButtonFocusListener == null) {
            defaultButtonFocusListener = new Listener() {
                @Override
                public void handleEvent(Event event) {
                    // dummy listener - see bug 419920
                }
            };
        }
        return defaultButtonFocusListener;
    }

    ///////////////////
    // Skinning support

    @Override
    void reskinChildren(int flags) {
        if (menuBar != null) {
            menuBar.reskin(flags);
        }
        for (Menu menu : this.getAdapter(MenuHolder.class)) {
            if (menu != null) {
                menu.reskin(flags);
            }
        }
        super.reskinChildren(flags);
    }

}