org.eclipse.emf.eef.runtime.ui.widgets.SWTUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.eef.runtime.ui.widgets.SWTUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2008, 2012 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.eef.runtime.ui.widgets;

import java.awt.Toolkit;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

/**
 * @author <a href="mailto:goulwen.lefur@obeo.fr">Goulwen Le Fur</a>
 */
public final class SWTUtils {

    /**
     * Image registry key for help image (value <code>"dialog_help_image"</code> ).
     */
    public static final String DLG_IMG_HELP = "dialog_help_image"; //$NON-NLS-1$

    /**
     * Create a label describing a properties of the view
     * 
     * @param parent
     *            the parent composite
     * @param text
     *            the label text
     * @param required
     *            defines if the associated properties is required or not
     */
    public static Label createPartLabel(Composite parent, String text, boolean required) {
        Label label = new Label(parent, SWT.NONE);
        label.setText(text);
        if (required)
            label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
        return label;
    }

    /**
     * Creates a button with a help image and put the defined tooltip in parameter.
     * 
     * @param parent
     *            the parent composite
     * @param the
     *            message to use for tooltip
     */
    public static Control createHelpButton(final Composite parent, String helpMessage, String helpID) {
        Image image = JFaceResources.getImage(DLG_IMG_HELP);
        if (helpID != null && !"".equals(helpID)) { //$NON-NLS-1$
            ToolBar result = new ToolBar(parent, SWT.FLAT | SWT.NO_FOCUS);
            ((GridLayout) parent.getLayout()).numColumns++;
            result.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
            ToolItem item = new ToolItem(result, SWT.NONE);
            item.setImage(image);
            if (helpMessage != null && !"".equals(helpMessage)) //$NON-NLS-1$
                item.setToolTipText(helpMessage);
            return result;
        } else {
            CLabel result = new CLabel(parent, SWT.NONE);
            if (helpMessage != null && !"".equals(helpMessage)) { //$NON-NLS-1$
                result.setImage(image);
                result.setToolTipText(helpMessage);
            }
            return result;
        }
    }

    public static final double HEIGHT = 0.66;

    public static final double WIDTH = 0.66;

    public static int getHeight() {
        return (int) (HEIGHT * Toolkit.getDefaultToolkit().getScreenSize().height) + 1;
    }

    public static int getWidth() {
        return (int) (WIDTH * Toolkit.getDefaultToolkit().getScreenSize().width) + 1;
    }

    public static int getEntireWidth() {
        return Toolkit.getDefaultToolkit().getScreenSize().width;
    }

    /** Utility classes don't need default constructors. */
    private SWTUtils() {
        // Hides default constructor.
    }

    /**
     * Creates a {@link SourceViewer} widget that knows how to hide its scroll bars.
     * 
     * @param parent
     *            The parent composite for this viewer.
     * @param style
     *            Style of the created viewer.
     * @return The created {@link SourceViewer}.
     */
    public static SourceViewer createScrollableSourceViewer(Composite parent, int style) {
        SourceViewer viewer = new ScrollableSourceViewer(parent, null, style);

        setUpScrollableListener(viewer.getTextWidget());

        return viewer;
    }

    /**
     * Creates a {@link StyledText} widget that knows how to hide its scroll bars.
     * 
     * @param parent
     *            The parent composite for this text.
     * @param style
     *            Style of the created text.
     * @return The created {@link StyledText} widget.
     */
    public static StyledText createScrollableStyledText(Composite parent, int style) {
        final StyledText text = new StyledText(parent, style);

        // If this text has no scroll bars, simply return it.
        if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0) {
            return text;
        }

        // Otherwise, set up its listeners
        setUpScrollableListener(text);

