Java 简单画板(二)
程序员文章站
2022-03-13 22:46:44
...
仿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中运行的时候可以找到资源文件,而打包之后就找不到了竟然,不得不在网上搜了一下解决的办法,确实要学东西有的时候必须得很好的利用网络资源
上一篇: Java 简单画板(二)