最近用java GUI的swing实现了一个仿QQ截图小工具,实现了最基本的系统热键启动截图,鼠标拖动画出截图区域,或者直接窗口检测,然后保存或者复制到系统剪切板等功能。效果如图所示:
代码都放在一个.java文件中,这样子post上来方便,接着介绍代码的具体实现细节。
(1)软件所用到的第三方包有:jintellitype-1.3.9.jar(用于注册系统热键包),以及JNA的两个包(用于保存窗体层次关系):jna-4.5.0.jar,jna-platform-4.5.0.jar
用到的dll就 jintellitype.dll放到System32中就可以了,jna两个包直接引入即可。
(2)软件启动后,弹出系统热键设置:
要设置成还没有被其他软件用过的热键,比如没有启动QQ的话,那么我们可以注册ctrl+alt+A,如果QQ启动后再注册ctrl+alt+A就没有效了,点击shot就可以将窗体最小化到托盘
热键注册代码是非常简单的,只需要执行注册函数,然后加入自己的按键监听器就可以了
static final int shotHotKey = 88;
//热键号随便,然后将CTRL+ALT+G注册进去
JIntellitype.getInstance().registerHotKey(shotHotKey, JIntellitype.MOD_CONTROL + JIntellitype.MOD_ALT,
(int)'G'));
JIntellitype.getInstance().addHotKeyListener(new GlobalHotKey());
class GlobalHotKey implements HotkeyListener {
public void onHotKey(int key) {
switch (key) {
case shotHotKey:
//开始截屏
processScreenShot();
break;
default:
System.exit(0);
}
}
}
(3)启动截图处理后,要做的事情是保存当前窗体的层次关系,主要是调用User32中的一些API,便于后面的矩形检测,具体代码见文末:
HashMap<Integer, Rectangle> winLayer = null;//这个HashMap用来保存窗体的层次,最顶层的先加进去。
//然后在鼠标Motion事件中遍历这个Map,判断当前鼠标位置是否包含在某个窗体里面,如果是则在点击后就自动点亮这个区域
(4)接着是将当前窗口的全屏图像截取下来,并且标出鼠标位置,代码如下:
rb = new Robot();
rb.createScreenCapture(new Rectangle(screenSize));//得到全屏图像
//调用drawMouse函数将鼠标画到图像上
private void drawMouse(BufferedImage bi){
Graphics2D g2d = (Graphics2D)bi.getGraphics();
g2d.drawImage(bi,0,0,bi.getWidth(),bi.getHeight(),null);
ImageIcon img = new ImageIcon(screenShot.class.getResource("whiteCursor.png"));
Point mp = MouseInfo.getPointerInfo().getLocation();
g2d.drawImage(img.getImage(),mp.x,mp.y,img.getIconWidth(),img.getIconHeight(),null);
g2d.dispose();
}
(5)接着新建一个JFrame,这个JFrame全屏,并且半透明黑色,置顶,半透明只需要在contentPane的paintComponent函数中画个有透明度的矩形黑色区域即可
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
Composite old = ((Graphics2D) g).getComposite();
((Graphics2D) g).setComposite(ac);
g.setColor(Color.BLACK);
g.fillRect(0, 0, screenSize.width, screenSize.height);
((Graphics2D) g).setComposite(old);
(6)并且改变鼠标的颜色为彩色光标,彩色光标在 这里找的,下载下来后是cur,转为png即可。
(7)然后就是鼠标事件了,鼠标事件主要是press,drag,release,Motion这四个事件,press用于记录按下时的点,然后drag用于拖拽出要截图的区域,release拖拽完成,motion用来判断当前鼠标位置标亮窗体区域。
这个区域主要用start点和end点表示,start点是矩形左上角,end是矩形右下角。
由于拖拽可以往任意方向,但是drawImage这个函数可以纠正,所以鼠标往任意方向拖都可以用。
public abstract boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer);
拖出区域后,肯定需要可以支持区域修正,也就是区域可拖动,可拉伸并且支持各个方向,效果如下图所示,这些功能的实现也是在鼠标事件中完成的,具体见代码。
拉伸主要是对区域进行判断:
(8)拖动完成后可以回车复制到剪切板上,参考java图片复制到剪切板
或者保存为jpg or png or bmp文件。
(8)其他的功能:在截屏状态下按esc就可以退出。
完整代码如下:
由于用了lambda表达式,所以需要jre1.8。然后托盘图像trayIcon.png,白色光标whiteCursor.png,彩色光标是刚才的cursor.png
这里有编译好的,双击即可运行。
package screenShot;
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import static com.sun.jna.platform.win32.WinUser.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
/**
* 截屏小工具。支持系统热键。
*/
public class screenShot {
JFrame jf;
JButton shotStart;
JLabel jl;
public static JTextField jtf;
public screenShot() {
jf = new JFrame("java screenShot");
jf.setSize(500,400);
jf.setLocationRelativeTo(null);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
jl = new JLabel("HotKey = CTRL+ALT+");
jl.setBounds(50,200,150,30);
jtf = new JTextField("G");
jtf.setBounds(200,200,100,30);
shotStart = new JButton("shot");
shotStart.setBounds(50, 300, 100, 30);
shotStart.addActionListener(new shotE());
jf.add(shotStart);
jf.add(jl); jf.add(jtf);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
public static void main(String[] args) {
new screenShot();
}
private class shotE implements ActionListener {
boolean first = false;
@Override
public void actionPerformed(ActionEvent e) {
jf.setVisible(false);
if (!first) {
createTray();
setHotKey();
first = true;
}
}
GlobalHotKey key;
private void setHotKey() {
key = new GlobalHotKey();
key.initHotkey();
}
private void createTray() {
PopupMenu pm = new PopupMenu();
MenuItem mi = new MenuItem("exit");
mi.addActionListener(e -> {JIntellitype.getInstance().unregisterHotKey(GlobalHotKey.shotHotKey);System.exit(0);});
pm.add(mi);
ImageIcon img = new ImageIcon(screenShot.class.getResource("trayIcon.png"));
TrayIcon ti = new TrayIcon(img.getImage(), "screenShot", pm);
ti.addActionListener(e -> jf.setVisible(true));
try {
SystemTray.getSystemTray().add(ti);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
}
class GlobalHotKey implements HotkeyListener {
HashMap<Integer, Rectangle> winLayer = null;
static final int shotHotKey = 88;
public volatile boolean enterBusy = false;//防止和全局热键冲突。
private String lastPath = null;
public volatile boolean shotBusy = false;//防止重复截图。
public volatile boolean isProcess = false;//第一次拖拽完成后,需要进行处理,这时候需要重新利用click,drag和release函数。
/**拖拽参数**/
private static final int BREADTH = 7;//边界拉伸范围
private static final int BREADTH2 = 14;//边界拉伸范围
private int dragType;
private static final int DRAG_NONE = 0;
private static final int DRAG_MOVE = 1;
private static final int DRAG_UP = 2;
private static final int DRAG_UPLEFT = 3;
private static final int DRAG_UPRIGHT = 4;
private static final int DRAG_LEFT = 5;
private static final int DRAG_RIGHT = 6;
private static final int DRAG_BOTTOM = 7;
private static final int DRAG_BOTTOMLEFT = 8;
private static final int DRAG_BOTTOMRIGHT = 9;
private Cursor getNewCursor(){
return Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(screenShot.class.getResource("cursor.png")).getImage(),new Point(0,0),"myCursor");
}
public void onHotKey(int key) {
switch (key) {
case shotHotKey:
if(shotBusy) return;
shotBusy = true;
saveLayer();//保存窗口层次。
registerESC();//注册窗体全局热键
shotProcess();
break;
default:
System.exit(0);
}
}
/**屏幕窗体层次保存**/
public void saveLayer() {
User32 u32 = User32.INSTANCE;
printAllNextWin(u32.GetWindow(u32.GetForegroundWindow(), new WinDef.DWORD(GW_HWNDFIRST)));
}
public HWND getNextWindow(HWND hWnd) {
return User32.INSTANCE.GetWindow(hWnd, new DWORD(GW_HWNDNEXT));
}
public boolean CheckLegal(HWND hWnd, Rectangle rt) {
WINDOWINFO winInfo = new WINDOWINFO();
User32.INSTANCE.GetWindowInfo(hWnd, winInfo);
int style = winInfo.dwStyle;
if ((style & WS_VISIBLE) == 0) {
return false;//去掉不可视窗口
}
if ((style & WS_DISABLED) != 0) {
return false;//去掉disable窗口
}
if (rt.width < 10 || rt.height < 10) {
return false;//去掉小不点窗口
}
if ((style & WS_MINIMIZE)!=0) {
return false;//去掉最小化状态的窗口
}
if((rt.getWidth() == screenSize.getWidth()) && (rt.getHeight() == screenSize.getHeight())){
return false;//去掉底层屏幕窗口
}
return true;
}
/** 遍历桌面所有窗体,如果是合法的就加入到winLayer **/
public void printAllNextWin(HWND h) {
HashMap<Integer, Rectangle> layerInfo = new HashMap<>();//0是最高层
HWND hWnd = h;
RECT r = new RECT();
int layerPos = 0;
Rectangle rect;
while ((hWnd = getNextWindow(hWnd)) != null) {
User32.INSTANCE.GetWindowRect(hWnd, r);
rect = r.toRectangle();
if (!CheckLegal(hWnd, rect)) continue;
layerInfo.put(layerPos++, rect);
}
winLayer = layerInfo;
}
AWTEventListener al;
private void registerESC() {
al = event -> {
KeyEvent ke = (KeyEvent) event;
if (ke.getID() == KeyEvent.KEY_PRESSED) {
if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
//System.out.println("当前AWT事件监听器数量"+ Toolkit.getDefaultToolkit().getAWTEventListeners().length);
clean();
unregisterESC();
jp.setDrag(false);
} else if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
if(enterBusy){
return;
}
pastePic();
}
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(al, AWTEvent.KEY_EVENT_MASK);
}
private void unregisterESC() {
Toolkit.getDefaultToolkit().removeAWTEventListener(al);
}
JFrame jf;
Cursor myCursor;
myContentPane jp;
BufferedImage bi;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private void shotProcess() {
jf = new JFrame();
jf.setUndecorated(true);
jf.setBounds(0, 0, screenSize.width, screenSize.height);
jf.setAlwaysOnTop(true);
jp = new myContentPane(this);
jp.setOpaque(false);
jp.setLayout(null);
Robot rb = null;
try {
rb = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
bi = rb.createScreenCapture(new Rectangle(screenSize));
drawMouse(bi);
img = new ImageIcon(bi);
mouseEvent e = new mouseEvent(this);
jp.addMouseListener(e);
jp.addMouseMotionListener(e);
jf.add(jp);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
myCursor = getNewCursor();
jf.setCursor(myCursor);//给系统设置彩色光标。
}
/**图像添加鼠标:http://blog.csdn.net/eguid_1/article/details/52973508 **/
private void drawMouse(BufferedImage bi){
Graphics2D g2d = (Graphics2D)bi.getGraphics();
g2d.drawImage(bi,0,0,bi.getWidth(),bi.getHeight(),null);
ImageIcon img = new ImageIcon(screenShot.class.getResource("whiteCursor.png"));
Point mp = MouseInfo.getPointerInfo().getLocation();
g2d.drawImage(img.getImage(),mp.x,mp.y,img.getIconWidth(),img.getIconHeight(),null);
g2d.dispose();
}
ImageIcon img;
private class myContentPane extends JPanel {
GlobalHotKey ek;
public myContentPane(GlobalHotKey ek) {
this.ek = ek;
}
public volatile boolean moveFlag = false;
public synchronized boolean isMove() {
return moveFlag;
}
public synchronized void setMove(boolean f) {
moveFlag = f;
}
public volatile boolean dragFlag = false;
public synchronized boolean isDrag() {
return dragFlag;
}
public synchronized void setDrag(boolean f) {
dragFlag = f;
}
@Override
protected void paintComponent(Graphics g) {
/**
* 设置透明度 https://wenku.baidu.com/view/d90f110d227916888486d7ee.html
*/
if (img != null)
g.drawImage(img.getImage(), 0, 0, getWidth(), getHeight(), this);
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
Composite old = ((Graphics2D) g).getComposite();
((Graphics2D) g).setComposite(ac);
g.setColor(Color.BLACK);
g.fillRect(0, 0, screenSize.width, screenSize.height);
((Graphics2D) g).setComposite(old);
g.drawImage(img.getImage(), start.x, start.y, end.x, end.y, start.x, start.y, end.x, end.y, this);
g.setColor(new Color(2, 169, 255));
if (isMove()) {
Stroke oldS = ((Graphics2D) g).getStroke();
((Graphics2D) g).setStroke(new BasicStroke(4.0f));
g.drawRect(start.x, start.y, end.x - start.x, end.y - start.y);
((Graphics2D) g).setStroke(oldS);
setMove(false);
} else {
drawBound(g);
}
super.paintComponent(g);
}
Point myStart = new Point(0, 0);
public void correctMyStart() {
if ((start.x <= end.x) && (start.y <= end.y)) {
myStart.x = start.x;
myStart.y = start.y;
} else if ((start.x <= end.x) && (start.y > end.y)) {
//右上角
myStart.x = start.x;
myStart.y = end.y;
} else if ((start.x > end.x) && (start.y <= end.y)) {
//左下角
myStart.x = end.x;
myStart.y = start.y;
} else {
myStart.x = end.x;
myStart.y = end.y;
}
}
int offset = 3;
int[][] point;
private void drawBound(Graphics g) {
myStart = new Point(0, 0);
/**纠正反方向错误**/
correctMyStart();
g.drawRect(myStart.x, myStart.y, Math.abs(end.x - start.x), Math.abs(end.y - start.y));
point = new int[][]{{start.x, start.y}, {(start.x + end.x) / 2, start.y}, {end.x, start.y}, {end.x, (start.y + end.y) / 2}, {end.x, end.y}, {(start.x + end.x) / 2, end.y}, {start.x, end.y}, {start.x, (start.y + end.y) / 2}};
for (int i = 0; i < point.length; i++)
g.fillRect(point[i][0] - offset, point[i][1] - offset, 2 * offset, 2 * offset);
}
}
Point start = new Point(0, 0), end = new Point(0, 0);
Point prePos,startCopy,endCopy;
/**
* 根据矩形的start和end两点裁剪出要截取的图形。
*/
private BufferedImage clipArea(){
BufferedImage shotArea = new BufferedImage(end.x - start.x, end.y - start.y, BufferedImage.TYPE_INT_RGB);
Graphics g = shotArea.getGraphics();
g.drawImage(bi, 0, 0, end.x - start.x, end.y - start.y, start.x, start.y, end.x, end.y, null);
return shotArea;
}
/**
* 将图像复制到系统剪贴板上
**/
private void pastePic() {
/**将图片复制到剪贴板,参考链接:http://blog.csdn.net/u010982856/article/details/44747029**/
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new Images((new ImageIcon(clipArea())).getImage()), null);
clean();
}
private void clean() {
jf.dispose();
shotBusy = false;
isProcess = false;
start = new Point(0, 0);
end = new Point(0, 0);
}
private class mouseEvent extends MouseAdapter {
GlobalHotKey ss;
public mouseEvent(GlobalHotKey screenShot) {
this.ss = screenShot;
}
private void typeSel(MouseEvent e){
Point p = e.getPoint();
if(new Rectangle(start.x-BREADTH,start.y-BREADTH,end.x-start.x+BREADTH2,end.y-start.y+BREADTH2).contains(p)){
/**在区域内部**/
}else{
/**如果不在内部,就结束**/
isProcess = false;
pressPro(e);
}
}
public void mousePressed(MouseEvent e) {
if(isProcess){
/**
* 在处理状态下press时,记录press的点,作为起点。
*/
prePos = e.getPoint();
startCopy = new Point(start);
endCopy = new Point(end);
typeSel(e);
}else{
pressPro(e);
}
}
private void pressPro(MouseEvent e){
isSelExist();
start = e.getPoint();
end = new Point(start.x,start.y);
ss.jp.setDrag(true);
ss.jp.updateUI();
}
public void mouseReleased(MouseEvent e) {
if(isProcess){
jf.setCursor(myCursor);
/**修正在反方向拖动时的区域修正及更新面板**/
correctDir();
reLocateSel();
return;
}else{
releaseProcess(e);
}
}
private void releaseProcess(MouseEvent e){
/** 如果只有点击没有拖拽,就进行窗体检测。
**/
if (!isDrag) {
Rectangle r;
for (int i = 0; i < winLayer.size(); i++) {
r = winLayer.get(i);
if (r.contains(e.getPoint())) {
//System.out.println("当前在矩形"+i+"中");
start.x = r.getX() >= 0 ? (int) r.getX() : 0;
start.y = r.getY() >= 0 ? (int) r.getY() : 0;
end.x = start.x + (int) r.getWidth();
end.y = start.y + (int) r.getHeight();
ss.jp.updateUI();//这个必须要。
break;
}
}
}
correctDir();
isSelExist();
createSel();
isDrag = false;
isProcess = true;
/**
* 进入处理状态,如果在指定区域内再次点击,就是拖拽拉伸。
*/
}
private void reLocateSel(){
Point refP;
//判断按钮会不会超出屏幕
if ((end.y + 30) >= screenSize.getHeight()) {
refP = new Point(end.x, start.y - 30);
} else {
refP = new Point(end.x, end.y);
}
selPanel.setBounds(refP.x-150,refP.y+10,150,20);
selPanel.updateUI();
}
private void createSel() {
Point refP;
//判断按钮会不会超出屏幕,上下左右方位都应该判断。
/***还不完善,左下角会挡住。***/
if ((end.y + 30) >= screenSize.getHeight()) {
refP = new Point(end.x, start.y - 30);
} else {
refP = new Point(end.x, end.y);
}
selPanel = new JPanel(null);
selPanel.setBounds(refP.x-150,refP.y+10,150,20);
ok = new JButton("Y");
ok.setBounds(100, 0, 50, 20);
ok.addActionListener(e -> {
pastePic();
ss.jp.setDrag(false);
});
cancel = new JButton("N");
cancel.setBounds(50, 0, 50, 20);
cancel.addActionListener(e -> {
clean();
ss.jp.setDrag(false);
});
save = new JButton("S");
save.addActionListener(e->{savePic();});
save.setBounds(0, 0, 50, 20);
selPanel.add(ok);
selPanel.add(cancel);
selPanel.add(save);
ss.jp.add(selPanel);
ss.jp.updateUI();
}
private void savePic(){
enterBusy = true;
if(File.separator.equals("\\"))//判断是windows系统
try {
UIManager.setLookAndFeel(com.sun.java.swing.plaf.windows.WindowsLookAndFeel.class.getName());
} catch (Exception e1) {
e1.printStackTrace();
}
JFileChooser jfc = new JFileChooser(lastPath);
jfc.setDialogTitle("Save");
jfc.removeChoosableFileFilter(jfc.getAcceptAllFileFilter());//去除"所有文件"项
jfc.addChoosableFileFilter(new FileNameExtensionFilter("PNG (*.png)","png"));
jfc.addChoosableFileFilter(new FileNameExtensionFilter("BMP (*.bmp)","bmp"));
jfc.addChoosableFileFilter(new FileNameExtensionFilter("JPEG (*.jpg;*.jpeg)","jpg"));
int retVal = jfc.showSaveDialog(jf);
if(retVal == JFileChooser.APPROVE_OPTION){
File f = jfc.getSelectedFile();
lastPath = jfc.getCurrentDirectory().getAbsolutePath();
//System.out.println("lastPath changes="+lastPath);
FileNameExtensionFilter ff = (FileNameExtensionFilter)jfc.getFileFilter();//得到当前的文件过滤器
String[] extendList = ff.getExtensions();
String extendName = null; int i;
//System.out.println("list length is "+extendList.length);
for(i=0;i<extendList.length;i++){
/**如果f扩展名在扩展名列表中就break,否则自动加上,默认第一个**/
if(f.getName().endsWith(extendList[i])){
extendName = extendList[i];
break;
}
}
if(i == extendList.length){
extendName = extendList[0];
f = new File(f.getAbsolutePath()+"."+extendName);
}
//System.out.println("save as="+f.getName()+" extension = "+extendName);
try {
ImageIO.write(clipArea(),extendName,f);
} catch (IOException e) {
e.printStackTrace();
}
}
if(File.separator.equals("\\"))//判断是windows系统
try {
UIManager.setLookAndFeel(javax.swing.plaf.metal.MetalLookAndFeel.class.getName());
} catch (Exception e1) {
e1.printStackTrace();
}
clean();
enterBusy = false;
}
private void isSelExist() {
ss.jp.removeAll();
ss.jp.updateUI();
}
JPanel selPanel;
JButton ok = null, cancel = null, save = null;
public volatile boolean isDrag = false;
public void mouseDragged(MouseEvent e) {
if(isProcess){
/**
* 判断拖拽拉伸类型,然后处理。
*/
dragPro(e);
}else{
/**获取的新的拖拽点必须加工后才能送到绘图板。**/
end = e.getPoint();
ss.jp.updateUI();//这个必须要。
isDrag = true;
}
}
private void dragPro(MouseEvent e){
Point curPos = e.getPoint();
switch(dragType){
case DRAG_MOVE:
start.x = startCopy.x+curPos.x- prePos.x;
start.y = startCopy.y+curPos.y-prePos.y;
end.x = endCopy.x+curPos.x- prePos.x;
end.y = endCopy.y+curPos.y-prePos.y;
break;
case DRAG_UPLEFT:
/** start更新为拖动点 **/
start = new Point(curPos);
break;
case DRAG_UP:
/** 只需要更新start.y **/
start.y = curPos.y;
break;
case DRAG_UPRIGHT:
/** 只需要更新start.y和end.x**/
start.y = curPos.y;
end.x = curPos.x;
break;
case DRAG_RIGHT:
end.x = curPos.x;
break;
case DRAG_BOTTOMRIGHT:
end = new Point(curPos);
break;
case DRAG_BOTTOM:
end.y = curPos.y;
break;
case DRAG_BOTTOMLEFT:
start.x = curPos.x;
end.y = curPos.y;
break;
case DRAG_LEFT:
start.x = curPos.x;
break;
default:
}
reLocateSel();
ss.jp.updateUI();
}
/**
* 纠正方向使得start始终是矩形左上角,stop始终是矩形右下角。
**/
private void correctDir() {
Point p;
//一共四个方向。
//右下角
if ((start.x <= end.x) && (start.y <= end.y)) {
return;
} else if ((start.x <= end.x) && (start.y > end.y)) {
//右上角
p = new Point(start);
start.y = end.y;
end.y = p.y;
} else if ((start.x > end.x) && (start.y <= end.y)) {
//左下角
p = new Point(end);
end.y = start.y;
start.y = p.y;
swap();
} else {
swap();
}
}
private void swap() {
Point p = start;
start = end;
end = p;
}
@Override
public void mouseMoved(MouseEvent e) {
/**鼠标移动自动判断当前哪个矩形中**/
if(isProcess){
Point p = e.getPoint();
if(new Rectangle(start.x-BREADTH, start.y-BREADTH,BREADTH2,BREADTH2).contains(p)){
/**stretch upper-left**/
dragType = DRAG_UPLEFT;
jf.setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
}else if(new Rectangle(start.x+BREADTH, start.y-BREADTH,end.x-start.x-BREADTH2,BREADTH2).contains(p)){
/**stretch upper**/
dragType = DRAG_UP;
jf.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
}else if(new Rectangle(end.x-BREADTH, start.y-BREADTH,BREADTH2,BREADTH2).contains(p)){
/**stretch upper-right**/
dragType = DRAG_UPRIGHT;
jf.setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
}else if(new Rectangle(end.x-BREADTH, start.y+BREADTH,BREADTH2,end.y-start.y-BREADTH2).contains(p)){
/**stretch right**/
dragType = DRAG_RIGHT;
jf.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
}else if(new Rectangle(end.x-BREADTH, end.y-BREADTH,BREADTH2,BREADTH2).contains(p)){
/**stretch bottom-right**/
dragType = DRAG_BOTTOMRIGHT;
jf.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
}else if(new Rectangle(start.x+BREADTH, end.y-BREADTH,end.x-start.x-BREADTH2,BREADTH2).contains(p)){
/**stretch bottom**/
dragType = DRAG_BOTTOM;
jf.setCursor(new Cursor(Cursor.S_RESIZE_CURSOR));
}else if(new Rectangle(start.x-BREADTH, end.y-BREADTH,BREADTH2,BREADTH2).contains(p)){
/**stretch bottom-left**/
dragType = DRAG_BOTTOMLEFT;
jf.setCursor(new Cursor(Cursor.SW_RESIZE_CURSOR));
}else if(new Rectangle(start.x-BREADTH, start.y+BREADTH,BREADTH2,end.y-start.y-BREADTH2).contains(p)){
/**stretch left**/
dragType = DRAG_LEFT;
jf.setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
}else if(new Rectangle(start.x,start.y,end.x-start.x,end.y-start.y).contains(p)){
/**如果在矩形内部,那么就是拖动**/
dragType = DRAG_MOVE;
jf.setCursor(new Cursor(Cursor.MOVE_CURSOR));
}else{
dragType = DRAG_NONE;
jf.setCursor(myCursor);
}
return;
}
if (ss.jp.isDrag()) {
return;
}
Rectangle r;
for (int i = 0; i < winLayer.size(); i++) {
r = winLayer.get(i);
if (r.contains(e.getPoint())) {
//System.out.println("当前在矩形"+i+"中");
start.x = r.getX() >= 0 ? (int) r.getX() : 0;
start.y = r.getY() >= 0 ? (int) r.getY() : 0;
end.x = start.x + (int) r.getWidth();
end.y = start.y + (int) r.getHeight();
ss.jp.setMove(true);
ss.jp.updateUI();//这个必须要。
return;//无须往下搜索。
}
}
}
}
public class Images implements Transferable {
private Image image; //得到图片或者图片流
public Images(Image image) {
this.image = image;
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.imageFlavor};
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (!DataFlavor.imageFlavor.equals(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return image;
}
}
void initHotkey() {
JIntellitype.getInstance().registerHotKey(shotHotKey, JIntellitype.MOD_CONTROL + JIntellitype.MOD_ALT,
(int)(screenShot.jtf.getText().toCharArray()[0]));
JIntellitype.getInstance().addHotKeyListener(this);
}
}