我需要在菜单中包含两列菜单项。这可以使用弹出菜单的 GridBagLayout 来实现。我的问题是:两列具有相同的宽度,即菜单中最大菜单项的宽度(但不在列中,因为 GridBagLayout 必须如此)。当我用按钮替换菜单中的菜单项时 - 布局工作正常。那么我如何建议菜单中的项目应该具有不同的宽度?
以下是屏幕:
当我使用菜单项时 - 两列具有相同的宽度(错误)
当我使用按钮时 - 列具有不同的宽度(正确)
下面是代码示例:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
public class MenuTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Menu test");
JMenuBar menuBar = new JMenuBar();
JMenu m1 = new JMenu("Menu items");
m1.getPopupMenu().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
m1.getPopupMenu().add(new JMenuItem("Very very very very long text"), gbc);
gbc.gridx = 1;
m1.getPopupMenu().add(new JMenuItem("Short text"), gbc);
menuBar.add(m1);
JMenu m2 = new JMenu("Buttons");
m2.getPopupMenu().setLayout(new GridBagLayout());
gbc.gridx = 0;
m2.getPopupMenu().add(new JButton("Very very very very long text"), gbc);
gbc.gridx = 1;
m2.getPopupMenu().add(new JButton("Short text"), gbc);
menuBar.add(m2);
frm.setJMenuBar(menuBar);
frm.add(new JScrollPane(new JTextArea("Sample text", 10, 40)));
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
}
最佳答案
显然,JMenuItem
布局基于同一父组件中所有包含的 JMenuItem
的最大宽度。查看 Sun/Oracle 的代码后,似乎很难干扰这一点,并且每个 JMenuItem
的首选大小将是等效的。
然而,我找到了一种方法来克服这个问题,通过重写 JMenutItem
的 getPreferredSize()
,虽然不太漂亮,但似乎有效:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
public class MenuTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Menu test");
JMenuBar menuBar = new JMenuBar();
JMenu m1 = new JMenu("Menu items");
m1.getPopupMenu().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
JMenuItem comp1 = new JMenuItem("Very very very very long text") {
@Override
public Dimension getPreferredSize() {
return new JMenuItem(getText(), getIcon()).getPreferredSize();
}
};
m1.getPopupMenu().add(comp1, gbc);
gbc.gridx = 1;
JMenuItem comp2 = new JMenuItem("Short text") {
@Override
public Dimension getPreferredSize() {
return new JMenuItem(getText(), getIcon()).getPreferredSize();
}
};
m1.getPopupMenu().add(comp2, gbc);
menuBar.add(m1);
JMenu m2 = new JMenu("Buttons");
m2.getPopupMenu().setLayout(new GridBagLayout());
gbc.gridx = 0;
m2.getPopupMenu().add(new JButton("Very very very very long text"), gbc);
gbc.gridx = 1;
m2.getPopupMenu().add(new JButton("Short text"), gbc);
menuBar.add(m2);
frm.setJMenuBar(menuBar);
frm.add(new JScrollPane(new JTextArea("Sample text", 10, 40)));
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
comp1.setVerticalTextPosition(SwingConstants.TOP);
comp2.setVerticalTextPosition(SwingConstants.TOP);
}
}
当然,如果您使用 JMenuItem 的其他属性来修改 JMenuItem
的 UI,则需要将其传递给“内部”JMenuItem
,如下所示出色地。它也可能很难维护,并且无法在所有 L&F 中工作。
您还可以通过在不同的调用中重复使用相同的“内部”JMenuItem
来改进这一点。
关于java - 布局JPopupMenu : How to provide different size for menu items in same menu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166669/