关于java编写画图板的思考

来源:互联网 发布:淘宝宝贝排名查询软件 编辑:程序博客网 时间:2024/06/02 05:29

                                   <一> 画图板的简介

     

                画图板是一种很实用的画图工具。它的界面如下:

                

--------------------------------------------  1   --------------------------------------------------------------------------------------------------------

    

                            <二>  java语言实现它


                画图板大致可以分为三个部分:左侧工具面板、中间面板和底部颜色面板。

                在构架画图板时,就必须得构建一个窗体,3个面板。考虑到程序的可维护

性和职责分离,以及提高效率,在实现画图板时将其抽象为5个类。

                 在构建窗体和面板时,直接通过继承相应的类,如JFrame、JPanel。在

具体的类中,可以用  this.属性或方法 来替代直接new一个对象.属性或方法。

                  接下来,具体讲每个类的实现。

                           

                      第一部分     DrawBoard.java 类

       

   

package cn.huaxin.ui2.layer;import java.awt.BorderLayout;import java.awt.Graphics2D;import javax.swing.JFrame;public class DrawBoard {JFrame jfDrawFrame = null;// 全局变量// ------------------------------------------------------------------------------// 构造方法public DrawBoard() {/** 第一步:设置窗体属性:大小、位置、标题、可见(必须要最后(add后)设置)、释放 **/setFrameParams();// 调用了自己的方法/** 第二步: add 控件 **/// 左边面板PanelLeft panelLeft = new PanelLeft(null);jfDrawFrame.add(panelLeft, BorderLayout.WEST);// 中间面板PanelCenter panelCenter = new PanelCenter(panelLeft, null);jfDrawFrame.add(panelCenter, BorderLayout.CENTER);// 设置底部的面板PanelBottom panelBottom = new PanelBottom(panelLeft, null);jfDrawFrame.add(panelBottom, BorderLayout.SOUTH);/** 第三步: 事件 **/jfDrawFrame.setAlwaysOnTop(true);jfDrawFrame.setVisible(true);// 必须在获得画笔:Graphics2D graphics2 = (Graphics2D) panelCenter.getGraphics();// 获得画笔// TODO 要给左边面板的g赋值panelLeft.graphics = graphics2;panelCenter.graphics = graphics2;panelBottom.graphics = graphics2;}/** 第一步:设置窗体属性:大小、位置、标题、可见(必须要最后(add后)设置)、释放 **/public void setFrameParams() {jfDrawFrame = new JFrame();jfDrawFrame.setSize(500, 500);jfDrawFrame.setLocationRelativeTo(null);jfDrawFrame.setTitle("画图板");jfDrawFrame.setDefaultCloseOperation(3);jfDrawFrame.setLayout(new BorderLayout());// 布局// null 空布局直接:给x,y坐标(屏幕适配有问题,做桌面程序没什么影响)}}




DrawBoard类中,分为属性和方法。构造函数中,主要是建立窗体和面板,以及获得画笔。大致分为三步:

              (1)为窗体设置属性

              (2)为窗体添加面板

              (3)事件

 

在构建窗体时,一定要注意一个“先”和一个“后”。标准就是窗体的可见性。

先:  设置窗体其他属性要先于可见性(this.setVisible());

          在窗体上添加面板要先于可见性(this.setVisible());

后:   获得画笔和为面板添加画笔要后于可见性(this.setVisible());


画笔

Graphics2D继承自抽象类
Graphics。它的用法在下面面板的应用中讲解

                      第二部分     PanelLeft.java 类

   




 

package cn.huaxin.DrawBoard;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics2D;import java.awt.Stroke;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JPanel;public class PanelLeft extends JPanel {public int pressedCount;// 按下的次数 int pressedCount=0public String currentComman = "line"; // 默认一开始就是直线public Color currentColor = Color.black;public Graphics2D graphics = null;public PanelLeft(Graphics2D g) {graphics = g;// 左边Dimension dSizie = new Dimension(70, 100); // 尺寸this.setPreferredSize(dSizie);// 设置大小this.setBackground(Color.black);// 设置背景颜色// 添加jbutton 添加图片String[] images = { "airbrush", "brush", "color_picker", "curve","dot_rect", "eraser", "fill", "line", "magnifier", "oval","pencil", "polygon", "rect", "round_rect", "star", "word" };// 1.先要有监听器 :一个类implements ActionListener ;;// 接口不能new,有一个普通类,没有类名-》匿名类 =>匿名内部类ActionListener actionListener = new ActionListener() {// 重写了接口的抽象方法// 事件触发public void actionPerformed(ActionEvent e) {System.out.println("监听到了~~~");pressedCount = 0;// 区分是哪个按钮?currentComman = e.getActionCommand();// 获得当前触发按钮的命令if ("eraser".equals(currentComman)) {// 设置橡皮的颜色:白色graphics.setColor(Color.WHITE);// 接口 s = 子类; 子类 s = 接口;Stroke s = new BasicStroke(10);// BasicStroke ss = (BasicStroke) s; // 接口 赋值给 子类graphics.setStroke(s);} else if ("brush".equals(currentComman)) {// 设置刷子的颜色graphics.setColor(currentColor);// 接口 s = 子类; 子类 s = 接口;Stroke s = new BasicStroke(10);// BasicStroke ss = (BasicStroke) s; // 接口 赋值给 子类graphics.setStroke(s);} else if ("line".equals(currentComman)) {// 设置直线的颜色graphics.setColor(currentColor);// ???不能写死// 接口 s = 子类; 子类 s = 接口;Stroke s = new BasicStroke(1);graphics.setStroke(s);} else {// 设置白色graphics.setColor(currentColor);// ???不能写死// 接口 s = 子类; 子类 s = 接口;Stroke s = new BasicStroke(1);graphics.setStroke(s);}}};for (int i = 0; i < images.length; i++) {ImageIcon imageIcon = new ImageIcon("images/" + images[i] + ".jpg");JButton btnIcon = new JButton(imageIcon);Dimension preferredSize = new Dimension(25, 25);btnIcon.setPreferredSize(preferredSize);this.add(btnIcon);// 2.给按钮添加监听btnIcon.addActionListener(actionListener);//// 3.给触发按钮设置一个命令btnIcon.setActionCommand(images[i]);//}}}




        通过继承JPanel,可以直接用this来代替:PanelLeft 的对象。

        在设置构件大小时,一定要注意:除了JFrame可以直接通过  (new JFrame()).setSize(int length,int width)外,其他的一般通过Dimension来间接设置大小。如:

          Dimension dSizie = new Dimension(70, 100);
          this.setPreferredSize(dSizie);
    实现左侧面板的大致思想是:
 (1)建立左侧面板是,设置属性
 (2)为面板添加按钮
 (3)位每个按钮添加事件(得先建一个监听器才能添加监听器)
添加事件需要设置监听器和命令。由于ActionListener是接口,不能继承,在此用了一个懒办法:匿名内部类。它要求实现ActionListener里的抽象方法。BasicStroke()为Graphics2D里的设置画笔宽度的方法。

        

               第三部分     PanelCneter.java 类

    



           

package cn.huaxin.DrawBoard;
import java.awt.Color;import java.awt.Graphics2D;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.util.Random;import javax.swing.JPanel;public class PanelCenter extends JPanel {public PanelLeft panelLeft;public Graphics2D graphics;int polygonMiddleX;int polygonMiddleY;// 坐标int xStart = 0;int yStart = 0;int xEnd = 0;int yEnd = 0;// 多边形int polygonStartX; // 起点 收尾相连的时候用int polygonStartY;Random random = new Random();// 随机数生成器public PanelCenter(PanelLeft pl, Graphics2D g) {this.panelLeft = pl;graphics = g;// 1.1有个一个监听器;匿名内部类MouseListener mouseListener = new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {int clickCount = e.getClickCount();System.out.println("点击了" + clickCount);if ("polygon".equals(panelLeft.currentComman)) {if (clickCount == 1) {// 画直线graphics.drawLine(polygonMiddleX, polygonMiddleY,e.getX(), e.getY());// 交换中间点polygonMiddleX = e.getX();polygonMiddleY = e.getY();} else if (clickCount == 2) {// 收尾相连graphics.drawLine(polygonStartX, polygonStartY,polygonMiddleX, polygonMiddleY);// 还原点击次数panelLeft.pressedCount = 0;}}}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("按下了");// 起始点xStart = e.getX();yStart = e.getY();if ("polygon".equals(panelLeft.currentComman)) {// 多边形// 第一次if (panelLeft.pressedCount == 0) {polygonStartX = xStart;polygonStartY = yStart;}}}@Overridepublic void mouseReleased(MouseEvent e) {System.out.println("释放了");xEnd = e.getX();yEnd = e.getY();// 画if ("line".equals(panelLeft.currentComman)) // 区分 直线 还是椭圆???// 通过命令区分{// 当前是画直线graphics.drawLine(xStart, yStart, xEnd, yEnd);} else if ("oval".equals(panelLeft.currentComman)) {// 反着画 : xStart>xEnd width<0// TODO x较小的 y较小的 :绝对值:xEnd - xStartgraphics.drawOval(xStart, yStart, xEnd - xStart, yEnd- yStart);} else if ("rect".equals(panelLeft.currentComman)) {// 反着画 : xStart>xEnd width<0// TODO x较小的 y较小的 :绝对值:xEnd - xStartgraphics.drawRect(xStart, yStart, xEnd - xStart, yEnd- yStart);} else if ("round_rect".equals(panelLeft.currentComman)) {graphics.drawRoundRect(xStart, yStart, xEnd - xStart, yEnd- yStart, 100, 100);} else if ("polygon".equals(panelLeft.currentComman)) {// 多边形// 画第一条线if (panelLeft.pressedCount == 0) {graphics.drawLine(xStart, yStart, xEnd, yEnd);polygonMiddleX = xEnd;polygonMiddleY = yEnd;panelLeft.pressedCount++;}}}@Overridepublic void mouseEntered(MouseEvent e) {System.out.println("进入了");}@Overridepublic void mouseExited(MouseEvent e) {System.out.println("退出了");}};// 1.2鼠标拖动的事件监听器MouseMotionListener mouseMotionListener = new MouseMotionListener() {//public void mouseDragged(MouseEvent e) {// System.out.println("鼠标拖动~~");int x1 = e.getX();int y1 = e.getY();if ("pencil".equals(panelLeft.currentComman)) {// graphics.drawLine(x1, y1, x1, y1);// 不能画圆点graphics.drawLine(xStart, yStart, x1, y1);xStart = x1;yStart = y1;} else if ("eraser".equals(panelLeft.currentComman)) {// System.out.println("~~~~");graphics.drawLine(xStart, yStart, x1, y1);xStart = x1;yStart = y1;} else if ("brush".equals(panelLeft.currentComman)) {// System.out.println("~~~~");graphics.drawLine(xStart, yStart, x1, y1);xStart = x1;yStart = y1;} else if ("airbrush".equals(panelLeft.currentComman))// 喷枪{for (int i = 0; i < 30; i++) {// 生成的随机数int nextInt = random.nextInt(8) - 4;// [0,9]->[-5,4]int nextInt2 = random.nextInt(8) - 4;// [0,9]->[-5,4]System.out.println(nextInt);graphics.drawLine(x1 + nextInt, y1 + nextInt2, x1+ nextInt, y1 + nextInt2);// 画点}}}public void mouseMoved(MouseEvent e) {// System.out.println("鼠标移动");}};this.setBackground(Color.WHITE);// 2.给panel添加监听器this.addMouseListener(mouseListener);this.addMouseMotionListener(mouseMotionListener);}}

 
 中间面板,主要就是通过鼠标在面板上操作。所以,这里涉及到鼠标事件。

鼠标事件有:进入,按下,点击,释放,退出,拖动,移动。

监听器分为两种:MouseListener 和  MouseMotionListener

具体的每个按钮对应的事件如图所示。

第四部分     PanelBotton.java 类

package cn.huaxin.DrawBoard;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics2D;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JPanel;public class PanelBottom extends JPanel {// 1 默认颜色的数组Color[] colors = { Color.red, Color.black, Color.blue, Color.yellow };PanelLeft panelLeft;public Graphics2D graphics;public PanelBottom(PanelLeft p, Graphics2D g) {panelLeft = p;graphics = g;Dimension d = new Dimension(100, 70);this.setPreferredSize(d);/** 创建按钮的点击事件 **/ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("颜色选择了~~");String actionCommand = e.getActionCommand();int i = Integer.valueOf(actionCommand);// String -> int// :Integer整数System.out.println(i);Color color = colors[i];graphics.setColor(color);// 改了颜色panelLeft.currentColor = color;if ("eraser".equals(panelLeft.currentComman))// 橡皮檫的时候颜色还原{graphics.setColor(Color.WHITE);}}};/** 面板上面添加默认颜色的Button **/// 1 默认颜色的数组for (int i = 0; i < colors.length; i++) {// 2创建ButtonJButton button = new JButton();button.setBackground(colors[i]);Dimension dd = new Dimension(25, 25);button.setPreferredSize(dd);button.addActionListener(listener);button.setActionCommand(i + "");// 3.添加this.add(button);}}}

0 0