问题
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);
回答1:
This works for me.
menuBar.add(Box.createHorizontalGlue());
JTextField textField = new JTextField(10);
textField.setMaximumSize( textField.getPreferredSize() );
menuBar.add(textField);
Post an SSCCE if you need more help.
Edit:
Again, the code is posted was just to show that the problem is in containing the maximum size of the text field. How you choose to do this is up to you.
回答2:
My solution is similar to camickr's, but without the need for setMaximumSize(). Not that I'm against it, but I know there are zealots on SO who swear by "never ever ever ever call setXxxsize() EVER!!!" I'm not one of them, but they're out there.
Anyway, I'd make a JPanel with GridBagLayout, and put the JTextField in it with a fill of NONE, and a Box.createHorizontalGlue() with a fill of HORIZONTAL. Then, put this panel in your menubar.
EDIT:
For completeness, here's a solution using a JPanel w/o having to call setMaximumSize(...)
(and thus avoid burning in hell for all eternity... according to some):
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);
Some comments:
1) Man, I forgot how verbose GBL is. Normally I use a helper class that reduces the code greatly, but I didn't feel like posting it for such a small example.
2) If going the panel route, camickr's suggestion (see comment below) of using BorderLayout not only works, but is far simpler code.
3) Also, as camickr pointed out, using a panel affects the appearance of the "glue" area. It gets painted like a JPanel instead of a JMenuBar. Honestly, I didn't even notice it on my machine (using Metal L&F) until he mentioned it, but it IS different and may be an undesireable side-effect.
来源:https://stackoverflow.com/questions/15237450/resizing-jtextfield-in-jmenubar