多线程调用REpaint(),遇到一个问题,谢谢大家

悲催的孩子_ 2014-04-06 05:14:43
今天按照老师的要求就是做一个类似于电子钟一样的程序,但是在线程调用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;

}
}
...全文
355 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
悲催的孩子_ 2014-04-07
  • 打赏
  • 举报
回复
引用 6 楼 dingyouzhuan0221 的回复:
感觉是没有把 多线程 与 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) {
		
		NewClock frame = new NewClock();//实例化窗体		
		//启动线程
		Times ti = new Times(panel);
		Thread t = new Thread(ti);
		t.start();
	}
}
整个代码如下
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();
//	}
//}

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) {
		
		NewClock frame = new NewClock();//实例化窗体		
		//启动线程
		Times ti = new Times(panel);
		Thread t = new Thread(ti);
		t.start();
	}
}

class ClockPanel extends JPanel{
	
	static String time = "";//初始值为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();//重绘,问题就在这里,重绘后面板不会刷新
		//this.update(getGraphics());
		//System.out.println("ocao");
		repaint();
	}
	
}
class Times implements Runnable {

	static int seconds;//秒
	static int minute;//分
	static int hour;//时
	static boolean flag = true;//标记,用于停止线程,暂时无用
	//ClockPanel panel = new ClockPanel();
	ClockPanel panel;
	
	public Times(ClockPanel panel){
		this.panel = panel;
		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;

	}
}
好的 知道了 原来是又实例化了一个面板,谢谢老师
悲催的孩子_ 2014-04-07
  • 打赏
  • 举报
回复
引用 5 楼 aaaaaqiwang 的回复:
很明显一个问题,repaint方法要放在循环体内,其他代码没细看
倒不是这个问题
行者-丁又专 2014-04-07
  • 打赏
  • 举报
回复
感觉是没有把 多线程 与 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) {
		
		NewClock frame = new NewClock();//实例化窗体		
		//启动线程
		Times ti = new Times(panel);
		Thread t = new Thread(ti);
		t.start();
	}
}
整个代码如下
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();
//	}
//}

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) {
		
		NewClock frame = new NewClock();//实例化窗体		
		//启动线程
		Times ti = new Times(panel);
		Thread t = new Thread(ti);
		t.start();
	}
}

class ClockPanel extends JPanel{
	
	static String time = "";//初始值为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();//重绘,问题就在这里,重绘后面板不会刷新
		//this.update(getGraphics());
		//System.out.println("ocao");
		repaint();
	}
	
}
class Times implements Runnable {

	static int seconds;//秒
	static int minute;//分
	static int hour;//时
	static boolean flag = true;//标记,用于停止线程,暂时无用
	//ClockPanel panel = new ClockPanel();
	ClockPanel panel;
	
	public Times(ClockPanel panel){
		this.panel = panel;
		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;

	}
}
Kristen_Ge 2014-04-06
  • 打赏
  • 举报
回复
很明显一个问题,repaint方法要放在循环体内,其他代码没细看
lhcapricorn 2014-04-06
  • 打赏
  • 举报
回复
看了看,飘过
VIP-稻草人 2014-04-06
  • 打赏
  • 举报
回复
我看了,表示不发表话题啊!看视频去,敲吧,敲吧!
悲催的孩子_ 2014-04-06
  • 打赏
  • 举报
回复
就真的没有人看看嘛
悲催的孩子_ 2014-04-06
  • 打赏
  • 举报
回复
具体就是 68行的repaint()没有生效

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