gpt4 book ai didi

java - 使用JMenuBar、JMenu和JMenuItem自行设计菜单栏时呈现奇怪的效果

转载 作者:行者123 更新时间:2023-12-01 09:40:46 24 4
gpt4 key购买 nike

我想设计一个半透明的菜单栏,包括菜单和菜单项,所以我使用了JMenuBarJMenuJMenuItem来完成代码。这意味着我只喜欢遵循我的代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
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.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicMenuItemUI;
import javax.swing.plaf.basic.BasicMenuUI;

public class Library extends JFrame {

private int FRAME_WIDTH = SizeCtrl.mainFrameSizeCtrl().width; // Main frame's width
private int FRAME_HEIGHT = SizeCtrl.mainFrameSizeCtrl().height; // Main frame's height

private String title = "Library Management System?"; // System name
private String copyright = "<html><b>Designer: RyougiChan &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
+ "Email : ryougi.chan.fire@gmail.com<br/></b></html>"; // copyright in bottom
private String libImgURL = "res\\Library.jpg";
private String mLogoURL = "res\\ryougi_logo.png"; // designer logo
private String sLogoURL = "res\\LMS.png"; // Systen logo
private String[] manage = new String[] {"Books M", "Personel M", "Other M", "System M"}; // text of menu
private String[] bookMng = new String[] {"borrow", " remand ", "buy", "donate ", "search"}; // text of menu items
private String[] userMng = new String[] {"operator", "student", "teacher"};
private String[] otherMng = new String[] {"authority", "fine"};
private String[] sysMng = new String[] {"Message", "Update"};

private Toolkit toolkit = Toolkit.getDefaultToolkit();; // Get system tookit
private final int SCREEN_WIDTH = toolkit.getScreenSize().width; // Get current screen width
private final int SCREEN_HEIGHT = toolkit.getScreenSize().height; // Get current screen height

private Color bgColor = new Color(0, 0, 0, 0.25f); // Background color most used
private Color fgColor = Color.WHITE; // Foreground color most used
private JPanel rootPanel; // Create a root panel
private JMenuBar jMenuBar; // A menu bar
private JMenu menu; // menus on menu bar
private JMenuItem menuItem; // items on menu
private JPanel bodyPanel; // A panel below the menu bar
private JPanel mlogo, slogo; // two logo container
private JPanel footPanel; // The last panel on root panel
private JLabel footLabel; // label on foot panel

private MenuMouseAdapter menuAdapter; // mouse event listener
private MenuItemMouseAdapter menuItemAdapter; // mouse event listener

public void initModule() {
/*
* RyougiModule is a class to include all of my self-define module
* RyougiModule.ImagePanel() is a panel to show a panel with background image
* RyougiModule.NoticeLabel() is a label which can set properties of font, bounds and etc.
*/
rootPanel = RyougiModule.ImagePanel(this, libImgURL, FRAME_WIDTH, FRAME_HEIGHT-30, 0, 0);
jMenuBar = new MainMenuBar();
bodyPanel = new JPanel();
footPanel = new JPanel();
footLabel = RyougiModule.NoticeLabel(footPanel, copyright, 16, null, fgColor);
}

public Library() {
super();
frameSizeCtrl();
setTitle(title);
setLocation(LocationCtrl.mainFrameLocationCtrl());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);

initModule();
rootPanel.setLayout(null);
rootPanel.setBackground(Color.PINK);
addBodyPanel();
addBodyDetail();
addFootPanel();
add(rootPanel);
setJMenuBar(addMenuBar());

setResizable(false);
}

