设置半透明的JMenuBar

源作:陈思羽.
更新:龚德伟.   2008.07.20

效果图



更新的内容:
优化了paint方法,不需要每次都创建一个BufferedImage.

修正了鼠标开时时菜单项背景不会变成半透明的问题
支持菜单普通情况下和鼠标选中时两种半透明设定


修正鼠标选中菜单时,文字变成不透明

import  java.awt.AlphaComposite;
import  java.awt.Color;
import  java.awt.Graphics;
import  java.awt.Graphics2D;
import  java.awt.Rectangle;

import  javax.swing.ButtonModel;
import  javax.swing.JComponent;
import  javax.swing.JMenu;
import  javax.swing.JMenuItem;
import  javax.swing.plaf.ComponentUI;
import  javax.swing.plaf.basic.BasicMenuItemUI;

/** */ /**
 * 一个支持半透明的菜单UI
 * 
 * 
@author  陈思羽,龚德伟
 * @history 2008-7-20
 * 
@see  <a href=" http://www.blogjava.net/chensiyu04/articles/201425.html ">
 *      在试牛刀(设置半透明的JMenuBar)</a>
 
*/

public   class  CustomMenuItemUI  extends  BasicMenuItemUI  {
    
public   static  ComponentUI createUI(JComponent c)  {
        
return   new  CustomMenuItemUI();
    }


    
/** */ /**  菜单的透明度  */
    
private   static   float  alpha  =   0.5f ;
    
private   static   float  selectionAlpha  =   0.8f ;

    
public   static   float  getAlpha()  {
        
return  alpha;
    }


    
public   static   void  setAlpha( float  _alpha)  {
        alpha 
=  _alpha;
    }


    @Override
    
public   void  installUI(JComponent c)  {
        
super .installUI(c);
        
// 设为透明,这样才会更新菜单低下的内容(这个请了解Opaque的作用)
        menuItem.setOpaque( false );
    }


    
public   void  paint(Graphics g, JComponent comp)  {
        
// 创建一个graphics的副本
        Graphics2D gx  =  (Graphics2D) g.create();
        
// alpha 就是透明度.值越小 透明度越大
        gx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        
// 将控件画到半透明 的画布上
         super .paint(gx, comp);
        
// graphics使用后要销毁,这是良好习惯
        gx.dispose();
    }


    
/**/ /*
     * 重写了背景的绘制方法,不管Opaque的属性,只按不透明方式画菜单背景
     
*/

    @Override
    
protected   void  paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)  {
        ButtonModel model 
=  menuItem.getModel();
        Color oldColor 
=  g.getColor();
        
int  menuWidth  =  menuItem.getWidth();
        
int  menuHeight  =  menuItem.getHeight();
        
if  (model.isArmed()  ||  (menuItem  instanceof  JMenu  &&  model.isSelected()))  {
            Graphics2D g2 
=  (Graphics2D) g.create(); 
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, selectionAlpha));
            g2.setColor(bgColor);
            g2.fillRect(
0 0 , menuWidth, menuHeight);
        }
  else   {
            g.setColor(menuItem.getBackground());
            g.fillRect(
0 0 , menuWidth, menuHeight);
        }

        g.setColor(oldColor);
    }


    @Override
    
protected   void  paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text)  {
        ButtonModel model 
=  menuItem.getModel();
        
// 鼠标移动菜单时文字不透明
         if  (model.isArmed()  ||  model.isSelected())  {
            Graphics2D g2 
=  (Graphics2D) g.create();
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 
1.0f ));
            
super .paintText(g2, menuItem, textRect, text);
            g2.dispose();
        }
  else   {
            
super .paintText(g, menuItem, textRect, text);
        }

    }


    
/** */ /**
     * 设置选中时是否透明
     * 
@param  b
     
*/

    
public   static   void  setSelectionAlpha( float  alpha)  {
        selectionAlpha  
=  alpha;
    }

}


import  javax.swing.JComponent;
import  javax.swing.JPanel;
import  javax.swing.JPopupMenu;
import  javax.swing.Popup;
import  javax.swing.plaf.ComponentUI;
import  javax.swing.plaf.basic.BasicPopupMenuUI;

public   class  CustomPopupMenuUI  extends  BasicPopupMenuUI 
  
public   static  ComponentUI createUI(JComponent c) 
   
return   new  CustomPopupMenuUI(); 
  }
 
  
public   void  installUI(JComponent c) 
   
super .installUI(c); 
   popupMenu.setOpaque(
false ); 
  }
 
  
public  Popup getPopup(JPopupMenu popup,  int  x,  int  y) 
   Popup pp 
=   super .getPopup(popup,x,y); 
   JPanel panel 
=  (JPanel)popup.getParent(); 
   panel.setOpaque(
false ); 
   
