一般情况下,JMenuItem的UI样式是不会改变的,如果有特殊要求,一般也是根据系统设置的UI来适应,如UIManager.setLookAndFeel()来改变整体的外观。最近在工作上,美工设计的UI要求是,要在菜单栏中的图标和文本中间加入垂直分割线,如下图:
右侧可以看到,Java Project 与图标之间存在浅灰色的分割线,这中一般是指定系统的look and feel自带的,一般设置成UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())就有了,但好像自从win10之后就没有了,本人最近了查了不少资料,最后发现码友们对于这方面的信息不是特别多,很难找到匹配的资料,于是花了一个晚上的时间研究了一下,最后用了一个方法可以实现以上的功能。废话不多说,直接上代码:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
//菜单栏---JMenuBar
public class JMenuBar_ps extends JFrame{
final ButtonGroup butGroup = new ButtonGroup();
private JMenuBar menuBar = new JMenuBar();
public static void main(String[] args) {
try {
UIManager.setLookAndFeel( new FlatDarkLaf());
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch( Exception ex ) {
System.err.println( "Failed to initialize LaF" );
}
JMenuBar_ps frame = new JMenuBar_ps();
frame.setVisible(true);
}
public JMenuBar_ps() {
super();
Font font = new Font(null, 0, 30);
setTitle("桌面面板和内部窗体");
setBounds(100,100,500,375);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();//创建菜单栏对象
setJMenuBar(menuBar);//给窗体添加菜单--注意:用的不是add
JMenu menu1 = new JMenu("文件(F)");//创建菜单对象
menu1.setFont(font);
menu1.setMnemonic(KeyEvent.VK_F);//添加快捷键:F(按alt+F)
menuBar.add(menu1);
ImageIcon icon1 = new ImageIcon("D:\\DesktopFile\\gd.png"){
@Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
// System.out.println("x:"+x+",y:"+y);
x=6;
super.paintIcon(c, g, x, y);
}
};
icon1.setImage(icon1.getImage().getScaledInstance(30,30,Image.SCALE_DEFAULT));
JMenuItem newMenu = new JMenuItem("新建", icon1);
newMenu.setBorder(BorderFactory.createLineBorder(Color.red));
newMenu.setIconTextGap(50);
newMenu.setFont(font);
newMenu.setUI(new BEMenuItemUI());
menu1.add(newMenu);
JMenu openMenu = new JMenu("打开");//创建菜单对象---其里面还可以包含菜单项
openMenu.setFont(font);
ImageIcon icon = new ImageIcon("D:\\DesktopFile\\gd.png"){
@Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
System.out.println("x:"+x+",y:"+y);
super.paintIcon(c, g, x, y);
}
};
icon.setImage(icon.getImage().getScaledInstance(30,30,Image.SCALE_DEFAULT));
JMenuItem saveMenu = new JMenuItem("保存",icon);
saveMenu.setFont(font);
saveMenu.setUI(new BEMenuItemUI());
menu1.add(saveMenu);
menu1.addSeparator();//添加分隔符
JMenuItem exitMenu = new JMenuItem("退出");
exitMenu.setFont(font);
menu1.add(exitMenu);
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicMenuItemUI;
public class BEMenuItemUI extends BasicMenuItemUI {
public BEMenuItemUI(){
}
@Override
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
super.paintBackground(g, menuItem, bgColor);
System.out.println(menuItem.getIcon().getIconWidth());
int x = menuItem.getIcon().getIconWidth() + 10 ;
Color color = new Color(94,94,94);
g.setColor(color);
g.drawLine(x,0,x,menuItem.getHeight());
}
}
运行起来的效果图如下:
其中的图标和字体之间很明显有一条垂直分割线,这只是一个例子,分割线与图标和字体之间的距离可以自行设置,代码里面也对图标的位置做了重写,码友们请认真查看。
至此,以上就简单的实现了在JMenuItem中的图标和文本之间插入垂直分隔符的功能。