这学期从零开始接触JAVA,最近做了第一个简单小程序XP版画图板,写一篇日志,既算是记录我JAVA学习的脚步,也算是对画图板开发的总结。
标题我写了画图板的设计思路和总结,其实说是设计思路,不如说在编写过程中必然会遇到的问题的解决顺序。首先需要建立一个画图板窗体,并在上面添加各种工具栏,菜单栏,按钮以及设定可绘制区域。然后通过给各个组件加上监听器来实现各种功能
一、窗体框架 界面设计
这个貌似没什么好说的,JFrame建立窗体,根据用途差异在窗体上加上几个不同大小和位置的JToolBar和JPanel,然后在上面加上按钮,按钮图标等比较多的时候,可以通过命名规则的控制循环添加组件。通过布局和诸如setBorder(new BevelBorder()等简单操作可以给界面带来很大程度的美化。
以下是一段较典型的添加并设置组件的代码示例:
//创建中间面板 javax.swing.JPanel centre = new MyPanel(); //设置中间画板背景颜色 centre.setBackground(java.awt.Color.GRAY); //设置布局 FlowLayout fl = new FlowLayout(FlowLayout.LEFT,1,1); centre.setLayout(fl); //创建画布对象 javax.swing.JPanel drawPanel = new javax.swing.JPanel(); //设置大小 drawPanel.setPreferredSize(new Dimension(500,350)); //设置画布背景颜色 drawPanel.setBackground(java.awt.Color.WHITE); centre.add(drawPanel);
二、监听器
要实现窗体界面上各个组件的设计功能,就必须在相应组件上加上监听器,并在监听器中写入方法,则相应事件发生时能激发预设的方法完成功能和操作。
我们可以新建一个监听器类,也可以直接写一个匿名内部监听器类。
监听器部分的难点主要是对象的传递,可能是习惯不好,我之前经常因为这个问题导致空指针错误。
三、重绘
要使窗体最小化后打开等操作后画板上依然显示相同图案和数据,我们使用了重绘。
重绘的方法我们学了三种:队列,数组,还有一种数组的优化
队列重绘:构造以shape为父类,line等图形对象类为子类的继承体系,定义动态数组存储图像类对象,使用抽象类来实现诸如line等具有相同性质即都属于形状但又不同的类的存储和绘制。
抽象类与接口的理解:
二维数组重绘:先创建二维数组用于存储各点颜色,用Robot类createScreenCapture截屏,返回一个BufferedImage对象,然后用该对象的getRGB(j, i)方法得到该点颜色,存入二维数组。在paint方法中遍历取点并绘制即可。 用同样方法可以实现取色笔的取色。
以下为二维数组重绘即优化的代码:
public void paint(java.awt.Graphics g) { // 调用父类的方法来正确的绘制组件,super的使用 super.paint(g); //第三种重绘方法,直接用image重绘 //if (dlis != null && dlis.img != null) { // g.drawImage(dlis.img, 0, 0, dlis.img.getWidth(), // dlis.img.getHeight(), null); // } //第二种重绘方法,二维数组保存并遍历,缺点是每个点需计算一遍比较慢 if (dlis != null&&dlis.area!=null) { // 遍历二维数组 for (int i = 0; i < dlis.area.length; i++) { for (int j = 0; j < dlis.area[i].length; j++) { // 取出颜色 int cNum = dlis.area[i][j]; //如果存储的颜色与背景色不一样,就绘制一次 if(cNum!=this.getBackground().getRGB()){ // 将数字转成Color对象 Color color = new Color(cNum); // 绘制这个点 g.setColor(color); g.drawLine(j, i, j, i); } } } }
诸如直线、矩形、椭圆之类直接调用方法即可,而铅笔、刷子、橡皮是给直线设置颜色、粗细,并使用MouseMotionListener接口中的mouseDragged方法来实现。取色笔先用robot.createScreenCapture() getRGB(j, i)取色然后绘制即可,矩形剪裁同样用robot.createScreenCapture()截屏,保存,然后通过鼠标监听器得到鼠标横纵坐标改变量,先将截屏矩形区绘为白色,再将保存的图像放到新位置(顺序不能倒,因为新位置和截屏区可能重叠),写字功能通过布尔变量(也可以用计数器)和if语句判断是否已写字然后 对象.add和对象.remove 来实现文本框的出现和消失。放大镜先通过e.getSource()获得对象,然后得到对象原本大小,重新setPreferredSize,放大倍数几倍就设置新大小为原大小几倍,然后用updateUI刷新即可,然后曲线据说是用贝塞尔曲线可以做,目前还没试过.....
完成这个小程序的收获主要在于一方面养成了一些编程习惯,比如注释,详细的注释对于整体的思路,错误的查找修正都很有帮助。另一方面对一些编程技巧,关键字super,final之类还有接口 抽象类 类等有了更多的理解。