为什么重写Jpanel 的paint方法后 出现这种效果呀 ??点击按钮在画图就多出了按钮的图案。 代码如下:

publicclassDrawLineextendsJPanel{Pointstart;Pointend;Pointtemp;intwhich;Pointlinestar... public class DrawLine extends JPanel{
Point start;
Point end;
Point temp;
int which;
Point linestart;
Point lineend;
public DrawLine(){
this.setBackground(Color.WHITE);
this.start=new Point(0,0);
this.end =new Point(0,0);
this.linestart=new Point(0,0);
this.lineend =new Point(0,0);
this.temp=new Point(0,0);
which=0;
this.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
start.setX(e.getX());
start.setY(e.getY());
end.setX(e.getX());
end.setY(e.getY());
linestart.setX(e.getX());
linestart.setY(e.getY());
lineend.setX(e.getX());
lineend.setY(e.getY());}
public void mouseDragged(MouseEvent de) {
linestart.setP(lineend);
temp.setP(end);
end.setX(de.getX());
end.setY(de.getY());
lineend.setX(de.getX());
lineend.setY(de.getY());
repaint();}});}
public void paint(Graphics g){
if(which==3){
g.setColor(Color.WHITE);
g.fillArc(end.getX(), end.getY(), 50, 50, 0, 360);}
if(which==4){
g.setColor(Color.WHITE);
super.paint(g);
which=0;}
if(which==0){
g.setColor(Color.RED);
g.drawLine(linestart.getX(), linestart.getY(), lineend.getX(), lineend.getY());}
if(which==1){
g.setColor(Color.WHITE);
g.drawLine(start.getX(), start.getY(), temp.getX(), temp.getY());
g.setColor(Color.RED);
g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());}
if(which==2){
g.setColor(Color.WHITE);
g.drawArc(start.getX(), start.getY(), temp.getX()-start.getX(), temp.getY()-start.getY(), 0, 360);
g.setColor(Color.blue);
g.drawArc(start.getX(), start.getY(), end.getX()-start.getX(), end.getY()-start.getY(), 0, 360);}}}
public class DrawFrame {
private DrawLine line;
private JFrame frame;
private JPanel buttons;
private JButton change;
private JButton clean;
private JLabel label;
public DrawFrame() {
line = new DrawLine();
line.setFocusable(true);
frame = new JFrame();
buttons = new JPanel();
label = new JLabel("dxx");
change = new JButton("CHANGE");
clean = new JButton("CLEAR");
change.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
line.which++;
line.setFocusable(true);
if(line.which==4)line.which=0;}});
clean.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
line.which=4;
line.setFocusable(true);
line.repaint();}});
buttons.add(change);
buttons.add(clean);
frame.setLayout(new BorderLayout());
buttons.setBackground(Color.green);
// frame.add(label,BorderLayout.SOUTH);
frame.add(line, BorderLayout.CENTER);
frame.add(buttons, BorderLayout.SOUTH);}
public void show() {
frame.setSize(600, 400);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}
展开
 我来答
回家先睡觉
推荐于2017-09-19 · TA获得超过796个赞
知道小有建树答主
回答量:475
采纳率:0%
帮助的人:644万
展开全部
这是因为paint(Graphics g)是直接往屏幕上画,就好比屏幕是一副油画,不管屏幕上原来有什么东西,draw都只会往上添笔画。
每次paint的时候都一定要先清理屏幕clearRect(0, 0, getWidth(), getHeight())
如果不这样的话屏幕上就有可能留下各种的图案。而且并不是说没有没有残留图片就没有问题了,因为Panel不会记住上副图片,你可以试着把窗口最小化一下:复原后什么都没有了,因为操作系统也不会记住先前数据,只会给清屏。
解决办法是使用一个BufferedImage,把当前屏幕内容存在内存里,每次paint的时候往BufferedImage上画,再把BufferedImage画到清空的屏幕上。
要注意的BufferedImage的大小是固定的,但窗口的大小是可变的,所以需要监听窗口大小变更,重新创造一个符合屏幕大小的BufferedImage。

