如何在JMenu和JMenuItems中去掉白色边框

3
我正在使用Swing制作此图形界面。我的问题是,我无法将围绕JMenuItems的白色边框全部涂成黑色。以下是图片:enter image description here
我想要像这样涂色(我用画图软件编辑了图片:D):enter image description here
有人能帮我吗?我会感激任何帮助。谢谢!

这是组装组件的所有代码吗? - Perdomoff
我没有深入研究过这个问题,但我记得弹出窗口是由外观委托生成的,不太容易拦截或控制。 - MadProgrammer
你可以尝试查看PopupMenu.border UIManager属性,但这会影响所有弹出菜单。 - MadProgrammer
2个回答

7
我刚刚进行了一个快速测试,使用以下代码: UIManager.put("PopupMenu.border", new LineBorder(Color.RED)); 下面是测试截图: Test
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                UIManager.put("PopupMenu.border", new LineBorder(Color.RED));

                JMenuBar menuBar = new JMenuBar();
                JMenu menu = new JMenu("Stuff");
                menu.add(new JMenuItem("A"));
                menu.add(new JMenuItem("BB"));
                menu.add(new JMenuItem("CCC"));
                menuBar.add(menu);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.setJMenuBar(menuBar);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

现在,这可能不是理想的选择,因为这将影响程序中所有的弹出菜单。

更新

我研究了JMenu及其UI代理,并发现弹出菜单是在JMenu的一个名为ensurePopupMenuCreated的私有方法中创建的,这可能是注入您自己的自定义代码的绝佳位置。

该方法实际上在许多不同的地方被调用,但可能getPopupMenu是最容易访问的地方。

Help

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JMenuBar menuBar = new JMenuBar();
                JMenu menu = new JMenu("Stuff") {
                    private Border border = new LineBorder(Color.RED);
                    @Override
                    public JPopupMenu getPopupMenu() {
                        JPopupMenu menu = super.getPopupMenu();
                        menu.setBorder(border);
                        return menu;
                    }

                };
                JMenuItem mi = new JMenuItem("Help", 'H');
                mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, KeyEvent.META_MASK));
                menu.add(new JMenuItem("A"));
                menu.add(new JMenuItem("BB"));
                menu.add(new JMenuItem("CCC"));
                menu.add(mi);
                menuBar.add(menu);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.setJMenuBar(menuBar);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

@LuxxMiner 这取决于您想要实现什么以及您对底层代码的访问权限以及是否真的想要为您创建的每个 JMenu 应用 Border,而不是使用一行代码或自定义类来实现它 ;) - MadProgrammer
@LuxxMiner 而且我想深入了解弹出窗口是如何创建的 ;) - MadProgrammer

0
我正在添加第二种方法。您可以使用 setBorder 方法:
menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));

这个解决方案的优点是你可以设置厚度级别。在上面的例子中,厚度级别被设置为2。

此外,你可以在许多组件中使用setBorder来绘制各种边框,如下面的例子所示:

首先是基本代码:

主类:

import javax.swing.*;

public class Main {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            CustomGUI sw = new CustomGUI();
            sw.setVisible(true);
        });

    }
} 

CustomGui.class:

import java.awt.*;
import javax.swing.*;

public class CustomGUI extends JFrame {

    public CustomGUI()  {
        super("Simple example");
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        setSize(500,500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setBackground(Color.DARK_GRAY);



        JMenuBar menuBar = new JMenuBar();
        JMenu menu1 = new JMenu("menu B");
        menuBar.add(menu1);

        JMenuItem item = new JMenuItem("A text-only menu item");
        menu1.add(item);

        JMenu menu2 = new JMenu("menu B");
        menuBar.add(menu2);

        JMenuItem item2 = new JMenuItem("A text-only menu item");
        menu2.add(item2);


        add(menuBar);
    }
}

现在通过添加以下行:

menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));

CustomGUI()中,我们得到: enter image description here 现在,如果我们想要为jmenu添加边框(这是OP所要求的),我们需要添加以下内容:
menu1.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.BLUE, 4));
menu2.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.BLUE, 4));

在这里输入图像描述 (如您所见,我没有为菜单栏设置边框,但是可以按照上述方法使用以下代码完成: menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2)); 同时,我添加了另一个项目以使菜单更大且易于看到边框...)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接