【问题标题】:How to take out white borders in JMenu and JMenuItems如何在 JMenu 和 JMenuItems 中去掉白色边框
【发布时间】:2015-12-24 23:22:04
【问题描述】:

我正在用 Swing 做这个图形界面。我遇到的问题是我不能将 JMenuItems 周围的白色边框全部涂成黑色。这是一张图片:

我想把它画成这样(我已经用paint :D 编辑了图像):

有人可以帮我吗?我会很感激任何帮助。谢谢!

【问题讨论】:

  • 这就是组装组件的所有代码吗?
  • 我没有对此进行研究,但我记得,弹出窗口是从外观委托生成的,以一种不太容易拦截或控制的方式
  • 您可以尝试查看PopupMenu.border UIManager 属性,但这会影响所有弹出菜单

标签: java swing jmenu jmenuitem jmenubar


【解决方案1】:

我刚刚做了这个快速测试,使用

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

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 委托,似乎弹出菜单是在 JMenuprivate 方法中创建的,称为 ensurePopupMenuCreated,这将是注入您的自定义代码。

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

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 这将取决于您要实现的目标以及您对底层代码的评估程度以及您是否真的想将Border 应用于您创建的每个JMenu,而不是使用单行代码或自定义类来实现它;)
  • @LuxxMiner 那我想更深入地研究弹出窗口的实际创建方式;)
【解决方案2】:

我正在添加第二种方法。你可以使用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() 我们得到:

现在,如果我们想为 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)); 我还添加了另一个项目,只是为了让菜单更大,更容易看到边框......)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2014-08-05
    相关资源
    最近更新 更多