/**
* Add a menu bar, and add menu into it.
* @return Return a menu bar with specific style.
*/
public JMenuBar addMenuBar() {
jMenuBar.setBackground(bgColor);
jMenuBar.setBorder(null);
jMenuBar.setPreferredSize(new Dimension(getWidth(), 40));

for (int i = 0; i < manage.length; i++) {
String s = manage[i];
addMenu(s);
switch (i) {
case 0:
addMenuItem(bookMng);
break;
case 1:
addMenuItem(userMng);
break;
case 2:
addMenuItem(otherMng);
break;
case 3:
addMenuItem(sysMng);
break;
default:
break;
}
}

return jMenuBar;
}
/**
* Add menu into menu bar
* @param s Text to display on menu
*/
public void addMenu (String s) {
menu = new JMenu(s);
menuAdapter = new MenuMouseAdapter(menu, bgColor, fgColor);
menu.setBorder(null);
menu.setBackground(bgColor);
menu.setForeground(fgColor);
menu.addMouseListener(menuAdapter);
jMenuBar.add(menu);
}
/**
* Add menu item to menu to display a drop down menu
* @param s Text to show on menu items
*/
public void addMenuItem (String[] s) {
for (int j = 0; j < s.length; j++) {
menuItem = new JMenuItem(s[j]);
menuItemAdapter = new MenuItemMouseAdapter(menuItem, bgColor, fgColor);
menuItem.setBackground(bgColor);
menuItem.setForeground(Color.BLUE);
menuItem.setBorder(null);
menuItem.setPreferredSize(new Dimension(60, 40));
menu.add(menuItem);
}
}
/**
* Add panel below the menu bar
* Including twoLogo
*/
public void addBodyPanel() {
bodyPanel.setLayout(null);
bodyPanel.setPreferredSize(new Dimension(getWidth(), getHeight() - 30 - getWidth()*57/800));
bodyPanel.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.25f));
bodyPanel.setForeground(null);
bodyPanel.setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT-110);
rootPanel.add(bodyPanel);
}
/**
* Add two logo to body panel
*/
public void addBodyDetail() {
int MLogoX = FRAME_WIDTH * 19/25, MLogoY = 30, // Location of mLogo;
SLogoX =FRAME_WIDTH * 13/20, SLogoY = FRAME_HEIGHT * 10/15; // Location of sLogo;
mlogo = new ImagePanel(mLogoURL, FRAME_WIDTH * 5/24, FRAME_WIDTH * 5/91, MLogoX, MLogoY); // ?????logo
bodyPanel.add(mlogo);
slogo = new ImagePanel(sLogoURL, FRAME_WIDTH * 5/16, FRAME_WIDTH * 5/64, SLogoX, SLogoY);
bodyPanel.add(slogo);

}
/**
* Add panel in bottom to display the copyright message
* Including a Jlabel to show message
*/
public void addFootPanel() {
footPanel.setBackground(new Color(0, 0, 0, 0));
footPanel.setForeground(null);
footLabel.setBackground(null);
footLabel.setForeground(fgColor);
footPanel.setBounds(0, FRAME_HEIGHT-110, FRAME_WIDTH,40);
footPanel.add(footLabel);
rootPanel.add(footPanel);
}
/**
* Control the size of frame
*/
public void frameSizeCtrl() {
Dimension dimension = SizeCtrl.mainFrameSizeCtrl();
setSize(dimension);
}
}

class MenuItemMouseAdapter extends MouseAdapter {

private JMenuItem menuItem;
private MenuItemUI menuItemUI;

public MenuItemMouseAdapter(JMenuItem menuItem, Color bgColor, Color fgColor) {
this.menuItem = menuItem;
menuItemUI = new MenuItemUI(bgColor, fgColor);
MenuItemExitedUI exitedUI = new MenuItemExitedUI();
}

@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Entered");
menuItem.setUI(menuItemUI);
menuItem.setBorder(null);
}

@Override
public void mouseExited(MouseEvent e) {
System.out.println("Exited");
menuItem.setUI(null);
menuItem.setUI(menuItemUI);
menuItem.setBorder(null);
}

}

