Package com.eviware.soapui.support.components

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

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI 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 Lesser General Public License for more details at gnu.org.
*/

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.