Java getGraphics()的用法是否涉及线程同步啊?

fearlessMore 2012-07-22 09:44:27
我在使用Java Awt 的 Graphics类时,使用getGraphics()得到相关Component的Graphics context,然后在上面进行绘图,而不是采用重写paint()方法。但是遇到一个问题,必须在组件被实现后,调用Thread.sleep()方法才能使得之后的绘图线条显示出来。并且sleep()时间还不能太短。。比如我的程序Thread.sleep(100)可以,Thread.sleep(20)就不行了。完整代码如下:

package com.han;

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Graphics_1 extends JFrame {

/**
*
*/
private static final long serialVersionUID = -5861565474703590207L;

JButton button = new JButton("JButton");
Container container;
public Graphics_1() {
// TODO Auto-generated constructor stub
container = getContentPane();
container.setLayout(new FlowLayout());
container.add(button);
}

void paintJButton() {


/*
* Creates a graphics context for Container (you can also try it for
* JFrame)
*/
Graphics g = container.getGraphics();
g.setColor(Color.BLACK);

/*
* Draws a line, using the current color, between the points (x1, y1)
* and (x2, y2) in this graphics context's coordinate system.
*/
g.drawLine(5, 5, 15, 5);
System.out.println("here");

}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final Graphics_1 frame = new Graphics_1();
frame.setTitle("Painting figures on the JButton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 300, 200);
frame.setVisible(true);
try {
Thread.sleep(100); // Thread.sleep(20); does not work !
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

frame.paintJButton();
}

}



希望哪位大侠予以解释。。。。
...全文
236 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
MiceRice 2012-07-23
  • 打赏
  • 举报
回复
Canvas顾名思义就是画布。

从语义上来说,应该只用来进行绘画,而不会放置什么控件在里面。

所以你理解是正确的。
fearlessMore 2012-07-23
  • 打赏
  • 举报
回复
不好意思,另外一个疑问:
我刚刚查了API文档,那个Container类的paint()被重写的话,是必须使用super.paint();才能正确渲染其Children componnets。但是对于Canvas类的paint(), API上写道:need not to use super.paint();,这是否意味着Canvas并不允许在上面存放component组件?我查了下API,Canvas类好像也没有像Container类的那种添加组件的add()方法。。。

希望能给于答复,谢谢

[Quote=引用 4 楼 的回复:]
理解的基本到位。

“我画上去的东西不消失,但是JButton给消失了”
public void paint(Graphics g) {
super.paint(g); // 增加这句话很重要,否则resize时就父类就没机会执行重绘了
g.setColor(Color.BLACK);
g.drawLine(5, 5, 15, 5);
}


当然还有一个负责特定控……
[/Quote]
fearlessMore 2012-07-22
  • 打赏
  • 举报
回复
其实第一印象令我深刻的是:你的ID图,。。-- 她也是我曾经最喜欢的star -_-

[Quote=引用 5 楼 的回复:]

突然发现JAVA有点复杂了
感觉不爽
[/Quote]
fearlessMore 2012-07-22
  • 打赏
  • 举报
回复
谢谢你,你的讲解完全解决了我的疑惑。结贴了~~分全给你

[Quote=引用 4 楼 的回复:]

理解的基本到位。

“我画上去的东西不消失,但是JButton给消失了”
public void paint(Graphics g) {
super.paint(g); // 增加这句话很重要,否则resize时就父类就没机会执行重绘了
g.setColor(Color.BLACK);
g.drawLine(5, 5, 15, 5);
}


当然还有一个负责特定……
[/Quote]
zhangyong369 2012-07-22
  • 打赏
  • 举报
回复
突然发现JAVA有点复杂了
感觉不爽
MiceRice 2012-07-22
  • 打赏
  • 举报
回复
理解的基本到位。

“我画上去的东西不消失,但是JButton给消失了”
public void paint(Graphics g) {
super.paint(g); // 增加这句话很重要,否则resize时就父类就没机会执行重绘了
g.setColor(Color.BLACK);
g.drawLine(5, 5, 15, 5);
}


当然还有一个负责特定控件重绘的函数是:paintComponents(Graphics g)
因为你没有把这个函数也给重写了,所以当“我鼠标移动到JButton所在位置时”,这个函数发挥效用了。
fearlessMore 2012-07-22
  • 打赏
  • 举报
回复
哦 忘记了附上改变之后的代码:

package com.han;

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Graphics_1 extends JFrame {

/**
*
*/
private static final long serialVersionUID = -5861565474703590207L;

JButton button = new JButton("JButton");
@SuppressWarnings("serial")
Container container = new Container() {
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.drawLine(5, 5, 15, 5);
}
};
public Graphics_1() {
// TODO Auto-generated constructor stub
this.add(container);
container.setLayout(new FlowLayout());
container.add(button);

}


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final Graphics_1 frame = new Graphics_1();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 300, 200);
frame.setVisible(true);

}

}



[Quote=引用 2 楼 的回复:]

你的意思是每次调整界面尺寸的时候,系统就自动调用了对componentTree的paint(),所以才覆盖掉了用container.getGraphics()画上去的东西。

那么我按你说的去改变了下,直接在Container上paint()。这次就不需使用Thread.sleep(100)来等待GUI线程的界面的初始化输出。但是当我调整界面尺寸的时候,我画上去的东西不消失,但是JButto……
[/Quote]
fearlessMore 2012-07-22
  • 打赏
  • 举报
回复
你的意思是每次调整界面尺寸的时候,系统就自动调用了对componentTree的paint(),所以才覆盖掉了用container.getGraphics()画上去的东西。

那么我按你说的去改变了下,直接在Container上paint()。这次就不需使用Thread.sleep(100)来等待GUI线程的界面的初始化输出。但是当我调整界面尺寸的时候,我画上去的东西不消失,但是JButton给消失了,相反当我鼠标移动到JButton所在位置时,JButton又显现并且可以响应鼠标事件。

这又是为什么呢,怎么解决,是要使用awt.Canvas来代替awt.Container,或者是要使用JPanel中的paint()吗?

谢谢!

[Quote=引用 1 楼 的回复:]

这是因为你没有用重写 paint() 函数的原因所致。

frame.setVisible(true); 之后,GUI线程会开始对界面进行输出,如果你立即运行frame.paintJButton();

那么结果就是你画上去的内容 paint() 直接给覆盖掉了。



其实你就算画上去了,你稍微调整下界面的尺寸,也会发生覆盖的。



所以一般建议是不要直接画在cont……
[/Quote]
MiceRice 2012-07-22
  • 打赏
  • 举报
回复
这是因为你没有用重写 paint() 函数的原因所致。

frame.setVisible(true); 之后,GUI线程会开始对界面进行输出,如果你立即运行frame.paintJButton();

那么结果就是你画上去的内容 paint() 直接给覆盖掉了。



其实你就算画上去了,你稍微调整下界面的尺寸,也会发生覆盖的。



所以一般建议是不要直接画在container.getGraphics();上面,而是画在一个BufferedImage上,然后重写paint()函数,内容就是把BufferedImage输出到 Graphics 上。

62,614

社区成员

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

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