您的位置:首页 > 其它

小郁闷中的大智慧

2009-03-31 14:00 183 查看
昨天写程序的时候碰到个很神的问题。代码如下:

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后进行,保证线不会被覆盖掉。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: