解决方案 »

  1.   

    下面是上贴中小弟未写完的源代码:
             //一个内部类,它表示一个面板,一个可以被放进tabpane的面板
        //也有自己的一套处理保存和复制的方法
        private class PicPanel extends JPanel implements ActionListener{
            /**
     * 
     */
    private static final long serialVersionUID = 1L;
    JButton save,copy,close;//表示保存,复制,关闭的按钮
            BufferedImage get;//得到的图片
            public PicPanel(BufferedImage get){
                super(new BorderLayout());
                this.get=get;
                initPanel();
            }
            private void initPanel(){
                save=new JButton("保存(S)");
                copy=new JButton("复制到剪帖板(C)");
                close=new JButton("关闭(X)");
                save.setMnemonic('S');
                copy.setMnemonic('C');
                close.setMnemonic('X');
                JPanel buttonPanel=new JPanel();
                buttonPanel.add(copy);
                buttonPanel.add(save);
                buttonPanel.add(close);
                JLabel icon=new JLabel(new ImageIcon(get));
                this.add(new JScrollPane(icon),BorderLayout.CENTER);
                this.add(buttonPanel,BorderLayout.SOUTH);
                save.addActionListener(this);
                copy.addActionListener(this);
                close.addActionListener(this);
            }
            public void actionPerformed(ActionEvent e) {
                Object source=e.getSource();
                if(source==save){
                    doSave(get);
                }else if(source==copy){
                    doCopy(get);
                }else if(source==close){
                    get=null;
                    doClose(this);
                }
            }
        }
        
        //保存BMP格式的过滤器
        private class BMPfilter extends javax.swing.filechooser.FileFilter{
            public BMPfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".bmp")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.BMP(BMP图像)";
            }
        }
        
        //保存JPG格式的过滤器
        private class JPGfilter extends javax.swing.filechooser.FileFilter{
            public JPGfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".jpg")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.JPG(JPG图像)";
            }
        }
        
        //保存GIF格式的过滤器
        private class GIFfilter extends javax.swing.filechooser.FileFilter{
            public GIFfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".gif")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.GIF(GIF图像)";
            }
        }
        
        //保存PNG格式的过滤器
        private class PNGfilter extends javax.swing.filechooser.FileFilter{
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".png")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.PNG(PNG图像)";
            }
        }
        
        //一个临时类,用于显示当前的屏幕图像
        private class Temp extends JPanel implements MouseListener,MouseMotionListener{
            /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private BufferedImage bi;
            private int width,height;
            private int startX,startY,endX,endY,tempX,tempY;
            private JFrame jf;
            private Rectangle select=new Rectangle(0,0,0,0);//表示选中的区域
            private Cursor cs=new Cursor(Cursor.CROSSHAIR_CURSOR);//表示一般情况下的鼠标状态(十字线)
            private States current=States.DEFAULT;// 表示当前的编辑状态
            private Rectangle[] rec;//表示八个编辑点的区域
            //下面四个常量,分别表示谁是被选中的那条线上的端点
            public static final int START_X=1;
            public static final int START_Y=2;
            public static final int END_X=3;
            public static final int END_Y=4;
            private int currentX,currentY;//当前被选中的X和Y,只有这两个需要改变
            private Point p=new Point();//当前鼠标移的地点
            private boolean showTip=true;//是否显示提示.如果鼠标左键一按,则提示就不再显示了
            
            public Temp(JFrame jf,BufferedImage bi,int width,int height){
                this.jf=jf;
                this.bi=bi;
                this.width=width;
                this.height=height;
                this.addMouseListener(this);
                this.addMouseMotionListener(this);
                initRecs();
            }
            
            private void initRecs(){
                rec=new Rectangle[8];
                for(int i=0;i<rec.length;i++){
                    rec[i]=new Rectangle();
                }
            }
            
            public void paintComponent(Graphics g){
                g.drawImage(bi,0,0,width,height,this);
                g.setColor(Color.RED);
                g.drawLine(startX,startY,endX,startY);
                g.drawLine(startX,endY,endX,endY);
                g.drawLine(startX,startY,startX,endY);
                g.drawLine(endX,startY,endX,endY);
                int x=startX<endX?startX:endX;
                int y=startY<endY?startY:endY;
                select=new Rectangle(x,y,Math.abs(endX-startX),Math.abs(endY-startY));
                int x1=(startX+endX)/2;
                int y1=(startY+endY)/2;
                g.fillRect(x1-2,startY-2,5,5);
                g.fillRect(x1-2,endY-2,5,5);
                g.fillRect(startX-2,y1-2,5,5);
                g.fillRect(endX-2,y1-2,5,5);
                g.fillRect(startX-2,startY-2,5,5);
                g.fillRect(startX-2,endY-2,5,5);
                g.fillRect(endX-2,startY-2,5,5);
                g.fillRect(endX-2,endY-2,5,5);
                rec[0]=new Rectangle(x-5,y-5,10,10);
                rec[1]=new Rectangle(x1-5,y-5,10,10);
                rec[2]=new Rectangle((startX>endX?startX:endX)-5,y-5,10,10);
                rec[3]=new Rectangle((startX>endX?startX:endX)-5,y1-5,10,10);
                rec[4]=new Rectangle((startX>endX?startX:endX)-5,(startY>endY?startY:endY)-5,10,10);
                rec[5]=new Rectangle(x1-5,(startY>endY?startY:endY)-5,10,10);
                rec[6]=new Rectangle(x-5,(startY>endY?startY:endY)-5,10,10);
                rec[7]=new Rectangle(x-5,y1-5,10,10);
                if(showTip){
                    g.setColor(Color.CYAN);
                    g.fillRect(p.x,p.y,170,20);
                    g.setColor(Color.RED);
                    g.drawRect(p.x,p.y,170,20);
                    g.setColor(Color.BLACK);
                    g.drawString("请按住鼠标左键不放选择截图区",p.x,p.y+15);
                }
            }
            
            //根据东南西北等八个方向决定选中的要修改的X和Y的座标
            private void initSelect(States state){
                switch(state){
                    case DEFAULT:
                        currentX=0;
                        currentY=0;
                        break;
                    case EAST:
                        currentX=(endX>startX?END_X:START_X);
                        currentY=0;
                        break;
                    case WEST:
                        currentX=(endX>startX?START_X:END_X);
                        currentY=0;
                        break;
                    case NORTH:
                        currentX=0;
                        currentY=(startY>endY?END_Y:START_Y);
                        break;
                    case SOUTH:
                        currentX=0;
                        currentY=(startY>endY?START_Y:END_Y);
                        break;
                    case NORTH_EAST:
                        currentY=(startY>endY?END_Y:START_Y);
                        currentX=(endX>startX?END_X:START_X);
                        break;
                    case NORTH_WEST:
                        currentY=(startY>endY?END_Y:START_Y);
                        currentX=(endX>startX?START_X:END_X);
                        break;
                    case SOUTH_EAST:
                        currentY=(startY>endY?START_Y:END_Y);
                        currentX=(endX>startX?END_X:START_X);
                        break;
                    case SOUTH_WEST:
                        currentY=(startY>endY?START_Y:END_Y);
                        currentX=(endX>startX?START_X:END_X);
                        break;
                    default:
                        currentX=0;
                        currentY=0;
                        break;
                }
            }
            
            public void mouseMoved(MouseEvent me){
                doMouseMoved(me);
                initSelect(current); // current:当前状态(state)
                if(showTip){
                    p=me.getPoint();
                    repaint();
                }
            }
            
           
            
      

  2.   

     //特意定义一个方法处理鼠标移动,是为了每次都能初始化一下所要选择的区域
            private void doMouseMoved(MouseEvent me){
                if(select.contains(me.getPoint())){
                    this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
                    current=States.MOVE;
                } else{
                    States[] st=States.values();
                    for(int i=0;i<rec.length;i++){
                        if(rec[i].contains(me.getPoint())){
                            current=st[i];
                            this.setCursor(st[i].getCursor());
                            return;
                        }
                    }
                    this.setCursor(cs);
                    current=States.DEFAULT;
                }
            }
            
            public void mouseExited(MouseEvent me){
            }
            
            public void mouseEntered(MouseEvent me){
            }
            
            public void mouseDragged(MouseEvent me){
                int x=me.getX();
                int y=me.getY();
                // 分别处理一系列的(光标)状态(枚举值)
                if(current==States.MOVE){
                    startX+=(x-tempX);
                    startY+=(y-tempY);
                    endX+=(x-tempX);
                    endY+=(y-tempY);
                    tempX=x;
                    tempY=y;
                }else if(current==States.EAST||current==States.WEST){
                    if(currentX==START_X){
                        startX+=(x-tempX);
                        tempX=x;
                    }else{
                        endX+=(x-tempX);
                        tempX=x;
                    }
                }else if(current==States.NORTH||current==States.SOUTH){
                    if(currentY==START_Y){
                        startY+=(y-tempY);
                        tempY=y;
                    }else{
                        endY+=(y-tempY);
                        tempY=y;
                    }
                }else if(current==States.NORTH_EAST||current==States.NORTH_EAST||
                        current==States.SOUTH_EAST||current==States.SOUTH_WEST){
                    if(currentY==START_Y){
                        startY+=(y-tempY);
                        tempY=y;
                    }else{
                        endY+=(y-tempY);
                        tempY=y;
                    }
                    if(currentX==START_X){
                        startX+=(x-tempX);
                        tempX=x;
                    }else{
                        endX+=(x-tempX);
                        tempX=x;
                    }                
                }else{
                    startX=tempX;
                    startY=tempY;
                    endX=me.getX();
                    endY=me.getY();
                }
                this.repaint();
            }
            
            public void mousePressed(MouseEvent me){
                showTip=false;
                tempX=me.getX();
                tempY=me.getY();
            }
            
            public void mouseReleased(MouseEvent me){
                if(me.isPopupTrigger()){ // 右键
                    if(current==States.MOVE){
                        showTip=true;
                        p=me.getPoint();
                        startX=0;
                        startY=0;
                        endX=0;
                        endY=0;
                        repaint();
                    } else{ // 普通情况
                        jf.dispose();
                        updates();
                    }
                }
            }
            
            public void mouseClicked(MouseEvent me){
                if(me.getClickCount()==2){
                    //Rectangle rec=new Rectangle(startX,startY,Math.abs(endX-startX),Math.abs(endY-startY));
                    Point p=me.getPoint();
                    if(select.contains(p)){
                        if(select.x+select.width<this.getWidth()&&select.y+select.height<this.getHeight()){
                            get=bi.getSubimage(select.x,select.y,select.width,select.height);
                            jf.dispose();
                            updates();
                        }else{
                            int wid=select.width,het=select.height;
                            if(select.x+select.width>=this.getWidth()){
                                wid=this.getWidth()-select.x;
                            }
                            if(select.y+select.height>=this.getHeight()){
                                het=this.getHeight()-select.y;
                            }
                            get=bi.getSubimage(select.x,select.y,wid,het);
                            jf.dispose();
                            updates();
                        }
                    }
                }
            }
        } @Override
    public void windowActivated(WindowEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void windowClosed(WindowEvent arg0) {
    // TODO Auto-generated method stub
    this.dispose();
    } @Override
    public void windowClosing(WindowEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void windowDeactivated(WindowEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void windowDeiconified(WindowEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void windowIconified(WindowEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void windowOpened(WindowEvent arg0) {
    // TODO Auto-generated method stub

    }
    }//一些表示状态的枚举
    enum States{
        NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)),//表示西北角
        NORTH(new Cursor(Cursor.N_RESIZE_CURSOR)),
        NORTH_EAST(new Cursor(Cursor.NE_RESIZE_CURSOR)),
        EAST(new Cursor(Cursor.E_RESIZE_CURSOR)),
        SOUTH_EAST(new Cursor(Cursor.SE_RESIZE_CURSOR)),
        SOUTH(new Cursor(Cursor.S_RESIZE_CURSOR)),
        SOUTH_WEST(new Cursor(Cursor.SW_RESIZE_CURSOR)),
        WEST(new Cursor(Cursor.W_RESIZE_CURSOR)),
        MOVE(new Cursor(Cursor.MOVE_CURSOR)),
        DEFAULT(new Cursor(Cursor.DEFAULT_CURSOR));
        
        private Cursor cs;
        
        States(Cursor cs){
            this.cs=cs;
        }
        
        public static void main(String[] args){
         new CaptureScreen();
        }
        
        public Cursor getCursor(){
            return cs;
        }
    }
            高手,上面的类型运行后,效果如下:
             
             我做了一个全局键盘监视器,能够让我的用户点击组合键后,直接把上面的窗口调用出来.
             但是我看到:
             我的用户希望能够在“长期使用”我的软件作品的过程中,希望能够“尽可能节省自己的时间”,我看到:
             腾讯的QQ,在点击了快捷键的时候,能够:“直接画取图片的区域”.
             上面的代码经过我的初步研究,我把第一张帖子中的第19行代码修改成了下面的结果:
             public static void main(String[] args){
         new CaptureScreen().doStart();
        }
             
    运行后的效果,还是有“上面图片中的运行界面的一闪而过”,让用户的体验,不是最佳.
             并且,高手,您可以运行一下小弟贴出的代码,他在用户画完取图片的区域后,“双击图片区域”,出现下面的界面:
             
            这也是没有QQ的取图片功能强劲的一点:
            QQ能够让用户“点击一下”,“进行保存到文件”的选择,“点击两下”,“进行保存到剪贴板的功能直接调用”.
            可是在上面的取图片的功能中,如果把这个功能嵌入我的系统,将会有:
            让用户在这个功能上感到很麻烦,从而让我的IM在这个字段上输给QQ的缺陷出现.
            希望能够得到高手的指导:
            小弟上面的代码,如何修改,能够把“图片1”中的界面让小弟调用了本类型后,能够像QQ一样,直接进行图片的取图区域的选择,并且,如何修改,能够让小弟贴出的第二张图片上面代码所输给腾讯的字段,进行优化?
            希望得到高手的指导!!!!!
      

  3.   

    真心膜拜,如果不用JS插件什么的,用C#语言,打死我也写不出。只能帮楼主顶一下
      

  4.   

    可以在双击之后弹出的界面上加个保存按钮,保存按钮绑定click事件。click事件中弹出个路劲,保存动作是将File写到指定路劲。
      

  5.   

    谢谢4#楼的亲自提示!!!!
           小弟将把今后发送私信的频率,减少到原先的“5%".
           谢谢5#楼的CSDN技术无冕帝王withiter版主的再次亲临指导!!!!
           谢谢#6楼的郎晴大哥的精神鼓励!!!!
           小弟感谢CSDN的技术培养与诸位大大的不断帮助!!
           有CSDN!!!!无小弟的梦想不落地开花结果!!!!!!
      

  6.   

    请问withiter版主:
            QQ实现的”选择取图片的区域“的”选框画完后“”能够直接选择保存按钮“的功能,是怎么实现的?
            是借助了什么机制和方法做出来的?
            双击添加到剪切板,是一个相对比较好实现的功能.
            但是,在用户选择完毕后,出现的这个界面:
            
            版主,请问:
            QQ是通过什么技术方法实现的”用户选择完毕后“,“能够让下面的工具栏出现”的功能的.
            腾讯用了什么方法,什么类型实现的这个功能
            谢谢CSDN无冕帝王
      

  7.   

    楼主,代码还是有bug,刚刚测试了下,就是画了框后,你拖动右上角的箭头,他会出现重画。
    希望改善。
       不过总体效果还是不错。
      

  8.   

    总而言之,企图用java而不是用C/C++和QQ拼截图UI,纯属自虐!
      

  9.   

    参考这个http://technet.microsoft.com/zh-cn/sysinternals/bb897434
      

  10.   

    再参考这个http://www.codeproject.com/Articles/29184/A-lovely-goldfish-desktop-pet-using-alpha-PNG-and