仿XP画板今天终于将一些基本功能实现了包括画笔,画刷,矩形,圆角矩形,圆形,直线,任意多边形,喷枪,橡皮,以及矩形选择工具的中画出一个虚边框的矩形等这些的基本功能,还有油漆桶工具,以及在一些图形中可以选择不同类型这个功能没有实现,希望指教一下,我附上我的代码吧。
颜色选择工具栏:
package com.why.ui;
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;
/**
* 颜色选择工具栏放在窗体的南边区域
*
* @author why
*
*/
public class ColorPanel extends JPanel {
private static final long serialVersionUID = 1L;
private Color colorL;
private Color colorR;
public ColorPanel() {
initUI();
colorL = Color.BLACK;
colorR = Color.WHITE;
}
private void initUI() {
this.setPreferredSize(new Dimension(0, 45));
this.setLayout(new FlowLayout(FlowLayout.LEFT));
// 实例化一个JPanel对象
JPanel panel1 = new JPanel();
// 设置Panel1的大小
panel1.setPreferredSize(new Dimension(40, 40));
// 设置JPanel的布局为绝对布局
panel1.setLayout(null);
// 实例化一个按钮颜色
final JButton jbuL = new JButton();
// 给按钮设置背景色
jbuL.setBackground(Color.BLACK);
// 实例化一个按钮对象
final JButton jbuR = new JButton();
// 给按钮设置背景色
jbuR.setBackground(Color.WHITE);
panel1.setBackground(Color.DARK_GRAY);
jbuL.setBounds(10, 10, 15, 15);
jbuR.setBounds(17, 17, 15, 15);
panel1.add(jbuL);
panel1.add(jbuR);
this.add(panel1);
JPanel panel2 = new JPanel(new GridLayout(2, 5, 1, 1));
MouseAdapter ma = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
JButton button = (JButton) e.getSource();
if (e.getButton() == 1) {// 当按下鼠标左键的时候将鼠标左键对应的颜色设置为当前值
colorL = button.getBackground();
jbuL.setBackground(colorL);
} else if (e.getButton() == 3) {// 当按下鼠标右键的时候将鼠标右键对应的颜色设置为当前值
colorR = button.getBackground();
jbuR.setBackground(colorR);
}
}
};
// 定义一个数组,用来存储按钮的颜色
Color[] array = { Color.BLACK, Color.WHITE, Color.RED, Color.GREEN,
Color.BLUE, Color.GRAY, Color.ORANGE, Color.PINK, Color.CYAN, Color.MAGENTA };
for (Color color : array) {
JButton button = new JButton();
button.setBackground(color);
button.setPreferredSize(new Dimension(15, 15));
button.addMouseListener(ma);
panel2.add(button);
}
this.add(panel2);
}
public Color getColorL() {
return colorL;
}
public Color getColorR() {
return colorR;
}
}
图形选择工具栏:
package com.why.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
/**
* 定义图形工具栏放在窗体的西边,继承了JPanel
*
* @author why
*
*/
public class ToolsPanel extends JPanel {
private static final long serialVersionUID = 1L;
private String str;// 表示用户选择的图形
private JPanel panel;
public ToolsPanel() {
initUI();
this.str = "7";
}
private void initUI() {
this.setPreferredSize(new Dimension(60, 0));
// 用匿名内部类来创建一个按钮的监听器对象
ActionListener l = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
str = e.getActionCommand();
}
};
// 添加工具栏的按钮
for (int i = 1; i < 17; i++) {
// 生成一个图片资源的URL方便在将工程打包成jar文件的时候依然能够访问到资源图片
URL url = ToolsPanel.class.getResource("/res/" + i + ".png");
// 根据得到的URL来加载按钮的背景图片
ImageIcon icon = new ImageIcon(url);;
// 实例化一个按钮对象
JButton button = new JButton(icon);
// 设置按钮的大小
button.setPreferredSize(new Dimension(25, 25));
// 设置按钮的动作命令
button.setActionCommand(i + "");
// 给按钮绑定监听器
button.addActionListener(l);
// 将按钮添加到工具栏的容器中
this.add(button);
}
panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 3, 3));
panel.setPreferredSize(new Dimension(42, 66));
panel.setBackground(Color.WHITE);
this.add(panel);
}
public String getStr() {
return str;
}
public JPanel getPanel() {
return panel;
}
}
主窗体类:
package com.why.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import com.why.listener.DrawListener;
import com.why.listener.MenuListener;
/**
* XP画板的窗体类,继承JFrame
*
* @author why
*
*/
public class DrawerFrame extends JFrame {
private static final long serialVersionUID = 1L;
private List<JMenuItem> list;// list用于存放菜单选项方便给每个菜单选项添加监听器
/**
* 程序的入口主函数
*/
public static void main(String[] args) {
DrawerFrame frame = new DrawerFrame();
frame.initUI();
}
/**
* 窗体类的构造方法
*/
public DrawerFrame() {
this.list = new ArrayList<JMenuItem>();
}
/**
* 初始化画板主界面的方法
*/
public void initUI() {
// 设置窗体的属性
this.setTitle("画板");
this.setSize(new Dimension(1024, 700));
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setIconImage(new ImageIcon("res" + File.separator + "icon.png").getImage());
// 调用创建菜单选项的方法在窗体上创建菜单选项
createMenuBar();
// 实例化一个JPanel对象用于放置画板绘图区域
JPanel centerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 4));
// 设置背景色为灰色
centerPanel.setBackground(Color.GRAY);
// 实例化一个画图区域对象,实际上就是JPanel的实例
JPanel drawPanel = new JPanel();
// 设置绘图区域的背景色为白色
drawPanel.setBackground(Color.WHITE);
// 设置绘图区域的大小为500*400像素
drawPanel.setPreferredSize(new Dimension(880, 500));
// 将绘图区域添加到centerPanel中
centerPanel.add(drawPanel);
// 将centerPanel添加到窗体中
this.add(centerPanel, BorderLayout.CENTER);
// 实例化一个颜色工具条
ColorPanel colorPanel = new ColorPanel();
// 实例化一个图形选择工具条
ToolsPanel toolsPanel = new ToolsPanel();
// 将颜色工具条添加到窗体上
this.add(colorPanel, BorderLayout.SOUTH);
// 将图形选择工具条添加到窗体上
this.add(toolsPanel, BorderLayout.WEST);
this.setVisible(true);
// 给DrawPanel添加监听器
Graphics2D graphics2d = (Graphics2D) drawPanel.getGraphics();
// 实例化一个绘图区域的监听器
DrawListener dl = new DrawListener(graphics2d, toolsPanel, colorPanel);
drawPanel.addMouseListener(dl);
drawPanel.addMouseMotionListener(dl);
// 实例化一个菜单选项监听器对象
MenuListener ml = new MenuListener(graphics2d);
for (JMenuItem item : list) {
item.addActionListener(ml);
}
}
/**
* 创建菜单选项的方法
*/
private void createMenuBar() {
JMenuBar menuBar = new JMenuBar();
String[] arrayMenu = { "文件(F)", "编辑(E)", "查看(V)", "图像(I)", "颜色(C)", "帮助(H)" };
String[][] arrayMenuItem = { { "新建(N)", "打开(O)", "保存(S)", "退出(E)" }, { "复制(C)", "粘贴(P)" },
{ "工具箱(T)", "颜料盒" }, { "清除图像", "反色", "属性" }, { "编辑颜色" },
{ "帮助主题", "关于画图" } };
for (int i = 0; i < arrayMenu.length; i++) {
// 实例化一个JMenu对象
JMenu menu = new JMenu(arrayMenu[i]);
for (int j = 0; j < arrayMenuItem[i].length; j++) {
// 实例化一个JMenuItem对象
JMenuItem item = new JMenuItem(arrayMenuItem[i][j]);
list.add(item);
// 将JMenuItem对象添加到JMenu中
menu.add(item);
}
// 将JMenu添加到JMenuBar中
menuBar.add(menu);
}
// 给menuBar设置大小
menuBar.setPreferredSize(new Dimension(800, 30));
// 给窗体设置菜单栏
this.setJMenuBar(menuBar);
}
}
绘图区域的监听器:
package com.why.listener;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import com.why.ui.ColorPanel;
import com.why.ui.ToolsPanel;
/**
* 绘图区域的事件监听器类继承了MouseAdapter类,该类已经实现了MouseListener和MouseMotionListener接口
*
* @author why
*
*/
public class DrawListener extends MouseAdapter {
private Graphics2D graphics2d;// 绘图区域的Graphic2D对象,用于绘制给定的图形
private ToolsPanel toolsPanel;// 图形选择工具条
private ColorPanel colorPanel;// 颜色选择工具条
private int x1, x2, y1, y2, startx, starty;
private boolean flag;// 用于标记当前绘制的任意多边形是否绘制完成
/**
* 构造方法
*
* @param graphics2d 画图的画笔对象
* @param toolsPanel 工具栏对象
* @param colorPanel 颜色栏对象
*/
public DrawListener(Graphics2D graphics2d, ToolsPanel toolsPanel,
ColorPanel colorPanel) {
this.graphics2d = graphics2d;
this.toolsPanel = toolsPanel;
this.colorPanel = colorPanel;
this.flag = false;
}
@Override
public void mouseDragged(MouseEvent e) {
String action = toolsPanel.getStr();
if (action.equals("8")) {// 当用户选择画刷工具执行的动作
// 设置画笔的粗细
graphics2d.setStroke(new BasicStroke(7));
// 获取拖动过程中的坐标值
x2 = e.getX();
y2 = e.getY();
// 绘制直线
graphics2d.drawLine(x1, y1, x2, y2);
// 交换坐标
x1 = x2;
y1 = y2;
} else if (action.equals("7")) {// 当用户选择的是铅笔工具执行的动作
// 获取拖动过程中的坐标值
x2 = e.getX();
y2 = e.getY();
// 绘制直线
graphics2d.drawLine(x1, y1, x2, y2);
// 交换坐标
x1 = x2;
y1 = y2;
} else if (action.equals("3")) {// 当用户选择的是橡皮工具执行的动作
graphics2d.setStroke(new BasicStroke(8));
// 获取拖动过程中的坐标值
x2 = e.getX();
y2 = e.getY();
// 绘制直线
graphics2d.drawLine(x1, y1, x2, y2);
// 交换坐标
x1 = x2;
y1 = y2;
}
}
@Override
public void mousePressed(MouseEvent e) {
String action = toolsPanel.getStr();
if (!action.equals("14")) {// 判断当前绘制的不是任意多边形
x1 = e.getX();
y1 = e.getY();
} else {// 如果当前绘制是任意多边形
if (!flag) {// 判断当前的鼠标按下的位置是多边形的起点
startx = x1 = e.getX();
starty = y1 = e.getY();
flag = true;
}
}
if (e.getButton() == 1) {// 如果按下的是鼠标的左键那么将graphics2d颜色设置为选择的颜色
graphics2d.setColor(colorPanel.getColorL());
if (toolsPanel.getStr().equals("3")) {
graphics2d.setColor(Color.WHITE);
}
System.out.println("left");
} else if (e.getButton() == 3) {// 如果按下的是鼠标的右键那么将graphics2d颜色设置为选择的颜色
graphics2d.setColor(colorPanel.getColorR());
System.out.println("right");
}
graphics2d.setStroke(new BasicStroke(1));
}
@Override
public void mouseReleased(MouseEvent e) {
String action = toolsPanel.getStr();
if (action.equals("11")) {// 当用户选择的是直线执行绘制直线的步骤
x2 = e.getX();
y2 = e.getY();
graphics2d.drawLine(x1, y1, x2, y2);
} else if (action.equals("2")) {// 当用户选择的是选框工具按钮执行的动作
x2 = e.getX();
y2 = e.getY();
drawDash();
} else if (action.equals("13")) {// 当用户选择的是矩形工具按钮的动作
x2 = e.getX();
y2 = e.getY();
graphics2d.drawRect(x1, y1, x2 - x1, y2 - y1);
} else if (action.equals("16")) {// 当用户选择的是圆角矩形工具执行的动作
x2 = e.getX();
y2 = e.getY();
graphics2d.drawRoundRect(x1, y1, x2 - x1, y2 - y1, 12, 12);
} else if (action.equals("15")) {// 当用户选择的是圆形工具执行的动作
x2 = e.getX();
y2 = e.getY();
graphics2d.drawOval(x1, y1, x2 - x1, y2 - y1);
} else if (action.equals("14")) {// 当用户学选择的是任意多边形工具执行的动作
x2 = e.getX();
y2 = e.getY();
if ((x2 - startx) * (x2 - startx) + (y2 - starty) * (y2 - starty) <= 64) {// 判断当前的点是不是多边形的终点
x2 = startx;
y2 = starty;
flag = false;
}
graphics2d.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
} else if (action.equals("9")) {// 当用户选择的是喷枪工具执行的动作
// 实例化一个随机数生成的对象
x1 = e.getX();
y1 = e.getY();
Random random = new Random();
for (int i = 0; i < 200; i++) {
x2 = random.nextInt(25) - 12;
y2 = random.nextInt(25) - 12;
if (x2 * x2 + y2 * y2 > 121)
continue;// 如果生成的点不在以点击的位置为圆心以11为半径的圆内那么直接跳过这个点
graphics2d.drawLine(x1 + x2, y1 + y2, x1 + x2, y1 + y2);
}
}
}
/**
* 绘制虚线边框的矩形函数
*/
private void drawDash() {
// 取得graphics2d原本的颜色
Color c = graphics2d.getColor();
Color color = new Color(51, 153, 255);
// 绘制两条水平线
for (int i = x1; i <= x2; i += 4) {
// 设置虚线可见部分的颜色
graphics2d.setColor(color);
graphics2d.drawLine(i, y1, i + 2, y1);
graphics2d.drawLine(i, y2, i + 2, y2);
// 设置虚线不可见部分为白色
graphics2d.setColor(Color.WHITE);
graphics2d.drawLine(i + 2, y1, i + 4, y1);
graphics2d.drawLine(i + 2, y2, i + 4, y2);
}
for (int i = y1; i <= y2; i += 4) {
// 设置虚线可见部分的颜色
graphics2d.setColor(color);
graphics2d.drawLine(x1, i, x1, i + 2);
graphics2d.drawLine(x2, i, x2, i + 2);
// 设置虚线不可见部分为白色
graphics2d.setColor(Color.WHITE);
graphics2d.drawLine(x1, i + 2, x1, i + 4);
graphics2d.drawLine(x2, i + 2, x2, i + 4);
}
// 绘制虚线框的四个定点以及四条边的中点使其变得更明显
graphics2d.setColor(color);
// 设置画笔的粗细
graphics2d.setStroke(new BasicStroke(3));
graphics2d.drawLine(x1, y1, x1, y1);
graphics2d.drawLine(x1, y2, x1, y2);
graphics2d.drawLine(x2, y1, x2, y1);
graphics2d.drawLine(x2, y2, x2, y2);
graphics2d.drawLine((x1 + x2) >> 1, y1, (x1 + x2) >> 1, y1);
graphics2d.drawLine(x1, (y1 + y2) >> 1, x1, (y1 + y2) >> 1);
graphics2d.drawLine(x2, (y1 + y2) >> 1, x2, (y1 + y2) >> 1);
graphics2d.drawLine((x1 + x2) >> 1, y2, (x1 + x2) >> 1, y2);
// 恢复graphics2d原本的颜色
graphics2d.setColor(c);
}
}
本来以为将工程打包成一个jar文件不会出什么问题,结果悲剧的出现了在eclipse中运行的时候可以找到资源文件,而打包之后就找不到了竟然,不得不在网上搜了一下解决的办法,确实要学东西有的时候必须得很好的利用网络资源