Package com.eviware.soapui.support.components

Source Code of com.eviware.soapui.support.components.PreviewPopup

/*
* Copyright 2004-2014 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/

package com.eviware.soapui.support.components;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.MenuSelectionManager;

import com.eviware.soapui.support.UISupport;

/**
* This is a button which is designed to be the corner component of a
* <code>JScrollPane</code>. It triggers a popup menu which holds a scaled image
* of the component contained inside the <code>JScrollPane</code>.
*/

public class PreviewCorner extends JButton implements ActionListener {
    private String _corner;
    private PreviewPopup _previewPopup;

    /**
     * @param scrollPane        the <code>JScrollPane</code> to preview
     * @param zoomIcon          the icon to use for the button
     * @param doCloseAfterClick When <code>true</code> the preview popup menu is closed on mouse
     *                          click.
     * @param corner            Supposed to be one of the four corners of a
     *                          <code>JScrollPane</code>, like
     *                          <code>JScrollPane.LOWER_RIGHT_CORNER</code> for example, which
     *                          should match the position of the corner component of the scroll
     *                          pane. Note: If this parameter is not set correctly,
     *                          <code>JScrollPane.UPPER_LEFT_CORNER</code> will be used instead.
     */

    public PreviewCorner(JScrollPane scrollPane, ImageIcon zoomIcon, boolean doCloseAfterClick, String corner) {

        super(zoomIcon);
        this._corner = corner;

        // Creates the popup menu, containing the scaled image of the component.
        _previewPopup = new PreviewPopup(scrollPane, doCloseAfterClick);

        setToolTipText("Show a Panorama View of the contained editor");

        // The action listener is used to trigger the popup menu.
        addActionListener(this);
    }

    public PreviewCorner(JScrollPane scrollPane, ImageIcon zoomIcon, String corner) {
        this(scrollPane, zoomIcon, false, corner);
    }

    public void actionPerformed(ActionEvent e) {
        _previewPopup.showUpInCorner(this, _corner);
    }

    public void release() {
        _previewPopup.release();
        removeActionListener(this);
    }
}

class PreviewPopup extends JPopupMenu implements MouseListener, MouseMotionListener {

    private JScrollPane _scrollPane;
    private JViewport _viewPort;

    private JLabel _zoomWindow; // the JLabel containing the scaled image

    private JPanel _cursorLabel; // the JLabel mimicking the fake rectangle
    // cursor

    // This component will hold both JLabels _zoomWindow and _cursorLabel,
    // the latter on top of the other.
    private JLayeredPane _layeredPane;

    private int _iconWidth;
    private int _iconHeight;

    private boolean _doCloseAfterClick;

    float _ratio;

    // DELTA is the space between the scroll pane and the preview popup menu.
    private static int DELTA = 5;

    public PreviewPopup(JScrollPane scrollPane, boolean doCloseAfterClick) {
        this.setBorder(BorderFactory.createEtchedBorder());

        _doCloseAfterClick = doCloseAfterClick;

        _scrollPane = scrollPane;
        _viewPort = _scrollPane.getViewport();

        _zoomWindow = new JLabel();
        _cursorLabel = createCursor();

        _layeredPane = new JLayeredPane();

        _layeredPane.add(_zoomWindow, new Integer(0));
        _layeredPane.add(_cursorLabel, new Integer(1));

        // Creates a blank transparent cursor to be used as the cursor of
        // the popup menu.
        BufferedImage bim = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
        setCursor(getToolkit().createCustomCursor(bim, (new Point(0, 0)), "PreviewCursor"));

        this.add(_layeredPane);

        // Adds the mouse input listeners to the _layeredPane to scroll the
        // viewport and to move the fake cursor (_cursorLabel).
        _layeredPane.addMouseListener(this);
        _layeredPane.addMouseMotionListener(this);
    }

    public void release() {
        if (getParent() != null) {
            getParent().remove(this);
        }

        _layeredPane.removeMouseListener(this);
        _layeredPane.removeMouseMotionListener(this);

        _scrollPane = null;
        _layeredPane = null;
        _viewPort = null;
    }

    /**
     * By default, the right corner of a popup menu is positionned at the right
     * of a mouse click. What we want is to have the preview popup menu
     * positionned <i>inside</i> the scroll pane, near the corner component. The
     * purpose of this method is to display the scaled image of the component of
     * the scroll pane, and to calculate the correct position of the preview
     * popup menu.
     */

