在做一个java桌面项目,程序贴了大量的图片,其中有一些按钮的图片是半透明的。当刷新按钮上的半透明图像时,往往会出现错位重叠,也就是说,透明像素下该显示的背景没有显示,显示的是其他地方的贴图。这个问题在XP下没有显现出来,只是偶尔的时候会出现透明区域的局部刷新混乱,换到win7系统,界面刷新惨不忍睹,我试着在每一次有UI元素需要更新时,都进行全局repaint(),情况好了很多。但是在刷新点击贴有透明图片的按钮时,图片仍会出现刷新错误。
    由此导致现在的情况就是我的代码里到处充满了全局重绘的调用(用repaint(1)调用的),但刷新混乱的问题仍旧存在。
任务很急啊,哪位大哥有swing项目经验,望赐教一二,不尽感激!

解决方案 »

  1.   

    既然要透明,为什么还要用JButton?
    JButton在鼠标Enter和Exit的时候会repaint一下的,
    很可能会造成半透明像素的叠加,造成颜色变化
    而且JButton本身背景就不是透明的
    难道你们用了setOpaque(true)?
    这个和透明差的远了……要透明,就用JLabel来代替JButton
    用JLabel的MouseListener
    代替JButton的ActionListener
      

  2.   

    我们的按钮做了三种状态,正常状态,鼠标划过和鼠标按下,现在鼠标划过时刷新很正常,鼠标按下时刷新有些不正常,会出现透明像素的重叠。如果按你说的用JLabel代替JButton,也是要做三种状态,然后状态切换时也需要重绘的,JLabel重绘不会出现这种现象吗?
    另外,我是用setContentAreaFilled(false)这个方法让按钮透视出下方的背景的
      

  3.   

    我们的按钮做了三种状态,正常状态,鼠标划过和鼠标按下,现在鼠标划过时刷新很正常,鼠标按下时刷新有些不正常,会出现透明像素的重叠。如果按你说的用JLabel代替JButton,也是要做三种状态,然后状态切换时也需要重绘的,JLabel重绘不会出现这种现象吗?
    另外,我是用setContentAreaFilled(false)这个方法让按钮透视出下方的背景的
      

  4.   


    不知道你们是怎么重绘的,如果是用setIcon(...)的方法改变的状态,那应该不会有这种现象
    如果你们是重写的paint()方法或者是paintComponent()方法,你们在重写的时候,是否先调用了
    super.paint(g);或者super.paintComponent(g)?
    如果有调用,应该也不会出现这种现象
      

  5.   

    重写了paintComponent方法,一开始是有调用super.paintComponent(g),但是发现super后按钮被加上边框了,刷新混乱现象也更加严重了,又去掉了。另外,也试过用setIcon setPressedIcon等方法,也不好使,感觉就是图像层次太多,像素透明造成的刷新混乱。有没有好的解决办法?
      

  6.   


    所以说用JLabel嘛,这个本身就是一个完全透明的组件
    也绝对不会有什么边框问题的困扰
    你重写组件的paint()一类的方法,
    一定要先调用super.paint()
    否则很多Swing帮你考虑好,处理好的问题就会浮现出来了
    给楼主一个可以完全替代JButton的Label试试看
    你要做按下事件,自己加个MouseListener就可以了 class MyLabel extends JLabel {
    private int state;
    private ImageIcon icoExited = null;
    private ImageIcon icoEntered = null;
    private ImageIcon icoPressed = null;

    public MyLabel() {
    super();
    init();
    }

    public MyLabel(ImageIcon ico) {
    super(ico);
    init();
    }

    /**
     * 构造方法
     * @param icoExited 平时的图标
     * @param icoEntered 进入后的图标
     * @param icoPressed 按下后的图标
     */
    public MyLabel(ImageIcon icoExited, ImageIcon icoEntered, ImageIcon icoPressed) {
    super(icoExited);
    this.icoExited = icoExited;
    this.icoEntered = icoEntered;
    this.icoPressed = icoPressed;
    init();
    }

    private void init() {
    addMouseListener(new MouseAdapter(){
    @Override
    public void mouseEntered(MouseEvent e) {
    state = 1;
    setIcon(icoEntered);
    }

    @Override
    public void mouseExited(MouseEvent e) {
    state = 0;
    setIcon(icoExited);
    } @Override
    public void mousePressed(MouseEvent e) {
    state = 2;
    setIcon(icoPressed);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    if (state == 2) {
    state = 1;
    setIcon(icoEntered);
    }
    }
    });
    } public void setIcoExited(ImageIcon icoExited) {
    this.icoExited = icoExited;
    } public ImageIcon getIcoExited() {
    return icoExited;
    } public void setIcoEntered(ImageIcon icoEntered) {
    this.icoEntered = icoEntered;
    } public ImageIcon getIcoEntered() {
    return icoEntered;
    } public void setIcoPressed(ImageIcon icoPressed) {
    this.icoPressed = icoPressed;
    } public ImageIcon getIcoPressed() {
    return icoPressed;
    }
    }
      

  7.   

    十分感谢sunyiz,我先试试你的方法