java仿QQ截图带窗体检测

来源:互联网 发布:mysql登录后修改密码 编辑:程序博客网 时间:2024/05/17 23:10

最近用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);    }}

原创粉丝点击