一 :
1:先在初始化函数内 为主窗口添加3个面板并把布局设置为 边框布局
最左边面板 left 用来存放图形选择 单选按钮
中间面板 center 用来存放画图界面
最下面面板 foot 用来存放颜色标签
this.setTitle("画图板");
this.setSize(600, 500); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置边框布局 BorderLayout layout=new BorderLayout(); this.setLayout(layout); //建立3个panel 面板 JPanel left =new JPanel(); JPanel center =new JPanel(); JPanel foot =new JPanel(); //设置面板首选大小 Dimension dimen=new Dimension(80,1); left.setPreferredSize(dimen); foot.setPreferredSize(new Dimension(1,80)); //设置面板颜色 left.setBackground(new Color(235,235,235)); foot.setBackground(new Color(235,235,235)); center.setBackground(Color.GRAY); //将面板添加进主框架中 this.add(left,BorderLayout.WEST); this.add(center,BorderLayout.CENTER); this.add(foot,BorderLayout.SOUTH);
2:为center面板上再加上 drawpanel 用来绘制图形的面板
为了方便保存绘制图形 应该在drawpanel中panit函数中绘制 所以要重写paint
函数
public class DrawPanel extends JPanel { public void paint(Graphics g) { super.paint(g); } }
在主框架初始化中定义
DrawPanel drawPanel=new DrawPanel(); drawPanel.setPreferredSize(new Dimension(400,300)); drawPanel.setBackground(Color.WHITE); //将center布局设置为左对齐 FlowLayout flow=new FlowLayout(FlowLayout.LEFT); center.setLayout(flow); //将画图板添加到center面板中去 center.add(drawPanel);
二 left面板中图形选择单选按钮的创建
1:图形选择单选按钮的创建
left面板中存放的是单选按钮 也就是说所有的单选按钮属于一个grouop
只有一个按钮可以被选中
// ************在left上加上形状选择按钮****************// ButtonGroup group=new ButtonGroup(); String[] commands = { "0", "1", "橡皮擦", "3", "4", "5", "pencil", "7", "画刷", "9", "line", "11", "rect", "13", "oval", "圆角矩形" }; for(int i=0;i<16;i++){ // 单选按钮 JRadioButton Btn=new JRadioButton(); // 设置按钮的默认图标 ImageIcon icon = new ImageIcon("imgs/draw"+i+".jpg"); Btn.setIcon(icon); //设置按钮的翻转图标。 ImageIcon icon1 = new ImageIcon("imgs/draw"+i+"-1.jpg"); Btn.setRolloverIcon(icon1); //设置按钮的按下图标 ImageIcon icon2 = new ImageIcon("imgs/draw"+i+"-2.jpg"); Btn.setPressedIcon(icon2); //设置按钮的选择图标。 ImageIcon icon3 = new ImageIcon("imgs/draw"+i+"-3.jpg"); Btn.setSelectedIcon(icon3); //为按钮添加动作命令 Btn.setActionCommand(commands[i]); //设置 初默认选中pencil if(i==6){ Btn.setSelected(true); } //将按钮添加到left面板中 group.add(Btn); left.add(Btn); }
注:①我为每个单选按钮都添加了 按钮的默认图标,按钮的翻转图标,按钮的按下图标,按钮的选择图标 让每次点击按钮都有视觉效果
②为每个单选按钮都添加动作命令 方便在绘制时判断选择的是绘制那种图形
三 foot面板中颜色选择标签的创建
//将foot面板设置为右对齐
FlowLayout flow2 = new FlowLayout(FlowLayout.RIGHT); foot.setLayout(flow2); //添加标签 用来显示当前颜色 JLabel colorlabel = new JLabel("color"); colorlabel.setPreferredSize(new Dimension(40,40)); colorlabel.setBackground(Color.black); foot.add(colorlabel); colorlabel.setOpaque(true); ColorListener clis = new ColorListener(colorlabel); Color[] colorArray = {Color.WHITE,Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,Color.GRAY,Color.red}; for(int i=0;i<colorArray.length;i++){ JLabel label = new JLabel(); //设置初始大小 label.setPreferredSize(new Dimension(20,20)); //设置背景颜色 label.setBackground(colorArray[i]); //设置边框颜色 label.setBorder(new LineBorder(Color.BLACK)); //如果为 true,则该组件绘制其边界内的所有像素。否则该组件可能不绘制部分或所有像素,从而允许其底层像素透视出来。 label.setOpaque(true); //添加鼠标监听器 foot.add(label); //给每个标签都添加一个鼠标监听器来响应鼠标事件 label.addMouseListener(clis); } //添加颜色选择按钮 JButton colorbutton = new JButton(); colorbutton.setPreferredSize(new Dimension(28,25)); ImageIcon colorimage = new ImageIcon("coloricon.jpg"); colorbutton.setIcon(colorimage); foot.add(colorbutton); //为颜色选择按钮添加action监听器 colorbutton.addActionListener(clis);
注:①通过标签背景颜色的方式来显示颜色
②每个标签都添加一个MouseListener监听器 用来监听选择的颜色
③colorbutton为颜色选择按钮 添加ActionListener监听器 单击时会出现系统颜色选取器
四 创建Shape及要绘制图形类
1:创建Shape类 作为所有要绘制图形的父类 内部有抽象函数draw 让每个子类都必须重写这个函数
public abstract class Shape { int x1,x2,y1,y2; Graphics g; //颜色 Color typecolor=Color.black; Shape(int x1,int y1,int x2,int y2,Color typecolor){ this.x1=x1; this.x2=x2; this.y1=y1; this.y2=y2; this.typecolor=typecolor; } //声明一个抽象函数 让子类重写 abstract void draw(Graphics g); }
注:draw函数的参数是Graphics类 Graphics 类是所有图形上下文的抽象基类,允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
2: 定义直线类 继承Shape
class Line extends Shape{ Line(int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(typecolor); g.drawLine(x1, y1, x2, y2); } }
3:定义椭圆类 继承Shape
class Oval extends Shape{ Oval(int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(typecolor); int minX=Math.min(x1, x2); int minY=Math.min(y1, y2); g.drawOval(minX, minY, Math.abs(x2-x1),Math.abs(y2-y1)); } }
4:定义圆角矩形类 继承Shape
class Round extends Shape{ Round (int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(typecolor); int minX=Math.min(x1, x2); int minY=Math.min(y1, y2); g.drawRoundRect(minX, minY, Math.abs(x2-x1),Math.abs(y2-y1),20,50); } }
5:定义画笔类 继承Shape:
class Pencil extends Shape{ Pencil (int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(typecolor); g.drawLine(x1, y1, x2, y2); } }
6:定义画刷类 继承Shape
class HuaShua extends Shape{ HuaShua (int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(typecolor); //以x2,y2为圆心 在其周围随机40个点 且都在 半径15的圆内 int j,k; Random random=new Random(); for(int i=0;i<40;i++){ j=random.nextInt(15); k=random.nextInt(15); if(i%4==0&&Math.pow(j, 2)+Math.pow(k, 2)<225) g.drawLine(x2+j, y2+k, x2+j, y2+k); else if(i%4==1&&Math.pow(j, 2)+Math.pow(k, 2)<225) g.drawLine(x2+j, y2-k, x2+j, y2-k); else if(i%4==2&&Math.pow(j, 2)+Math.pow(k, 2)<225) g.drawLine(x2-j, y2-k, x2-j, y2-k); else if(i%4==3&&Math.pow(j, 2)+Math.pow(k, 2)<225) g.drawLine(x2-j, y2+k, x2-j, y2+k); } } }
注:绘制画刷时 我先在鼠标拖动时当前坐标 周围随机40个点 且都在 半径15的圆内
然后绘制点
7: 定义橡皮擦类 继承Shape类
class Eraser extends Shape{ Eraser (int x1,int y1,int x2,int y2,Color typecolor){ super(x1,y1,x2,y2,typecolor); } void draw(Graphics g){ this.g=g; g.setColor(Color.WHITE); for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ g.drawLine(x2+i, y2+j, x2+i, y2+j); g.drawLine(x2+i, y2-j, x2+i, y2-j); g.drawLine(x2-i, y2-j, x2-i, y2-j); g.drawLine(x2-i, y2+j, x2-i, y2+j); } } } }
五:创建MouseListener, MouseMotionListener监听器 并为mypanel添加
改监听器必须实现MouseListener, MouseMotionListener接口
public class DrawListener implements MouseListener, MouseMotionListener { private int x1, x2, y1, y2; private String type = "line"; private Color typecolor = Color.black; private Graphics g; private ButtonGroup group; private DrawPanel drawpanel; private int xx = 0, yy = 0; ColorListener colorlistener; public DrawListener(DrawPanel drawpanel, ButtonGroup group,ColorListener colorlistener) { // 获取监听区域的画板和单选组 this.drawpanel = drawpanel; this.group = group; g = drawpanel.getGraphics(); this.colorlistener = colorlistener; } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub x1 = e.getX(); y1 = e.getY(); type = group.getSelection().getActionCommand(); // 设置颜色 typecolor = colorlistener.color; } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub x2 = e.getX(); y2 = e.getY(); // 绘制图形 if (type.equals("line")) { Line line = new Line(x1, y1, x2, y2, typecolor); drawpanel.list.add(line); line.draw(g); } else if (type.equals("rect")) { Rect rect = new Rect(x1, y1, x2, y2, typecolor); drawpanel.list.add(rect); rect.draw(g); } else if (type.equals("oval")) { Oval oval = new Oval(x1, y1, x2, y2, typecolor); drawpanel.list.add(oval); oval.draw(g); } else if (type.equals("圆角矩形")) { Round round = new Round(x1, y1, x2, y2, typecolor); drawpanel.list.add(round); round.draw(g); } } // 鼠标按键在组件上按下并拖动时调用。 @Override public void mouseDragged(MouseEvent e) { // TODO Auto-generated method stub int x3 = e.getX(); int y3 = e.getY(); if (type.equals("pencil")) { Pencil pencil = new Pencil(x1, y1, x3, y3, typecolor); drawpanel.list.add(pencil); pencil.draw(g); x1 = x3; y1 = y3; } else if (type.equals("画刷")) { HuaShua huashua = new HuaShua(x1, y1, x3, y3, typecolor); drawpanel.list.add(huashua); huashua.draw(g); } else if (type.equals("橡皮擦")) { Eraser eraser = new Eraser(x1, y1, x3, y3, typecolor); drawpanel.list.add(eraser); eraser.draw(g); } } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } // 鼠标单击事件 public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub int x3 = e.getX(); int y3 = e.getY(); if (type.equals("橡皮擦")) { Eraser eraser = new Eraser(x1, y1, x3, y3, typecolor); drawpanel.list.add(eraser); eraser.draw(g); } else if (type.equals("画刷")) { HuaShua huashua = new HuaShua(x1, y1, x3, y3, typecolor); drawpanel.list.add(huashua); huashua.draw(g); } } @Override public void mouseMoved(MouseEvent e) { // TODO Auto-generated method stub if (type.equals("橡皮擦")) { } } }
注:①在构造函数中 得到要绘制区域的面板 和颜色监听器
②在鼠标按下函数中 通过group得到选中的按钮 并获得动作命令 才能知道选择绘制的图形是什么
③在DrawPanel面板中定义动态数组用来存放每次绘制的图形类 然后重写panit函数
public class DrawPanel extends JPanel { public ArrayList<Shape> list=new ArrayList<Shape>(); public void paint(Graphics g) { super.paint(g); for(int i=0;i<list.size();i++){ list.get(i).draw(g); } } }
④在监听器中每次绘制图形时 都创建一个绘制图形的对象 并调用对象中draw函数俩绘制图形 然后将每个图形对象保存到 drawpanel面板动态数组list中
⑤在鼠标释放函数中 绘制 直线 矩形 椭圆 圆角矩形
⑥在鼠标拖动函数中 绘制 画笔 画刷 橡皮擦
⑦在主框架类中 为drawpanel添加监听器
//为drawPanel添加监听器 DrawListener drawlis=new DrawListener(drawPanel,group,clis); drawPanel.addMouseListener(drawlis); drawPanel.addMouseMotionListener(drawlis);
六 创建颜色选择监听器
public class ColorListener implements MouseListener ,ActionListener{ public Color color = Color.BLACK; public JLabel colorlabel; public ColorListener(JLabel colorlabel){ this.colorlabel=colorlabel; } @Override public void mouseReleased(MouseEvent e) { //获得事件源对象 JLabel label = (JLabel)e.getSource(); // color = label.getBackground(); colorlabel.setBackground(color); } //**************************************************************************// //实现ActionListener @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub color = JColorChooser.showDialog(null, "请选择颜色", Color.RED); colorlabel.setBackground(color); } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } }
这个小项目只是简单的模仿xp画图板 还有很多功能没有实现 有待我去开发
通过这个项目让我对java中图形化界面认识很多 对一些控件有所了解 认识
以后还要通过每次的项目 让自己有所收获