java画图板可选颜色,java学习——画图板

[size=large][/size]

姗姗迟来的画图板总结啊~~其实早就想写了,但是本来是想通过画图板来练习我参数传递的本领的,但因为各阶段的学习及学校的一些事就耽误了这么长时间了。。这次来做个总结的开头吧,之后有时间定会慢慢再完善的。

先让大家看看我的成果~

[img]http://dl.iteye.com/upload/picture/pic/121331/0666b573-8eb8-323d-a879-9a0a75fd07e5.jpg[/img]

大家可以看到画板实现了较多的功能,直线、矩形、多边形、椭圆、铅笔、橡皮等功能都实现了,还有14种颜色可以供我们使用。

下面来为大家简略讲解下我的画图板制作课程:

一、界面的生成

首先,当然是先实例化一个窗体对象出来,设置好窗体的各种属性:标题、大小、背景颜色等。

接着,我们可以看到,在整个的窗体上大致分成了三部分。其实这就是三个面板对象,分别是工具栏面板、画图面板、颜色面板。然后我们可以看到,在颜色面板的左下方,还有一个很小的取色面板,就相当于现实生活中画家手中的那个取色板,用左键点某个颜色,取色板后面的小按钮就会变为该颜色,如果是用右键点某个颜色,取色板前面的小按钮就会变为该颜色。还有上面有一行菜单栏,但里面具体的选项功能我都没有实现出来...很是惭愧...下面我附上这一块的代码,应该能详细描述下这些功能是怎么实现的。

package Simple_Draw;

import java.awt.BorderLayout;

import java.awt.Graphics;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.UIManager;

/**

* 主函数类

*

* @author 王成威

*

*/

