2016-11-10 11 views
0

JLabel을 가운데 놓을 일련의 열이있는 JDialog가 있습니다. 나는 그것을하는 방법에 관해 무엇인가 발견 할 수 없을 것 같다. 셀 안에 배치 할 수는 있지만 스팬 된 열 집합에는 배치 할 수 없습니다. 이 이미지의 레이블 "Target"과 "Change"는 중앙에 위치해야합니다. Time Line SettingsGridBagLayout을 사용하여 스팬 된 열 중앙에 맞추기

다음은이 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

여러 열을 걸쳐 1보다 [gridwidth (http://docs.oracle.com/javase/8/docs/api/java/awt/GridBagConstraints.html#gridwidth)가 큰 사용한다. – VGR

+1

@VGR 그는 적어도'targetHeader'에 대해서'gridwidth = 7'을 이미 가지고 있습니다. (나는 다른 하나를 보지 않았다) – dsh

답변

3

팁 의미 : 레이아웃을 디버깅 할 때, 나는 그것이 유용한 다른 배경 색상을 가지고 각 구성 요소를 설정 찾을 수 있습니다. 그런 다음 해당 특정 구성 요소에 할당되거나 지정된 특정 영역을 볼 수 있습니다. 대부분의 구성 요소는 기본적으로 투명한 배경으로되어있어 경계가 표시되지 않습니다. (예 :)

레이아웃과 함께하는 상황은 JLabel이 지정한 7 개의 열을 채우는 것입니다. 그러나 레이블 자체는 포함 된 텍스트를 채우는 공간의 가장 왼쪽 부분에 그립니다. 당신이 하지에 레이아웃을 말할 수있는, 또는 targetHeader.setHorizontalAlignment(JLabel.CENTER);

  • :

    1. 당신이 레이블 내에서 텍스트를 가운데에 원하는 라벨을 알려주기 :

      는 두 개의 다른 솔루션이 있습니다 공간을 채우십시오. gbc.fill=GridBagConstraints.NONE;

  • +0

    고마워. gbc.fill = GridBagConstraints.NONE;을 사용했습니다. 그게 속임수 였어. 이름에서 알 수있는 것과는 반대되는 것으로 보이는 값을 다시 읽어야합니다. –

    +0

    GBC 채우기 상수는 정확히 무엇을 말합니다. 시각적으로 볼 수 있도록 레이블의 배경 및 불투명도를 설정하십시오. 'fill = NONE'으로 라벨은 셀을 채우지 않습니다. 'fill = HORIZONTAL'을 사용하면 레이블이 그것을 채 웁니다. 레이블은 레이블의 영역 왼쪽에서 시작하여 텍스트를 그립니다 (그렇지 않으면 레이블의 자체 수평 정렬을 설정하지 않는 한). GBC의 앵커는 구성 요소가 채워지지 않을 때만 의미가 있습니다. 구성 요소가 공간을 채우면 구성 요소가 시작되는 위치가 중요하지 않기 때문입니다. 열쇠는 다양한 속성과 값 사이의 상호 작용입니다. – dsh

    +0

    * 팁 : 레이아웃을 디버깅 할 때 각 구성 요소의 배경색을 다르게 설정하는 것이 유용하다는 것을 알았습니다. * 나머지 대답은 읽지 만, '사람에게 물고기를 가르쳐주세요. '가능한 코멘트.Nice one :) 많은 레이아웃 문제는 OP가 아닌 경우 컴포넌트가 크기로 늘어나거나 레이아웃 제약 사항이 예상보다 많거나 적은 열 또는 행이 할당되는 결과로 추정됩니다. BG 색상을 설정하는 것은 코드에서 사용 된 레이아웃 가정의 일종의 '산성 테스트'로 간주되어야합니다. –

    1

    VGR이 언급 한 바에 따르면 GridBagLayout이 두 개의 최상위 레이블을 쉽게 처리 할 수 ​​있도록하기 위해 제약 조건에 격자 폭을 설정해야합니다.

    대상 레이블에 대한 gridwidth를 7로 설정하고 변경 레이블에 대한 gridwidth를 2로 설정합니다. 아래의 모든 레이블은 1로 설정되어야합니다.

    GridBagConstraints.anchor = GridBagConstants.CENTER를 설정하면 찾고자하는 동작을 수행해야합니다.

    편집 : 나는 5 대상 레이블을했다,하지만 난 7