2012-06-05 105 views
3

我在代碼中生成一些JComponents並使用GridBag佈局來排列它們。我的佈局由12行和3列組成,每行由JSlider,JCheckBox和JLabel組成。下面的代碼我用生成UI:如何在文本更改時阻止JLabel更改其大小?

final int NUM_MOTORS = 12; 

// This is the panel I'm adding the components to. 
pnlMotorSliders.setLayout(new GridBagLayout()); 
GridBagConstraints c = new GridBagConstraints(); 

for (int i = 0; i < NUM_MOTORS; ++i) { 
    c.gridy = i; 

    // Create the slider 
    JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 10, 4085, 10); 
    c.fill = GridBagConstraints.HORIZONTAL; 
    c.gridx = 0; 
    c.weightx = 0.9; 
    pnlMotorSliders.add(slider, c); 

    // Create the checkbox 
    JCheckBox checkBox = new JCheckBox(); 
    checkBox.setOpaque(true); 
    checkBox.setBackground(Color.blue); 
    c.fill = GridBagConstraints.NONE; 
    c.gridx = 1; 
    c.weightx = 0.1; 
    pnlMotorSliders.add(checkBox, c); 

    // Create the current label 
    JLabel label = new JLabel("0"); 
    label.setBorder(BorderFactory.createLineBorder(Color.red)); 
    c.fill = GridBagConstraints.HORIZONTAL; 
    c.gridx = 2; 
    c.weightx = 0.2; 
    pnlMotorSliders.add(label, c); 
} 

我遇到的問題是,當我設置在任何的JLabel的文本,他們改變寬度和影響佈局的其餘部分,即使我設置的文本的寬度看起來比JLabel的寬度小得多。下面的兩個屏幕截圖展示了我的意思(紅色和藍色的邊框是用於調試):

The layout before changing the JLabel text.

The layout after changing the bottom JLabel text. Notice how the label has gotten bigger.

我設置文本底部的JLabel爲「-12」。儘管JLabel看起來比文本寬得多,但它已經改變了它的大小,影響了其餘的佈局。

爲什麼會發生這種情況,我該怎麼做才能防止它發生?

+0

如果您防止標籤擴展以適應其文本,則可能會變得無法閱讀;更多[這裏](http://stackoverflow.com/q/7229226/230513)。 – trashgod

回答

5

您可以通過設置最低,者優先和最大尺寸固定標籤的大小:

label.setMinimumSize(width, height); 
label.setPreferedSize(width, height); 
label.setMaximumSize(width, height); 

還要確保設置的GridBagConstraints#填到無,但我不知道這仍然是必要的(我認爲是)。

編輯:順便說一句,擺脫圍繞焦點的組件那些討厭的虛線,你可以將其設置爲不可作爲焦點:

slider.setFocusable(false); 
+0

謝謝,這似乎工作。我嘗試了一下,發現我只需要調用setPreferredSize來設置JLabel的大小。另外兩個似乎沒有區別。另外,感謝setFocusable上的提示。我現在的問題是爲什麼我首先面對這個問題?使用我的原始佈局,標籤比需要的寬度更寬,但文本更改後仍會更改寬度,即使文本明顯比標籤小得多。 –

+0

@AmrBekhit是的,如果有可用空間,setPreferredSize就足夠了。但是,如果不是,其他組件將把它拿​​走,標籤將被迫變小(或更大)。但對於你的應用程序,我想setPreferredSize就足夠了。它改變的原因是,如果未設置,標​​籤的首選大小取決於所顯示的文本。順便說一句:'label.setHorizo​​ntalAlignment(JLabel.RIGHT);'也很有幫助。 ;) – brimborium

+0

如果它不是可調焦的,你如何從鍵盤調整它? –

0

明確地設置使用JLabel#setPreferredSize(Dimension)首選大小的標籤。

這樣,你組件的大小,並告訴佈局管理器不要調整它的大小。

+0

這似乎並不奏效。生成標籤時,我添加了以下行:'label.setSize(new Dimension(50,label.getPreferredSize()。height));'並將GridBag Fill設置爲NONE。不幸的是,標籤會忽略我的尺寸,使用默認尺寸並在文字更改時更改其寬度。我試圖在將它添加到父容器之前和之後設置標籤大小。 –

+0

我已編輯原始答案。做了一些編碼,似乎只是設置'preferredSize'就足夠了(不管fill的值是多少)。檢查它是否適用於您,如果您需要,我會發布一些代碼。 – npe

+0

不,不管什麼問題,[調整組件的大小提示是不是一個解決方案](http://stackoverflow.com/a/7229519/203657)...而是,使用體面的LayoutManager – kleopatra

1

的設置的首選尺寸解決方案僅當您沒有將組件水平地填充到GridBagLayout中。

另一種解決方法是刪除已放置在GridBagLayout該列中組件上的重量。然後您可以手動控制列寬。這樣做的一個簡單方法(在設計時)是將JLabel放置在零高度和您希望的特定寬度的列中。

這是爲什麼?您需要深入瞭解GridBagLayout的工作方式:

GridBagLayout根據所需的空間調整列的大小,然後使用權重分配「剩餘」空間,以便生成的列寬合計爲總寬度的面板。每列所需的空間是通過查找該列中最寬的組件來計算的。

每個組件所需的空間是通過詢問它希望的寬度來確定的。在你的情況下,帶有「0」的JLabel小於帶有「-12」的JLabel,因此列正在改變大小。

剩餘空間是根據分配給每列中組件的水平權重分配的。合計權重,並根據該欄的總數百分比確定每欄的百分比。

列大小根據所需的空間PLUS剩餘空間確定。因此,如果列中的所有組件都沒有重量,那麼您將不會留下任何空間,因此不會進行動態更改。

第三個解決方案是不使用GridBagLayout。

相關問題