2016-11-10 69 views
0

我有一個JDialog,其中有一列我想要居中JLabel的列。我似乎無法找到如何做到這一點。我可以將它居中在一個單元格中,但不在一組跨列的列中。此圖像中的標籤「目標」和「更改」需要居中。 Time Line Settings使用GridBagLayout居中橫跨列

這是生成此JDialog的SSCCE。

package stokerMonitor; 

import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.Dialog.ModalityType; 

import javax.swing.JDialog; 
import javax.swing.JLabel; 
import javax.swing.JSeparator; 
import javax.swing.SwingConstants; 


public class test { 

static JDialog timeLineDialog; 
static int row=0; 

public static void main(String[] args) { 
    timeLineDialog = new JDialog(); 
    timeLineDialog.setLayout(new GridBagLayout()); 
    timeLineDialog.setModalityType(ModalityType.MODELESS); 
    timeLineDialog.setTitle("Time Line Settings"); 
    timeLineDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
    JLabel timeLabel = new JLabel("Time"); 
    JLabel actionLabel = new JLabel("Action"); 
    JLabel probeTempLabel=null; 
    JLabel pitTempLabel=null; 
    JLabel targetHeader=new JLabel("Target"); 
    Font boldFont=targetHeader.getFont().deriveFont(Font.BOLD, (float) 14); 
    targetHeader.setFont(boldFont); 
    JLabel changeHeader=new JLabel("Change"); 
    changeHeader.setFont(boldFont); 
    if (Configuration.getInstance().celsius) { 
     probeTempLabel = new JLabel("Temp (\u00B0 C)"); 
     pitTempLabel = new JLabel("Temp (\u00B0 C)"); 
    } 
    else { 
     probeTempLabel = new JLabel("Temp (\u00B0 F)"); 
     pitTempLabel = new JLabel("Temp (\u00B0 F)"); 
    } 
    JLabel meatLabel=new JLabel("Meat"); 
    JLabel cookTimeLabel=new JLabel("Est. Time"); 
    JLabel weightLabel=new JLabel("Weight"); 
    JLabel probeLabel=new JLabel("Probe"); 
    JLabel pitLabel=new JLabel("Pit"); 
    setNewSeparator(1,row); 
    GridBagConstraints gbc=makeGbc(2, row); 
    gbc.gridwidth=7; 
    gbc.fill=GridBagConstraints.HORIZONTAL; 
    gbc.anchor=GridBagConstraints.CENTER; 
    timeLineDialog.add(targetHeader,gbc); 
    setNewSeparator(9,row); 
    timeLineDialog.add(changeHeader,makeGbc(10, row)); 
    setNewSeparator(12,row++); 
    setNewSeparator(1,row); 
    timeLineDialog.add(timeLabel, makeGbc(2, row)); 
    timeLineDialog.add(probeTempLabel,makeGbc(3, row)); 
    timeLineDialog.add(meatLabel,makeGbc(4, row)); 
    timeLineDialog.add(weightLabel,makeGbc(5, row)); 
    timeLineDialog.add(cookTimeLabel,makeGbc(6, row)); 
    timeLineDialog.add(probeLabel,makeGbc(7, row)); 
    timeLineDialog.add(actionLabel, makeGbc(8, row)); 
    setNewSeparator(9,row); 
    timeLineDialog.add(pitLabel,makeGbc(10, row)); 
    timeLineDialog.add(pitTempLabel, makeGbc(11, row++)); 
    setNewSeparator(12,row); 
    timeLineDialog.pack(); 
    timeLineDialog.setLocationRelativeTo(GUI.getInstance().getFrame()); 
    timeLineDialog.setVisible(true); 
} 

static void setNewSeparator(int column_,int row_) { 
    JSeparator sep=new JSeparator(SwingConstants.VERTICAL); 
    sep.setPreferredSize(new Dimension(1,1)); 
    GridBagConstraints gbc=makeGbc(column_, row_); 
    gbc.fill=GridBagConstraints.VERTICAL; 
    gbc.weighty=1.; 
    timeLineDialog.add(sep,gbc); 
} 

static GridBagConstraints makeGbc(int x, int y) { 
     GridBagConstraints gbc = new GridBagConstraints(); 
     Insets WEST_INSETS=new Insets(5,0,5,5); 
     Insets EAST_INSETS=new Insets(5,5,5,0); 
     gbc.gridx = x; 
     gbc.gridy = y; 
     gbc.gridwidth = 1; 
     gbc.gridheight = 1; 

     gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST; 
     gbc.fill = (x == 0) ? GridBagConstraints.BOTH 
      : GridBagConstraints.HORIZONTAL; 

     gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS; 
     gbc.weightx = (x == 0) ? 0.1 : 1.0; 
     gbc.weighty = 1.0; 
     return gbc; 
    } 
} 

有人可以解釋我需要做什麼來居中這些標題嗎? TIA。

+0

使用[gridwidth](http://docs.oracle.com/javase/8/docs/api/java/awt/GridBagConstraints.html#gridwidth)大於1跨越多個列。 – VGR

+1

@VGR他已經有'gridwidth = 7',至少對於'targetHeader'。 (我沒有看另一個) – dsh

回答

3

提示:調試佈局的時候,我發現它有用設置各個部件具有不同的背景顏色。然後,我可以看到由該特定組件分配/填充的區域。大多數組件默認爲透明背景,這意味着它們的邊界不可見。 (例如targetHeader.setOpaque(true); targetHeader.setBackground(Color.RED);

您在佈局中遇到的情況是JLabel會填充您指定的7列。但是,標籤本身會將其包含的文本繪製在其填充的空間的最左側部分。

有兩種可選方案:

  1. 告訴標籤,你想讓它居中標籤中的文字: targetHeader.setHorizontalAlignment(JLabel.CENTER);

  2. 或者,你可以告訴佈局填滿空間。 gbc.fill=GridBagConstraints.NONE;

+0

謝謝。我用gbc.fill = GridBagConstraints.NONE;那就是訣竅。我需要重新閱讀這些值,因爲它似乎與名稱所暗示的相反。 –

+0

GBC填充常量完全符合他們所說的內容。設置標籤的背景和不透明度以直觀地查看它。使用'fill = NONE',標籤不會填充單元格。用'fill = HORIZONTAL',那麼標籤會填充它;標籤只是從標籤所在區域的左側開始繪製文本(除非您另行設置標籤自己的水平對齊)。 GBC的錨僅在組件未填充時纔有意義,因爲如果組件填充了空間,那麼它不會影響組件的啓動位置。關鍵是各種屬性和價值之間的相互作用。 – dsh

+0

*「提示:在調試佈局時,我發現將每個組件設置爲不同的背景顏色非常有用。」*我將閱讀其餘的答案,但您會爲此付諸表決「教導一個人釣魚'發表評論。不錯的一個:)很多佈局問題歸咎於OP,假設一個組件不會被拉伸到一定的尺寸,或者佈局約束導致分配的列或行多於或少於預期分配。設置BG顏色應被視爲代碼中使用的佈局假設的一種「酸性測試」。 –

1

正如VGR在他的評論中所說的,你應該在約束中設置一個網格寬度,以便GridBagLayout更容易理解如何處理兩個頂級標籤。

我會將目標標籤的網格寬度設置爲7,並將更改標籤的網格寬度設置爲2.下面的所有標籤都應該設置爲1。

然後,當您設置GridBagConstraints.anchor = GridBagConstants.CENTER ;,它應該做你正在尋找的行爲。

編輯:我說的目標標籤到5,但我的意思是7