可用代码如下:
class DrawLine extends JPanel implements ComponentListener {
Point start;
Point end;
Point temp;
int which;
Point linestart;
Point lineend;
BufferedImage cache;
public DrawLine() {
this.setBackground(Color.WHITE);
this.start = new Point(0, 0);
this.end = new Point(0, 0);
this.linestart = new Point(0, 0);
this.lineend = new Point(0, 0);
this.temp = new Point(0, 0);
which = 0;
this.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
start.setX(e.getX());
start.setY(e.getY());
end.setX(e.getX());
end.setY(e.getY());
linestart.setX(e.getX());
linestart.setY(e.getY());
lineend.setX(e.getX());
lineend.setY(e.getY());
}
public void mouseDragged(MouseEvent de) {
linestart.setP(lineend);
temp.setP(end);
end.setX(de.getX());
end.setY(de.getY());
lineend.setX(de.getX());
lineend.setY(de.getY());
repaint();
}
});
}
public void paint(Graphics g_orig) {
if(cache!=null) {
Graphics g = cache.getGraphics(); //替换Graphics,转往缓存上画图
if (which == 3) {
g.setColor(Color.WHITE);
g.fillArc(end.getX(), end.getY(), 50, 50, 0, 360);
}
if (which == 4) {
//清空屏幕,BufferedImage默认背景为黑色,需要手动设置颜色
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
which = 0;
}
if (which == 0) {
g.setColor(Color.RED);
g.drawLine(linestart.getX(), linestart.getY(), lineend.getX(),
lineend.getY());
}
if (which == 1) {
g.setColor(Color.WHITE);
g.drawLine(start.getX(), start.getY(), temp.getX(), temp.getY());
g.setColor(Color.RED);
g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());
}
if (which == 2) {
g.setColor(Color.WHITE);
g.drawArc(start.getX(), start.getY(), temp.getX() - start.getX(),
temp.getY() - start.getY(), 0, 360);
g.setColor(Color.blue);
g.drawArc(start.getX(), start.getY(), end.getX() - start.getX(),
end.getY() - start.getY(), 0, 360);
}
//清屏,把缓存画到屏幕上
g_orig.clearRect(0, 0, getWidth(), getHeight());
g_orig.drawImage(cache, 0, 0, null);
}
}
public static void main(String[] args) {
DrawFrame d = new DrawFrame();
d.show();
}
@Override
public void componentHidden(ComponentEvent arg0) {
}
@Override
public void componentMoved(ComponentEvent arg0) {
}
@Override
public void componentResized(ComponentEvent arg0) { //这个方法会在程序启动的时候被执行一次,所以不用在别的地方初始化缓存
//创建新的缓存
BufferedImage newCache = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
if(cache!=null) { //把上个缓存的内容画到新缓存上
//这个地方如果Java版本太老无法编译的话的话改用getGraphics()
newCache.createGraphics().drawImage(cache, 0, 0, null);
}
cache = newCache; //交替缓存
}
@Override
public void componentShown(ComponentEvent arg0) {
}
}
class DrawFrame {
private DrawLine line;
private JFrame frame;
private JPanel buttons;
private JButton change;
private JButton clean;
private JLabel label;
public DrawFrame() {
line = new DrawLine();
line.setFocusable(true);
frame = new JFrame();
buttons = new JPanel();
label = new JLabel("dxx");
change = new JButton("CHANGE");
clean = new JButton("CLEAR");
change.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
line.which++;
line.setFocusable(true);
if (line.which == 4)
line.which = 0;
}
});
clean.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
line.which = 4;
line.setFocusable(true);
line.repaint();
}
});
buttons.add(change);
buttons.add(clean);
frame.setLayout(new BorderLayout());
buttons.setBackground(Color.green);
// frame.add(label,BorderLayout.SOUTH);
frame.add(line, BorderLayout.CENTER);
frame.add(buttons, BorderLayout.SOUTH);
frame.addComponentListener(line); //监听大小变更
}
public void show() {
frame.setSize(600, 400);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
追问
在Panel上为什么会多出  按钮团呢,都没有画的,加载的????
追答
(昨天回复的好像没出来,再写一次,如果发重了请见谅)
那个是Java优化用的。没有setOpaque(false)的话,你是有义务进行清屏的,关于这一点API很明确的提到了。具体Java会画什么上去和操作系统和显卡驱动有关,比如如果开启显卡加速,在我的电脑上会有稍微不同的显示(不能保证你的系统+显卡效果和我这里一样)。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式