0

I'm trying to add a JTextField as a search bar to a JMenuBar at the top of my JFrame. My problem is that the JTextField keeps getting resized to take up all available space in the JMenuBar, and I don't want it to. I've tried setPreferredSize() and setMaximum Size(), but these didnt work, presumably because the LayoutManager used in the JMenuBar doesn't respect these sizes. I also tried adding the JTextField to a JPanel with a FlowLayout and adding the panel to the JMenuBar, but I get something that looks like this:

The panel is on the right side of the JMenuBar, and the size seems to be correct, but I can't see anything in it other than this weird blue bar.

Here's the code that (I think) is relevant. Let me know if more is needed:

       JPanel searchPanel = new JPanel();
    searchPanel.setPreferredSize(new Dimension(100, 25));


    JTextField searchBar = new JTextField(50);

    String[] fields = {"title", "author", "subject", "publisher", "year", "circulating", "catalog" };


    JComboBox searchFields = new JComboBox(fields);

    JButton searchBtn = new JButton("search");

    searchPanel.add(searchBar);
    searchPanel.add(searchFields);
    searchPanel.add(searchBtn);
    searchPanel.setVisible(true);

    fileMenu.add(open);
    fileMenu.add(save);
    fileMenu.add(exit);

    libMenu.add(viewLib);
    libMenu.addSeparator();
    libMenu.add(newBook);
    libMenu.add(search);

    this.setJMenuBar(topBar);
       topBar.add(fileMenu);
    topBar.add(libMenu);
    topBar.add(Box.createHorizontalGlue());
   topBar.add(searchPanel);
4

2 回答 2

3

我的解决方案类似于 camickr 的,但不需要 setMaximumSize()。并不是说我反对它,但我知道 SO 的狂热者发誓“永远永远不会调用 setXxxsize() 永远!!!” 我不是他们中的一员,但他们在外面。

无论如何,我会用 GridBagLayout 制作一个 JPanel,然后将 JTextField 放入其中并填充 NONE,然后将 Box.createHorizo​​ntalGlue() 填充为 HORIZONTAL。然后,将此面板放在菜单栏中。

编辑:

为了完整起见,这是一个使用 JPanel 的解决方案,无需调用 setMaximumSize(...)
(从而避免永远在地狱中燃烧......根据某些人的说法):

GridBagConstraints gbc = new GridBagConstraints();
JPanel gbPanel = new JPanel(new GridBagLayout());
gbc.gridx = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbPanel.add(Box.createHorizontalGlue(), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbPanel.add(new JTextField(10), gbc);
menuBar.add(gbPanel);

一些评论:
1)伙计,我忘记了 GBL 是多么冗长。通常我使用一个帮助类来大大减少代码,但我不想为这样一个小例子发布它。

2)如果采用面板路线,camickr 的使用 BorderLayout 的建议(见下面的评论)不仅有效,而且是更简单的代码。

3)此外,正如 camickr 指出的那样,使用面板会影响“胶水”区域的外观。它被绘制成 JPanel 而不是 JMenuBar。老实说,在他提到它之前,我什至没有在我的机器上注意到它(使用 Metal L&F),但它是不同的,可能是一个不受欢迎的副作用。

于 2013-03-06T04:41:38.300 回答
3

这对我有用。

menuBar.add(Box.createHorizontalGlue());
JTextField textField = new JTextField(10);
textField.setMaximumSize( textField.getPreferredSize() );
menuBar.add(textField);

如果您需要更多帮助,请发布 SSCCE。

编辑:

同样,发布代码只是为了表明问题在于包含文本字段的最大大小。您如何选择执行此操作取决于您。

于 2013-03-06T02:04:56.360 回答