JAVA截屏程序(第三版)

JAVA截屏程序(第三版)
呵呵,昨天也看到朋友的留言,又增加了一些功能,

1,增加了一个把截到的图片复制到系统的剪帖板,这样一来就可以直接粘帖到word,photoshop,画图等程序里面了

2,增加了每截一张图片都会新开一个tab来放它,并且tab里面各自有各自的操作方法.

点击下载源文件和可执行JAR文件

/*
 * CaptureScreen.java
 *
 * Created on 2007年8月30日, 下午12:46
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 
*/

package  hadeslee.swing;

/**
 *
 * 
@author  lbf
 
*/
import  java.awt. * ;
import  java.awt.datatransfer.DataFlavor;
import  java.awt.datatransfer.Transferable;
import  java.awt.datatransfer.UnsupportedFlavorException;
import  java.awt.event. * ;
import  javax.swing. * ;
import  java.io. * ;
import  javax.imageio. * ;
import  java.awt.image. * ;

public   class  CaptureScreen  extends  JFrame  implements  ActionListener{
    
private  JButton start,cancel;
    
private  JPanel c;
    
private  BufferedImage get;
    
private  JTabbedPane jtp; // 一个放置很多份图片
     private   int  index; // 一个一直会递增的索引,用于标认图片
     private  JRadioButton java,system; // JAVA界面,系统界面
     /**  Creates a new instance of CaptureScreen  */
    
public  CaptureScreen() {
        
super ( " 屏幕截取软件(第三版) " );
        
try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
catch (Exception exe){
            exe.printStackTrace();
        }
        initWindow();
        initOther();
    }
    
private   void  initOther(){
        jtp
= new  JTabbedPane(JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT);
    }
    
private   void  initWindow(){
        start
= new  JButton( " 开始截取 " );
        cancel
= new  JButton( " 退出 " );
        start.addActionListener(
this );
        cancel.addActionListener(
this );
        JPanel buttonJP
= new  JPanel();
        c
= new  JPanel( new  BorderLayout());
        JLabel jl
= new  JLabel( " 屏幕截取 " ,JLabel.CENTER);
        JLabel jl1
= new  JLabel( " 作者:千里冰封 " ,JLabel.CENTER);
        jl.setFont(
new  Font( " 黑体 " ,Font.BOLD, 40 ));
        jl1.setFont(
new  Font( " 宋体 " ,Font.BOLD, 20 ));
        jl.setForeground(Color.RED);
        jl1.setForeground(Color.BLUE);
        c.add(jl,BorderLayout.CENTER);
        c.add(jl1,BorderLayout.SOUTH);
        buttonJP.add(start);
        buttonJP.add(cancel);
        buttonJP.setBorder(BorderFactory.createTitledBorder(
" 公共操作区 " ));
        JPanel jp
= new  JPanel(); // 放两个单选按钮的面板
        jp.add(java = new  JRadioButton( " java界面 " ));
        jp.add(system
= new  JRadioButton( " 系统界面 " , true ));
        java.addActionListener(
this );
        system.addActionListener(
this );
        jp.setBorder(BorderFactory.createTitledBorder(
" 界面风格 " ));
        ButtonGroup bg
= new  ButtonGroup();
        bg.add(java);
        bg.add(system);
        JPanel all
= new  JPanel();
        all.add(jp);
        all.add(buttonJP);
        
this .getContentPane().add(c,BorderLayout.CENTER);
        
this .getContentPane().add(all,BorderLayout.SOUTH);
        
this .setSize( 500 , 400 );
        
this .setLocationRelativeTo( null );
        
this .setVisible( true );
        
this .setAlwaysOnTop( true );
        
this .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
private   void  updates(){
        
this .setVisible( true );
        
if (get != null ){
            
// 如果索引是0,则表示一张图片都没有被加入过,
            
// 则要清除当前的东西,重新把tabpane放进来
             if (index == 0 ){
                c.removeAll();
                c.add(jtp,BorderLayout.CENTER);
            }
else { // 否则的话,直接对tabpane添加面板就可以了
                
// 就什么都不用做了
            }
            PicPanel pic
= new  PicPanel(get);
            jtp.addTab(
" 图片 " + ( ++ index),pic);
            jtp.setSelectedComponent(pic);
            SwingUtilities.updateComponentTreeUI(c);
        }
    }
    
private   void  doStart(){
        
try {
            
this .setVisible( false );
            Thread.sleep(
500 ); // 睡500毫秒是为了让主窗完全不见
            Robot ro = new  Robot();
            Toolkit tk
= Toolkit.getDefaultToolkit();
            Dimension di
= tk.getScreenSize();
            Rectangle rec
= new  Rectangle( 0 , 0 ,di.width,di.height);
            BufferedImage bi
= ro.createScreenCapture(rec);
            JFrame jf
= new  JFrame();
            Temp temp
= new  Temp(jf,bi,di.width,di.height);
            jf.getContentPane().add(temp,BorderLayout.CENTER);
            jf.setUndecorated(
true );
            jf.setSize(di);
            jf.setVisible(
true );
            jf.setAlwaysOnTop(
true );
        } 
catch (Exception exe){
            exe.printStackTrace();
        }
    }
    
/**
     *公用的处理保存图片的方法
     *这个方法不再私有了
     
*/
    
public    void  doSave(BufferedImage get){
        
try {
            
if (get == null ){
                JOptionPane.showMessageDialog(
this , " 图片不能为空!! " , " 错误 " ,JOptionPane.ERROR_MESSAGE);
                
return ;
            }
            JFileChooser jfc
= new  JFileChooser( " . " );
            jfc.addChoosableFileFilter(
new  GIFfilter());
            jfc.addChoosableFileFilter(
new  BMPfilter());
            jfc.addChoosableFileFilter(
new  JPGfilter());
            jfc.addChoosableFileFilter(
new  PNGfilter());
            
int  i = jfc.showSaveDialog( this );
            
if (i == JFileChooser.APPROVE_OPTION){
                File file
= jfc.getSelectedFile();
                String about
= " PNG " ;
                String ext
= file.toString().toLowerCase();
                javax.swing.filechooser.FileFilter ff
= jfc.getFileFilter();
                
if (ff  instanceof  JPGfilter){
                    
if ( ! ext.endsWith( " .jpg " )){
                        String ns
= ext + " .jpg " ;
                        file
= new  File(ns);
                        about
= " JPG " ;
                    }
                } 
else   if (ff  instanceof  PNGfilter){
                    
if ( ! ext.endsWith( " .png " )){
                        String ns
= ext + " .png " ;
                        file
= new  File(ns);
                        about
= " PNG " ;
                    }
                }
else   if (ff  instanceof  BMPfilter){
                    
if ( ! ext.endsWith( " .bmp " )){
                        String ns
= ext + " .bmp " ;
                        file
= new  File(ns);
                        about
= " BMP " ;
                    }
                }
else   if (ff  instanceof  GIFfilter){
                    
if ( ! ext.endsWith( " .gif " )){
                        String ns
= ext + " .gif " ;
                        file
= new  File(ns);
                        about
= " GIF " ;
                    }
                }
                
if (ImageIO.write(get,about,file)){
                    JOptionPane.showMessageDialog(
this , " 保存成功! " );
                } 
else
                    JOptionPane.showMessageDialog(
this , " 保存失败! " );
            }
        } 
catch (Exception exe){
            exe.printStackTrace();
        }
    }
    
/**  
     *公共的处理把当前的图片加入剪帖板的方法
     
*/
    
public   void  doCopy( final  BufferedImage image){
        
try {
            
if (get == null ){
                JOptionPane.showMessageDialog(
this , " 图片不能为空!! " , " 错误 " ,JOptionPane.ERROR_MESSAGE);
                
return ;
            }
            Transferable trans 
=   new  Transferable(){
                
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 (isDataFlavorSupported(flavor))
                        
return  image;
                    
throw   new  UnsupportedFlavorException(flavor);
                }
                
            };
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, 
null );
            JOptionPane.showMessageDialog(
this , " 已复制到系统粘帖板!! " );
        }
catch (Exception exe){
            exe.printStackTrace();
            JOptionPane.showMessageDialog(
this , " 复制到系统粘帖板出错!! " , " 错误 " ,JOptionPane.ERROR_MESSAGE);
        }
    }
    