        return text;
    }

    /**
     * Creates a {@link Text} widget that knows how to hide its scroll bars.
     * 
     * @param parent
     *            The parent composite for this text.
     * @param style
     *            Style of the created text.
     * @return The created {@link Text} widget.
     */
    public static Text createScrollableText(Composite parent, int style) {
        final Text text = new Text(parent, style);

        // If this text has no scroll bars, simply return it.
        if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0) {
            return text;
        }

        // Otherwise, set up its listeners
        setUpScrollableListener(text);

        return text;
    }

    /**
     * Sets up the listeners allowing us to hide the scroll bars of the given scrollable when they are not
     * needed.
     * 
     * @param scrollable
     *            The scrollable widget to setup.
     */
    public static void setUpScrollableListener(final Scrollable scrollable) {
        final ControlAdapter resizeListener = new ScrollableResizeListener(scrollable);
        scrollable.addControlListener(resizeListener);

        final ModifyListener modifyListener = new ScrollableModifyListener(scrollable);
        if (scrollable instanceof Text) {
            ((Text) scrollable).addModifyListener(modifyListener);
        } else if (scrollable instanceof StyledText) {
            ((StyledText) scrollable).addModifyListener(modifyListener);
        }

        scrollable.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                scrollable.removeControlListener(resizeListener);
                if (scrollable instanceof Text) {
                    ((Text) scrollable).removeModifyListener(modifyListener);
                } else if (scrollable instanceof StyledText) {
                    ((StyledText) scrollable).removeModifyListener(modifyListener);
                }
            }
        });
    }

    /**
     * Computes the size of the text displayed by the given {@link Text} widget.
     * 
     * @param widget
     *            The widget on which is displayed the text.
     * @param text
     *            The actual displayed text.
     * @return The actual size of the {@link Text} widget's content.
     */
    protected static Point computeTextSize(Control widget, String text) {
        String[] lines = text.split("\r\n|\n|\r"); //$NON-NLS-1$

        String longestLine = ""; //$NON-NLS-1$
        if (lines.length > 0) {
            longestLine = lines[0];
            for (int i = 0; i < lines.length; i++) {
                if (lines[i].length() > longestLine.length()) {
                    longestLine = lines[i];
                }
            }
        }
        GC gc = new GC(widget);
        gc.setFont(widget.getFont());
        final int textWidth = gc.stringExtent(longestLine).x;
        final int textHeight = gc.stringExtent("W").y * lines.length; //$NON-NLS-1$
        gc.dispose();

        return new Point(textWidth, textHeight);
    }

    /**
     * This will be used as the resize listener for our scrollable text controls in order to determine whether
     * the scroll bars are needed.
     * 
     * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
     */
    protected static class ScrollableModifyListener implements ModifyListener {
        /** The {@link Scrollable} widget against which this listener has been registered. */
        private final Scrollable text;

        /**
         * Instantiates our modify listener for the given text widget.
         * 
         * @param text
         *            The text widget to listen to.
         */
        public ScrollableModifyListener(Scrollable text) {
            this.text = text;
        }

        /**
         * {@inheritDoc}
         * 
         * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
         */
        public void modifyText(ModifyEvent e) {
            final Rectangle clientArea = text.getClientArea();
            final String currentText;
            if (text instanceof Text) {
                currentText = ((Text) text).getText();
            } else if (text instanceof StyledText) {
                currentText = ((StyledText) text).getText();
            } else {
                return;
            }
            final Point textSize = computeTextSize(text, currentText);
            if (clientArea.width > textSize.x && text.getHorizontalBar() != null) {
                text.getHorizontalBar().setVisible(false);
            } else if (text.getHorizontalBar() != null) {
                text.getHorizontalBar().setVisible(true);
            }
            if (clientArea.height > textSize.y && text.getVerticalBar() != null) {
                text.getVerticalBar().setVisible(false);
            } else if (text.getVerticalBar() != null) {
                text.getVerticalBar().setVisible(true);
            }
        }
    }

    /**
     * This will be used as the resize listener for our scrollable text controls in order to determine whether
     * the scroll bars are needed.
     * 
     * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
     */
    protected static class ScrollableResizeListener extends ControlAdapter {
        /** Keeps a reference to the last size we computed. */
        private Point lastSize;

        /** Keeps a reference to the last text we computed a size for. */
        private String lastText;

        /** The {@link Scrollable} widget against which this listener has been registered. */
        private final Scrollable text;

        /**
         * Instantiates our resize listener for the given text widget.
         * 
         * @param text
         *            The text widget to listen to.
         */
        public ScrollableResizeListener(Scrollable text) {
            this.text = text;
        }

        /**
         * {@inheritDoc}
         * 
         * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent)
         */
        @Override
        public void controlResized(ControlEvent e) {
            final Rectangle clientArea = text.getClientArea();
            final String currentText;
            if (text instanceof Text) {
                currentText = ((Text) text).getText();
            } else if (text instanceof StyledText) {
                currentText = ((StyledText) text).getText();
            } else {
                return;
            }
            Point textSize = lastSize;
            if (textSize == null || !lastText.equals(currentText)) {
                textSize = computeTextSize(text, currentText);
                lastText = currentText;
                lastSize = textSize;
            }
            if (clientArea.width > textSize.x && text.getHorizontalBar() != null) {
                text.getHorizontalBar().setVisible(false);
            } else if (text.getHorizontalBar() != null) {
                text.getHorizontalBar().setVisible(true);
            }
            if (clientArea.height > textSize.y && text.getVerticalBar() != null) {
                text.getVerticalBar().setVisible(false);
            } else if (text.getVerticalBar() != null) {
                text.getVerticalBar().setVisible(true);
            }
        }
    }

    /**
     * This subclass of a source viewer will only show its scroll bars if they are needed.
     * 
     * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
     */
    protected static class ScrollableSourceViewer extends SourceViewer {
        /**
         * Constructs a new source viewer. The vertical ruler is initially visible. The viewer has not yet
         * been initialized with a source viewer configuration.
         * 
         * @param parent
         *            the parent of the viewer's control.
         * @param ruler
         *            the vertical ruler used by this source viewer.
         * @param styles
         *            the SWT style bits for the viewer's control,
         *            <em>if <code>SWT.WRAP</code> is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()}.
         */
        public ScrollableSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
            super(parent, ruler, styles);
        }

        /**
         * {@inheritDoc}
         * 
         * @see org.eclipse.jface.text.TextViewer#createTextWidget(org.eclipse.swt.widgets.Composite, int)
         */
        @Override
        protected StyledText createTextWidget(Composite parent, int styles) {
            return super.createTextWidget(parent, styles);
        }
    }
}