- 浏览: 457231 次
- 性别:
- 来自: 长沙
文章分类
- 全部博客 (132)
- Java (17)
- Eclipse (2)
- Struts2 (6)
- SWT (9)
- Java Web Start (2)
- Heritrix (4)
- Nutch (1)
- Internet (2)
- J2me (2)
- Windows (4)
- Swing (8)
- JavaScript (11)
- Hibernate (1)
- Spring (6)
- Mysql (9)
- Oracle (10)
- Linux (6)
- RESTful (3)
- XML (1)
- Flex (4)
- EL (1)
- Apache (4)
- VC (3)
- OpenSourceLicence (1)
- Tomcat (4)
- Tiles2 (1)
- nosql (6)
- else (4)
- Nginx (2)
最新评论
-
mzlogin:
然而并没有讲 hash 函数
深入理解HashMap(及hash函数的真正巧妙之处) -
czp11210:
hi,你这篇文章很好。有两个细节跟你确认下:1.你使用的amo ...
Mysql 基于 Amoeba 的 水平和垂直 分片 -
Mybeautiful:
It seems the amoeba doesn't sup ...
Mysql 基于 Amoeba 的 水平和垂直 分片 -
xs.cctv:
言简意赅。。。。。。
深入理解HashMap(及hash函数的真正巧妙之处) -
mnhkahn:
h & (length-1)这个其实还是一个模运算,只 ...
深入理解HashMap(及hash函数的真正巧妙之处)
前面两节完成了,截图软件的基本功能:全屏,区域截图 功能
本节实现:涂鸦
, 画线 ,
画圈 和
保存
第一步:实现涂鸦功能。
涂鸦也就是说:使用鼠标随意的拖动,去绘制随意的线条。那么就只需要在主程序的展示截图的JLabel中添加鼠标拖动监听。在鼠标每个移动点是绘制“一个点”,这样就可以按照鼠标的移动轨迹,来绘制任意的线条了。
按照上面的思路给出代码:SnapShoot.java
import java.awt.AWTException; import java.awt.Color; import java.awt.Container; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import javax.swing.GroupLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * 屏幕截图小程序 * @author pengranxiang * */ public class SnapShoot extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JButton snapButton; private JLabel imageLabel; private int x, y; //记录鼠标坐标 public SnapShoot() { initUI(); initLayout(); createAction(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(600, 400); this.setTitle("截图小工具"); this.setLocationRelativeTo(null); //居中 this.setVisible(true); } private void initUI() { snapButton = new JButton("开始截图(点右键退出)"); imageLabel = new JLabel(); } private void initLayout() { JPanel pane = new JPanel(); pane.add(imageLabel); JScrollPane imgScrollPane = new JScrollPane(pane); Container container = this.getContentPane(); GroupLayout layout = new GroupLayout(container); container.setLayout(layout); layout.setAutoCreateContainerGaps(true); layout.setAutoCreateGaps(true); GroupLayout.ParallelGroup hGroup = layout.createParallelGroup(); hGroup .addComponent(snapButton) .addComponent(imgScrollPane); layout.setHorizontalGroup(hGroup); GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup(); vGroup .addComponent(snapButton) .addComponent(imgScrollPane); layout.setVerticalGroup(vGroup); } private void createAction() { snapButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { //开启模拟屏幕,将显示截图的目标组件传入 new ScreenWindow(imageLabel); } catch (AWTException e1) { e1.printStackTrace(); } catch (InterruptedException e1) { e1.printStackTrace(); } } }); imageLabel.addMouseMotionListener(new MouseMotionListener() { public void mouseDragged(MouseEvent e) { x = e.getX(); y = e.getY(); //鼠标移动时,在imageLabel展示的图像中,绘制点 //1. 取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //2. 创建一个缓冲图形对象 bi BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = (Graphics2D) bi.getGraphics(); //3. 将截图的原始图像画到 bi g2d.drawImage(img, 0, 0, null); //4. 在鼠标所在的点,画一个点 g2d.setColor(Color.RED); //设置画笔颜色为红色 g2d.drawLine(x, y, x, y); //Java中没有提供点的绘制,使用起点和终点为同一个点的画线代替 g2d.dispose(); //5. 为了保留每一个点,不能直接使用imageLabel.getGraphics()来画, //需要使用imageLabel.setIcon()来直接将画了点的图像,设置到imageLabel中, //这样,在第一步中,取得img时,就为已经划过上一个点的图像了。 imageLabel.setIcon(new ImageIcon(bi)); } public void mouseMoved(MouseEvent e) { } }); } public static void main(String[] args) { new SnapShoot(); } }
运行该代码,发现在涂鸦时,跟踪鼠标画的点,太过分散,不连续。鼠标移动越快,点就越不连续。如图:
可见,在监听鼠标移动时,画点的速度,跟不上鼠标移动的速度。又图想到,如果把上面的散点全部连接起来,则可以构成一条平滑的线了。
于是:改变思路,由画点,改为画线。将鼠标移动监听到的每一个点,都首尾连接的画线。
节约篇幅:展示修改的部分代码,在createActon()中
imageLabel.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { //鼠标按下的点,作为画线的最初的起点 x = e.getX(); y = e.getY(); } }); imageLabel.addMouseMotionListener(new MouseMotionListener() { public void mouseDragged(MouseEvent e) { xEnd = e.getX(); yEnd = e.getY(); //鼠标移动时,在imageLabel展示的图像中,绘制点 //1. 取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //2. 创建一个缓冲图形对象 bi BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = (Graphics2D) bi.getGraphics(); //3. 将截图的原始图像画到 bi g2d.drawImage(img, 0, 0, null); //4. 在鼠标所在的点,画一个点 g2d.setColor(Color.RED); //设置画笔颜色为红色 g2d.drawLine(x, y, xEnd, yEnd); //将画点,改为画线 g2d.dispose(); //5. 为了保留每一个点,不能直接使用imageLabel.getGraphics()来画, //需要使用imageLabel.setIcon()来直接将画了点的图像,设置到imageLabel中, //这样,在第一步中,取得img时,就为已经划过上一个点的图像了。 imageLabel.setIcon(new ImageIcon(bi)); //下次画线起点是设置为这次画线的终点 x = xEnd; y = yEnd; } public void mouseMoved(MouseEvent e) { } });
改变思路后,涂鸦的线条效果,就好多了。如图:
第二步:实现画线功能。
画线的话,与涂鸦有点不同。 涂鸦是根据鼠标移动实时画线。 而画线功能要求是:从鼠标按下, 到鼠标弹起的两点之间画一条线段。鼠标移动时,只是展示最后效果,并不直接画上去。 鼠标弹起后,才真的画上去。
同时因为,有了连个功能,我们给个功能开关,是要涂鸦,还是要画线。
代码片段:createAction() 中
imageLabel.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { //鼠标按下的点,作为画线的最初的起点 x = e.getX(); y = e.getY(); } public void mouseReleased(MouseEvent e) { if(isLine) { //该方法只用作画线时处理 //鼠标弹起时需要将最后定为的图像 bi,调用imageLabel.setIcon()方法,设置进去。 //这样就可以将线段真的画进去了。为了使用变量 bi 将其转为 该类的private变量 imageLabel.setIcon(new ImageIcon(bi)); } } }); imageLabel.addMouseMotionListener(new MouseMotionListener() { public void mouseDragged(MouseEvent e) { if(isDoodle) { //涂鸦开关 xEnd = e.getX(); yEnd = e.getY(); //鼠标移动时,在imageLabel展示的图像中,绘制点 //1. 取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //2. 创建一个缓冲图形对象 bi bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = (Graphics2D) bi.getGraphics(); //3. 将截图的原始图像画到 bi g2d.drawImage(img, 0, 0, null); //4. 在鼠标所在的点,画一个点 g2d.setColor(Color.RED); //设置画笔颜色为红色 g2d.drawLine(x, y, xEnd, yEnd); //Java中没有提供点的绘制,使用起点和终点为同一个点的画线代替 g2d.dispose(); //5. 为了保留每一个点,不能直接使用imageLabel.getGraphics()来画, //需要使用imageLabel.setIcon()来直接将画了点的图像,设置到imageLabel中, //这样,在第一步中,取得img时,就为已经划过上一个点的图像了。 imageLabel.setIcon(new ImageIcon(bi)); //下次画线起点是设置为这次画线的终点 x = xEnd; y = yEnd; } if(isLine) { //画线开关 xEnd = e.getX(); yEnd = e.getY(); //鼠标移动时,在imageLabel展示的图像中,绘制点 //1. 取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); //2. 创建一个缓冲图形对象 bi bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = (Graphics2D) bi.getGraphics(); //3. 将截图的原始图像画到 bi g2d.drawImage(img, 0, 0, null); //4. 在鼠标所在的点,画一个点 g2d.setColor(Color.RED); //设置画笔颜色为红色 g2d.drawLine(x, y, xEnd, yEnd); //Java中没有提供点的绘制,使用起点和终点为同一个点的画线代替 g2d.dispose(); //5. 不需要保留在鼠标拖动过程中所画的线段,所以直接使用imageLabel.getGraphics()绘制 //这样imageLabel.getIcon()并没有被改变,所以每次都只到原始截图和多了一条线,即为最后效果的演示 Graphics g = imageLabel.getGraphics(); g.drawImage(bi, 0, 0, null); //将处理后的图片,画到imageLabel g.dispose(); } }
运行情况如图:
完整代码,见附件:SnapShoot1.jar 源码在 jar 包中。
第三步:实现画圈功能。
画圈的功能实现与画线就很想了, 只是修改一下,drawLine -- > drawOval
代码片段:
if(isLine) { g2d.drawLine(x, y, xEnd, yEnd); //Java中没有提供点的绘制,使用起点和终点为同一个点的画线代替 } if(isCircle) { //因为如果鼠标向上,或向左移动时,xEnd > x, yEnd > y ,所以画圆的起点要取两者中的较小的, //而宽度和高度是不能 < 0 的,所以取绝对值 g2d.drawOval(Math.min(x, xEnd), Math.min(y, yEnd), Math.abs(xEnd - x), Math.abs(yEnd - y)); }
运行如图:
完成代码见附件:SnapShoot2.jar 源码在 jar 包中。
第四步: 为了然该小软件有点用处,光截图,涂鸦之类的,只能看不能用。所以现在就加入 保存 功能吧。
代码片段:
chooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images", "jpg", "png"); chooser.setFileFilter(filter); saveButton = new JButton("保存"); saveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(imageLabel.getIcon() == null) { JOptionPane.showMessageDialog(SnapShoot.this, "没有图片信息,请先截图", "提示", JOptionPane.INFORMATION_MESSAGE); return; } File file = null; int returnVal = chooser.showOpenDialog(SnapShoot.this); if(returnVal == JFileChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); } //取得imageLabel中的图像 Image img = ((ImageIcon)imageLabel.getIcon()).getImage(); try { if(file != null) { ImageIO.write((BufferedImage)img, "png", file); JOptionPane.showMessageDialog(SnapShoot.this, "保存成功", "提示", JOptionPane.INFORMATION_MESSAGE); } } catch (IOException e1) { e1.printStackTrace(); } } });
运行如图:
完成代码见附件:SnapShoot3.jar 源码在 jar 包中
最后,界面是丑了点啦。。。
想要稍微让界面好看点,可以修改 LookAndFeel 为本地皮肤,修改 main()方法
public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame.setDefaultLookAndFeelDecorated(true); } catch (Exception e) { System.out.println("Error setting native LAF: " + e); } new SnapShoot(); }
如图:
完成代码见附件:SnapShoot.jar 源码在 jar 包中
到此,该小软件还剩下,水印功能。 明天继续。。。O(∩_∩)O~
- SnapShoot1.jar (16.6 KB)
- 下载次数: 196
- SnapShoot2.jar (17.8 KB)
- 下载次数: 167
- SnapShoot3.jar (19.7 KB)
- 下载次数: 169
- SnapShoot.jar (20.1 KB)
- 下载次数: 329
评论
发表评论
-
Swing 实现截图小软件 (六)
2011-03-02 17:32 2904既然 sdtm1016 兄 给出新的建议,那我们就继续完善下 ... -
Swing 实现截图小软件 (五)
2011-03-01 12:13 2154应大家的要求, 继续完善截图小软件。 这次增加两个功能: ... -
Swing 实现截图小软件 (四)
2011-02-25 12:14 1557接上一节, 我们的截图小软件,功能基本完成,就剩下最后的 ... -
Swing 实现截图小软件 (二)
2011-02-23 23:10 2022刚才写了 Swing 实现截图小软件(一)后,点击“保存 ... -
Swing 实现截图小软件 (一)
2011-02-23 23:09 2082软件功能: ... -
Swing 做的一個模仿 阿里旺旺 的界面
2010-05-19 17:39 1994有朋友向我要,“Swing做的QQ登陸介面”的源碼,呵呵,不好 ... -
Swing 做了一个模仿QQ2009的登录界面
2009-06-23 10:10 3658今天用Swing 做了一个模仿QQ2009的登录界面,用到了开 ...
相关推荐
NULL 博文链接:https://pengranxiang.iteye.com/blog/935433
java swing 截屏软件实现,下载文件导入eclipse即可,可运行。
swing实现的仿qq截图小工具 功能比较完善 项目可直接导入Eclipse中 也可直接运行jar包查看效果
java swing 实现的带启动界面的简易截图软件,启动界面有进度条,可保存可粘贴到qq微信,简单实用
java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java ...
java贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇...
Java基于Swing实现的简单聊天室,支持多人在线闲谈.zip
java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源...
本项目是一套Java swing实现的一款餐厅点餐系统,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目可以直接作为bishe使用。 项目都经过严格调试,...
java swing mysql实现的酒店管理系统项目源码.zip java swing mysql实现的酒店管理系统项目源码.zip java swing mysql实现的酒店管理系统项目源码.zip java swing mysql实现的酒店管理系统项目源码.zip java swing ...
本项目是一套基于Java swing和mysql实现的银行管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。...
这个java项目是一个基于数据库的简单jdbc项目,只要在自己数据库中建立相应的表就可以实现操作。比较简单,可以帮助大家学习.
使用java swing和开源jar包jgraph完成的故障分析树软件。包含可执行jar文件,源代码,以及说明文档和演示的PPT,视频。 图形界面美观,自动由公式生成树形结构,也可以用鼠标增删改。支持图形和公式编辑以及切换。
基于java swing实现的贪吃蛇小游戏源码+可执行的jar文件
最后,作者想说的是,1.9块钱的资源,你买不了吃亏,买不了上当,只需省一片绿箭口香糖的钱,你就能拥有一个用于整蛊的Java Swing实现,你在玩的过程中,还可以初步了解一些Java Swing的知识,如此说来,少年,抓紧时间下载吧。
自己做的通讯录,主要是练习的,对初学者有用 导入工程之后要重新添加sqljdbc驱动,数据库没有给出,不过有创建数据库的语句了 采用布局管理,图片是直接存入数据库的(建议不用这个方法)
基于java的QQ截屏工具的设计和实现能够实现对屏幕的随机截取,复制,保存以及添加文字等操作,便于用户对数据的处理。 该软件的功能: (1)随机获取屏幕指定区域; (2)编辑(添加文字)截图; (3)存储...
用于swing学习,入门专用。实现了多线程通讯和私聊。
使用java swing技术实现的考勤工时计算工具,是有人找我专门定制的,通过ecxel报表上送考勤记录后再进行计算,数据存储使用的是sqllite
swing+socket的QQ简单通信,实现了简单的socket通信,添加查找好友,QQ对聊等功能.