import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;import static java.awt.BorderLayout.*;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;/**
* Description:
* <br/>Copyright (C), 2005-2008, Yeeku.H.Lee
* <br/>This program is protected by copyright laws.
* <br/>Program Name:
* <br/>Date:
* @author Yeeku.H.Lee [email protected]
* @version 1.0
*/
public class HandDraw
{
//画图区的宽度
private final static int AREA_WIDTH = 500;
//画图区的高度
private final static int AREA_HEIGHT = 400;
//下面的preX、preY保存了上一次鼠标拖动事件的鼠标座标
private int preX = -1;
private int preY = -1;
//定义一个右键菜单用于设置画笔颜色
PopupMenu pop = new PopupMenu();
MenuItem redItem = new MenuItem("红色");
MenuItem greenItem = new MenuItem("绿色");
MenuItem blueItem = new MenuItem("蓝色");
//定义一个BufferedImage对象
static BufferedImage image = new BufferedImage(AREA_WIDTH , AREA_HEIGHT ,
BufferedImage.TYPE_INT_RGB);
//获取image对象的Graphics
Graphics g = image.getGraphics();
private Frame f = new Frame("简单手绘程序");
private DrawCanvas drawArea = new DrawCanvas();
//用于保存需要绘制什么图形的字符串属性
private String shape = "";
//用于保存画笔颜色
private Color foreColor = new Color(255, 0 ,0);
// 画笔样式的监听事件
private ButtonStrokeAction buttonStrokeAction = null;
private Label drawWidth = null;
// 画笔端点的装饰
private Label drawCap = null;
public void init()
{
// 画笔颜色选择器
Panel paneStroke = new Panel(new GridLayout(1, 13));
// 控制画笔样式
buttonStrokeAction = new ButtonStrokeAction();
Button [] buttonStroke = new Button[11];
buttonStroke[0] = new Button("1");
buttonStroke[1] = new Button("3");
buttonStroke[2] = new Button("5");
buttonStroke[3] = new Button("7");
buttonStroke[4] = new Button("9");
buttonStroke[5] = new Button("11");
buttonStroke[6] = new Button("13");
buttonStroke[7] = new Button("15");
buttonStroke[8] = new Button("17");
buttonStroke[9] = new Button("■");
buttonStroke[10] = new Button("●");
drawWidth = new Label("3", Label.CENTER);
drawCap = new Label("●", Label.CENTER);
drawWidth.setBackground(Color.lightGray);
drawCap.setBackground(Color.lightGray);
paneStroke.add(drawWidth);
for(int i = 0; i < buttonStroke.length; i++){
paneStroke.add(buttonStroke[i]);
buttonStroke[i].addActionListener(buttonStrokeAction);
if(i <= 8){
buttonStroke[i].setName("width");
}else{
buttonStroke[i].setName("cap");
}
if(i == 8){
paneStroke.add(drawCap);
}
}
//定义右键菜单的事件监听器。
ActionListener menuListener = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("绿色"))
{
foreColor = new Color(0 , 255 , 0);
}
if (e.getActionCommand().equals("红色"))
{
foreColor = new Color(255 , 0 , 0);
}
if (e.getActionCommand().equals("蓝色"))
{
foreColor = new Color(0 , 0 , 255);
}
}
};
//为三个菜单添加事件监听器
redItem.addActionListener(menuListener);
greenItem.addActionListener(menuListener);
blueItem.addActionListener(menuListener);
//将菜单项组合成右键菜单
pop.add(redItem);
pop.add(greenItem);
pop.add(blueItem);
//将右键菜单添加到drawArea对象中
drawArea.add(pop);
//将image对象的背景色填充成白色
g.fillRect(0 , 0 ,AREA_WIDTH , AREA_HEIGHT);
drawArea.setPreferredSize(new Dimension(AREA_WIDTH , AREA_HEIGHT));
//监听鼠标移动动作
drawArea.addMouseMotionListener(new MouseMotionAdapter()
{
//实现按下鼠标键并拖动的事件处理器
public void mouseDragged(MouseEvent e)
{
//如果preX和preY大于0
if (preX > 0 && preY > 0)
{
//设置当前颜色
g.setColor(foreColor);
//绘制从上一次鼠标拖动事件点到本次鼠标拖动事件点的线段
g.drawLine(preX , preY , e.getX() , e.getY());
}
//将当前鼠标事件点的X、Y座标保存起来
preX = e.getX();
preY = e.getY();
//重绘drawArea对象
drawArea.repaint();
}
});
//监听鼠标事件
drawArea.addMouseListener(new MouseAdapter()
{
//实现鼠标松开的事件处理器
public void mouseReleased(MouseEvent e)
{
//弹出右键菜单
if (e.isPopupTrigger())
{
pop.show(drawArea , e.getX() , e.getY());
}
//松开鼠标键时,把上一次鼠标拖动事件的X、Y座标设为-1。
preX = -1;
preY = -1;
}
});
class MyListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
f.addWindowListener(new MyListener());
f.add(paneStroke, NORTH);
f.add(drawArea);
f.pack();
f.setVisible(true);
}
public static void main(String[] args)
{
new HandDraw().init();
}
static class DrawCanvas extends Canvas
{private static BasicStroke stroke = null;
//重写Canvas的paint方法,实现绘画
public void paint(Graphics g)
{
//将image绘制到该组件上
g.drawImage(image , 0 , 0 , null);
}
public BasicStroke getStroke() {
return getStroke();
} /**
* @param stroke 要设置的 stroke
*/
public void setStroke(BasicStroke stroke) {
this.stroke = stroke;
}
/**
* 设置画笔粗细
* @param width
*/
public static void setStroke(float width) {
stroke = new BasicStroke(width, stroke.getEndCap(), stroke.getLineJoin());
}
/**
* 设置画笔端点的装饰
* @param cap 参考 java.awt.BasicStroke 类静态字段
*/
public static void setStroke(int cap) {
stroke = new BasicStroke(stroke.getLineWidth(), cap, stroke.getLineJoin());
}
}
class ButtonStrokeAction implements ActionListener { public void actionPerformed(ActionEvent e) {
Button button_temp = (Button) e.getSource();
String name = button_temp.getName();
if(name.equalsIgnoreCase("width")){
drawWidth.setText(button_temp.getLabel());
DrawCanvas.setStroke(Float.parseFloat(button_temp.getLabel()));
}else if(name.equalsIgnoreCase("cap")){
drawCap.setText(button_temp.getLabel());
if(button_temp.getLabel().equals("■")){
DrawCanvas.setStroke(BasicStroke.CAP_SQUARE);
}else if(button_temp.getLabel().equals("●")){
DrawCanvas.setStroke(BasicStroke.CAP_ROUND);
}
}
}
}}
运行时候随便点任一个按钮都提示
提示Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at HandDraw$DrawCanvas.setStroke(HandDraw.java:233)
at HandDraw$ButtonStrokeAction.actionPerformed(HandDraw.java:257)
at java.awt.Button.processActionEvent(Unknown Source)
at java.awt.Button.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
import java.awt.event.*;
import java.awt.image.BufferedImage;import static java.awt.BorderLayout.*;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;/**
* Description: <br/>
* Copyright (C), 2005-2008, Yeeku.H.Lee <br/>
* This program is protected by copyright laws. <br/>
* Program Name: <br/>
* Date:
*
* @author Yeeku.H.Lee [email protected]
* @version 1.0
*/
public class HandDraw {
// 画图区的宽度
private final static int AREA_WIDTH = 500;
// 画图区的高度
private final static int AREA_HEIGHT = 400;
// 下面的preX、preY保存了上一次鼠标拖动事件的鼠标座标
private int preX = -1;
private int preY = -1;
// 定义一个右键菜单用于设置画笔颜色
PopupMenu pop = new PopupMenu();
MenuItem redItem = new MenuItem("红色");
MenuItem greenItem = new MenuItem("绿色");
MenuItem blueItem = new MenuItem("蓝色");
// 定义一个BufferedImage对象
static BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT,
BufferedImage.TYPE_INT_RGB);
// 获取image对象的Graphics
Graphics g = image.getGraphics();
private Frame f = new Frame("简单手绘程序");
private DrawCanvas drawArea = new DrawCanvas();
// 用于保存需要绘制什么图形的字符串属性
private String shape = "";
// 用于保存画笔颜色
private Color foreColor = new Color(255, 0, 0); // 画笔样式的监听事件
private ButtonStrokeAction buttonStrokeAction = null;
private Label drawWidth = null; // 画笔端点的装饰
private Label drawCap = null; public void init() { // 画笔颜色选择器
Panel paneStroke = new Panel(new GridLayout(1, 13)); // 控制画笔样式
buttonStrokeAction = new ButtonStrokeAction();
Button[] buttonStroke = new Button[11];
buttonStroke[0] = new Button("1");
buttonStroke[1] = new Button("3");
buttonStroke[2] = new Button("5");
buttonStroke[3] = new Button("7");
buttonStroke[4] = new Button("9");
buttonStroke[5] = new Button("11");
buttonStroke[6] = new Button("13");
buttonStroke[7] = new Button("15");
buttonStroke[8] = new Button("17");
buttonStroke[9] = new Button("■");
buttonStroke[10] = new Button("●");
drawWidth = new Label("3", Label.CENTER);
drawCap = new Label("●", Label.CENTER);
drawWidth.setBackground(Color.lightGray);
drawCap.setBackground(Color.lightGray);
paneStroke.add(drawWidth);
for (int i = 0; i < buttonStroke.length; i++) {
paneStroke.add(buttonStroke[i]); buttonStroke[i].addActionListener(buttonStrokeAction);
if (i <= 8) {
buttonStroke[i].setName("width");
} else {
buttonStroke[i].setName("cap");
}
if (i == 8) {
paneStroke.add(drawCap);
}
} // 定义右键菜单的事件监听器。
ActionListener menuListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("绿色")) {
foreColor = new Color(0, 255, 0);
}
if (e.getActionCommand().equals("红色")) {
foreColor = new Color(255, 0, 0);
}
if (e.getActionCommand().equals("蓝色")) {
foreColor = new Color(0, 0, 255);
}
}
};
// 为三个菜单添加事件监听器
redItem.addActionListener(menuListener);
greenItem.addActionListener(menuListener);
blueItem.addActionListener(menuListener);
// 将菜单项组合成右键菜单
pop.add(redItem);
pop.add(greenItem);
pop.add(blueItem);
// 将右键菜单添加到drawArea对象中
drawArea.add(pop);
// 将image对象的背景色填充成白色
g.fillRect(0, 0, AREA_WIDTH, AREA_HEIGHT);
drawArea.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));
// 监听鼠标移动动作
drawArea.addMouseMotionListener(new MouseMotionAdapter() {
// 实现按下鼠标键并拖动的事件处理器
public void mouseDragged(MouseEvent e) {
// 如果preX和preY大于0
if (preX > 0 && preY > 0) {
// 设置当前颜色
g.setColor(foreColor);
// 绘制从上一次鼠标拖动事件点到本次鼠标拖动事件点的线段
g.drawLine(preX, preY, e.getX(), e.getY());
}
// 将当前鼠标事件点的X、Y座标保存起来
preX = e.getX();
preY = e.getY();
// 重绘drawArea对象
drawArea.repaint();
}
});
// 监听鼠标事件
drawArea.addMouseListener(new MouseAdapter() {
// 实现鼠标松开的事件处理器
public void mouseReleased(MouseEvent e) {
// 弹出右键菜单
if (e.isPopupTrigger()) {
pop.show(drawArea, e.getX(), e.getY());
}
// 松开鼠标键时,把上一次鼠标拖动事件的X、Y座标设为-1。
preX = -1;
preY = -1;
}
}); class MyListener extends WindowAdapter {
public void windowClosing(WindowEvent e) { System.exit(0);
}
}
f.addWindowListener(new MyListener());
f.add(paneStroke, NORTH);
f.add(drawArea);
f.pack();
f.setVisible(true);
} public static void main(String[] args) {
new HandDraw().init();
} static class DrawCanvas extends Canvas {
private static BasicStroke stroke = null; // 重写Canvas的paint方法,实现绘画
public void paint(Graphics g) {
// 将image绘制到该组件上
g.drawImage(image, 0, 0, null);
} public BasicStroke getStroke() {
return getStroke();
} /**
* @param stroke
* 要设置的 stroke
*/
public void setStroke(BasicStroke stroke) {
this.stroke = stroke;
} /**
* 设置画笔粗细
*
* @param width
*/
public static void setStroke(float width) {
stroke = new BasicStroke(width);
} /**
* 设置画笔端点的装饰
*
* @param cap
* 参考 java.awt.BasicStroke 类静态字段
*/
public static void setStroke(int cap) {
stroke = new BasicStroke(stroke.getLineWidth(), cap,
stroke.getLineJoin());
} } class ButtonStrokeAction implements ActionListener { public void actionPerformed(ActionEvent e) {
Button button_temp = (Button) e.getSource();
String name = button_temp.getName();
if (name.equalsIgnoreCase("width")) {
drawWidth.setText(button_temp.getLabel());
DrawCanvas.setStroke(Float.parseFloat(button_temp.getLabel()));
} else if (name.equalsIgnoreCase("cap")) {
drawCap.setText(button_temp.getLabel());
if (button_temp.getLabel().equals("■")) {
DrawCanvas.setStroke(BasicStroke.CAP_SQUARE);
} else if (button_temp.getLabel().equals("●")) {
DrawCanvas.setStroke(BasicStroke.CAP_ROUND);
}
}
} }}
改成这个后,点击按钮,线条不会发生改变的。。为什么呢