今天看到了一款mini小画板的程序,看起来不错,跟大家分享一下:
package drawingpanel;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class MiniDrawPad extends JFrame // 主类,扩展了JFrame类,用来生成主界面
{
private ObjectInputStream input;
private ObjectOutputStream output; // 定义输入输出流,用来调用和保存图像文件
private JButton choices[]; // 按钮数组,存放以下名称的功能按钮
private String names[] = { "New", "Open", "Save", // 这三个是基本操作按钮,包括"新建"、"打开"、"保存"
/* 接下来是我们的画图板上面有的基本的几个绘图单元按钮 */
"Pencil", // 铅笔画,也就是用鼠标拖动着随意绘图
"Line", // 绘制直线
"Rect", // 绘制空心矩形
"fRect", // 绘制以指定颜色填充的实心矩形
"Oval", // 绘制空心椭圆
"fOval", // 绘制以指定颜色填充的实心椭圆
"Circle", // 绘制圆形
"fCircle", // 绘制以指定颜色填充的实心圆形
"RoundRect", // 绘制空心圆角矩形
"frRect", // 绘制以指定颜色填充的实心圆角矩形
"Rubber", // 橡皮擦,可用来擦去已经绘制好的图案
"Color", // 选择颜色按钮,可用来选择需要的颜色
"Stroke", // 选择线条粗细的按钮,输入需要的数值可以实现绘图线条粗细的变化
"Word" // 输入文字按钮,可以在绘图板上实现文字输入
};
private String styleNames[] = { " 宋体 ", " 隶书 ", " 华文彩云 ", " 仿宋_GB2312 ",
" 华文行楷 ", " 方正舒体 ", " Times New Roman ", " Serif ", " Monospaced ",
" SonsSerif ", " Garamond " }; // 可供选择的字体项
// 当然这里的灵活的结构可以让读者自己随意添加系统支持的字体
private Icon items[];
private String tipText[] = {
// 这里是鼠标移动到相应按钮上面上停留时给出的提示说明条
// 读者可以参照上面的按钮定义对照着理解
"Draw a new picture", "Open a saved picture",
"Save current drawing", "Draw at will", "Draw a straight line",
"Draw a rectangle", "Fill a ractangle", "Draw an oval",
"Fill an oval", "Draw a circle", "Fill a circle",
"Draw a round rectangle", "Fill a round rectangle",
"Erase at will", "Choose current drawing color",
"Set current drawing stroke", "Write down what u want" };
JToolBar buttonPanel; // 定义按钮面板
private JLabel statusBar; // 显示鼠标状态的提示条
private DrawPanel drawingArea; // 画图区域
private int width = 800, height = 550; // 定义画图区域初始大小
drawings[] itemList = new drawings[5000]; // 用来存放基本图形的数组
private int currentChoice = 3; // 设置默认画图状态为随笔画
int index = 0; // 当前已经绘制的图形数目
private Color color = Color.black; // 当前画笔颜色
int R, G, B; // 用来存放当前色彩值
int f1, f2; // 用来存放当前字体风格
String style1; // 用来存放当前字体
private float stroke = 1.0f; // 设置画笔粗细,默认值为1.0f
JCheckBox bold, italic; // 定义字体风格选择框
// bold为粗体,italic为斜体,二者可以同时使用
JComboBox styles;
public MiniDrawPad() // 构造函数
{
super("Drawing Pad");
JMenuBar bar = new JMenuBar(); // 定义菜单条
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
// 新建文件菜单条
JMenuItem newItem = new JMenuItem("New");
newItem.setMnemonic('N');
newItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newFile(); // 如果被触发,则调用新建文件函数段
}
});
fileMenu.add(newItem);
// 保存文件菜单项
JMenuItem saveItem = new JMenuItem("Save");
saveItem.setMnemonic('S');
saveItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFile(); // 如果被触发,则调用保存文件函数段
}
});
fileMenu.add(saveItem);
// 打开文件菜单项
JMenuItem loadItem = new JMenuItem("Load");
loadItem.setMnemonic('L');
loadItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
loadFile(); // 如果被触发,则调用打开文件函数段
}
});
fileMenu.add(loadItem);
fileMenu.addSeparator();
// 退出菜单项
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('X');
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0); // 如果被触发,则退出画图板程序
}
});
fileMenu.add(exitItem);
bar.add(fileMenu);
// 设置颜色菜单条
JMenu colorMenu = new JMenu("Color");
colorMenu.setMnemonic('C');
// 选择颜色菜单项
JMenuItem colorItem = new JMenuItem("Choose Color");
colorItem.setMnemonic('O');
colorItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
chooseColor(); // 如果被触发,则调用选择颜色函数段
}
});
colorMenu.add(colorItem);
bar.add(colorMenu);
// 设置线条粗细菜单条
JMenu strokeMenu = new JMenu("Stroke");
strokeMenu.setMnemonic('S');
// 设置线条粗细菜单项
JMenuItem strokeItem = new JMenuItem("Set Stroke");
strokeItem.setMnemonic('K');
strokeItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setStroke();
}
});
strokeMenu.add(strokeItem);
bar.add(strokeMenu);
// 设置提示菜单条
JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic('H');
// 设置提示菜单项
JMenuItem aboutItem = new JMenuItem("About this Drawing Pad!");
aboutItem.setMnemonic('A');
aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane
.showMessageDialog(
null,
"This is a mini drawing pad!\nCopyright (c) 2002 Tsinghua University ",
" 画图板程序说明 ", JOptionPane.INFORMATION_MESSAGE);
}
});
helpMenu.add(aboutItem);
bar.add(helpMenu);
items = new ImageIcon[names.length];
// 创建各种基本图形的按钮
drawingArea = new DrawPanel();
choices = new JButton[names.length];
buttonPanel = new JToolBar(JToolBar.VERTICAL);
buttonPanel = new JToolBar(JToolBar.HORIZONTAL);
ButtonHandler handler = new ButtonHandler();
ButtonHandler1 handler1 = new ButtonHandler1();
// 导入我们需要的图形图标,这些图标都存放在与源文件相同的目录下面
for (int i = 0; i < choices.length; i++) {// items[i]=new ImageIcon(
// MiniDrawPad.class.getResource(names[i]
// +".gif"));
// 如果在jbuilder下运行本程序,则应该用这条语句导入图片
items[i] = new ImageIcon(names[i] + ".gif");
// 默认的在jdk或者jcreator下运行,用此语句导入图片
choices[i] = new JButton("", items[i]);
choices[i].setToolTipText(tipText[i]);
buttonPanel.add(choices[i]);
}
// 将动作侦听器加入按钮里面
for (int i = 3; i < choices.length - 3; i++) {
choices[i].addActionListener(handler);
}
choices[0].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newFile();
}
});
choices[1].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
loadFile();
}
});
choices[2].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFile();
}
});
choices[choices.length - 3].addActionListener(handler1);
choices[choices.length - 2].addActionListener(handler1);
choices[choices.length - 1].addActionListener(handler1);
// 字体风格选择
styles = new JComboBox(styleNames);
styles.setMaximumRowCount(8);
styles.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
style1 = styleNames[styles.getSelectedIndex()];
}
});
// 字体选择
bold = new JCheckBox("BOLD");
italic = new JCheckBox("ITALIC");
checkBoxHandler cHandler = new checkBoxHandler();
bold.addItemListener(cHandler);
italic.addItemListener(cHandler);
JPanel wordPanel = new JPanel();
buttonPanel.add(bold);
buttonPanel.add(italic);
buttonPanel.add(styles);
styles.setMinimumSize(new Dimension(50, 20));
styles.setMaximumSize(new Dimension(100, 20));
Container c = getContentPane();
super.setJMenuBar(bar);
c.add(buttonPanel, BorderLayout.NORTH);
c.add(drawingArea, BorderLayout.CENTER);
statusBar = new JLabel();
c.add(statusBar, BorderLayout.SOUTH);
statusBar.setText(" Welcome To The Little Drawing Pad!!! :)");
createNewItem();
setSize(width, height);
show();
}
// 按钮侦听器ButtonHanler类,内部类,用来侦听基本按钮的操作
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (int j = 3; j < choices.length - 3; j++) {
if (e.getSource() == choices[j]) {
currentChoice = j;
createNewItem();
repaint();
}
}
}
}
// 按钮侦听器ButtonHanler1类,用来侦听颜色选择、画笔粗细设置、文字输入按钮的操作
public class ButtonHandler1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == choices[choices.length - 3]) {
chooseColor();
}
if (e.getSource() == choices[choices.length - 2]) {
setStroke();
}
if (e.getSource() == choices[choices.length - 1]) {
JOptionPane
.showMessageDialog(
null,
"Please hit the drawing pad to choose the word input position",
"Hint", JOptionPane.INFORMATION_MESSAGE);
currentChoice = 14;
createNewItem();
repaint();
}
}
}
// 鼠标事件mouseA类,继承了MouseAdapter,用来完成鼠标相应事件操作
class mouseA extends MouseAdapter {
public void mousePressed(MouseEvent e) {
statusBar.setText(" Mouse Pressed @:[" + e.getX() + ", "
+ e.getY() + "]");// 设置状态提示
itemList[index].x1 = itemList[index].x2 = e.getX();
itemList[index].y1 = itemList[index].y2 = e.getY();
// 如果当前选择的图形是随笔画或者橡皮擦,则进行下面的操作
if (currentChoice == 3 || currentChoice == 13) {
itemList[index].x1 = itemList[index].x2 = e.getX();
itemList[index].y1 = itemList[index].y2 = e.getY();
index++;
createNewItem();
}
// 如果当前选择的图形式文字输入,则进行下面操作
if (currentChoice == 14) {
itemList[index].x1 = e.getX();
itemList[index].y1 = e.getY();
String input;
input = JOptionPane
.showInputDialog("Please input the text you want!");
itemList[index].s1 = input;
itemList[index].x2 = f1;
itemList[index].y2 = f2;
itemList[index].s2 = style1;
index++;
currentChoice = 14;
createNewItem();
drawingArea.repaint();
}
}
public void mouseReleased(MouseEvent e) {
statusBar.setText(" Mouse Released @:[" + e.getX() + ", "
+ e.getY() + "]");
if (currentChoice == 3 || currentChoice == 13) {
itemList[index].x1 = e.getX();
itemList[index].y1 = e.getY();
}
itemList[index].x2 = e.getX();
itemList[index].y2 = e.getY();
repaint();
index++;
createNewItem();
}
public void mouseEntered(MouseEvent e) {
statusBar.setText(" Mouse Entered @:[" + e.getX() + ", "
+ e.getY() + "]");
}
public void mouseExited(MouseEvent e) {
statusBar.setText(" Mouse Exited @:[" + e.getX() + ", "
+ e.getY() + "]");
}
}
// 鼠标事件mouseB类继承了MouseMotionAdapter,用来完成鼠标拖动和鼠标移动时的相应操作
class mouseB extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
statusBar.setText(" Mouse Dragged @:[" + e.getX() + ", "
+ e.getY() + "]");
if (currentChoice == 3 || currentChoice == 13) {
itemList[index - 1].x1 = itemList[index].x2 = itemList[index].x1 = e
.getX();
itemList[index - 1].y1 = itemList[index].y2 = itemList[index].y1 = e
.getY();
index++;
createNewItem();
} else {
itemList[index].x2 = e.getX();
itemList[index].y2 = e.getY();
}
repaint();
}
public void mouseMoved(MouseEvent e) {
statusBar.setText(" Mouse Moved @:[" + e.getX() + ", "
+ e.getY() + "]");
}
}
// 选择字体风格时候用到的事件侦听器类,加入到字体风格的选择框中
private class checkBoxHandler implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (e.getSource() == bold)
if (e.getStateChange() == ItemEvent.SELECTED)
f1 = Font.BOLD;
else
f1 = Font.PLAIN;
if (e.getSource() == italic)
if (e.getStateChange() == ItemEvent.SELECTED)
f2 = Font.ITALIC;
else
f2 = Font.PLAIN;
}
}
// 画图面板类,用来画图
class DrawPanel extends JPanel {
public DrawPanel() {
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
setBackground(Color.white);
addMouseListener(new mouseA());
addMouseMotionListener(new mouseB());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g; // 定义画笔
int j = 0;
while (j <= index) {
draw(g2d, itemList[j]);
j++;
}
}
void draw(Graphics2D g2d, drawings i) {
i.draw(g2d);// 将画笔传入到各个子类中,用来完成各自的绘图
}
}
// 新建一个画图基本单元对象的程序段
void createNewItem() {
if (currentChoice == 14)// 进行相应的游标设置
drawingArea.setCursor(Cursor
.getPredefinedCursor(Cursor.TEXT_CURSOR));
else
drawingArea.setCursor(Cursor
.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
switch (currentChoice) {
case 3:
itemList[index] = new Pencil();
break;
case 4:
itemList[index] = new Line();
break;
case 5:
itemList[index] = new Rect();
break;
case 6:
itemList[index] = new fillRect();
break;
case 7:
itemList[index] = new Oval();
break;
case 8:
itemList[index] = new fillOval();
break;
case 9:
itemList[index] = new Circle();
break;
case 10:
itemList[index] = new fillCircle();
break;
case 11:
itemList[index] = new RoundRect();
break;
case 12:
itemList[index] = new fillRoundRect();
break;
case 13:
itemList[index] = new Rubber();
break;
case 14:
itemList[index] = new Word();
break;
}
itemList[index].type = currentChoice;
itemList[index].R = R;
itemList[index].G = G;
itemList[index].B = B;
itemList[index].stroke = stroke;
}
// 选择当前颜色程序段
public void chooseColor() {
color = JColorChooser.showDialog(MiniDrawPad.this, "Choose a color",
color);
R = color.getRed();
G = color.getGreen();
B = color.getBlue();
itemList[index].R = R;
itemList[index].G = G;
itemList[index].B = B;
}
// 选择当前线条粗细程序段
public void setStroke() {
String input;
input = JOptionPane
.showInputDialog("Please input a float stroke value! ( >0 )");
stroke = Float.parseFloat(input);
itemList[index].stroke = stroke;
}
// 保存图形文件程序段
public void saveFile() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showSaveDialog(this);
if (result == JFileChooser.CANCEL_OPTION)
return;
File fileName = fileChooser.getSelectedFile();
fileName.canWrite();
if (fileName == null || fileName.getName().equals(""))
JOptionPane.showMessageDialog(fileChooser, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE);
else {
try {
fileName.delete();
FileOutputStream fos = new FileOutputStream(fileName);
output = new ObjectOutputStream(fos);
drawings record;
output.writeInt(index);
for (int i = 0; i < index; i++) {
drawings p = itemList[i];
output.writeObject(p);
output.flush(); // 将所有图形信息强制转换成父类线性化存储到文件中
}
output.close();
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
// 打开一个图形文件程序段
public void loadFile() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showOpenDialog(this);
if (result == JFileChooser.CANCEL_OPTION)
return;
File fileName = fileChooser.getSelectedFile();
fileName.canRead();
if (fileName == null || fileName.getName().equals(""))
JOptionPane.showMessageDialog(fileChooser, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE);
else {
try {
FileInputStream fis = new FileInputStream(fileName);
input = new ObjectInputStream(fis);
drawings inputRecord;
int countNumber = 0;
countNumber = input.readInt();
for (index = 0; index < countNumber; index++) {
inputRecord = (drawings) input.readObject();
itemList[index] = inputRecord;
}
createNewItem();
input.close();
repaint();
} catch (EOFException endofFileException) {
JOptionPane.showMessageDialog(this, "no more record in file",
"class not found", JOptionPane.ERROR_MESSAGE);
} catch (ClassNotFoundException classNotFoundException) {
JOptionPane.showMessageDialog(this, "Unable to Create Object",
"end of file", JOptionPane.ERROR_MESSAGE);
} catch (IOException ioException) {
JOptionPane.showMessageDialog(this,
"error during read from file", "read Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
// 新建一个文件程序段
public void newFile() {
index = 0;
currentChoice = 3;
color = Color.black;
stroke = 1.0f;
createNewItem();
repaint();// 将有关值设置为初始状态,并且重画
}
// 主函数段
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}// 将界面设置为当前windows风格
MiniDrawPad newPad = new MiniDrawPad();
newPad.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
// 定义画图的基本图形单元
class drawings implements Serializable// 父类,基本图形单元,用到串行化接口,保存时所用
{
int x1, y1, x2, y2; // 定义坐标属性
int R, G, B; // 定义色彩属性
float stroke; // 定义线条粗细属性
int type; // 定义字体属性
String s1;
String s2; // 定义字体风格属性
void draw(Graphics2D g2d) {
};// 定义绘图函数
}
/*******************************************************************************
* 下面是各种基本图形单元的子类,都继承自父类drawings,请仔细理解继承的概念
********************************************************************************/
class Line extends drawings // 直线类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g2d.drawLine(x1, y1, x2, y2);
}
}
class Rect extends drawings// 矩形类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2),
Math.abs(y1 - y2));
}
}
class fillRect extends drawings// 实心矩形类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2),
Math.abs(y1 - y2));
}
}
class Oval extends drawings// 椭圆类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2),
Math.abs(y1 - y2));
}
}
class fillOval extends drawings// 实心椭圆
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2),
Math.abs(y1 - y2));
}
}
class Circle extends drawings// 圆类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.drawOval(Math.min(x1, x2), Math.min(y1, y2),
Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
}
}
class fillCircle extends drawings// 实心圆
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.fillOval(Math.min(x1, x2), Math.min(y1, y2),
Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
}
}
class RoundRect extends drawings// 圆角矩形类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.drawRoundRect(Math.min(x1, x2), Math.min(y1, y2),
Math.abs(x1 - x2), Math.abs(y1 - y2), 50, 35);
}
}
class fillRoundRect extends drawings// 实心圆角矩形类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke));
g2d.fillRoundRect(Math.min(x1, x2), Math.min(y1, y2),
Math.abs(x1 - x2), Math.abs(y1 - y2), 50, 35);
}
}
class Pencil extends drawings// 随笔画类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g2d.drawLine(x1, y1, x2, y2);
}
}
class Rubber extends drawings// 橡皮擦类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(255, 255, 255));
g2d.setStroke(new BasicStroke(stroke + 4, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g2d.drawLine(x1, y1, x2, y2);
}
}
class Word extends drawings// 输入文字类
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setFont(new Font(s2, x2 + y2, ((int) stroke) * 18));
if (s1 != null)
g2d.drawString(s1, x1, y1);
}
}
效果: