Package org.gephi.ui.components.richtooltip

Source Code of org.gephi.ui.components.richtooltip.RichTooltip

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.ui.components.richtooltip;

import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.Popup;
import javax.swing.PopupFactory;

/*
* Copyright (c) 2005-2009 Flamingo Kirill Grouchnikov. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  o Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  o Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  o Neither the name of Flamingo Kirill Grouchnikov nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Rich tooltip for command buttons.
*
* <p>
* In its most basic form, the rich tooltip has a title and one (possible
* multiline) description text:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* |        Some description text   |
* +--------------------------------+
* </pre>
*
* <p>
* The {@link #addDescriptionSection(String)} can be used to add multiple
* sections to the description:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* |        First multiline         |
* |        description section     |
* |                                |
* |        Second multiline        |
* |        description section     |
* |                                |
* |        Third multiline         |
* |        description section     |
* +--------------------------------+
* </pre>
*
* <p>
* The {@link #setMainImage(Image)} can be used to place an image below the
* title and to the left of the description sections:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* | *******  First multiline       |
* | *image*  description section   |
* | *******                        |
* |          Second multiline      |
* |          description section   |
* +--------------------------------+
* </pre>
*
* <p>
* The {@link #addFooterSection(String)} can be used to add (possibly) multiple
* footer sections that will be shown below a horizontal separator:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* |        First multiline         |
* |        description section     |
* |                                |
* |        Second multiline        |
* |        description section     |
* |--------------------------------|
* | A multiline footer section     |
* | placed below a separator       |
* +--------------------------------+
* </pre>
*
* <p>
* The {@link #setFooterImage(Image)} can be used to place an image to the left
* of the footer sections:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* |        First multiline         |
* |        description section     |
* |                                |
* |        Second multiline        |
* |        description section     |
* |--------------------------------|
* | *******  A multiline           |
* | *image*  footer section        |
* | *******                        |
* +--------------------------------+
* </pre>
*
* <p>
* Here is a fully fledged rich tooltip that shows all these APIs in action:
* </p>
*
* <pre>
* +--------------------------------+
* | Title                          |
* | *******  First multiline       |
* | *image*  description section   |
* | *******                        |
* |          Second multiline      |
* |          description section   |
* |--------------------------------|
* | *******  First multiline       |
* | *image*  footer section        |
* | *******                        |
* |          Second multiline      |
* |          footer section        |
* +--------------------------------+
* </pre>
*
* @author Kirill Grouchnikov
*/
public class RichTooltip {

    /**
     * The main title of this tooltip.
     *
     * @see #RichTooltip(String, String)
     * @see #setTitle(String)
     * @see #getTitle()
     */
    protected String title;
    /**
     * The main image of this tooltip. Can be <code>null</code>.
     *
     * @see #getMainImage()
     * @see #setMainImage(Image)
     */
    protected Image mainImage;
    /**
     * The description sections of this tooltip.
     *
     * @see #RichTooltip(String, String)
     * @see #addDescriptionSection(String)
     * @see #getDescriptionSections()
     */
    protected List<String> descriptionSections;
    /**
     * The footer image of this tooltip. Can be <code>null</code>.
     *
     * @see #getFooterImage()
     * @see #setFooterImage(Image)
     */
    protected Image footerImage;
    /**
     * The footer sections of this tooltip. Can be empty.
     *
     * @see #addFooterSection(String)
     * @see #getFooterSections()
     */
    protected List<String> footerSections;

    /**
     * Creates an empty tooltip.
     */
    public RichTooltip() {
    }

    /**
     * Creates a tooltip with the specified title and description section.
     *
     * @param title
     *            Tooltip title.
     * @param descriptionSection
     *            Tooltip main description section.
     */
    public RichTooltip(String title, String descriptionSection) {
        this.setTitle(title);
        this.addDescriptionSection(descriptionSection);
    }
    private Popup tipWindow;
    private boolean tipShowing = false;

