小郁闷中的大智慧
2009-03-31 14:00
183 查看
昨天写程序的时候碰到个很神的问题。代码如下:
这代码有个神奇的问题:偶尔能画出直线来,偶尔又画不出直线来。这就搞笑了,按道理说,程序的执行是具有确定性的,怎么会偶尔能画偶尔又不能画呢?
把代码发给同门师兄弟,一起研究,4个脑袋转了将近1个多小时还是没有解决。后来只能去Java的官网上看下drawLine的样例程序,把代码改了下:
线被顺利画出来。这是为什么呢?后来有个师弟在painComponent中设了个断点,Debug了一下,原因一下子就出来了:
原来,一般的Java程序默认是有两种线程在运行的,一种是用户线程,就是从main那里开始执行的线程,另一种是守护线程。
在错误的程序中,drawLine是在用户线程中运行的,即主线程。而对用户界面的绘制则是在守护线程中绘制的。因此则可能出现如下两种情况:
一,主线程跑得更快一些,因此drawLine先运行完,然后用户界面的绘制线程后运行的时候就把drawLine画出的线擦掉了。所以截面上啥也没。
二,主线程跑得慢一些,用户界面绘制线程跑得快一些,先完成用户界面绘制的初始化工作,然后drawLine再画线,所以直线就出来了。
修改后的程序解决了这一问题,把drawLine放到paintComponent中去,这个函数是在用户绘制界面线程中的,是事件触发式的,也就是每次界面初始化或者窗口改变的时候就会被调用。这样一定是界面初始化先进行,drawLine后进行,保证线不会被覆盖掉。
import java.awt.Graphics; import javax.swing.JFrame; public class Face extends JFrame { private static final int DEFAULT_HEIGHT = 800; private static final int DEFAULT_WIDTH = 600; public static void main(String [] args) { Face face = new Face(); face.setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); face.setVisible(true); Graphics gp = face.getGraphics(); gp.drawLine(200, 200,399, 400); gp.drawLine(500, 500,399, 400); } }
这代码有个神奇的问题:偶尔能画出直线来,偶尔又画不出直线来。这就搞笑了,按道理说,程序的执行是具有确定性的,怎么会偶尔能画偶尔又不能画呢?
把代码发给同门师兄弟,一起研究,4个脑袋转了将近1个多小时还是没有解决。后来只能去Java的官网上看下drawLine的样例程序,把代码改了下:
import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Face extends JPanel { private static final int DEFAULT_HEIGHT = 800; private static final int DEFAULT_WIDTH = 600; @Override public void paintComponent(Graphics g) { g.drawLine(200, 200,399, 400); g.drawLine(500, 500,399, 400); } public static void main(String [] args) { Face face = new Face(); JFrame jframe = new JFrame(); jframe.add(face); jframe.setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); jframe.setVisible(true); } }
线被顺利画出来。这是为什么呢?后来有个师弟在painComponent中设了个断点,Debug了一下,原因一下子就出来了:
原来,一般的Java程序默认是有两种线程在运行的,一种是用户线程,就是从main那里开始执行的线程,另一种是守护线程。
在错误的程序中,drawLine是在用户线程中运行的,即主线程。而对用户界面的绘制则是在守护线程中绘制的。因此则可能出现如下两种情况:
一,主线程跑得更快一些,因此drawLine先运行完,然后用户界面的绘制线程后运行的时候就把drawLine画出的线擦掉了。所以截面上啥也没。
二,主线程跑得慢一些,用户界面绘制线程跑得快一些,先完成用户界面绘制的初始化工作,然后drawLine再画线,所以直线就出来了。
修改后的程序解决了这一问题,把drawLine放到paintComponent中去,这个函数是在用户绘制界面线程中的,是事件触发式的,也就是每次界面初始化或者窗口改变的时候就会被调用。这样一定是界面初始化先进行,drawLine后进行,保证线不会被覆盖掉。
相关文章推荐
- 郁闷,怎么我的S5pv210 android kernel 怎么突然不能make编译了?
- 郁闷的一天
- nyoj 467 中缀式变后缀式 nyoj 257 郁闷的C小加(一)
- 周一,最郁闷的一天
- NYOJ 267 郁闷的C小加(二)
- 【NOI2004】郁闷的出纳员(splay tree WA中。。)
- 正在郁闷的人不妨进来转转
- 郁闷的早晨...
- 【Struct(结构体)杂谈之八】小个头也有大智慧---C语言Struct中的函数和函数指针
- 【BZOJ1503】【NOI2004】郁闷的出纳员
- 【NOI2004】【splay】【SBT】郁闷的出纳员
- awk中让人郁闷的system()函数
- 让我郁闷半天的一段javaScript代码
- 感冒了郁闷
- 小知识,大智慧!
- NYOJ 267(郁闷的C小加(二)) 后缀表达式求值
- 经历了一个郁闷的下午,终于在下班后半小时内成功利用IIS7.5部署网站
- 今天解决了郁闷的问题
- 小设备 大智慧——天霆交互技术让终端变得更智能
- POS机刷卡失败的郁闷事