在一个JPanel上的画图函数:
   void draw(Graphics g,int x, int y, Color color){
        g.setColor(color);
        //g.setXORMode(color);   //加上就画不出圆
        g.fillOval(x,y,20,20);
   }
单击事件:
  public void mouseClicked(MouseEvent event){
       g  = getGraphics();  
       draw(g,event.getX(),event.getY(),Color.black);
  }
我想单击鼠标画一个圆,再单击一次擦去。可是在draw函数中若加上g.setXORMode(color);就画不出圆来,注释掉则能正常作图,请问这是怎么回事??

解决方案 »

  1.   

    setXORMode()方法设置绘图模式可以使一个新的对象一异或操作的方式加入窗口中
    他指定了绘制对象时户窗口进行异或操作的颜色。import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;public class DrawsDemo{ public static void main(String[] args){

    ShapesFrame sf=new ShapesFrame();

    }
    }
    class ShapesFrame extends JFrame{

    public ShapesFrame(){
    setTitle("请教setXORMode的用法");
    setSize(300,200);
    XORPanel xp=new XORPanel();
    Container container=getContentPane();
    container.add(xp);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    }}
    class XORPanel extends JPanel{
    static boolean flag=false;
    public XORPanel(){
    addMouseListener( new MouseAdapter(){
    public void mouseClicked(MouseEvent mevent){

    repaint();
    }
    }
    );

    }


    public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.red);
    if(!flag){
    g.setXORMode(Color.blue);   //加上就画不出圆
    }
    flag=!flag;
            g.fillOval(10,10,20,20); //draw(g,10,10,Color.blue); }   void draw(Graphics g,int x, int y, Color color){   }
    }
      

  2.   

    多谢冷月兄答得这么详细
    可是这段代码在运行时画不出图。跟踪了一下发现单击鼠标的时候并没有执行paintComponent事件,请问这是为什么?代码里addMouseListener明明已经加进去了,程序编译也没有出错
      

  3.   

    楼主,冷月的代码可以划出图来,并且通过点击鼠标可以进行红色与蓝色的转换。如果要实现你所要求的功能“单击鼠标画一个圆,再单击一次擦去”,可以将冷月的public void paintComponent(Graphics g)方法中的代码改为以下形式:
    public void paintComponent(Graphics g)
            {
              super.paintComponent(g);
              g.setColor(Color.red);
              g.fillOval(10, 10, 200, 200);//*
              if (!flag) 
              {
                g.clearRect(10, 10, 200, 200);//*
              }
              flag = !flag;
            }
      

  4.   

    可现在的问题是程序不执行paintComponent()。
    我在mouseClicked的第一行加了一句:System.out.println("Clicked");
    在paintComponent()的第一行加了一句:System.out.println("paintComponent");
    结果输出"Clicked",说明已触发了单击事件
    但是并没有得到“paintComponent”的输出,说明未执行paintComponent()。不知道为什么
      

  5.   

    还有,setXORMode(Color.red),然后执行fillOval(10,10,20,20),应该能在执行奇数次时画出红色的圆,偶数次时擦去吧。XOR不就是做这个用的吗?我记得以前用Delphi做的时候就是这么干的。可是现在一加上setXORMode干脆什么都画不出来了,难道java里不一样?还有什么代码要写?
      

  6.   

    我刚才在单位里的机器上试了一下,可以的.你不要改我的代码./*
     * Created on Nov 16, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package com.didoleo.util;import java.awt.Color;
    import java.awt.Container;
    import java.awt.Graphics;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;import javax.swing.JFrame;
    import javax.swing.JPanel;/**
     * @author Administrator
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class DrawsDemo{ public static void main(String[] args){

    ShapesFrame sf=new ShapesFrame();

    }
    }
    class ShapesFrame extends JFrame{

    public ShapesFrame(){
    setTitle("请教setXORMode的用法");
    setSize(300,200);
    XORPanel xp=new XORPanel();
    Container container=getContentPane();
    container.add(xp);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    }}
    class XORPanel extends JPanel{
    static boolean flag=false;
    public XORPanel(){
    addMouseListener( new MouseAdapter(){
    public void mouseClicked(MouseEvent mevent){

    repaint();
    }
    }
    );

    }


    public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.blue);
    if(!flag){
    g.setXORMode(Color.blue);   //加上就画不出圆
    }
    flag=!flag;
            g.fillOval(10,10,20,20); //draw(g,10,10,Color.blue); }   void draw(Graphics g,int x, int y, Color color){   }
    }
      

  7.   

    顺便说一下,paintComponent方法不要直接去调用他,用repaint()
      

  8.   

    呵,冷月兄的代码是对的
    一行一行对过去,终于发现,自己把paintComponent的p敲成P了。难怪死活不执行,当即吐血数升最后有一点不明白:我理解的setXORMode(color)应该是把指定的color与要绘图的区域内的颜色进行异或操作。即:
    如区域内无颜色,应能绘出指定颜色的图形。
    如区域内已存在指定颜色,异或操作后应擦去指定颜色的图形
    如区域内内已存在其它颜色,应绘制出该颜色和指定颜色进行异或操作后的新颜色的图形。可程序运行结果是:如果区域内无颜色,无法绘制出图形.是不是我理解的有问题?
    文档对setXORMode的说明是:Sets the paint mode of this graphics context to alternate between this graphics context's current color and the new specified color
    让图形上下文的绘图模式在其原有颜色与指定的新颜色间进行转换也没有说当不存在原有颜色时就绘不出图形来啊
      

  9.   

    CoffeeMachine(TwoBeds)兄说的对的,我对java图形也没怎么研究过,但是对setXormode的理解
    和你稍微有点不同,我也认为setXormode可以搽去图形,但是
    g.setColor(Color.blue);
    g.setXORMode(Color.blue);   
    两句话每次都执行的话,蓝色和蓝色xor就没了,什么也显示不出来了,其实 xor是发生作用的,
    但要有个开关变量,第一次让他不xor,第二次让他xor,把图形就xor没了,
    不信,你把setXormode(这里的颜色换成别的)你可以看到xor后的颜色既不是蓝也不是...
    是两种颜色的叠加。
    不知道对不对,请指教。
      

  10.   

    对的,xor能擦去相同颜色的图形,能对不同颜色进行叠加。但似乎是绘图区已绘制某种颜色的情况下用xor才能画出图形来。
    记得以前学delphi的时候用异或模式是能在未着色的区域上绘图的。执行一次绘出指定颜色图形,再执行一次擦去,方便得很,java好象不太一样。是不是对未着色的区域进行异或操作时使用的“空”颜色是类似null的概念,任何值与之运算结果都是“空”,所以绘不出图形?java文档上关于setXORMode的说明我也看不是很明白:When drawing operations are performed, pixels which are the current color are changed to the specified color, and vice versa
    执行绘图操作时当前颜色的象素将变为指定颜色,反之亦然。但是若当前颜色为Color.red,setXORMode(Color.blue),绘图后明明会变成绿色,而不是指定的蓝色呀。这文档写的是不是有问题了?