    public void showUpInCorner(Component c, String corner) {

        if (_viewPort.getComponentCount() == 0) {
            return;
        }

        float scaleFactor = 1.1f; // _viewPort.getComponent( 0 ).getHeight() /
        // _scrollPane.getHeight() * 2;

        // if (_viewPort.getWidth() < (_viewPort.getHeight() * scaleFactor))
        // _ratio =( int ) ( _viewPort.getComponent(0).getWidth() /
        // (_viewPort.getWidth() / scaleFactor) );
        //
        // else
        // _ratio = ( int ) (( _viewPort.getComponent(0).getHeight() /
        // (_viewPort.getHeight()) / scaleFactor ));
        _ratio = (((float) _viewPort.getComponent(0).getHeight() / ((float) _viewPort.getHeight()) / scaleFactor));

        if (_ratio < 2) {
            _ratio = 2;
        }

        // System.out.println( "ratio = " + _ratio );

        int zoomWindowImageWidth = (int) (_viewPort.getComponent(0).getWidth() / _ratio);
        if (zoomWindowImageWidth < 10) {
            UISupport.showInfoMessage("Viewport too large for readable image, use scrollbar instead");
            return;
        }

        int zoomWindowImageHeight = (int) (_viewPort.getComponent(0).getHeight() / _ratio);

        // System.out.println( "ratio = " + _ratio + ", zoomWindowImageWidth = " +
        // zoomWindowImageWidth +
        // ", zoomWindowImageHeight = " + zoomWindowImageHeight);

    /*
         * Image componentImage =
     * captureComponentViewAsBufferedImage(_viewPort.getComponent(0))
     * .getScaledInstance( zoomWindowImageWidth, zoomWindowImageHeight,
     * Image.SCALE_SMOOTH);
     */
    /*
     * Based on Shannon Hickey's comments. This is much faster way to scale
     * instance Thanks! Shannon
     */
        Image capture = captureComponentViewAsBufferedImage(_viewPort.getComponent(0));
        Image componentImage = new BufferedImage(zoomWindowImageWidth, zoomWindowImageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = (Graphics2D) componentImage.getGraphics();
    /* if you want smoother scaling */
        if (zoomWindowImageWidth > 15) {
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        }
        g2d.drawImage(capture, 0, 0, zoomWindowImageWidth, zoomWindowImageHeight, null);
        g2d.dispose();

        // Converts the Image to an ImageIcon to be used with a JLabel.
        ImageIcon componentIcon = new ImageIcon(componentImage);

        _iconWidth = componentIcon.getIconWidth();
        _iconHeight = componentIcon.getIconHeight();

        _zoomWindow.setIcon(componentIcon);

        _zoomWindow.setBounds(0, 0, _iconWidth, _iconHeight);

        int cursorWidth = (int) (_viewPort.getWidth() / _ratio);

        int cursorHeight = (int) (_viewPort.getHeight() / _ratio);

        _cursorLabel.setBounds(0, 0, cursorWidth, cursorHeight);

        _layeredPane.setPreferredSize(new Dimension(_iconWidth, _iconHeight));

        int dx = componentIcon.getIconWidth() + DELTA;
        int dy = componentIcon.getIconHeight() + DELTA;

        if (corner.equals(JScrollPane.UPPER_LEFT_CORNER)) {
            ;
        } else if (corner.equals(JScrollPane.UPPER_RIGHT_CORNER)) {
            dx = -dx;
        } else if (corner.equals(JScrollPane.LOWER_RIGHT_CORNER)) {
            dx = -dx;
            dy = -dy;
        } else if (corner.equals(JScrollPane.LOWER_LEFT_CORNER)) {
            dy = -dy;
        }

        if (dy < 0 && Math.abs(dy) > _viewPort.getHeight()) {
            dy = -_viewPort.getHeight() - 10;
        }

        // System.out.println( "Showing at " + dx + ", " + dy );

        // Shows the popup menu at the right place.
        this.show(c, dx, dy);

    }

    public JPanel createCursor() {
        JPanel label = new JPanel() {

            @Override
            protected void paintComponent(Graphics g) {
                Composite composite = ((Graphics2D) g).getComposite();
                ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
                super.paintComponent(g);
                ((Graphics2D) g).setComposite(composite);
            }

        };
        label.setBorder(BorderFactory.createLineBorder(Color.gray));
        label.setVisible(false);
        label.setOpaque(true);
        label.setBackground(Color.orange.darker());
        return label;
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
        // When the mouse enters the preview popup menu, set the visibility
        // of the fake cursor to true.
        _cursorLabel.setVisible(true);
    }

    public void mouseExited(MouseEvent e) {
        // When the mouse exits the preview popup menu, set the visibility
        // of the fake cursor to false.
        _cursorLabel.setVisible(false);
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
        // When the mouse is released, set the visibility of the preview
        // popup menu to false only if doCloseAfterClick is set to true.
        if (_doCloseAfterClick) {
            this.setVisible(false);
            _cursorLabel.setVisible(false);
            MenuSelectionManager.defaultManager().clearSelectedPath();
            setInvoker(null);
        }
    }

    public void mouseDragged(MouseEvent e) {
        moveCursor(e.getX(), e.getY());
        scrollViewPort();
    }

    public void mouseMoved(MouseEvent e) {
        moveCursor(e.getX(), e.getY());
        scrollViewPort();
    }

    /**
     * Centers the fake cursor (_cursorLabel) position on the coordinates
     * specified in the parameters.
     */
    private void moveCursor(int x, int y) {
        int dx = x - _cursorLabel.getWidth() / 2;
        int dy = y - _cursorLabel.getHeight() / 2;
        _cursorLabel.setLocation(dx, dy);
    }

    /**
     * Scrolls the viewport according to the fake cursor position in the preview
     * popup menu.
     */
    private void scrollViewPort() {
        Point cursorLocation = _cursorLabel.getLocation();
        int dx = (int) Math.max(cursorLocation.getX(), 0);
        int dy = (int) Math.max(cursorLocation.getY(), 0);

        dx = (int) (dx * _ratio);
        dy = (int) (dy * _ratio);

        ((JComponent) _viewPort.getComponent(0)).scrollRectToVisible(new Rectangle(dx, dy, _viewPort.getWidth(),
                _viewPort.getHeight()));
    }

    /**
     * takes a java component and generates an image out of it.
     *
     * @param c the component for which image needs to be generated
     * @return the generated image
     */
    public static BufferedImage captureComponentViewAsBufferedImage(Component c) {
        Dimension size = c.getSize();
        BufferedImage bufferedImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
        Graphics bufferedGraphics = bufferedImage.createGraphics();
        c.paint(bufferedGraphics);
        return bufferedImage;
    }

}
TOP

Related Classes of com.eviware.soapui.support.components.PreviewPopup

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.