public class Draw_xp extends JFrame {

/**

* 主函数

*

* @param args

*/

public static void main(String args[]) {

Draw_xp dp = new Draw_xp();

dp.showFrame();

}

private void showFrame() {

this.setTitle("仿XP画板");

this.setSize(700, 600);

this.setDefaultCloseOperation(3);

this.setLocationRelativeTo(null);

// 创建工具面板对象

Tool_panel tpl = new Tool_panel();

this.add(tpl, BorderLayout.WEST);

Color_panel cpl = new Color_panel();

this.add(cpl, BorderLayout.SOUTH);

Draw_panel dpl = new Draw_panel(tpl);

this.add(dpl, BorderLayout.CENTER);

// 调用创建菜单栏的方法,获取到菜单栏的对象

JMenuBar jmb = createMenuBar();

// 将菜单栏的对象设置为窗体的菜单栏

this.setJMenuBar(jmb);

this.setVisible(true);

/**

* 创建菜单栏的方法

*

* @return 返回JMenuBar的对象

*/

private JMenuBar createMenuBar() {

// 实例化一个JMenuBar的对象

JMenuBar jmb = new JMenuBar();

// 菜单项的数组

String[] arrayMenu = { "文件", "颜色", "帮助" };

// 菜单子项的数组

String[][] arrayMenuItem = { { "新建", "保存", "打开", "退出" }, { "编辑颜色" },

{ "帮助主题", "关于画图" } };

// 根据数据循环来创建菜单栏

for (int i = 0; i < arrayMenu.length; i++) {

// 实例化一个JMenu的对象

JMenu menu = new JMenu(arrayMenu[i]);

// 将menu添加到jmb对象中

jmb.add(menu);

for (int j = 0; j < arrayMenuItem[i].length; j++) {

// 实例化JMenuItem的对象

JMenuItem jmi = new JMenuItem(arrayMenuItem[i][j]);

// 将jmi对象添加到menu中

menu.add(jmi);

}

}

return jmb;

}

下面是工具栏面板类的代码:

package Simple_Draw;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Image;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.Icon;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JPanel;

/**

* 工具类

*

* @author 王成威

*

*/

public class Tool_panel extends JPanel {

//声明一个存储用户选择的图形属性

public String shape_command = "line";

private Graphics g;

// 构造方法

public Tool_panel() {

show();// 调用方法

}

// 制作工具栏的方法

public void show() {

// 实例化一个JPanel对象,充当容器来添加工具。

JPanel panel = new JPanel();

// 设置面板的布局为网格布局

panel.setLayout(new GridLayout(5, 2, 4, 4));

// 定义一个数组。

String[] array = { "brush.jpg", "easer.jpg",

"fillRect.jpg", "line.jpg", "oval.jpg",

"pencil.jpg", "polygon.jpg", "rect.jpg",

"roundrect.jpg", "spray.jpg" };

// 循环创建按钮对象

for (int i = 0; i < array.length; i++) {

// 实例化一个ImageIcon的对象

// ImageIcon image = new ImageIcon(array[i]);

Icon image = new ImageIcon(this.getClass().getResource(

array[i]));

// 实例化按钮对象,并设置按钮的图标

JButton btn = new JButton(image);

// 设置按钮的大小

btn.setPreferredSize(new Dimension(25, 25));

//获取到唯一的动作命令(截取图片的名字)(这里特别再注意下是怎么弄的,这是专门用于截取图片动作命令的方法)

String fileName = array[i].substring(array[i].indexOf("/")+1, array[i].lastIndexOf(".jpg"));

//设置按钮的动作命令值

btn.setActionCommand(fileName);

//设置按钮的动作命令监听器方法,绑定事件处理类的对象tool_listener

btn.addActionListener(tool_listener);

// 将按钮添加到面板上

panel.add(btn);

// 设置Tool_panel的布局为流式布局布局

this.setLayout(new FlowLayout());

}

// 将panel添加到Tool_panel上

this.add(panel);

// 设置工具栏颜色

this.setBackground(null);

}

/**

* 使用匿名内部类来实现动作事件处理接口add

*/

private ActionListener tool_listener = new ActionListener() {

/**

* 事件处理方法

*/

public void actionPerformed(ActionEvent e) {

//将按钮上的动作命令值获取到,存储到属性shape_command中

shape_command =e.getActionCommand();

}

};

}

接着是颜色面板类的代码:

package Simple_Draw;

/**

* 颜色类

*/

import java.awt.Color;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.GridLayout;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import javax.swing.JButton;

import javax.swing.JPanel;

public class Color_panel extends JPanel {

//定义存储前景色和背景色的颜色属性

public Color bcolor = Color.WHITE,fcolor = Color.BLACK;

/**

* 构造方法(构造方法里面不能实例化对象)

*/

public Color_panel() {

init();// 调用显示的方法

}

// 将颜色栏显示的方法

private void init() {

// 实例化一个panelFB对象

JPanel panelFB = new JPanel();

// 设置面板大小

panelFB.setPreferredSize(new Dimension(30, 30));

// 设置面板布局为空布局

panelFB.setLayout(null);

// 创建两个按钮(这里必须要定义为final类型,要控制其不能改变)

final JButton btnF = new JButton();

final JButton btnB = new JButton();

// 设置颜色按钮的位置和大小。setBounds,记住,去查询下。

btnF.setBounds(5, 5, 15, 15);

btnB.setBounds(10, 10, 15, 15);

// 设置颜色按钮的颜色

btnF.setBackground(Color.black);

btnB.setBackground(Color.red);

// 将颜色按钮添加到面板上

panelFB.add(btnF);

panelFB.add(btnB);

// 将可换颜色面板添加到总的颜色面板上

this.add(panelFB);

/**

* 实例化一个MouseAdapter抽象类的对象(匿名内部类)

*/

MouseAdapter ma = new MouseAdapter(){

/**

* 鼠标按下时执行的方法

*/

public void mousePressed(MouseEvent e) {

//获取到事件源对象 按钮(什么意思?问熊哥)

JButton btn = (JButton)e.getSource();

//判断当前点击的是否是左键,如果是则改变背景色,条件是e.getButton()返回的值是否为1

if(e.getButton() == 1){

//获取到按钮上的颜色了

fcolor = btn.getBackground();

//改变背景色按钮上的颜色

btnF.setBackground(fcolor);

}else if(e.getButton() == 3){//表示点击了右键

//获取到按钮上的颜色了

bcolor = btn.getBackground();

//改变背景色按钮上的颜色

btnB.setBackground(bcolor);

}

}

};

// 创建一个 可选颜色面板的对象

JPanel panel1 = new JPanel();

Color[] array = {Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,

Color.GRAY,Color.GREEN,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANGE,

Color.PINK,Color.RED,Color.YELLOW,Color.WHITE,new Color(150,200,130),

new Color(100,120,130),new Color(150,125,130),new Color(150,125,130),new Color(150,125,130),

new Color(150,125,130),new Color(150,90,130),new Color(150,160,130),new Color(150,175,130),

new Color(150,190,130),new Color(150,125,120),new Color(160,125,130),

new Color(180,100,130),new Color(150,125,160),new Color(150,125,160) };

for (int i = 0; i < array.length; i++) {

// 创建颜色按钮对象

JButton jbn = new JButton();

// 设置颜色按钮大小,颜色

jbn.setPreferredSize(new Dimension(20, 20));

jbn.setBackground(array[i]);

//给按钮添加鼠标监听器方法,绑定事件处理类的对象

jbn.addMouseListener(ma);

// 将按钮添加到可选颜色面板对象上

panel1.add(jbn);

}

// 设置可选颜色面板上的布局为网格布局

panel1.setLayout(new GridLayout(2, 14));

// 设置为从左至右的流式布局

this.setLayout(new FlowLayout(FlowLayout.LEFT));

// 设置背景颜色

this.setBackground(null);

// 将可选颜色面板添加到颜色面板上

this.add(panel1);

}

}

二、监听器的添加

我觉得画图板的最大难点就是在于这一块了,监听器对于之前添加上的面板和窗体来说,就像赋予了它们生命,使它们能动起来。这里会用到两种监听器,一种是动作监听器,是添加到工具栏上各种工具按钮上和颜色面板上各种颜色按钮上。还有另一种是鼠标监听器,鼠标监听器主要是用于拿鼠标绘图时,各种图形的绘制的实现。动作监听器已经在上面两个颜色面板和工具栏面板里实现了,下面我们来看看鼠标监听器和画图面板类的代码。

package Simple_Draw;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.Graphics;

import javax.swing.JPanel;

public class Draw_panel extends JPanel{

// 创建一个面板对象

public JPanel panel = new JPanel();

public Tool_panel tp;

/**

* 构造方法

*/

public Draw_panel(Tool_panel tp) { //括号里面的参数到底什么时候要加,起了什么作用?为什么这里ab不用加进?!

this.tp=tp;

init();// 调用初始化面板的方法

}

private void init() {

// 设置Draw_panel的布局为流式布局布局

this.setLayout(new FlowLayout(FlowLayout.LEFT));

//设置背景颜色

this.setBackground(Color.GRAY);

//设置背景颜色大小

panel.setBackground(Color.WHITE);

panel.setPreferredSize(new Dimension(400,300));

// 将panel添加到Draw_panel上

this.add(panel);

}

public void paint(Graphics g){

super.paint(g);

for(int i=1;i

g.drawLine(MyMouseListener.array[4*i-4],MyMouseListener.array[4*i-3] ,MyMouseListener.array[4*i-2],MyMouseListener.array[4*i-1]);

g.drawOval(MyMouseListener.array1[4*i-4], MyMouseListener.array1[4*i-3],Math.abs(MyMouseListener.array1[4*i-4]-MyMouseListener.array1[4*i-2]), Math.abs(MyMouseListener.array1[4*i-3]-MyMouseListener.array1[4*i-1]));

}

for(int i=1;i

g.drawLine(MyMouseListener.array2[4*i-4],MyMouseListener.array2[4*i-3] ,MyMouseListener.array2[4*i-2],MyMouseListener.array2[4*i-1]);

}

}

}

package Simple_Draw;

/**

* 鼠标监听器类

*/

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.util.Random;

import javax.swing.JPanel;

public class MyMouseListener extends MouseAdapter {

// 定义一些基本属性

private Graphics g;

private int x1, y1, x2, y2,x3,y3,x4,y4,i=1;

private Tool_panel tp ;

private Color_panel cp;

private Color color = Color.BLACK;

static int array[]=new int[10000];

static int array1[]=new int[10000];//熊哥说静态的,不需要实例化对象。再问下是什么意思。

static int array2[]=new int[10000];

public static boolean flag;

/**

* 构造方法

*/

public MyMouseListener(Tool_panel tp ,Color_panel cp,JPanel panel){

this.tp = tp;

this.cp = cp;

this.g = panel.getGraphics();

}

public void mousePressed(MouseEvent e) {

// 获得x1,y1的坐标

x1 = e.getX();

y1 = e.getY();

//判断当前点击的是否是左键

if(e.getButton() == 1){

color = cp.fcolor;

}else if(e.getButton() == 3){

color = cp.bcolor;

}

}

public void mouseReleased(MouseEvent e) {

x2 = e.getX();

y2 = e.getY();

//设置图形的颜色

g.setColor(color);

//判断是否是直线

if(tp.shape_command.equals("line")){

array[4*i-4]=x1;

array[4*i-3]=y1;

array[4*i-2]=x2;

array[4*i-1]=y2;

i++;

g.drawLine(x1, y1, x2, y2);

}else if(tp.shape_command.equals("oval")){

array1[4*i-4]=x1;

array1[4*i-3]=y1;

array1[4*i-2]=x2;

array1[4*i-1]=y2;

i++;

if(x1

g.drawOval(x1, y1,Math.abs(x1-x2), Math.abs(y1-y2));

}else if(x1>x2&&y1>y2){

g.drawOval(x2, y2, Math.abs(x1-x2), Math.abs(y1-y2));

}else if (x1>x2&&y1

g.drawOval(x2,y1, Math.abs(x1-x2), Math.abs(y1-y2));

}else if(x1y2){

g.drawOval(x1, y2,Math.abs(x1-x2) , Math.abs(y1-y2));

}

}else if(tp.shape_command.equals("rect")) {

if(x1

g.drawRect(x1, y1,Math.abs(x1-x2), Math.abs(y1-y2));

}else if(x1>x2&&y1>y2){

g.drawRect(x2, y2, Math.abs(x1-x2), Math.abs(y1-y2));

}else if(x1>x2&&y1

g.drawRect(x2, y1, Math.abs(x1-x2), Math.abs(y1-y2));

}else if(x1y2){

g.drawRect(x1, y2, Math.abs(x1-x2), Math.abs(y1-y2));

}

}else if(tp.shape_command.equals("roundrect")){

if(x1

g.drawRoundRect(x1, y1,Math.abs( x2-x1), Math.abs(y2-y1),10,10);

}else if(x1>x2&&y1>y2){

g.drawRoundRect(x2, y2, Math.abs(x1-x2), Math.abs(y1-y2),10,10);

}else if(x1>x2&&y1

g.drawRoundRect(x2, y1, Math.abs(x1-x2), Math.abs(y1-y2),10,10);

}else if(x1y2){

g.drawRoundRect(x1, y2, Math.abs(x1-x2), Math.abs(y1-y2),10,10);

}

}

}

public void mouseDragged(MouseEvent e){

//设置设置图形颜色

g.setColor(color);

if(tp.shape_command.equals("brush")){

x2=e.getX();

y2=e.getY();

//设置线条粗细

Graphics2D g2d = (Graphics2D)g;

//将Graphics类型的g对象强制转换为Graphics2D的对象

//调用Graphics2D设置线条粗细的方法来设置线条的粗细

g2d.setStroke(new BasicStroke(8));

//绘制粗线条

g2d.drawLine(x1, y1, x2, y2);

//将直线结束点的坐标作为下一条线的开始点

x1=x2;

y1=y2;

g2d.setStroke(new BasicStroke(1));

}else if(tp.shape_command.equals("easer")){

//设置图形颜色

g.setColor(Color.WHITE);

//g.setColor(cp.getColor());

x2=e.getX();

y2=e.getY();

//将Graphics类型的g对象强制装换为Graphics2D的对象

Graphics2D g2d = (Graphics2D)g;

//调用Graphics2D设置线条粗细的方法来设置线条的粗细

g2d.setStroke(new BasicStroke(8));

//绘制粗线条

g2d.drawLine(x1, y1, x2, y2);

//将直线结束点的坐标作为下一条直线的开始点

x1=x2;

y1=y2;

//重新设置线条的粗细

g2d.setStroke(new BasicStroke(1));

}else if(tp.shape_command.equals("pencil")){

// 设置图形的颜色

// g.setColor(cp.getColor());

array2[4*i-4]=x1;

array2[4*i-3]=y1;

x3=e.getX();

y3=e.getY();

//绘制线条

g.drawLine(x1, y1, x3, y3);

//将直线的结束点的坐标作为下一条直线的开始点

x1=x3;

y1=y3;

array2[4*i-2]=x1;

array2[4*i-1]=y1;

i++;

}else if(tp.shape_command.equals("spray")){//如果是喷枪

//获取坐标值

x2=e.getX();

y2=e.getY();

//实例化一个随机数对象

Random rand = new Random();

//循环画多个点

for(int i=0;i<20;i++){

//随机生成新的x和y点,用来绘制不同的点

int x = rand.nextInt(8);

int y = rand.nextInt(8);

//开始绘制点

g.drawLine(x2+x, y2+y, x2+x, y2+y);

}

}

else if(tp.shape_command.equals("polygon")){//如果是多边形

//获取坐标

x4=e.getX();

y4=e.getY();

if(flag==true){

g.drawLine(x1, y1, x2, y2);

x3=x2;

y3=y2;

x4=x1;

y4=y1;

flag=false;

}else if(flag==false){

if(e.getClickCount()==2){

g.drawLine(x3,y3,x4,y4);

flag=true;

}else{

g.drawLine(x3,y3,x2,y2);

x3=x2;

y3=y2;

}

}

}

}

}

大家可以看到,鼠标监听器里的各种图形的绘制方法可以说就是画图板的大脑了,都是关键,大家可以仔细研究下。

另外还有一个难点在于画图板的重绘,我会再细细道来的~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值