- 浏览: 462886 次
- 性别:
- 来自: 长沙
文章分类
- 全部博客 (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 2939既然 sdtm1016 兄 给出新的建议,那我们就继续完善下 ... -
Swing 实现截图小软件 (五)
2011-03-01 12:13 2216应大家的要求, 继续完善截图小软件。 这次增加两个功能: ... -
Swing 实现截图小软件 (四)
2011-02-25 12:14 1588接上一节, 我们的截图小软件,功能基本完成,就剩下最后的 ... -
Swing 实现截图小软件 (二)
2011-02-23 23:10 2073刚才写了 Swing 实现截图小软件(一)后,点击“保存 ... -
Swing 实现截图小软件 (一)
2011-02-23 23:09 2109软件功能: ... -
Swing 做的一個模仿 阿里旺旺 的界面
2010-05-19 17:39 2059有朋友向我要,“Swing做的QQ登陸介面”的源碼,呵呵,不好 ... -
Swing 做了一个模仿QQ2009的登录界面
2009-06-23 10:10 3693今天用Swing 做了一个模仿QQ2009的登录界面,用到了开 ...
相关推荐
NULL 博文链接:https://pengranxiang.iteye.com/blog/935433
本项目是使用Swing实现的一个仿QQ截图小工具,它旨在提供类似QQ截图的功能,让用户在桌面环境中能够方便地进行屏幕截图并进行编辑。 首先,Swing组件库提供了丰富的组件,如JFrame、JButton、JPanel等,这些组件...
以下是对这个"java swing 截屏软件实现"的详细知识点解析: 1. **Swing组件**: Swing提供了一套丰富的组件库,如JFrame、JButton、JLabel等,用于构建用户界面。在这个截屏软件中,可能会用到JFrame作为主窗口,...
java swing 实现的带启动界面的简易截图软件,启动界面有进度条,可保存可粘贴到qq微信,简单实用
总的来说,用Java Swing实现一个PDF阅读器是一个涉及多方面技能的任务,包括对PDF格式的理解、Java GUI编程、IO操作以及第三方库的熟练使用。通过不断学习和实践,可以构建出功能强大且用户友好的PDF阅读器。
java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java swing实现学生住宿管理系统(源码) java ...
【Swing小管理项目源码】是一个基于Java Swing开发的桌面应用程序示例,它涵盖了多个核心功能,包括用户界面的设计、数据操作以及交互逻辑。Swing是Java的标准库,用于构建图形用户界面(GUI),提供了丰富的组件库...
本项目是一套基于Java Swing实现的日历记事本系统,主要针对计算机相关专业的正在学习java的学生与需要项目实战练习的Java学习者。 包含:项目源码、报告文档等。 项目都经过严格调试,确保可以运行! 该系统功能...
最后,作者想说的是,1.9块钱的资源,你买不了吃亏,买不了上当,只需省一片绿箭口香糖的钱,你就能拥有一个用于整蛊的Java Swing实现,你在玩的过程中,还可以初步了解一些Java Swing的知识,如此说来,少年,抓紧时间下载吧。
java贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇javaswing实现贪吃蛇...
这个“Java基于Swing实现的简单聊天室,支持多人在线闲谈.zip”文件是一个示例项目,展示了如何利用Swing构建一个基本的多用户聊天应用。下面将详细阐述其涉及的关键知识点。 1. **Swing组件**:Swing提供了丰富的...
在这个特定的Demo中,我们关注的是如何使用Swing来实现一个商品列表,其中包含商品的数量加减功能以及整行删除的功能。这个功能通常在电商应用或者库存管理软件中会用到。 首先,我们需要了解`JTable`,这是Swing中...
本项目"java swing写的聊天软件"利用了Swing组件来设计和实现了一个能够支持多达1000个用户同时在线的聊天应用。以下是关于这个聊天软件的关键知识点和实现细节: 1. **Swing组件库**:Swing 提供了丰富的组件,如...
java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源代码java小游戏 (源码)swing五子棋源...
8. Java swing组件的使用:Java swing组件可以用于创建各种图形化用户界面,例如计算器、游戏、聊天软件等。 9. 计算器的实现:计算器是Java swing组件中的一种常见应用,通过使用JFrame、JButton、JPanel、...
标题中的“Swing写的一个简易记事小软件”指的是使用Java Swing库开发的一款简单应用程序,主要用于记录日常事项。Swing是Java提供的一种图形用户界面(GUI)工具包,它允许开发者创建桌面应用,包括窗口、按钮、...
本项目是一套Java swing实现的一款餐厅点餐系统,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目可以直接作为bishe使用。 项目都经过严格调试,...
"java 截屏 swing"这个主题涉及到的是如何利用Swing来实现屏幕截图功能。在这个项目中,开发人员创建了一个应用程序,允许用户选择屏幕上的任意矩形区域进行截图,未被选中的部分会显示为阴影效果,同时支持拖动和...
《Java Swing实现学生信息管理系统》是一个基于Java Swing GUI工具集开发的应用程序,旨在提供一个高效、直观的方式来管理学校或教育机构中学生的信息。该系统的核心功能包括学生信息的录入、查询、更新和删除。通过...
【Java Swing制作的通讯录软件与SQL数据库连接】 在编程领域,Java Swing 是一个用于创建图形用户界面(GUI)的工具包,它提供了丰富的组件和功能,使得开发者能够构建出功能完善的桌面应用。本项目是一个基于Java ...