日期:2014-05-20  浏览次数:20784 次

多线程调用REpaint(),遇到一个问题,谢谢大家
今天按照老师的要求就是做一个类似于电子钟一样的程序,但是在线程调用repaint()方法重绘面板时发现,调用的repaint()方法无效,百度了很久也没有办法解决,就希望各位大神能看看有什么方法可以解决。

下面是代码
import java.awt.Font;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.*;


public class NewClock {

public static void main(String[] args) {

ClockFrame frame = new ClockFrame();//实例化窗体

//启动线程
Times ti = new Times();
Thread t = new Thread(ti);
t.start();


}

}
class ClockFrame extends JFrame{

static ClockPanel panel = new ClockPanel();//实例化面板

public ClockFrame(){

this.add(panel);//添加面板

this.setTitle("简单时钟");
this.setSize(400, 200);



this.setVisible(true);//设置可见
this.setLocationRelativeTo(null);//设置位置居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//响应关闭
}

}

class ClockPanel extends JPanel{

static String time = "yes";//初始值为YES
//static ClockPanel 

public ClockPanel(){

this.setSize(300, 150);//设置大小  这个可以忽略

}

public void paint(Graphics g){

//super.paint(g); //百度说这句可以刷新整个面板,但是加上后仍然没有效果

//设置字体和绘制字体
g.setFont(new Font("宋体",0,20));
g.drawString(time, 50, 100);
//System.out.println(time);
}

public void settimes(int h,int m,int s){//设置面板类中的时间

time=h+":"+m+":"+s;
this.repaint();//重绘,问题就在这里,重绘后面板不会刷新
//System.out.println("ocao");
}

}
class Times implements Runnable {

static int seconds;//秒
static int minute;//分
static int hour;//时
static boolean flag = true;//标记,用于停止线程,暂时无用
ClockPanel panel = new ClockPanel();

public Times(){
settimes();//获取本地时间后设置时分秒
}

@Override
public void run() {//线程运行
// TODO Auto-generated method stub

while(flag){
/*********************************************************/

try {
Thread.sleep(1000);//休眠1S
timesadd();//seconds +1  也就是增加时间

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
panel.settimes(hour,minute,seconds);

/*********************************************************/
}

}

public int gethour(){//获取时,暂时无用
return hour;
}

public int getminute(){//获取分,暂时无用
return minute;
}

public int getseconds(){//获取秒,暂时无用
return seconds;
}


public void setflag(boolean f){//设置标记

this.flag = f;

}

private static void timesadd(){//记时

seconds++;
if(seconds == 60){
seconds = 0;
minute++;
}
if(minute == 60){
minute = 0;
hour++;
settimes();//每小时重新校正一次时间
}
if(hour == 12){
hour = 0;
}


}

private static void settimes(){//设置时间

String date =redate();

seconds = Integer.parseInt(date.substring(12, 14));
minute = Integer.parseInt(date.substring(10, 12));
hour = Integer.parseInt(date.substring(8, 10));

}

private static String redate() {// 返回日期
Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");// 可以方便地修改日期格式
String strDate = dateFormat.format(now);
return strDate;

}
}

------解决方案--------------------
感觉是没有把 多线程 与  JPanel(容器)之间联系在一起。
本意:我们想时间过去一秒钟后,让窗体重新进行绘制。但 79行(ClockPanel panel = new ClockPanel();),初始化的时钟 与 主程序时钟没有关系,故修改如下2处:
1. 修改79-83行为如下代码
    
ClockPanel panel ;  //只定义一个变量即可
     
    public Times(ClockPanel panel){
        this.panel = panel;  //从外界出入一个Clock面板,这样下面设置时间 与 更新时间,就有了实施的实体
        settimes();//获取本地时间后设置时分秒
    }

2. 合并NewClock 与 ClockFrame 类,代码如下
public class NewClock extends JFrame{

static ClockPanel panel = new ClockPanel();//实例化面板

public NewClock(){

this.add(panel);//添加面板

this.setTitle("简单时钟");
this.setSize(400, 200);

this.setVisible(true);//设置可见
this.setLocationRelativeTo(null);//设置位置居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//响应关闭
}

public static void main(String[] args) {