首页 > 代码库 > 【Swing 4】方块绘制、删除与多按钮监听
【Swing 4】方块绘制、删除与多按钮监听
其实这个问题酝酿好久了。不过一直找不到删除方块的正确姿势。这不,昨晚好不容易找到一个
通过双按钮注册同个接口来实现的方法。下午又折腾了好久,才算解决这个问题。
参考: http://blog.csdn.net/meditator_hkx/article/details/50734158
先来说说之前一直没有解决的问题。当我们通过下列代码产生一只小可爱时(我吐),表面上一切
正常。然而当我们移动它是
版本一
1 package demo; // 导入包名 2 3 import javax.swing.*; 4 import java.awt.*; 5 import java.awt.event.*; 6 7 public class Test extends JPanel { 8 public static void main(String[] args) { 9 new Test(); // 创建Test对象, 实际是调用构造函数 10 } 11 12 Test() { // 构造函数在类实例化时(使用new方法)被调用 13 JFrame frame = new JFrame(); // (对象是类的实体/实例) 14 15 frame.getContentPane().add(this); // 添加JPanel及其组件 16 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口时退出javaw.exe进程 17 frame.setSize(600, 500); // 窗口大小设为宽800像素, 高600像素 18 frame.setVisible(true); 19 } 20 21 public void paintComponent(Graphics g) { // paintComponent()是程序自己会执行的方法 22 int red = (int)(Math.random() * 255); 23 int green = (int)(Math.random() * 255); 24 int blue = (int)(Math.random() * 255); 25 26 Color randColor = new Color(red, green, blue); // 红绿蓝是三原色, 由它们混合产生其它颜色 27 g.setColor(Color.pink); 28 g.fillOval(0, 0, this.getWidth(), this.getHeight()); // 如果这里变成g.fillRect(), 那么则是设置背景颜色 29 30 g.setColor(randColor); 31 g.fillOval(200, 150, 50, 50); // 设置椭圆, 参数依旧是左上角坐标和长宽 32 g.setColor(randColor); 33 g.fillOval(400, 150, 50, 50); 34 35 } 36 }
噢耶,前线发来贺电,目前一切正常。可是当我们拉动界面边框时。奇迹出现了。哦不,应该是说
Bug出现了。请看大屏幕。小心亮瞎你的铝合金眼。
出乎意料的,界面拉长后,小可爱的眼睛变色了。于是我们猜测, 当拉伸窗口时,系
统自动执行的paintComponent()函数又被执行了一次。怎么办呢?天知道。这个时候
想起了一直默默无闻的布尔型变量。没错,它就是被拿来控制if语句执行与否的
版本二
1 package demo; // 导入包名 2 3 import javax.swing.*; 4 import java.awt.*; 5 import java.awt.event.*; 6 7 public class Test extends JPanel { 8 boolean isMove = true; // 添加控制画图函数执行的布尔变量 9 public static void main(String[] args) { 10 new Test(); // 创建Test对象, 实际是调用构造函数 11 } 12 13 Test() { // 构造函数在类实例化时(使用new方法)被调用 14 JFrame frame = new JFrame("猜猜我是谁"); // (对象是类的实体/实例) 15 16 frame.getContentPane().add(this); // 添加JPanel及其组件 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口时退出javaw.exe进程 18 frame.setSize(600, 500); // 窗口大小设为宽800像素, 高600像素 19 frame.setVisible(true); 20 } 21 22 public void paintComponent(Graphics g) { // paintComponent()是电脑自己会执行的方法 23 if (isMove) { 24 int red = (int)(Math.random() * 255); 25 int green = (int)(Math.random() * 255); 26 int blue = (int)(Math.random() * 255); 27 28 Color randColor = new Color(red, green, blue); // 红绿蓝是三原色, 由它们混合产生其它颜色 29 g.setColor(Color.pink); 30 g.fillOval(0, 0, this.getWidth(), this.getHeight()); // 如果这里变成g.fillRect(), 那么则是设置背景颜色 31 32 g.setColor(randColor); 33 g.fillOval(200, 150, 50, 50); // 设置椭圆, 参数依旧是左上角坐标和长宽 34 g.setColor(randColor); 35 g.fillOval(400, 150, 50, 50); 36 isMove = false; // 执行一次画图函数后, isMove变为false 37 } 38 39 } 40 }
这个版本只是把控制paintComponent()函数执行的布尔变量设为实例变量, 然后在执行
过一次函数之后, 也就是界面打开之后。当我们再次拉动窗口时,会发现,这回连图形都没有了。
哎我的妈呀, 这又是怎么回事呢?原来呀,当我们再次拉动窗口时,画图函数依然会被执行,只
不过是isMove被设为了false,所以程序无法重画,所以界面上当然什么图形都没有啦。
改进的方法是添加一个else语句, 再重复一遍画图的代码。这样,即使是isMove
变为false, 函数仍然能重画!
版本三
1 package demo; // 导入包名 2 3 import javax.swing.*; 4 import java.util.*; 5 import java.awt.*; 6 import java.awt.event.*; 7 8 public class Test extends JPanel { 9 boolean isMove = true; // 添加控制画图函数执行的布尔变量 10 Color randColor; 11 public static void main(String[] args) { 12 new Test(); // 创建Test对象, 实际是调用构造函数 13 } 14 15 Test() { // 构造函数在类实例化时(使用new方法)被调用 16 JFrame frame = new JFrame("猜猜我是谁"); // (对象是类的实体/实例) 17 18 frame.getContentPane().add(BorderLayout.CENTER, this); 19 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口时退出javaw.exe进程 20 frame.setSize(600, 500); // 窗口大小设为宽800像素, 高600像素 21 frame.setVisible(true); 22 } 23 24 public void paintComponent(Graphics g) { // paintComponent()是电脑自己会执行的方法 25 if (isMove) { 26 int red = (int)(Math.random() * 255); 27 int green = (int)(Math.random() * 255); 28 int blue = (int)(Math.random() * 255); 29 30 randColor = new Color(red, green, blue); // 红绿蓝是三原色, 由它们混合产生其它颜色 31 32 g.setColor(Color.pink); 33 g.fillOval(0, 0, this.getWidth(), this.getHeight()); // 如果这里变成g.fillRect(), 那么则是设置背景颜色 34 g.setColor(randColor); 35 g.fillOval(200, 150, 50, 50); // 设置椭圆, 参数依旧是左上角坐标和长宽 36 g.setColor(randColor); 37 g.fillOval(400, 150, 50, 50); 38 isMove = false; // 执行一次画图函数后, isMove变为false 39 } 40 else { 41 g.setColor(Color.pink); 42 g.fillOval(0, 0, this.getWidth(), this.getHeight()); 43 g.setColor(randColor); 44 g.fillOval(200, 150, 50, 50); 45 g.setColor(randColor); 46 g.fillOval(400, 150, 50, 50); 47 } 48 49 } 50 }
由于空间和时间有限, 就不详细介绍主角了。直接贴上代码。大家自个研究下哈。
主要是利用了多个ArrayList数组分别保存了方块的坐标, 尺寸和颜色。然后在返回/
撤销,清屏时分别迭代或者删除。
至于布局,就是把三个按钮都设置在同一个面板上。最后把面板放在了构架的南区。
--------------------------------------------------------------------------------------------------------
1 package demo; 2 3 import javax.swing.*; 4 import java.awt.*; 5 import java.awt.event.*; 6 import java.util.*; 7 8 public class Test extends JPanel { 9 boolean isDraw, isBack, isClear; 10 int listLength, endIndex; 11 JFrame frame; 12 ArrayList<Color> colorList = new ArrayList<Color>(); 13 ArrayList<Integer> xList = new ArrayList<Integer>(); 14 ArrayList<Integer> yList = new ArrayList<Integer>(); 15 ArrayList<Integer> widthList = new ArrayList<Integer>(); 16 ArrayList<Integer> heightList = new ArrayList<Integer>(); 17 18 static Music m; 19 public static void main(String[] args) { 20 m = new Music(); 21 } 22 // 构造函数 23 Music() { 24 frame = new JFrame("绘制删除方块"); 25 JButton drawButton = new JButton("绘制"); 26 JButton clearButton = new JButton("清屏"); 27 JButton backButton = new JButton("回退"); 28 drawButton.addActionListener(new DrawListener()); 29 clearButton.addActionListener(new ClearListener()); 30 backButton.addActionListener(new BackListener()); 31 32 JPanel panel = new JPanel(); 33 panel.add(drawButton); 34 panel.add(backButton); 35 panel.add(clearButton); 36 37 frame.getContentPane().add(BorderLayout.SOUTH, panel); 38 frame.getContentPane().add(this); 39 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 40 frame.setSize(800, 600); 41 frame.setVisible(true); 42 } 43 44 public void paint(Graphics g) { 45 // 绘图 46 if (isDraw) { 47 int red = (int)(Math.random() * 255); 48 int green = (int)(Math.random() * 255); 49 int blue = (int)(Math.random() * 255); 50 51 int x = (int)(Math.random() * 700); 52 int y = (int)(Math.random() * 500); 53 int width = (int)(Math.random() * 101); 54 int height = (int)(Math.random() * 101); 55 56 Color randColor = new Color(red, green, blue); 57 58 xList.add(x); 59 yList.add(y); 60 widthList.add(width); 61 heightList.add(height); 62 colorList.add(randColor); 63 64 for (int i = 0; i < xList.size(); i++) { 65 g.setColor(colorList.get(i)); 66 g.fillRect(xList.get(i), yList.get(i), widthList.get(i), heightList.get(i)); 67 } 68 isDraw = false; 69 } 70 // 防止拉长窗口的时候图像消失或者改变 71 else { 72 for (int i = 0; i < xList.size(); i++) { 73 g.setColor(colorList.get(i)); 74 g.fillRect(xList.get(i), yList.get(i), widthList.get(i), heightList.get(i)); 75 } 76 } 77 // 回退 78 try { 79 if (isBack) { 80 endIndex = xList.size() - 1; 81 g.clearRect(xList.get(endIndex), yList.get(endIndex), widthList.get(endIndex), heightList.get(endIndex)); 82 colorList.remove(endIndex); 83 xList.remove(endIndex); 84 yList.remove(endIndex); 85 widthList.remove(endIndex); 86 heightList.remove(endIndex); 87 isBack = false; 88 } 89 } catch (ArrayIndexOutOfBoundsException ex) {System.out.println("你的异常已送达"); ex.printStackTrace();} 90 // 清屏 ————注意不能在迭代数组的同时删除其元素 91 if (isClear) { 92 listLength = xList.size(); 93 for (int i = 0; i < listLength; i++) { 94 g.clearRect(xList.get(0), yList.get(0), widthList.get(0), heightList.get(0)); 95 colorList.remove(0); 96 xList.remove(0); 97 yList.remove(0); 98 widthList.remove(0); 99 heightList.remove(0); 100 } 101 isClear = false; 102 } 103 104 105 } 106 // 绘图接口 107 class DrawListener implements ActionListener { 108 public void actionPerformed(ActionEvent event) { 109 isDraw = true; 110 frame.repaint(); 111 } 112 } 113 // 撤销接口 114 class BackListener implements ActionListener { 115 public void actionPerformed(ActionEvent event) { 116 isBack = true; 117 frame.repaint(); 118 } 119 } 120 // 清屏接口 121 class ClearListener implements ActionListener { 122 public void actionPerformed(ActionEvent event) { 123 isClear = true; 124 frame.repaint(); 125 } 126 } 127 128 }
【Swing 4】方块绘制、删除与多按钮监听