    public void showTooltip(JComponent component) {
        if (component == null || !component.isShowing()) {
            return;
        }
        Dimension size;
        Point screenLocation = component.getLocationOnScreen();
        Point location = new Point();
        GraphicsConfiguration gc;
        gc = component.getGraphicsConfiguration();
        Rectangle sBounds = gc.getBounds();
        Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
        // Take into account screen insets, decrease viewport
        sBounds.x += screenInsets.left;
        sBounds.y += screenInsets.top;
        sBounds.width -= (screenInsets.left + screenInsets.right);
        sBounds.height -= (screenInsets.top + screenInsets.bottom);

        hideTooltip();

        JRichTooltipPanel tip = new JRichTooltipPanel(this);
        size = tip.getPreferredSize();


        // display directly below or above it
        location.x = screenLocation.x;
        location.y = screenLocation.y + component.getHeight();
        if ((location.y + size.height) > (sBounds.y + sBounds.height)) {
            location.y = screenLocation.y - size.height;
        }


        // Tweak the X location to not overflow the screen
        if (location.x < sBounds.x) {
            location.x = sBounds.x;
        } else if (location.x - sBounds.x + size.width > sBounds.width) {
            location.x = sBounds.x + Math.max(0, sBounds.width - size.width);
        }

        PopupFactory popupFactory = PopupFactory.getSharedInstance();
        tipWindow = popupFactory.getPopup(component, tip, location.x, location.y);
        tipWindow.show();
        tipShowing = true;
    }

    public void hideTooltip() {
        if (tipWindow != null) {
            tipWindow.hide();
            tipWindow = null;
            tipShowing = false;
        }
    }

    /**
     * Sets the title for this tooltip.
     *
     * @param title
     *            The new tooltip title.
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * Sets the main image for this tooltip.
     *
     * @param image
     *            The main image for this tooltip.
     * @see #getMainImage()
     * @see #addDescriptionSection(String)
     */
    public void setMainImage(Image image) {
        this.mainImage = image;
    }

    /**
     * Adds the specified description section to this tooltip.
     *
     * @param section
     *            The description section to add.
     * @see #getDescriptionSections()
     * @see #setMainImage(Image)
     * @see #setTitle(String)
     */
    public void addDescriptionSection(String section) {
        if (this.descriptionSections == null) {
            this.descriptionSections = new LinkedList<String>();
        }
        this.descriptionSections.add(section);
    }

    /**
     * Sets the footer image for this tooltip.
     *
     * @param image
     *            The footer image for this tooltip.
     * @see #getFooterImage()
     * @see #addFooterSection(String)
     */
    public void setFooterImage(Image image) {
        this.footerImage = image;
    }

    /**
     * Adds the specified footer section to this tooltip.
     *
     * @param section
     *            The footer section to add.
     * @see #getFooterSections()
     * @see #setFooterImage(Image)
     */
    public void addFooterSection(String section) {
        if (this.footerSections == null) {
            this.footerSections = new LinkedList<String>();
        }
        this.footerSections.add(section);
    }

    /**
     * Returns the main title of this tooltip.
     *
     * @return The main title of this tooltip.
     * @see #RichTooltip(String, String)
     * @see #setTitle(String)
     */
    public String getTitle() {
        return this.title;
    }

    /**
     * Returns the main image of this tooltip. Can return <code>null</code>.
     *
     * @return The main image of this tooltip.
     * @see #setMainImage(Image)
     * @see #getDescriptionSections()
     */
    public Image getMainImage() {
        return this.mainImage;
    }

    /**
     * Returns an unmodifiable list of description sections of this tooltip.
     * Guaranteed to return a non-<code>null</code> list.
     *
     * @return An unmodifiable list of description sections of this tooltip.
     * @see #RichTooltip(String, String)
     * @see #addDescriptionSection(String)
     * @see #getTitle()
     * @see #getMainImage()
     */
    public List<String> getDescriptionSections() {
        if (this.descriptionSections == null) {
            return Collections.EMPTY_LIST;
        }
        return Collections.unmodifiableList(this.descriptionSections);
    }

    /**
     * Returns the footer image of this tooltip. Can return <code>null</code>.
     *
     * @return The footer image of this tooltip.
     * @see #setFooterImage(Image)
     * @see #getFooterSections()
     */
    public Image getFooterImage() {
        return this.footerImage;
    }

    /**
     * Returns an unmodifiable list of footer sections of this tooltip.
     * Guaranteed to return a non-<code>null</code> list.
     *
     * @return An unmodifiable list of footer sections of this tooltip.
     * @see #addFooterSection(String)
     * @see #getFooterImage()
     */
    public List<String> getFooterSections() {
        if (this.footerSections == null) {
            return Collections.EMPTY_LIST;
        }
        return Collections.unmodifiableList(this.footerSections);
    }
}

TOP

Related Classes of org.gephi.ui.components.richtooltip.RichTooltip

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.