一起来画画---模拟画图程序
- 代码
-
- 画布
- 图形选择窗体
- 画图窗体
- 总结
代码
画布
package com.zr.draw;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
/*
* 画布
* */
@SuppressWarnings("serial")
public class DrawPictureCanvas extends Canvas{
private Image image=null;
//设置画板中的图片
public void setImage(Image image) {
this.image=image;
}
//重写paint()方法,在画布中绘制图像
public void paint(Graphics g) {
g.drawImage(image, 0, 0, null);//在画布上绘制图像
}
//重写update()方法,解决屏幕闪耀问题
public void update(Graphics g) {
paint(g);//重新执行paint()方法
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
}
}
图形选择窗体
package com.zr.draw;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
/*
* 图形选择窗体
* */
@SuppressWarnings("serial")
public class DrawshapeJDialog extends JFrame{
public String shape;
public int weight;
public int height;
public DrawshapeJDialog() {
setTitle("图形选择窗体");
setBounds(800, 150, 200, 150);
JPanel jp=new JPanel();
jp.setLayout(new FlowLayout());
JRadioButton OvalButton=new JRadioButton("椭圆");
OvalButton.setSelected(true);
jp.add(OvalButton);
JRadioButton RectButton=new JRadioButton("矩形");
jp.add(RectButton);
getContentPane().add(jp,BorderLayout.NORTH);
ButtonGroup group=new ButtonGroup();
group.add(OvalButton);
group.add(RectButton);
JPanel jp1=new JPanel();
jp1.setLayout(new FlowLayout());
JLabel right=new JLabel("宽:");
jp1.add(right);
JTextField jtweight=new JTextField(5);
jp1.add(jtweight);
JLabel left=new JLabel("高");
jp1.add(left);
JTextField jtheight=new JTextField(5);
jp1.add(jtheight);
getContentPane().add(jp1,BorderLayout.CENTER);
JButton ok=new JButton("确定");
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(OvalButton.isSelected()) {
shape="椭圆";
}else {
shape="矩形";
}
weight=Integer.parseInt(jtweight.getText());
height=Integer.parseInt(jtheight.getText());
new DrawPictureFrame(shape,weight,height,true);
setVisible(false);
}
});
getContentPane().add(ok,BorderLayout.SOUTH);
setVisible(true);
}
}
画图窗体
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JToolBar;
import javax.swing.filechooser.FileNameExtensionFilter;
/*
* 画图窗体
* */
@SuppressWarnings("serial")
public class DrawPictureFrame extends JFrame {
// 声明成员变量
BufferedImage image = new BufferedImage(570, 390, BufferedImage.TYPE_INT_BGR);// 创建图片对象
Graphics gs = image.getGraphics();// 获得图像的绘图对象
Graphics2D g = (Graphics2D) gs;// 将绘图对象强转为Graphics2D
DrawPictureCanvas canvas = new DrawPictureCanvas();// 创建画布对象
Color foreColor = Color.BLACK;// 定义前景色
Color backgroundColor = Color.WHITE;// 定义背景色
// 鼠标绘制点横纵坐标
int x = -1;
int y = -1;
boolean rubber = false;// 橡皮标志变量
// 工具栏对象
private JToolBar toolbar;// 工具栏
private JButton eraserButton;// 橡皮按钮
private JRadioButton strokeButton1;// 细线单选按钮
private JRadioButton strokeButton2;// 粗线单选按钮
private JRadioButton strokeButton3;// 较粗单选按钮
private JButton backgroundButton;// 背景色按钮
private JButton foregroundButton;// 前景色按钮
private JButton clearButton;// 清除按钮
private JButton saveButton;// 保存按钮
private JButton shapeButton;// 图形按钮
// 图形对象
private Shape shape;
private String shapes;
private int weight;
private int height;
boolean shaper = false;// 图像标志变量
// 菜单栏对象
private JMenuItem strokeMenuItem1;// 细线菜单
private JMenuItem strokeMenuItem2;// 粗线菜单
private JMenuItem strokeMenuItem3;// 较粗菜单
private JMenuItem clearMenuItem;// 清除菜单
private JMenuItem foregroundMenuItem;// 前景色菜单
private JMenuItem backgroundMenuItem; // 背景色菜单
private JMenuItem eraserMenuItem;// 橡皮菜单
private JMenuItem exitMenuItem;// 退出菜单
private JMenuItem saveMenuItem;// 保存菜单
// 水印对象
private String shuiyin = "";// 水印
private JMenuItem shuiyinMenuItem;// 水印菜单
public DrawPictureFrame(String shape2, int weight2, int height2, boolean b) {
this.shapes = shape2;
this.weight = weight2;
this.height = height2;
this.shaper = b;
setResizable(false);// 不可改变窗体大小
setTitle("画图程序(水印内容:" + shuiyin + ")");// 标题
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(500, 100, 574, 460);
init();
setVisible(true);
addListener();
}// 构造方法
private void init() {
g.setColor(backgroundColor);// 用背景色设置绘图对象的颜色
g.fillRect(0, 0, 570, 390);// 用背景色填充整个画布
g.setColor(foreColor);// 用前景色设置绘图对象的颜色
canvas.setImage(image);// 设置画布的图像
getContentPane().add(canvas);// 将画布添加到窗体容器
// 工具栏初始化
toolbar = new JToolBar();
getContentPane().add(toolbar, BorderLayout.NORTH);// 工具栏放于窗体最北部
saveButton = new JButton("保存");
toolbar.add(saveButton);
toolbar.addSeparator();// 添加分隔条
strokeButton1 = new JRadioButton("细线");
strokeButton1.setSelected(true);
toolbar.add(strokeButton1);
strokeButton2 = new JRadioButton("粗线");
toolbar.add(strokeButton2);
strokeButton3 = new JRadioButton("较粗");
ButtonGroup strokeButton = new ButtonGroup();// 定义按钮组,使这三个按钮只能被选一个
strokeButton.add(strokeButton1);
strokeButton.add(strokeButton2);
strokeButton.add(strokeButton3);
toolbar.add(strokeButton3);
toolbar.addSeparator();// 添加分隔条
backgroundButton = new JButton("背景颜色");
toolbar.add(backgroundButton);
foregroundButton = new JButton("前景颜色");
toolbar.add(foregroundButton);
toolbar.addSeparator();// 添加分隔条
clearButton = new JButton("清除");
toolbar.add(clearButton);
eraserButton = new JButton("橡皮");
toolbar.add(eraserButton);
shapeButton = new JButton("图形");
toolbar.add(shapeButton);
// 菜单栏初始化
JMenuBar menubar = new JMenuBar();// 创建菜单栏
setJMenuBar(menubar);// 窗体载入菜单栏
JMenu jm1 = new JMenu("系统");
menubar.add(jm1);// 菜单栏添加菜单对象
saveMenuItem = new JMenuItem("保存");
jm1.add(saveMenuItem);
shuiyinMenuItem = new JMenuItem("水印");
jm1.add(shuiyinMenuItem);
jm1.addSeparator();
exitMenuItem = new JMenuItem("退出");
jm1.add(exitMenuItem);
JMenu jm2 = new JMenu("线型");
menubar.add(jm2);
strokeMenuItem1 = new JMenuItem("细线");
jm2.add(strokeMenuItem1);
strokeMenuItem2 = new JMenuItem("粗线");
jm2.add(strokeMenuItem2);
strokeMenuItem3 = new JMenuItem("较粗");
jm2.add(strokeMenuItem3);
JMenu jm3 = new JMenu("颜色");
menubar.add(jm3);
foregroundMenuItem = new JMenuItem("前景色");
jm3.add(foregroundMenuItem);
backgroundMenuItem = new JMenuItem("背景色");
jm3.add(backgroundMenuItem);
JMenu jm4 = new JMenu("编辑");
menubar.add(jm4);
clearMenuItem = new JMenuItem("清除");
jm4.add(clearMenuItem);
eraserMenuItem = new JMenuItem("橡皮");
jm4.add(eraserMenuItem);
menubar.setVisible(true);
}// init()初始化
private void addListener() {
// 画板添加鼠标移动事件监听
canvas.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(final MouseEvent e) {// 当鼠标拖拽式
if (x > 0 && y > 0) {
if (rubber) {// 若使用橡皮
g.setColor(backgroundColor);// 绘图工具使用背景色
g.fillRect(x, y, 10, 10);// 在鼠标划过的位置填充正方形
} else {// 若使用画笔
g.drawLine(x, y, e.getX(), e.getY());// 在鼠标划过的位置画直线
}
}
// 上次鼠标绘制点的x,y坐标
x = e.getX();
y = e.getY();
canvas.repaint();// 更新画布
}
public void mouseMoved(final MouseEvent arg0) {
if (rubber) {
Toolkit kit = Toolkit.getDefaultToolkit();// 获得系统默认的组建工具包
URL imgURL = DrawPictureFrame.class.getResource("3.png");// 获取图片地址
Image img = kit.createImage(imgURL);// 利用工具包获得图片
Cursor c = kit.createCustomCursor(img, new Point(0, 0), "clear");// 利用工具包创建一个自定义光标对象
setCursor(c);// 使用自定义光标
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));// 设置鼠标指针为十字形
}
}
});
// 画板添加鼠标单击事件监听器
canvas.addMouseListener(new MouseAdapter() {
public void mouseReleased(final MouseEvent arg0) {// 当鼠标抬起
x = -1;
y = -1;
}
public void mousePressed(final MouseEvent e) {// 当鼠标按下
if (shaper) {
if (shapes == "矩形") {
int fangX = e.getX() - weight;
int fangY = e.getY() - height;
shape = new Rectangle2D.Double(fangX, fangY, weight, height);
g.setColor(foreColor);// 绘图工具使用前景色
g.draw(shape);
} else if (shapes == "椭圆") {
int yuanX = e.getX() - weight / 2;
int yuanY = e.getY() - height / 2;
shape = new Ellipse2D.Double(yuanX, yuanY, weight, height);
g.setColor(foreColor);// 绘图工具使用前景色
g.draw(shape);
}
canvas.repaint();// 更新画布
}
}
});
// 调节画笔粗细事件监听
strokeButton1.addActionListener(new ActionListener() {// 细线按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
g.setStroke(bs);// 画图工具使用此画笔
}
});
strokeButton2.addActionListener(new ActionListener() {// 粗线按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
g.setStroke(bs);// 画图工具使用此画笔
}
});
strokeButton3.addActionListener(new ActionListener() {// 较粗按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
g.setStroke(bs);// 画图工具使用此画笔
}
});
// 背景颜色和画笔颜色选择事件监听
backgroundButton.addActionListener(new ActionListener() {// 背景颜色按钮添加动作监听事件
public void actionPerformed(final ActionEvent arg0) {
// 打开选择颜色对话框,默认选中为青色
Color bgColor = JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.CYAN);
if (bgColor != null) {
backgroundColor = bgColor;
}
backgroundButton.setBackground(bgColor);
g.setColor(backgroundColor);// 用背景色设置绘图对象的颜色
g.fillRect(0, 0, 570, 390);// 用背景色填充整个画布
g.setColor(foreColor);// 用前景色设置绘图对象的颜色
canvas.repaint();// 更新画布
}
});
foregroundButton.addActionListener(new ActionListener() {// 前景颜色按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
Color fColor = JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.CYAN);
if (fColor != null) {
foreColor = fColor;
}
foregroundButton.setBackground(foreColor);
g.setColor(foreColor);
}
});
// 清除事件监听
clearButton.addActionListener(new ActionListener() {// 清除按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
g.setColor(Color.WHITE);// 将画笔颜色变为白色
g.fillRect(0, 0, 570, 390);// 用白色色填充整个画布
g.setColor(foreColor);// 用前景色设置绘图对象的颜色
canvas.repaint();// 更新画布
}
});
// 橡皮事件监听
eraserButton.addActionListener(new ActionListener() {// 橡皮、画笔按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
if (eraserButton.getText().equals("橡皮")) {
rubber = true;
eraserButton.setText("画笔");
eraserMenuItem.setText("画笔");
} else {
rubber = false;
eraserButton.setText("橡皮");
eraserMenuItem.setText("橡皮");
g.setColor(foreColor);
}
}
});
// 图形事件监听
shapeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new DrawshapeJDialog();
setVisible(false);
}
});
// 保存事件监听
saveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String path;
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("图片文件", "JPG", "GIF", "PNG");
chooser.setFileFilter(filter);
int res = chooser.showSaveDialog(null);
if (res == JFileChooser.APPROVE_OPTION) {
path = chooser.getSelectedFile().getAbsolutePath() + ".PNG";// 获得保存路径
try {
File file = new File(path);
ImageIO.write(image, "PNG", file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
// 保存菜单事件监听
saveMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String path;
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("图片文件", "JPG", "GIF", "PNG");
chooser.setFileFilter(filter);
int res = chooser.showSaveDialog(null);
if (res == JFileChooser.APPROVE_OPTION) {
path = chooser.getSelectedFile().getAbsolutePath() + ".PNG";// 获得保存路径
try {
File file = new File(path);
ImageIO.write(image, "PNG", file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
// 退出菜单事件监听
exitMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// 细线菜单事件监听
strokeMenuItem1.addActionListener(new ActionListener() {// 细线按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
strokeButton1.setSelected(true);
g.setStroke(bs);// 画图工具使用此画笔
}
});
// 粗线菜单事件监听
strokeMenuItem2.addActionListener(new ActionListener() {// 粗线按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
strokeButton2.setSelected(true);
g.setStroke(bs);// 画图工具使用此画笔
}
});
// 较粗菜单事件监听
strokeMenuItem3.addActionListener(new ActionListener() {// 较粗按钮添加动作监听
public void actionPerformed(ActionEvent e) {
// 设置画笔属性
BasicStroke bs = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
strokeButton3.setSelected(true);
g.setStroke(bs);// 画图工具使用此画笔
}
});
// 前景色菜单事件监听
foregroundMenuItem.addActionListener(new ActionListener() {// 前景颜色按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
Color fColor = JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.CYAN);
if (fColor != null) {
foreColor = fColor;
}
foregroundButton.setBackground(foreColor);
foregroundMenuItem.setBackground(foreColor);
g.setColor(foreColor);
}
});
// 背景色菜单事件监听
backgroundMenuItem.addActionListener(new ActionListener() {// 背景颜色按钮添加动作监听事件
public void actionPerformed(final ActionEvent arg0) {
// 打开选择颜色对话框,默认选中为青色
Color bgColor = JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.CYAN);
if (bgColor != null) {
backgroundColor = bgColor;
}
backgroundButton.setBackground(bgColor);
backgroundMenuItem.setBackground(bgColor);
g.setColor(backgroundColor);// 用背景色设置绘图对象的颜色
g.fillRect(0, 0, 570, 390);// 用背景色填充整个画布
g.setColor(foreColor);// 用前景色设置绘图对象的颜色
canvas.repaint();// 更新画布
}
});
// 清除菜单事件监听
clearMenuItem.addActionListener(new ActionListener() {// 清除按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
g.setColor(Color.WHITE);// 将画笔颜色变为白色
g.fillRect(0, 0, 570, 390);// 用白色色填充整个画布
g.setColor(foreColor);// 用前景色设置绘图对象的颜色
canvas.repaint();// 更新画布
}
});
// 橡皮菜单事件监听
eraserMenuItem.addActionListener(new ActionListener() {// 橡皮、画笔按钮添加动作监听事件
public void actionPerformed(ActionEvent e) {
if (eraserMenuItem.getText().equals("橡皮")) {
rubber = true;
eraserMenuItem.setText("画笔");
eraserButton.setText("画笔");
} else {
rubber = false;
eraserButton.setText("橡皮");
eraserMenuItem.setText("橡皮");
g.setColor(foreColor);
}
}
});
// 水印菜单事件监听
shuiyinMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
shuiyin = JOptionPane.showInputDialog(DrawPictureFrame.this, "你想加什么水印?");
if (null == shuiyin) {
shuiyin = "";
} else {
setTitle("画图程序(水印内容:" + shuiyin + ")");// 修改窗体标题
addWatermarK();
}
}
});
// 工具栏事件监听
toolbar.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(final MouseEvent arg0) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));// 设置鼠标为默认光标
}
}); // 工具栏添加鼠标移动监听
}// addListener()添加监听
// 添加水印方法
private void addWatermarK() {
if (!"".equals(shuiyin.trim())) {
g.rotate(Math.toRadians(-30));// 将图片旋转-30度
Font font = new Font("楷体", Font.BOLD, 72);// 设置字体
g.setFont(font);// 载入字体
g.setColor(Color.GRAY);// 使用灰色
AlphaComposite alpha = AlphaComposite.SrcOver.derive(0.5f);// 设置透明效果
g.setComposite(alpha);// 使用透明效果
g.drawString(shuiyin, 150, 500);// 绘制文字
canvas.repaint();// 更新画布
// 还原画布
g.rotate(Math.toRadians(30));
alpha = AlphaComposite.SrcOver.derive(1f);// 不透明
g.setComposite(alpha);
g.setColor(foreColor);
}
}
public static void main(String[] args) {
new DrawPictureFrame("", 0, 0, false);
}// main方法
}
总结
- 大部分是对照的视频敲的,但也有一部分是自己想的。
不足:在图形处理上,没有办法从图形选择窗体传值给主窗体,就用了最简单的构造方法传值,但是带来的问题就是每次都是重新产生一个新的主窗体,原先画板上的内容消失。