Swing


天行健 君子以自强不息

posts - 69, comments - 215, trackbacks - 0, articles - 16
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

setXORMode的用法 转载不一定正确

Posted on 2007-08-09 11:17 zht 阅读(2305) 评论(0)  编辑  收藏 所属分类: Swing


在一个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);就画不出圆来,注释掉则能正常作图,请问这是怎么回事??

-------------------------------------
XOR 异或

------------------------------------
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){

   }


}


-------------------------------------
楼主,冷月的代码可以划出图来,并且通过点击鼠标可以进行红色与蓝色的转换。如果要实现你所要求的功能“单击鼠标画一个圆,再单击一次擦去”,可以将冷月的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;
        }

 

----------------------------------------------------

呵,冷月兄的代码是对的
一行一行对过去,终于发现,自己把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
让图形上下文的绘图模式在其原有颜色与指定的新颜色间进行转换

也没有说当不存在原有颜色时就绘不出图形来啊

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


不知道对不对,请指教。
---------------------------------------
对的,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),绘图后明明会变成绿色,而不是指定的蓝色呀。这文档写的是不是有问题了?