【问题标题】:Resizing a JMenuItem?调整 JMenuItem 的大小?
【发布时间】:2017-07-13 18:24:50
【问题描述】:

我目前正在尝试自定义 JMenuItem 的大小以使其更大。从此:

更像这样:

从表面上看,我有几个选择:

1:扩展 JMenuItem 并覆盖 getPreferredSize()。或者我想这样做(这就是上面的图像是如何实现的):

    private JMenuItem getCustomMenuItem(String s){
    JMenuItem item = new JMenuItem(s){
        @Override
        public Dimension getPreferredSize(){
            return new Dimension(100, 20);
        }
    };
    return item;
}

JMenuItem print = getCustomMenuItem("Print");

但我很确定这是不赞成的,因为布局管理器可能不尊重我给出的尺寸。我可能还需要编写或覆盖其他项目,例如 JCheckBoxMenuItems。

2:我还可以在每个菜单项之间添加水平支柱来处理垂直间距,并在标签的每一侧使用空格来处理菜单的宽度。但这看起来很笨重,当我想对齐文本和图像时可能会导致问题 menu.add(Box.createVerticalStrut(10))

3:或者我可以为每个菜单项添加一个复合边框: menuItem.setBorder(BorderFactory.createCompoundBorder(menuItem.getBorder(), new EmptyBorder(5,5,5,5)))

4:或者以某种方式告诉外观来设置菜单项宽度 - 我不太明白。

还有其他方法可以做到这一点吗?方法 1 有效,但我认为添加复合边框可能是我应该采用的方式。我想我可以扩展 JMenuItem 并将边框添加到自定义项目(这也将允许我投射 JCheckBoxMenuItem)?

感谢您提供任何帮助,但还没有真正找到明确的答案,并且想知道更普遍地自定义组件的最佳做法是什么,同时避免整个 get/set preferredSize() 陷阱。

【问题讨论】:

  • “我目前正在尝试自定义 JMenuItem 的大小以使其更大。” ...为什么?
  • 上图有点极端(我只是输入了 100 宽度来测试它是否有效),但我确实认为默认尺寸看起来局促。我只是希望能够稍微改变视觉效果
  • 不推荐吗?

标签: java swing


【解决方案1】:

我通常调用setIconTextGap (int) 方法来让菜单项看起来更好。

例子:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class TestMenuItem
{
    public static void main (String [] a) {
        Locale.setDefault (Locale.ENGLISH);
        SwingUtilities.invokeLater (new Runnable () {
            @Override public void run () {
                try {
                    UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
                    createAndShowGUI ();
                }
                catch (Exception e) {
                    e.printStackTrace ();
                }
            }
        });
    }
    private static void createAndShowGUI () {
        JFrame frame = new JFrame ("Test Menu Item");
        // --- JMenuBar ---
        JMenuBar menuBar = new JMenuBar ();
        JMenu menu = new JMenu ("File");
        menu.add (createMenuItem ("Print", KeyStroke.getKeyStroke (KeyEvent.VK_P, ActionEvent.ALT_MASK)));
        menu.add (createMenuItem ("Exit", KeyStroke.getKeyStroke (KeyEvent.VK_ESCAPE, 0)));
        JMenu anotherMenu = new JMenu ("View");
        JMenuItem longerMenuItem = createMenuItem ("Longer Item", null);
        longerMenuItem.setIconTextGap (80);
        anotherMenu.add (longerMenuItem);
        menuBar.add (menu);
        menuBar.add (anotherMenu);
        // --- Closing frame ---
        frame.setJMenuBar (menuBar);
        // frame.pack (); use pack in a real application !!
        frame.setSize (500, 400); // used just for convenience !!
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo (null);
        frame.setVisible (true);
    }
    public static JMenuItem createMenuItem (String text, KeyStroke keyStroke) {
        JMenuItem menuItem = new JMenuItem (text);
        if (keyStroke != null) menuItem.setAccelerator (keyStroke);
        menuItem.setIconTextGap (40);
        return menuItem;
    }
}

这是结果(值 = 20):

并且有较大的差距(值 = 80):

【讨论】:

  • 我得试试看它的样子,谢谢
【解决方案2】:
JMenuItem item = new JMenuItem("FILE");
item.add(new JButton("FILE BUTTON"));
item.setLayout(new FlowLayout()); // set FlowLayout for item
item.setPreferredSize(new Dimension(200, 100));//set size here
menu.add(item);

【讨论】:

  • 我读过最好覆盖 getPreferredSize() 而不是设置大小。我不知道为什么。这里有一个关于preferredSize() 的大线程,我已经阅读了几次,但我承认我并没有真正理解它。
【解决方案3】:

JMenuItem 扩展自 AbstractButton,它有一个 setMargin(...) 方法:

menuItem.setMargin( new Insets(...) );

编辑:

一些 LAF 允许您设置此属性:

UIManager.put("MenuItem.margin", new Insets(...));

查看UIManager Defaults了解更多信息。

【讨论】:

  • 哦,是的,我试过这个选项,但似乎没有任何效果。我现在再试一次
  • 是的,它似乎仍然不尊重这种方法。我在JMenuItem print = new JMenuItem("print") 之后立即调用它
  • @NickW,我之前在 JButton 上使用过 setMargin(...) 方法,不知道为什么它在菜单项上不起作用。我猜 LAF 会覆盖功能。见编辑。
  • 我之前实际上已经访问了您的网站 - 在那里发现了一些非常有用的东西,通常是在其他地方描述得不好的东西,所以很高兴看到您在 UIManager 上发布了一个帖子。感谢您的帮助
  • 奇怪 - 我绝对可以设置 MenuItem.margin 属性 - 我 Sysout 属性并显示正确的插图,但它没有影响。我在创建任何摆动组件之前设置了该属性,所以我不确定为什么它没有效果。我还打电话给SwingUtilities.updateComponentTreeUI(frame),因为我读到这可能会有所帮助。但它没有....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 2010-12-11
相关资源
最近更新 更多