关于java编写画图板的思考

                                   <一> 画图板的简介

     

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

                

--------------------------------------------  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=0
	public 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() {
			@Override
			public 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;
					}
				}

			}

			@Override
			public 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;
					}
				}

			}

			@Override
			public 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 - xStart
					graphics.drawOval(xStart, yStart, xEnd - xStart, yEnd
							- yStart);
				} else if ("rect".equals(panelLeft.currentComman)) {
					// 反着画 : xStart>xEnd width<0
					// TODO x较小的 y较小的 :绝对值:xEnd - xStart
					graphics.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++;
					}
				}
			}

			@Override
			public void mouseEntered(MouseEvent e) {
				System.out.println("进入了");
			}

			@Override
			public 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() {
			@Override
			public 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创建Button
			JButton 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);
		}

	}
}





  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值