class MenuMouseAdapter extends MouseAdapter {

private JMenu menu;
private MenuUI menuUI;

public MenuMouseAdapter(JMenu menu, Color bgColor, Color fgColor) {
this.menu = menu;
this.menuUI = new MenuUI(bgColor, fgColor);
}

@Override
public void mouseEntered(MouseEvent e) {
menu.setUI(menuUI);
menu.setBorder(null);
}
}

class ImagePanel extends JPanel {

private Toolkit toolkit = Toolkit.getDefaultToolkit();
private String imgURL = "res\\ryougi_img.png";
private int imgWidth, imgHeight, x, y;

public ImagePanel(String imgURL, int imgWidth, int imgHeight, int x, int y) {
this.imgURL = imgURL;
this.imgWidth = imgWidth;
this.imgHeight = imgHeight;
this.setBounds(x, y, imgWidth, imgHeight);
setBackground(new Color(0, 0, 0, 0));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image img = toolkit.getImage(imgURL);
g.drawImage(img, 0, 0, imgWidth, imgHeight, this);
}
}

class MainMenuBar extends JMenuBar {

private Toolkit toolkit = Toolkit.getDefaultToolkit();
private String imgURL = "res\\library_top.jpg";

public MainMenuBar() {
this.setForeground(Color.WHITE);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image img = toolkit.getImage(imgURL);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
}

class RyougiModule {

private static Color LIGHT_BLUE_COLOR = new Color(120, 150, 232); // 系统主题颜色
private static JPanel tPanel; // 带标签的输入框面板
private static JLabel tLabel;
private static JTextField tField;

private static JPanel pPanel; // 带标签的密码输入框面板
private static JLabel pLabel;
private static JPasswordField pField;

private static JPanel imgPanel; // 带背景的面板
private static JButton colorBtn; // 带颜色按钮
private static JLabel nLabel; // 带颜色文本

private static JTextArea tArea; // 文本区域

/**
* 带标签的文本输入框,标签颜色和输入框颜色 --> Color(120, 150, 232)
* @param c 父组件
* @param label 标签显示的文本
* @param text 输入框显示的文本
* @param x 当父布局 setLayout(null) 时,重新定位组件的水平位置
* @param y 当父布局 setLayout(null) 时,重新定位组件的垂直位置
*/
public static JPanel TextFieldWithLabel(JComponent c, String label, String text, int fontSize, int x, int y) {

tPanel = new JPanel();
tLabel = new JLabel(label);
tField = new JTextField(text);
tLabel.setForeground(LIGHT_BLUE_COLOR);
tLabel.setFont(new Font("", Font.BOLD, fontSize));

tField.setPreferredSize(new Dimension(180, 30));
tField.setBorder(BorderFactory.createEtchedBorder(LIGHT_BLUE_COLOR, LIGHT_BLUE_COLOR));
tField.setForeground(LIGHT_BLUE_COLOR);
tField.setBackground(null);

tPanel.setBounds(x, y, 280, 40);

tPanel.add(tLabel);
tPanel.add(tField);

return tPanel;
}
/**
* 带标签的文本输入框,标签颜色和输入框颜色 --> Color(120, 150, 232)
* @param c 父组件
* @param label 标签显示的文本
* @param text 输入框显示的文本
*/
public static JPanel TextFieldWithLabel(JComponent c, String label, String text, int fontSize) {

tPanel = new JPanel();
tLabel = new JLabel(label);
tField = new JTextField(text);
tLabel.setForeground(LIGHT_BLUE_COLOR);
tLabel.setFont(new Font("", Font.BOLD, fontSize));

tField.setPreferredSize(new Dimension(180, 30));
tField.setBorder(BorderFactory.createEtchedBorder(LIGHT_BLUE_COLOR, LIGHT_BLUE_COLOR));
tField.setForeground(LIGHT_BLUE_COLOR);
tField.setBackground(null);

tPanel.add(tLabel);
tPanel.add(tField);

return tPanel;
}
/**
* 带标签的密码输入框,标签颜色和输入框颜色 --> Color(120, 150, 232)
* @param c 父组件
* @param label 标签显示的文本
* @param text 输入框显示的文本
* @param x 当父布局 setLayout(null) 时,重新定位组件的水平位置
* @param y 当父布局 setLayout(null) 时,重新定位组件的垂直位置
*/
public static JPanel PasswordFieldWithLabel(JComponent c, String label, String text, int fontSize, int x, int y) {

pPanel = new JPanel();
pLabel = new JLabel(label);
pField = new JPasswordField(text);
pLabel.setForeground(LIGHT_BLUE_COLOR);
pLabel.setFont(new Font("", Font.BOLD, fontSize));

pField.setPreferredSize(new Dimension(180, 30));
pField.setBorder(BorderFactory.createEtchedBorder(LIGHT_BLUE_COLOR, LIGHT_BLUE_COLOR));
pField.setForeground(LIGHT_BLUE_COLOR);
pField.setBackground(null);

pPanel.setBounds(x, y, 240, 40);

pPanel.add(pLabel);
pPanel.add(pField);
return pPanel;
}
/**
* 带标签的密码输入框,标签颜色和输入框颜色 --> Color(120, 150, 232) 浅蓝色
* @param c 父组件
* @param label 标签显示的文本
* @param text 输入框显示的文本
*/
public static JPanel PasswordFieldWithLabel(JComponent c, String label, String text, int fontSize) {
pPanel = new JPanel();
pLabel = new JLabel(label);
pField = new JPasswordField(text);
pLabel.setForeground(LIGHT_BLUE_COLOR);
pLabel.setFont(new Font("", Font.BOLD, fontSize));

pField.setPreferredSize(new Dimension(180, 30));
pField.setBorder(BorderFactory.createEtchedBorder(LIGHT_BLUE_COLOR, LIGHT_BLUE_COLOR));
pField.setForeground(LIGHT_BLUE_COLOR);
pField.setBackground(null);

pPanel.add(pLabel);
pPanel.add(pField);
return pPanel;
}
/**
* 图片背景面板,加载背景图片等情况使用
* @param c 父组件
* @param imgURL 图片的存放路径
* @param imgWidth 设置图片宽度
* @param imgHeight 设置图片高度
* @param x 设置图片水平位置
* @param y 设置图片垂直位置
*/
public static JPanel ImagePanel(JComponent c, String imgURL, int imgWidth, int imgHeight, int x, int y) {
imgPanel = new ImagePanel(imgURL, imgWidth, imgHeight, x, y);
return imgPanel;
}
/**
* 图片背景面板,加载背景图片等情况使用
* @param f 父窗口
* @param imgURL 图片的存放路径
* @param imgWidth 设置图片宽度
* @param imgHeight 设置图片高度
* @param x 设置图片水平位置
* @param y 设置图片垂直位置
*/
public static JPanel ImagePanel(JFrame f, String imgURL, int imgWidth, int imgHeight, int x, int y) {
imgPanel = new ImagePanel(imgURL, imgWidth, imgHeight, x, y);
return imgPanel;
}
/**
* 背景颜色为 color 的按钮
* @param c 父组件
* @param label 按钮文本
* @param color 按钮背景颜色
* @param btnWidth 按钮宽度,多数情况下可设为 90
* @param btnHeight 按钮高度,多数情况下可设为 30
* @param x 按钮的水平位置
* @param y 按钮的垂直位置
*/
public static JButton ColorButton(JComponent c, String label, int fontSize, Color color, int btnWidth, int btnHeight, int x, int y) {
colorBtn = new JButton(label);
colorBtn.setFont(new Font("", Font.BOLD, fontSize));
colorBtn.setBackground(color);
colorBtn.setForeground(Color.WHITE);
colorBtn.setBorder(null);
colorBtn.setPreferredSize(new Dimension(90, 30));
colorBtn.setBounds(x, y, btnWidth, btnHeight);
return colorBtn;
}
/**
* 背景颜色为 color 的按钮
* @param c 父组件
* @param label 按钮文本
* @param color 按钮背景颜色
* @param btnWidth 按钮宽度,多数情况下可设为 90
* @param btnHeight 按钮高度,多数情况下可设为 30
*/
public static JButton ColorButton(JComponent c, String label, int fontSize, Color color, int btnWidth, int btnHeight) {
colorBtn = new JButton(label);
colorBtn.setFont(new Font("", Font.BOLD, fontSize));
colorBtn.setBackground(color);
colorBtn.setForeground(Color.WHITE);
colorBtn.setBorder(null);
colorBtn.setPreferredSize(new Dimension(90, 30));
return colorBtn;
}
/**
* 带样式的提示文本信息,具有前景色(文本颜色)和背景色属性,位置,宽高等
* @param c 父组件
* @param label 文本信息
* @param fontSize 文本字体大小
* @param bgColor 文本背景色
* @param fgColor 文本前景色(文本颜色)
* @param width 文本组件宽度
* @param height 文本组件高度
* @param x 文本的水平位置
* @param y 文本的垂直位置
*/
public static JLabel NoticeLabel(JComponent c, String label, int fontSize, Color bgColor, Color fgColor, int width, int height, int x, int y) {
nLabel = new JLabel(label);
nLabel.setFont(new Font("", Font.BOLD, fontSize));
nLabel.setBackground(bgColor);
nLabel.setForeground(fgColor);
nLabel.setBounds(x, y, width, height);
return nLabel;
}
/**
* 带样式的提示文本信息,具有前景色(文本颜色)和背景色属性等
* @param c 父组件
* @param label 文本信息
* @param fontSize 文本字体大小
* @param bgColor 文本背景色
* @param fgColor 文本前景色(文本颜色)
*/
public static JLabel NoticeLabel(JComponent c, String label, int fontSize, Color bgColor, Color fgColor) {
nLabel = new JLabel(label);
nLabel.setFont(new Font("", Font.BOLD, fontSize));
nLabel.setBackground(bgColor);
nLabel.setForeground(fgColor);
return nLabel;
}
public static JTextArea MTextArea(String text,String fontName, int fontStyle, int fontSize, Color bgColor, Color fgColor, int width, int height, int x, int y) {
tArea = new JTextArea(text);
tArea.setFont(new Font(fontName, fontStyle, fontSize));
tArea.setEditable(false);
tArea.setBackground(bgColor);
tArea.setForeground(fgColor);
tArea.setLineWrap(true);
tArea.setBounds(x, y, width, height);
tArea.setBorder(null);
return tArea;
}
}
class LocationCtrl {
private static Toolkit toolkit = Toolkit.getDefaultToolkit(); // 系统工具包
private static final int SCREEN_WIDTH = toolkit.getScreenSize().width; // 获取当前主屏幕宽度
private static final int SCREEN_HEIGHT = toolkit.getScreenSize().height; // 获取当前主屏幕高度
private static final double scale = SCREEN_WIDTH/SCREEN_HEIGHT; // 屏幕宽高比

private static int FRAME_WIDTH; // 主窗口宽度
private static int FRAME_HEIGHT; // 主窗口高度

private static int MAIN_XL = (SCREEN_WIDTH - SCREEN_HEIGHT*8/5)/2; // 主窗口水平位置(宽屏,下同)
private static int MAIN_YL = SCREEN_HEIGHT /20; // 主窗口垂直位置
private static int OTHER_XL = (SCREEN_WIDTH - SCREEN_HEIGHT*4/5)/2; // 其他窗口水平位置
private static int OTHER_YL = SCREEN_HEIGHT *11/40; // 其他窗口垂直位置
private static int DIALOG_XL = (SCREEN_WIDTH - SCREEN_HEIGHT*8/15)/2; // 提示窗口水平位置
private static int DIALOG_YL = SCREEN_HEIGHT * 7/20; // 提示窗口垂直位置

private static int MAIN_XS = SCREEN_WIDTH /20; // 主窗口水平位置(窄屏,下同)
private static int MAIN_YS= (SCREEN_HEIGHT - SCREEN_WIDTH * 81/160) /2; // 主窗口垂直位置
private static int OTHER_XS = SCREEN_WIDTH * 11/40; // 其他窗口水平位置
private static int OTHER_YS = (SCREEN_HEIGHT - SCREEN_WIDTH * 81/320)/2; // 其他窗口垂直位置
private static int DIALOG_XS = SCREEN_WIDTH * 7/20; // 提示窗口水平位置
private static int DIALOG_YS = (SCREEN_HEIGHT - SCREEN_WIDTH * 27/160)/2; // 提示窗口垂直位置

/**
* 主界面窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口位置为屏幕高的 8/5 和 9/10
* 如果小于等于 16/9,设置窗口位置为屏幕宽的 9/10 和 81/160
*/
public static Point mainFrameLocationCtrl() {
if (scale > 16/9) {
return new Point(MAIN_XL, MAIN_YL);
} else {
return new Point(MAIN_XS, MAIN_YS);
}
}
/**
* 提示窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口位置为屏幕高的 8/15 和 3/10
* 如果小于等于 16/9,设置窗口位置为屏幕宽的 3/10 和 27/160
*/
public static Point dialogLocationCtrl() {
if (scale > 16/9) {
return new Point(DIALOG_XL, DIALOG_YL);
} else {
return new Point(DIALOG_XS, DIALOG_YS);
}
}
/**
* 其他界面窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口位置为屏幕高的 4/5 和 9/20
* 如果小于等于 16/9,设置窗口位置为屏幕宽的 9/20 和 81/320
*/
public static Point otherFrameLocationCtrl() {
if (scale > 16/9) {
return new Point(OTHER_XL, OTHER_YL);
} else {
return new Point(OTHER_XS, OTHER_YS);
}
}
}
class SizeCtrl {
private static Toolkit toolkit = Toolkit.getDefaultToolkit(); // 系统工具包
private static final int SCREEN_WIDTH = toolkit.getScreenSize().width; // 获取当前主屏幕宽度
private static final int SCREEN_HEIGHT = toolkit.getScreenSize().height; // 获取当前主屏幕高度
private static final double scale = SCREEN_WIDTH/SCREEN_HEIGHT; // 屏幕宽高比

private static int FRAME_WIDTH; // 主窗口宽度
private static int FRAME_HEIGHT; // 主窗口高度

/**
* 主界面窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口宽高尺寸为屏幕高的 8/5 和 9/10
* 如果小于等于 16/9,设置窗口宽高尺寸为屏幕宽的 9/10 和 81/160
*/
public static Dimension mainFrameSizeCtrl() {
if (scale > 16/9) {
FRAME_WIDTH = SCREEN_HEIGHT * 8/5;
FRAME_HEIGHT = SCREEN_HEIGHT * 9/10;
} else {
FRAME_WIDTH = SCREEN_WIDTH * 9/10;
FRAME_HEIGHT = SCREEN_WIDTH * 81/160;
}
return new Dimension(FRAME_WIDTH, FRAME_HEIGHT);
}
/**
* 提示窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口宽高尺寸为屏幕高的 8/15 和 3/10
* 如果小于等于 16/9,设置窗口宽高尺寸为屏幕宽的 3/10 和 27/160
*/
public static Dimension dialogSizeCtrl() {
if (scale > 16/9) {
FRAME_WIDTH = SCREEN_HEIGHT * 8/15;
FRAME_HEIGHT = SCREEN_HEIGHT * 3/10;
} else {
FRAME_WIDTH = SCREEN_WIDTH * 3/10;
FRAME_HEIGHT = SCREEN_WIDTH * 27/160;
}
return new Dimension(FRAME_WIDTH, FRAME_HEIGHT);
}
/**
* 其他界面窗口尺寸控制
* 如果当前屏幕尺寸宽高比大于 16/9,设置窗口宽高尺寸为屏幕高的 4/5 和 9/20
* 如果小于等于 16/9,设置窗口宽高尺寸为屏幕宽的 9/20 和 81/320
*/
public static Dimension otherFrameSizeCtrl() {
if (scale > 16/9) {
FRAME_WIDTH = SCREEN_HEIGHT * 4/5;
FRAME_HEIGHT = SCREEN_HEIGHT * 9/20;
} else {
FRAME_WIDTH = SCREEN_WIDTH * 9/20;
FRAME_HEIGHT = SCREEN_WIDTH * 81/320;
}
return new Dimension(FRAME_WIDTH, FRAME_HEIGHT);
}
}
class MenuUI extends BasicMenuUI {
public MenuUI(Color bgColor, Color fgColor) {
super.selectionBackground = bgColor;
super.selectionForeground = fgColor;
}
}
class MenuItemUI extends BasicMenuItemUI {
public MenuItemUI(Color bgColor, Color fgColor) {
super.selectionBackground = bgColor;
super.selectionForeground = fgColor;
}
}
class MenuItemExitedUI extends BasicMenuItemUI {
public MenuItemExitedUI() {
super.selectionBackground = new Color(0, 0, 0, 0.25f);
super.selectionForeground = Color.WHITE;
}
}

我将所有这些项目的背景设置为new Color(0,0,0,0.25f)。他们我得到了这个结果:

My Running Result

我惊讶地发现我的 JMenuItem 下面有一个白色背景,如红色箭头所示。并且该项目具有正确的new Color(0,0,0,0.25f) 背景,如黑色箭头所示。顺便说一句,我已将主面板的背景设置为图片,如橙色箭头所示。

谁能回答我这个白色背景是从哪里来的?我该如何删除它或使其不可见?

最佳答案

enter image description here