// 处理关闭事件
     private   void  doClose(Component c){
        jtp.remove(c);
        c
= null ;
        System.gc();
    }
    
public   void  actionPerformed(ActionEvent ae){
        Object source
= ae.getSource();
        
if (source == start){
            doStart();
        } 
else   if (source == cancel){
            System.exit(
0 );
        }
else   if (source == java){
            
try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                SwingUtilities.updateComponentTreeUI(
this );
            }
catch (Exception exe){
                exe.printStackTrace();
            }
        }
else   if (source == system){
            
try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                SwingUtilities.updateComponentTreeUI(
this );
            }
catch (Exception exe){
                exe.printStackTrace();
            }
        }
    }
    
// 一个内部类,它表示一个面板,一个可以被放进tabpane的面板
    
// 也有自己的一套处理保存和复制的方法
     private   class  PicPanel  extends  JPanel  implements  ActionListener{
        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  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);
            
if (showTip){
                p
= me.getPoint();
                repaint();
            }
        }
        
// 特意定义一个方法处理鼠标移动,是为了每次都能初始化一下所要选择的地区
         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();
                    }
                    
                }
            }
        }
    }
    
    
public   static   void  main(String args[]){
        SwingUtilities.invokeLater(
new  Runnable(){
            
public   void  run(){
                
new  CaptureScreen();
            }
        });
    }
}
// 一些表示状态的枚举
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  Cursor getCursor(){
        
return  cs;
    }
}


尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.

你可能感兴趣的:(JAVA截屏程序(第三版))