2013-03-06 77 views
0

我試圖將JTextField作爲搜索欄添加到我的JFrame頂部的JMenuBar。我的問題是,JTextField不斷調整大小,以佔用JMenuBar中的所有可用空間,我不希望它。我試過setPreferredSize()setMaximum Size(),但這些都沒有奏效,大概是因爲JMenuBar中使用的LayoutManager不尊重這些尺寸。我也嘗試添加了JTextFieldJPanelFlowLayout並添加面板到JMenuBar,但我得到的東西看起來是這樣的:調整JMenuBar中的JTextField的大小

的面板上JMenuBar的右側,大小似乎是正確的,但除了這個奇怪的藍色條,我看不到任何東西。

以下是我認爲相關的代碼。讓我知道是否需要更多:

 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); 
+0

'JMenuBar'有它自己的佈局管理器,可能會忽略你的尺寸提示 – MadProgrammer 2013-03-06 01:44:10

+0

是的,我知道,但肯定有一個解決方法在這裏。看起來好像我發佈的那樣(將JTextField等添加到JPanel中)可以工作,但JPanel不能正確顯示,這是我真正不明白的 – drewmoore 2013-03-06 01:46:27

+0

'JPanel'會受到與'JTextField' ...對不起,需要一個關於此的思考空間;) – MadProgrammer 2013-03-06 01:56:29

回答

3

這適用於我。

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

如果您需要更多幫助,請發佈SSCCE。

編輯:

同樣,代碼發佈只是表明這個問題是在包含文本字段的最大尺寸。你如何選擇這個取決於你。

+0

依靠['getPreferredSize()'](http://stackoverflow.com/q/7229226/230513)+1。 – trashgod 2013-03-06 06:33:38

+0

有趣的是,這工作。它與我以前的代碼完全相同,只是我在代碼的早期創建了JTextField,並在創建水平膠後將其添加到菜單欄中。出於某種原因,在創建膠水之後創建並添加膠水會使其工作。任何人都可以解釋爲什麼這是? – drewmoore 2013-03-06 08:48:53

+0

arrggg ...這仍然是_hard-coding_對當前pref的最大值,對於所有已知的原因,這是一個**錯誤的想法。相反,重寫並讓getMax返回getPref – kleopatra 2013-03-07 15:40:40

3

我的解決方案與camickr的類似,但不需要setMaximumSize()。不是我反對它,但我知道那裏有狂熱者,他們發誓說「永遠不要打電話setXxxsize()永遠!!!」我不是其中之一,但他們在外面。

無論如何,我會使用GridBagLayout製作一個JPanel,並將JTextField填充爲NONE,並將Box.createHorizo​​ntalGlue()填充爲HORIZONTAL。然後,把這個面板放在你的菜單欄中。

編輯:

爲了完整起見,這裏使用的JPanel的解決方案W/O不必調用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)如果去面板路由,使用BorderLayout的camickr的建議(見下面的註釋)不僅可以工作,而且更簡單的代碼。 3)另外,正如camickr指出的那樣,使用面板會影響「膠水」區域的外觀。它像JPanel而不是JMenuBar一樣被繪製。老實說,我甚至沒有注意到它在我的機器上(使用Metal L & F),直到他提到它,但它是不同的,可能是一個不受歡迎的副作用。

+0

@ camickr的方法不違反原則,因爲它依賴['getPreferredSize()'](http://stackoverflow.com/q/7229226/230513)。 – trashgod 2013-03-06 06:36:38

+1

@trashgod:我認爲它確實違反了「無原則」,原因有二:(1)它將最大值設置爲ONCE,這意味着如果pref大小稍後改變,則max不會。 (2)索賠是「從不」。正如「永遠不會有過」(正如我所看到的那樣)。沒有資格或例外,這就是爲什麼我基本不同意這種絕對。相反,如果它是「強烈推薦的指導方針」,那麼我會同意。只是我的2c。 – splungebob 2013-03-06 14:39:05

+0

你是正確的任何使用'setMaximumSize()'都應該仔細檢查是否有意外的後果。 +1替代。 – trashgod 2013-03-06 15:17:17

相關問題