graphicutils.java

来自「开源项目openfire的完整源程序」· Java 代码 · 共 671 行 · 第 1/2 页

JAVA
671
字号
/**
 * $Revision: $
 * $Date: $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.spark.util;

import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.spark.util.log.Log;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;

/**
 * <code>GraphicsUtils</code> class defines common user-interface related utility
 * functions.
 */
public final class GraphicUtils {
    private static final Insets HIGHLIGHT_INSETS = new Insets(1, 1, 1, 1);
    public static final Color SELECTION_COLOR = new java.awt.Color(166, 202, 240);
    public static final Color TOOLTIP_COLOR = new java.awt.Color(166, 202, 240);

    protected final static Component component = new Component() {
    };
    protected final static MediaTracker tracker = new MediaTracker(component);

    private static Hashtable imageCache = new Hashtable();

    /**
     * The default Hand cursor.
     */
    public static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR);

    /**
     * The default Text Cursor.
     */
    public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);

    private GraphicUtils() {
    }


    /**
     * Sets the location of the specified window so that it is centered on screen.
     *
     * @param window The window to be centered.
     */
    public static void centerWindowOnScreen(Window window) {
        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        final Dimension size = window.getSize();

        if (size.height > screenSize.height) {
            size.height = screenSize.height;
        }

        if (size.width > screenSize.width) {
            size.width = screenSize.width;
        }

        window.setLocation((screenSize.width - size.width) / 2,
            (screenSize.height - size.height) / 2);
    }

    /**
     * Draws a single-line highlight border rectangle.
     *
     * @param g         The graphics context to use for drawing.
     * @param x         The left edge of the border.
     * @param y         The top edge of the border.
     * @param width     The width of the border.
     * @param height    The height of the border.
     * @param raised    <code>true</code> if the border is to be drawn raised,
     *                  <code>false</code> if lowered.
     * @param shadow    The shadow color for the border.
     * @param highlight The highlight color for the border.
     * @see javax.swing.border.EtchedBorder
     */
    public static void drawHighlightBorder(Graphics g, int x, int y,
                                           int width, int height, boolean raised,
                                           Color shadow, Color highlight) {
        final Color oldColor = g.getColor();
        g.translate(x, y);

        g.setColor(raised ? highlight : shadow);
        g.drawLine(0, 0, width - 2, 0);
        g.drawLine(0, 1, 0, height - 2);

        g.setColor(raised ? shadow : highlight);
        g.drawLine(width - 1, 0, width - 1, height - 1);
        g.drawLine(0, height - 1, width - 2, height - 1);

        g.translate(-x, -y);
        g.setColor(oldColor);
    }

    /**
     * Return the amount of space taken up by a highlight border drawn by
     * <code>drawHighlightBorder()</code>.
     *
     * @return The <code>Insets</code> needed for the highlight border.
     * @see #drawHighlightBorder
     */
    public static Insets getHighlightBorderInsets() {
        return HIGHLIGHT_INSETS;
    }

    public static ImageIcon createImageIcon(Image image) {
        if (image == null) {
            return null;
        }

        synchronized (tracker) {
            tracker.addImage(image, 0);
            try {
                tracker.waitForID(0, 0);
            }
            catch (InterruptedException e) {
                System.out.println("INTERRUPTED while loading Image");
            }
            tracker.removeImage(image, 0);
        }

        return new ImageIcon(image);
    }

    /**
     * Returns a point where the given popup menu should be shown. The
     * point is calculated by adjusting the X and Y coordinates from the
     * given mouse event so that the popup menu will not be clipped by
     * the screen boundaries.
     *
     * @param popup the popup menu
     * @param event the mouse event
     * @return the point where the popup menu should be shown
     */
    public static Point getPopupMenuShowPoint(JPopupMenu popup, MouseEvent event) {
        Component source = (Component)event.getSource();
        Point topLeftSource = source.getLocationOnScreen();
        Point ptRet = getPopupMenuShowPoint(popup,
            topLeftSource.x + event.getX(),
            topLeftSource.y + event.getY());
        ptRet.translate(-topLeftSource.x, -topLeftSource.y);
        return ptRet;
    }

    /**
     * Returns a point where the given popup menu should be shown. The
     * point is calculated by adjusting the X and Y coordinates so that
     * the popup menu will not be clipped by the screen boundaries.
     *
     * @param popup the popup menu
     * @param x     the x position in screen coordinate
     * @param y     the y position in screen coordinates
     * @return the point where the popup menu should be shown in screen
     *         coordinates
     */
    public static Point getPopupMenuShowPoint(JPopupMenu popup, int x, int y) {
        Dimension sizeMenu = popup.getPreferredSize();
        Point bottomRightMenu = new Point(x + sizeMenu.width, y + sizeMenu.height);

        Rectangle[] screensBounds = getScreenBounds();
        int n = screensBounds.length;
        for (int i = 0; i < n; i++) {
            Rectangle screenBounds = screensBounds[i];
            if (screenBounds.x <= x && x <= (screenBounds.x + screenBounds.width)) {
                Dimension sizeScreen = screenBounds.getSize();
                sizeScreen.height -= 32;  // Hack to help prevent menu being clipped by Windows/Linux/Solaris Taskbar.

                int xOffset = 0;
                if (bottomRightMenu.x > (screenBounds.x + sizeScreen.width))
                    xOffset = -sizeMenu.width;

                int yOffset = 0;
                if (bottomRightMenu.y > (screenBounds.y + sizeScreen.height))
                    yOffset = sizeScreen.height - bottomRightMenu.y;

                return new Point(x + xOffset, y + yOffset);
            }
        }

        return new Point(x, y); // ? that would mean that the top left point was not on any screen.
    }

    /**
     * Centers the window over a component (usually another window).
     * The window must already have been sized.
     */
    public static void centerWindowOnComponent(Window window, Component over) {
        if ((over == null) || !over.isShowing()) {
            centerWindowOnScreen(window);
            return;
        }


        Point parentLocation = over.getLocationOnScreen();
        Dimension parentSize = over.getSize();
        Dimension size = window.getSize();

        // Center it.
        int x = parentLocation.x + (parentSize.width - size.width) / 2;
        int y = parentLocation.y + (parentSize.height - size.height) / 2;

        // Now, make sure it's onscreen
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

        // This doesn't actually work on the Mac, where the screen
        // doesn't necessarily start at 0,0
        if (x + size.width > screenSize.width)
            x = screenSize.width - size.width;

        if (x < 0)
            x = 0;

        if (y + size.height > screenSize.height)
            y = screenSize.height - size.height;

        if (y < 0)
            y = 0;

        window.setLocation(x, y);
    }

    /**
     * @return returns true if the component of one of its child has the focus
     */
    public static boolean isAncestorOfFocusedComponent(Component c) {
        if (c.hasFocus()) {
            return true;
        }
        else {
            if (c instanceof Container) {
                Container cont = (Container)c;
                int n = cont.getComponentCount();
                for (int i = 0; i < n; i++) {
                    Component child = cont.getComponent(i);
                    if (isAncestorOfFocusedComponent(child))
                        return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns the first component in the tree of <code>c</code> that can accept
     * the focus.
     *
     * @param c the root of the component hierarchy to search
     * @see #focusComponentOrChild
     * @deprecated replaced by {@link #getFocusableComponentOrChild(Component,boolean)}
     */
    public static Component getFocusableComponentOrChild(Component c) {
        return getFocusableComponentOrChild(c, false);
    }

    /**
     * Returns the first component in the tree of <code>c</code> that can accept
     * the focus.
     *
     * @param c       the root of the component hierarchy to search
     * @param deepest if <code>deepest</code> is true the method will return the first and deepest component that can accept the
     *                focus.  For example, if both a child and its parent are focusable and <code>deepest</code> is true, the child is
     *                returned.
     * @see #focusComponentOrChild
     */
    public static Component getFocusableComponentOrChild(Component c, boolean deepest) {
        if (c != null && c.isEnabled() && c.isVisible()) {
            if (c instanceof Container) {
                Container cont = (Container)c;

                if (deepest == false) { // first one is a good one
                    if (c instanceof JComponent) {
                        JComponent jc = (JComponent)c;
                        if (jc.isRequestFocusEnabled()) {
                            return jc;
                        }
                    }
                }

                int n = cont.getComponentCount();
                for (int i = 0; i < n; i++) {
                    Component child = cont.getComponent(i);
                    Component focused = getFocusableComponentOrChild(child, deepest);
                    if (focused != null) {
                        return focused;
                    }
                }

                if (c instanceof JComponent) {
                    if (deepest == true) {
                        JComponent jc = (JComponent)c;
                        if (jc.isRequestFocusEnabled()) {
                            return jc;
                        }
                    }
                }
                else {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?