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

悲催的孩子_ 2014-04-06 05:14:43
今天按照老师的要求就是做一个类似于电子钟一样的程序,但是在线程调用repaint()方法重绘面板时发现,调用的repaint()方法无效,百度了很久也没有办法解决,就希望各位大神能看看有什么方法可以解决。

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

  5. import javax.swing.*;


  6. public class NewClock {

  7. public static void main(String[] args) {

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

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


  13. }

  14. }
  15. class ClockFrame extends JFrame{

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

  17. public ClockFrame(){

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

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



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

  25. }

  26. class ClockPanel extends JPanel{

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

  29. public ClockPanel(){

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

  31. }

  32. public void paint(Graphics g){

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

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

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

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

  44. }
  45. class Times implements Runnable {

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

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

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

  57. while(flag){
  58. /*********************************************************/

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

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

  67. /*********************************************************/
  68. }

  69. }

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

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

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


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

  80. this.flag = f;

  81. }

  82. private static void timesadd(){//记时

  83. seconds++;
  84. if(seconds == 60){
  85. seconds = 0;
  86. minute++;
  87. }
  88. if(minute == 60){
  89. minute = 0;
  90. hour++;
  91. settimes();//每小时重新校正一次时间
  92. }
  93. if(hour == 12){
  94. hour = 0;
  95. }


  96. }

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

  98. String date =redate();

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

  102. }

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

  108. }
  109. }
...全文
给本帖投票
463 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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,635

社区成员

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

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

手机看
关注公众号

关注公众号

客服 返回
顶部