org.eclipse.gmf.runtime.common.ui.util.WindowUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.gmf.runtime.common.ui.util.WindowUtil.java

Source

/******************************************************************************
 * Copyright (c) 2002, 2009 IBM Corporation 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:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.common.ui.util;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.util.Geometry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIDebugOptions;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIPlugin;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIStatusCodes;

/**
 * Utilities for windows.
 * 
 * There are also several utility methods that can be used on controls in a
 * window.
 * 
 * @author wdiu, Wayne Diu
 */
public class WindowUtil {
    /**
     * Center the dialog relative to a parent window.
     * @param dialogShell contains the dialog to center
     * @param parentShell contains the window to center relative to
     */
    public static void centerDialog(Shell dialogShell, Shell parentShell) {
        try {
            Point dialogSize = dialogShell.getSize();
            //don't use Display and then get shell from there, since
            //we are trying to find the shell of the whole Eclipse window
            Point windowLocation = parentShell.getLocation();
            Point windowSize = parentShell.getSize();
            //do not take the absolute value.
            dialogShell.setLocation(((windowSize.x - dialogSize.x) / 2) + windowLocation.x,
                    ((windowSize.y - dialogSize.y) / 2) + windowLocation.y);
        } catch (Exception e) {
            //any exception when centering a dialog may be ignored
            Trace.catching(CommonUIPlugin.getDefault(), CommonUIDebugOptions.EXCEPTIONS_CATCHING, WindowUtil.class,
                    "Failed to center dialog", e); //$NON-NLS-1$
            Log.error(CommonUIPlugin.getDefault(), CommonUIStatusCodes.GENERAL_UI_FAILURE,
                    "Failed to center dialog", e); //$NON-NLS-1$
        }
    }

    /**
     * Calculates the position of a window so that it does not run off the
     * screen while taking given initLocation into account. Also, if lowerY is
     * greater than -1 it takes that into account: if the window is moved above
     * requested initLocation.y, than it has to be completely above lowerY. This
     * is needed, for example, when the window is opened by clicking on the
     * button and we don't wont the button to be hidden by this popup.
     * 
     * @param shell
     *            Window shell
     * @param initLocation
     *            the initial location;
     * @param lowerY
     *            if -1, it is ignored; otherwise, if popup is moved up, it has
     *            to be completely above lowerY
     * @return Constrained location
     * @since 1.2
     */
    public static Point constrainWindowLocation(Shell shell, Point initLocation, int lowerY) {
        // First, find the (closest) monitor that contains the popup
        Monitor[] monitors = shell.getDisplay().getMonitors();
        int closest = Integer.MAX_VALUE;
        Monitor closestMonitor = monitors[0];
        Rectangle windowBounds = shell.getBounds();
        Point toFind = Geometry.centerPoint(windowBounds);
        for (int idx = 0; idx < monitors.length; idx++) {
            Monitor current = monitors[idx];
            Rectangle clientArea = current.getClientArea();
            if (clientArea.contains(toFind)) {
                closestMonitor = current;
                break;
            }
            int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind);
            if (distance < closest) {
                closest = distance;
                closestMonitor = current;
            }
        }
        Rectangle monitorBounds = closestMonitor.getClientArea();
        // Find location that ensures that popup stays within the screen.
        int windowX = Math.max(monitorBounds.x,
                Math.min(initLocation.x, monitorBounds.x + monitorBounds.width - windowBounds.width));
        int windowY = Math.max(monitorBounds.y,
                Math.min(initLocation.y, monitorBounds.y + monitorBounds.height - windowBounds.height));

        if (lowerY > -1 && windowY < initLocation.y && windowY + windowBounds.height > lowerY) {
            // popup is moved up and is hiding part or all of the button (or
            // another control that launched the window);
            // make sure it is completely above the button
            windowY = lowerY - windowBounds.height;
        }
        return new Point(windowX, windowY);
    }

    /**
     * Dispose a parent's children
     * 
     * @param parent composite containing children to be disposed.
     */
    public static void disposeChildren(Composite parent) {
        Control[] children = parent.getChildren();
        for (int i = 0; i < children.length; i++) {
            children[i].dispose();
        }
    }

    /**
     * Returns height and width data in a GridData for the button that was
     * passed in.  You can call button.setLayoutData with the returned
     * data.
     * 
     * @param button which has already been made.  We'll be making the
     * GridData for this button, so be sure that the text has already
     * been set.
     * @return GridData for this button with the suggested height and width
     */
    public static GridData makeButtonData(Button button) {
        GC gc = new GC(button);
        gc.setFont(button.getFont());

        GridData data = new GridData();
        data.heightHint = Dialog.convertVerticalDLUsToPixels(gc.getFontMetrics(), 14);
        data.widthHint = Math.max(
                Dialog.convertHorizontalDLUsToPixels(gc.getFontMetrics(), IDialogConstants.BUTTON_WIDTH),
                button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);

        gc.dispose();

        return data;
    }

    /**
     * Makes the GridData for a button to be a fixed size, regardless of
     * the contents of the button
     * @param button the button control that we'll make the GridData for.
     * @return GridData the new GridData for the button control.
     */
    public static GridData makeFixedButtonData(Button button) {
        GC gc = new GC(button);
        gc.setFont(button.getFont());

        GridData gridData = new GridData();

        gridData.widthHint = Dialog.convertHorizontalDLUsToPixels(gc.getFontMetrics(),
                IDialogConstants.BUTTON_WIDTH);

        gridData.heightHint = Dialog.convertVerticalDLUsToPixels(gc.getFontMetrics(), 14);

        gc.dispose();

        return gridData;
    }

    /**
     * Display a message box
     * @param message the String message for the message box
     * @param title the String title for the message box
     * @param swtStyle the int style for the message box
     * @param shell the Shell for the message box, such as Display.getActive().getShell()
     */
    public static void doMessageBox(String message, String title, int swtStyle, Shell shell) {
        MessageBox messageBox = new MessageBox(shell, swtStyle);

        //stuff inside
        messageBox.setMessage(message);

        //title
        messageBox.setText(title);
        messageBox.open();
    }

}