源作:陳思羽.
更新:龔德偉. 2008.07.20
效果圖
更新的內(nèi)容:
優(yōu)化了paint方法,不需要每次都創(chuàng)建一個(gè)BufferedImage.
修正了鼠標(biāo)開時(shí)時(shí)菜單項(xiàng)背景不會(huì)變成半透明的問題
支持菜單普通情況下和鼠標(biāo)選中時(shí)兩種半透明設(shè)定
修正鼠標(biāo)選中菜單時(shí),文字變成不透明
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;


/** *//**
* 一個(gè)支持半透明的菜單UI
*
* @author 陳思羽,龔德偉
* @history 2008-7-20
* @see <a href="http://m.tkk7.com/chensiyu04/articles/201425.html">
* 在試牛刀(設(shè)置半透明的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);
//設(shè)為透明,這樣才會(huì)更新菜單低下的內(nèi)容(這個(gè)請(qǐng)了解Opaque的作用)
menuItem.setOpaque(false);
}


public void paint(Graphics g, JComponent comp)
{
//創(chuàng)建一個(gè)graphics的副本
Graphics2D gx = (Graphics2D) g.create();
//alpha 就是透明度.值越小 透明度越大
gx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
//將控件畫到半透明 的畫布上
super.paint(gx, comp);
//graphics使用后要銷毀,這是良好習(xí)慣
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();
//鼠標(biāo)移動(dòng)菜單時(shí)文字不透明

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);
}
}


/** *//**
* 設(shè)置選中時(shí)是否透明
* @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;


/** *//**
* 半透明的菜單測(cè)試類
*
* @author 陳思羽,龔德偉
* @history 2008-7-20
* @see <a href="http://m.tkk7.com/chensiyu04/articles/201425.html"> * 在試牛刀(設(shè)置半透明的JMenuBar)<
* /a>
*/

public class MenuTest
{

public static void main(String[] args) throws Exception
{
//這樣把JFrame上所有JMenuBar的外觀全設(shè)置為上面兩個(gè)類已經(jīng)寫好的,這兩句必須放在JMenuBar的前面
//具體放在哪個(gè)方法里隨便你
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("菜單選中時(shí)背景不透明度:"));
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("一個(gè)支持半透明的菜單UI \r\n");
sbMsg.append("\r\n");
sbMsg.append("See Also:\r\n");
sbMsg.append("在試牛刀(設(shè)置半透明的JMenuBar)\r\n");
sbMsg.append("Author:\r\n");
sbMsg.append("陳思羽,龔德偉\r\n");
sbMsg.append("@history\r\n");
sbMsg.append("2008-7-20");
contentPane.add(new JScrollPane(new JTextArea(sbMsg.toString())));
frame.setContentPane(contentPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