return  pp; 
  }
 
}
 


import  javax.swing.Box;
import  javax.swing.BoxLayout;
import  javax.swing.JFrame;
import  javax.swing.JLabel;
import  javax.swing.JMenu;
import  javax.swing.JMenuBar;
import  javax.swing.JMenuItem;
import  javax.swing.JPanel;
import  javax.swing.JScrollPane;
import  javax.swing.JSeparator;
import  javax.swing.JSlider;
import  javax.swing.JTextArea;
import  javax.swing.UIManager;
import  javax.swing.event.ChangeEvent;
import  javax.swing.event.ChangeListener;

/** */ /**
 * 半透明的菜单测试类
 * 
 * 
@author  陈思羽,龚德伟
 * @history 2008-7-20
 * 
@see  <a href=" http://www.blogjava.net/chensiyu04/articles/201425.html "> * 在试牛刀(设置半透明的JMenuBar)<
 *      /a>
 
*/

public   class  MenuTest  {
    
public   static   void  main(String[] args)  throws  Exception  {
        
// 这样把JFrame上所有JMenuBar的外观全设置为上面两个类已经写好的,这两句必须放在JMenuBar的前面 
        
// 具体放在哪个方法里随便你 
        UIManager.put( " PopupMenuUI " " CustomPopupMenuUI " ); // 自己看API, 
        UIManager.put( " MenuItemUI " " CustomMenuItemUI " );
        JFrame frame 
=   new  JFrame();
        JMenuBar mb 
=   new  JMenuBar();
        frame.setJMenuBar(mb);
        JMenu menu 
=   new  JMenu( " File " );
        mb.add(menu);
        menu.add(
new  JMenuItem( " Open " ));
        menu.add(
new  JMenuItem( " Save " ));
        menu.add(
new  JMenuItem( " Close " ));
        menu.add(
new  JMenuItem( " Exit " ));
        menu 
=   new  JMenu( " Edit " );
        mb.add(menu);

// 如果你把UIManager.put("PopupMenuUI","CustomPopupMenuUI"); 
//    UIManager.put("MenuItemUI","CustomMenuItemUI");   
//  这两句在上面删掉 把他们放在这里 那么只有从这往下的JMenuITem可以为透明 以上的则无效果   
        menu.add( new  JMenuItem( " Cut " ));
        menu.add(
new  JMenuItem( " Copy " ));
        menu.add(
new  JMenuItem( " Paste " ));
        menu.add(
new  JMenuItem( " Paste Special.. " ));
        JPanel contentPane 
=   new  JPanel();
        BoxLayout layout 
=   new  BoxLayout(contentPane, BoxLayout.Y_AXIS);
        contentPane.setLayout(layout);
        contentPane.add(Box.createVerticalGlue());
        JSlider alphaSlider 
=   new  JSlider(JSlider.HORIZONTAL);
        contentPane.add(
new  JLabel( " 菜单背景不透明度: " ));
        contentPane.add(alphaSlider);
        alphaSlider.addChangeListener(
new  ChangeListener()  {
            
public   void  stateChanged(ChangeEvent e)  {
                JSlider slider 
=  (JSlider) e.getSource();
                
float  alpha  =  ( 1.0f   *  slider.getValue()  /   100 );
                CustomMenuItemUI.setAlpha(alpha);
                slider.setToolTipText(
" 不透明: "   +  slider.getValue());
            }

        }
);
        contentPane.add(
new  JSeparator(JSeparator.HORIZONTAL));
        JSlider selectionAlphaSlider 
=   new  JSlider(JSlider.HORIZONTAL);
        contentPane.add(
new  JLabel( " 菜单选中时背景不透明度: " ));
        contentPane.add(selectionAlphaSlider);
        selectionAlphaSlider.addChangeListener(
new  ChangeListener()  {
            
public   void  stateChanged(ChangeEvent e)  {
                JSlider slider 
=  (JSlider) e.getSource();
                
float  alpha  =  ( 1.0f   *  slider.getValue()  /   100 );
                CustomMenuItemUI.setSelectionAlpha(alpha);
                slider.setToolTipText(
" 不透明: "   +  slider.getValue());
            }

        }
);
        contentPane.add(
new  JSeparator(JSeparator.HORIZONTAL));
        contentPane.add(Box.createVerticalGlue());
        StringBuilder sbMsg 
=   new  StringBuilder();
        sbMsg.append(
" CustomMenuItemUI\r\n " );
        sbMsg.append(
" 一个支持半透明的菜单UI \r\n " );
        sbMsg.append(
" \r\n " );
        sbMsg.append(
" See Also:\r\n " );
        sbMsg.append(
" 在试牛刀(设置半透明的JMenuBar)\r\n " );
        sbMsg.append(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值