JMenuItem setMinimumSize不起作用

时间:2009-08-28 09:18:41

标签: java swing

我尝试为菜单项设置最小宽度,但似乎不起作用。这是我的函数,它创建项目:

 private JMenuItem newItem(String text, String iconPath) {
     JMenuItem myMenuItem;
     if (iconPath == null || iconPath.isEmpty()) {
         myMenuItem = new JMenuItem(text);
     }
     else {
         ImageIcon icon = new ImageIcon(iconPath);
         myMenuItem = new JMenuItem(text, icon);
     }
     // this would work, but then setMaximumSize doesn't have any effect
     // myMenuItem.setPreferredSize(new Dimension(250,20)); 
     myMenuItem.setMinimumSize(new Dimension(250,20)); 
     myMenuItem.setMaximumSize(new Dimension(350,20));

     return myMenuItem;
 }

我做错了什么?

PS。我在Windows XP上使用jdk1.6,在System Look& Feel上使用Servicepack 3

4 个答案:

答案 0 :(得分:4)

大多数布局管理器都会忽略最小和最大尺寸。这是一个有用的小技巧,可以在任何布局管理器中强制使用这些尺寸:

private class MyMenuItem extends JMenuItem {
    @Override
    public Dimension getPreferredSize() {
        Dimension preferred = super.getPreferredSize();
        Dimension minimum = getMinimumSize();
        Dimension maximum = getMaximumSize();
        preferred.width = Math.min(Math.max(preferred.width, minimum.width), 
            maximum.width);
        preferred.height = Math.min(Math.max(preferred.height, minimum.height), 
            maximum.height);
        return preferred;
    }
}

即使菜单项的内容发生变化,这也具有工作的优点。您需要添加构造函数以满足您的目的。

答案 1 :(得分:1)

我替换了你的

myMenuItem.setMinimumSize(new Dimension(250, 20));
myMenuItem.setMaximumSize(new Dimension(350, 20));

myMenuItem.setPreferredSize(new Dimension(250, 20));

它使它成为你寻找的宽度。根据我的经验,摆动组件对最佳尺寸的响应比最小和最大尺寸更好。

编辑:

经过另一次尝试之后,我觉得这很有效......它可以归结为和你一样,我认为无论字体是什么(你在哪里硬编码字体)都会有效。

然而,它没有考虑菜单项的主要装订线,但除非你的文字非常长,否则不应该有所作为。

 private JMenuItem newItem(String text, String iconPath) {
    JMenuItem myMenuItem;
    if (iconPath == null || iconPath.isEmpty()) {
        myMenuItem = new JMenuItem(text);
        myMenuItem.setPreferredSize(new Dimension(myMenuItem.getFontMetrics(myMenuItem.getFont()).stringWidth(text), 20));
    } else {
        ImageIcon icon = new ImageIcon(iconPath);
        myMenuItem = new JMenuItem(text, icon);
        myMenuItem.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
    }
    return myMenuItem;
}

答案 2 :(得分:0)

好的,所以我找到了一个解决方案,也许不是最好的解决方案,但似乎有效。不过,我仍然对FontMetrics语句有点担心。所以如果有人有更好的解决方案,我会很高兴看到它。这是我的代码(Menu.MINWIDTH设置为200,Menu.MAXWIDTH设置为300):

 private JMenuItem newItem(String text, String iconPath) {
     JMenuItem myMenuItem;
     ImageIcon icon= null;
     int iconPixels = 0;
     if (iconPath == null || iconPath.isEmpty()) {
         myMenuItem = new JMenuItem(text);
     }
     else {
         icon = new ImageIcon(iconPath);
         myMenuItem = new JMenuItem(text, icon);
         iconPixels = icon.getIconWidth();
     }

     FontMetrics fontM = myMenuItem.getFontMetrics(new Font("Default", Font.PLAIN, 12));
     int stringPixels = fontM.stringWidth(text);

     int newWidth = stringPixels + iconPixels;

     newWidth = newWidth < Menu.MINWIDTH ? Menu.MINWIDTH : newWidth;
     newWidth = newWidth > Menu.MAXWIDTH ? Menu.MAXWIDTH : newWidth;

     myMenuItem.setPreferredSize(new Dimension(newWidth, 20)); 
     System.out.println(text + " - " + newWidth);
     return myMenuItem;
 }

答案 3 :(得分:0)

如果我理解了这个问题,我不确定为什么需要使用FontMetrics。只需在菜单项上调用getPreferredSize()即可。如果首选大小小于最小值,请将首选大小重置为最小值。