  • 仅在 MetalLookAndFeel 上进行了测试。
import java.awt.*;
import java.awt.image.*;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.*;

public class MenuBarRootPaneTest {
private static final Color ALPHA_ZERO = new Color(0x0, true);
private static final Color POPUP_BACK = new Color(0, 0, 0, .25f);

private static JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar() {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 36;
return d;
}
@Override public boolean isOpaque() {
return false;
}
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(POPUP_BACK);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
};
String[] menuKeys = {"File", "Edit", "Help"};
for (String key : menuKeys) {
mb.add(createMenu(key));
}
return mb;
}

private static JMenu createMenu(String key) {
JMenu menu = new TransparentMenu(key);
menu.add(new JMenuItem("JMenuItem 1"));
menu.add(new JMenuItem("JMenuItem 2"));
menu.add(new JMenuItem("JMenuItem 3"));
return menu;
}

public static void main(String... args) {
EventQueue.invokeLater(() -> {
//UIManager.put("MenuBar.background", POPUP_BACK);
UIManager.put("MenuBar.border", BorderFactory.createEmptyBorder());
UIManager.put("PopupMenu.border", BorderFactory.createEmptyBorder());

UIManager.put("Menu.foreground", Color.WHITE);
UIManager.put("Menu.background", ALPHA_ZERO);
UIManager.put("Menu.selectionBackground", POPUP_BACK);
UIManager.put("Menu.selectionForeground", Color.WHITE);
UIManager.put("Menu.borderPainted", Boolean.FALSE);

UIManager.put("MenuItem.foreground", Color.WHITE);
UIManager.put("MenuItem.background", ALPHA_ZERO);
UIManager.put("MenuItem.selectionBackground", POPUP_BACK);
UIManager.put("MenuItem.selectionForeground", Color.WHITE);
UIManager.put("MenuItem.borderPainted", Boolean.FALSE);

JFrame frame = new JFrame() {
@Override protected JRootPane createRootPane() {
return new JRootPane() {
//private final Image img = new ImageIcon("img.png").getImage();
private final TexturePaint texture = makeTexturePaint();
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(texture);
g2.fillRect(0, 0, getWidth(), getHeight());
//g2.drawImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this);
g2.dispose();
}
@Override public boolean isOpaque() {
return true;
}
};
}
};
frame.getRootPane().setBackground(Color.BLUE);
((JComponent) frame.getContentPane()).setOpaque(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenuBar());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}

// TranslucentPopupMenu
// http://ateraimemo.com/Swing/TranslucentPopupMenu.html
static class TranslucentPopupMenu extends JPopupMenu {
@Override public boolean isOpaque() {
return false;
}
@Override public void show(Component c, int x, int y) {
EventQueue.invokeLater(() -> {
Container p = getTopLevelAncestor();
if (p instanceof JWindow) {
System.out.println("Heavy weight");
((JWindow) p).setBackground(ALPHA_ZERO);
}
});
super.show(c, x, y);
}
@Override protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(POPUP_BACK);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
}

static class TransparentMenu extends JMenu {
private JPopupMenu popupMenu;

protected TransparentMenu(String title) {
super(title);
}
@Override public boolean isOpaque() {
return false;
}
// Bug ID: JDK-4688783 JPopupMenu hardcoded i JMenu
// http://bugs.java.com/view_bug.do?bug_id=4688783
private void ensurePopupMenuCreated() {
if (Objects.isNull(popupMenu)) {
this.popupMenu = new TranslucentPopupMenu();
popupMenu.setInvoker(this);
popupListener = createWinListener(popupMenu);
}
}
@Override public JPopupMenu getPopupMenu() {
ensurePopupMenuCreated();
return popupMenu;
}
@Override public JMenuItem add(JMenuItem menuItem) {
ensurePopupMenuCreated();
menuItem.setOpaque(false);
return popupMenu.add(menuItem);
}
@Override public Component add(Component c) {
ensurePopupMenuCreated();
if (c instanceof JComponent) {
((JComponent) c).setOpaque(false);
}
popupMenu.add(c);
return c;
}
@Override public void addSeparator() {
ensurePopupMenuCreated();
popupMenu.addSeparator();
}
@Override public void insert(String s, int pos) {
if (pos < 0) {
throw new IllegalArgumentException("index less than zero.");
}
ensurePopupMenuCreated();
popupMenu.insert(new JMenuItem(s), pos);
}
@Override public JMenuItem insert(JMenuItem mi, int pos) {
if (pos < 0) {
throw new IllegalArgumentException("index less than zero.");
}
ensurePopupMenuCreated();
popupMenu.insert(mi, pos);
return mi;
}
@Override public void insertSeparator(int index) {
if (index < 0) {
throw new IllegalArgumentException("index less than zero.");
}
ensurePopupMenuCreated();
popupMenu.insert(new JPopupMenu.Separator(), index);
}
@Override public boolean isPopupMenuVisible() {
ensurePopupMenuCreated();
return popupMenu.isVisible();
}
}

private static TexturePaint makeTexturePaint() {
int cs = 6;
int sz = cs * cs;
BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setPaint(new Color(200, 200, 200, 50));
g2.fillRect(0, 0, sz, sz);
for (int i = 0; i * cs < sz; i++) {
for (int j = 0; j * cs < sz; j++) {
if ((i + j) % 2 == 0) {
g2.fillRect(i * cs, j * cs, cs, cs);
}
}
}
g2.dispose();
return new TexturePaint(img, new Rectangle(sz, sz));
}
}

关于java - 使用JMenuBar、JMenu和JMenuItem自行设计菜单栏时呈现奇怪的效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38473235/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com