package com.jb2011.im.cs;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Calendar;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileSystemView;
import com.jb2011.im.cs.window.MagnifierWindow;
import com.jb2011.im.cs.window.RectInfoWindow;
import com.jb2011.im.cs.window.ToolBarWindow;
import com.ufgov.component.special.util.SysUtil;
import com.ufgov.component.special.util.Util;
/**
* @describe 截屏功能
* @author suyanga
* @date 2015年5月10日 上午12:12:14
*/
public class CaptureScreen extends JPanel {
private static final long serialVersionUID = 1L;
/** 选区周围的敏感触点宽 */
public final static int SENSITIVE_REC_WIDTH = 5;
/** 选区周围的敏感触点高 */
public final static int SENSITIVE_REC_HEIGHT = 5;
/** 左上角敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_LEFT_TOP = 1;
/** 左中敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_LEFT_CENTER = 2;
/** 左下敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_LEFT_BOTTOM = 3;
/** 上中敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_TOP_CENTER = 4;
/** 下中敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_BOTTOM_CENTER = 5;
/** 右上角敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_RIGHT_TOP = 6;
/** 右中敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_RIGHT_CENTER = 7;
/** 右下角敏感区标识符 */
public final static int SENSITIVE_REC_IDENT_RIGHT_BOTTOM = 8;
/** 在选择区内滚动滚轴(x1,y1)坐标X轴方向的位移量(绝对值) */
public final static int DELTA_X_FOR_SCALE_SELECTED_AREA = 10;
/** 存放敏感区标识符 */
private int sensitive_rec_ident = 0;
/** 选择区坐标原点X */
public static int x = -1;
/** 选择区坐标原点Y */
public static int y = -1;
/** 选择区右下角坐标X */
public static int x1 = -1;
/** 选择区右下角坐标Y */
public static int y1 = -1;
/** 当mouse在选择区内按下左键瞬间时距左上点x距离 */
private static int x_rela = -1;
/** 当mouse在选择区内按下左键瞬间时距左上点y距离 */
private static int y_rela = -1;
/** 当mouse在选择区内按下左键瞬间时距右下点x1距离 */
private static int x1_rela = -1;
/** 当mouse在选择区内按下左键瞬间时距右下点y1距离 */
private static int y1_rela = -1;
/** 当mouse到达敏感区内按下左键瞬间时的坐标X */
private static int x_in_sensitive = -1;
/** 当mouse到达敏感区内按下左键瞬间时的坐标Y */
private static int y_in_sensitive = -1;
/** 面板的背景图像(缓存用于每次重绘) */
public static Image background = null;
public static BufferedImage bufferedImage = null;
/** 宿主窗口 */
private static JDialog parentDialog = null;
/** 是否重新确定选择区 */
private boolean isDraw = false;
/** 是否是选择区移动 */
private boolean isMove = false;
/** 是否是改变大小 */
private boolean isZoom = false;
public static CaptureScreen csStamdalone;
private static Robot rbt;
private static Toolkit toolKit = null;
/**
* 彩色鼠标指针
*/
private static Cursor colorfulCursor;
/**
* 选择区上的弹出框
*/
private static JPopupMenu popupMenu;
static {
try {
rbt = new Robot();
toolKit = Toolkit.getDefaultToolkit();
} catch (Exception e) {
System.out.println("无法实例化Robot!");
}
}
private CaptureScreen() throws Exception {
this.initGUI();
}
private void initGUI() {
this.setDoubleBuffered(true);
this.setSize(getScreenWidth(), getScreenHeight());
this.setVisible(true);
this.doAddMouseListener();
this.doAddMouseMotionListener();
}
/**
* 设置默认坐标(还原).
*/
public static void initLocation() {
x = -1;
y = -1;
x1 = -1;
y1 = -1;
x_rela = -1;
y_rela = -1;
x1_rela = -1;
y1_rela = -1;
x_in_sensitive = -1;
y_in_sensitive = -1;
}
public static void refreshBackgroud() {
if (rbt != null) {
//利用机器人捕获整个屏幕快照
background = rbt.createScreenCapture(new Rectangle(0, 0, (int) CaptureScreen.getScreenWidth(),
(int) CaptureScreen.getScreenHeight()));
bufferedImage = Util.toBufferedImage(CaptureScreen.background);
} else {
System.out.println("Robot引用为空,可能是无法实例化Robot对象!");
}
}
/**
* 添加mouse监听事件.
* @param com JComponent
*/
private void doAddMouseListener() {
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
//如果是左键
if (e.getButton() == MouseEvent.BUTTON1) {
//出于Java底层API对mouse事件的捕获粒度影响,在诸如敏感区等如此小的区
//域内进行移动事件捕获要想准确是相当困难的(以下代码是本程序的解决方法:一旦
//确定在哪个区进行伸缩,直到释放前,无需再进行其它处理)
if (isInsideSensitiveRec(e.getX(), e.getY())) {
//伸缩操作
isZoom = true;
//确定伸缩操作的开始位置(以决定伸缩方式)
if (isInsideRecLeftTop(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_LEFT_TOP;
} else if (isInsideRecLeftCenter(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_LEFT_CENTER;
} else if (isInsideRecLeftBottom(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_LEFT_BOTTOM;
} else if (isInsideRecTopCenter(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_TOP_CENTER;
} else if (isInsideRecBottomCenter(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_BOTTOM_CENTER;
} else if (isInsideRecRightTop(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_RIGHT_TOP;
} else if (isInsideRecRightCenter(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_RIGHT_CENTER;
} else if (isInsideRecRightBottom(e.getX(), e.getY())) {
sensitive_rec_ident = SENSITIVE_REC_IDENT_RIGHT_BOTTOM;
}
//当mouse在敏感区内时设定首次参考坐标,以便进行选择区伸缩
x_in_sensitive = e.getX();
y_in_sensitive = e.getY();
}
//当mouse在选择区内时设定首次参考坐标,以便进行选择区移动
else if (isInSelectedArea(e.getX(), e.getY())) {
isMove = true;
x_rela = e.getX() - x;
y_rela = e.getY() - y;
x1_rela = x1 - e.getX();
y1_rela = y1 - e.getY();
}
//区域外时不更新选择区坐标原点,但更新右下角坐标(以便重绘)
else {
isDraw = true;
x = e.getX();
y = e.getY();
}
}
}
public void mouseReleased(MouseEvent e) {
//mouse左键释放时选区矩形以确定(包括位置、大小),那么绘制它的左上角坐标
//和右下角坐标我们需根据不同情况进行调整(如从右上