Java 带网格布局的对中跨柱

Java 带网格布局的对中跨柱,java,swing,layout-manager,gridbaglayout,jdialog,Java,Swing,Layout Manager,Gridbaglayout,Jdialog,我有一个JDialog,其中有一系列列,我想在这些列上居中放置一个JLabel。我似乎找不到任何关于如何做到这一点的信息。我可以在单元格中居中,但不能在跨列集合中居中。此图像中的标签“目标”和“更改”需要居中。 下面是生成此JDialog的SSCCE package stokerMonitor; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.aw

我有一个JDialog,其中有一系列列,我想在这些列上居中放置一个JLabel。我似乎找不到任何关于如何做到这一点的信息。我可以在单元格中居中,但不能在跨列集合中居中。此图像中的标签“目标”和“更改”需要居中。

下面是生成此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。

正如VGR在评论中所说,您应该在约束中设置gridwidth,以便GridBagLayout更容易理解如何处理两个顶部标签

我将目标标签的gridwidth设置为7,更改标签的gridwidth设置为2。下面的所有标签都应设置为一个

然后,当您设置GridBagConstraints.anchor=GridBagConstants.CENTER;,它应该做你正在寻找的行为


编辑:我说的目标标签是5,但我的意思是7。

正如VGR在评论中所说的,您应该在约束中设置gridwidth,以便GridBagLayout更容易理解如何处理两个顶部标签

我将目标标签的gridwidth设置为7,更改标签的gridwidth设置为2。下面的所有标签都应设置为一个

然后,当您设置GridBagConstraints.anchor=GridBagConstants.CENTER;,它应该做你正在寻找的行为


编辑:我说的目标标签是5,但我的意思是7。

提示:调试布局时,我发现将每个组件设置为不同的背景色很有用。然后我可以看到指定给该特定组件/由该组件填充的区域。大多数组件默认为透明背景,这意味着它们的边界不可见。(例如
targetHeader.setOpaque(true);targetHeader.setBackground(Color.RED);

布局的情况是JLabel会填充指定的7列。但是,标签本身会绘制它所填充空间最左侧的文本

有两种替代解决方案:

  • 告诉标签您希望它将文本置于标签的中心:
    targetHeader.setHorizontalAlignment(JLabel.CENTER)

  • 或者,您可以告诉布局不要填充空间。
    gbc.fill=GridBagConstraints.NONE


  • 提示:调试布局时,我发现将每个组件设置为具有不同的背景色很有用。然后我可以看到指定给该特定组件/由该组件填充的区域。大多数组件默认为透明背景,这意味着它们的边界不可见。(例如
    targetHeader.setOpaque(true);targetHeader.setBackground(Color.RED);

    布局的情况是JLabel会填充指定的7列。但是,标签本身会绘制它所填充空间最左侧的文本

    有两种替代解决方案:

  • 告诉标签您希望它将文本置于标签的中心:
    targetHeader.setHorizontalAlignment(JLabel.CENTER)

  • 或者,您可以告诉布局不要填充空间。
    gbc.fill=GridBagConstraints.NONE


  • 使用大于1的值来跨越多列。@VGR他已经有了
    gridwidth=7
    ,至少对于
    targetHeader
    。(我没有看另一个)使用大于1的值来跨多列。@VGR他已经有了
    gridwidth=7
    ,至少对于
    targetHeader
    。(我没有看另一个)谢谢。我使用了gbc.fill=GridBagConstraints.NONE;这就成功了。我需要重新读取这些值,因为它似乎与名称的含义相反。GBC fill常量完全按照它们所说的做。设置标签的背景和不透明度以使其可见。如果
    fill=NONE
    ,则标签不会填充单元格。使用
    fill=HORIZONTAL
    ,则标签会填充它;标签仅从标签所在区域的左侧开始绘制文本(除非您另外设置标签自身的水平对齐方式)。GBC的锚只有在组件未填充时才有意义,因为如果组件填充了空间,那么组件从何处开始并不重要。关键是各种属性和值之间的相互作用。“提示:在调试布局时,我发现将每个组件设置为不同的背景色很有用。”我将阅读您的其余答案,但您会对“教人钓鱼”启用注释投赞成票。很好的一点:)许多布局问题都归结为OP,假设组件在没有拉伸时会拉伸到相应的大小,或者布局约束导致分配的列或行比预期的多或少。设置BG颜色应视为对代码中使用的布局假设的一种“酸性测试”。谢谢。我使用了gbc.fill=GridBagConstraints.NONE;这就成功了。我需要重新读取这些值,因为它似乎与名称的含义相反。GBC fill常量完全按照它们所说的做。设置标签的背景和不透明度以使其可见。如果
    fill=NONE
    ,则标签不会填充单元格。使用
    fill=HORIZONTAL
    ,则标签会填充它;标签仅从标签所在区域的左侧开始绘制文本(除非您另外设置标签自身的水平对齐方式)。GBC的锚只有在组件未填充时才有意义,因为如果组件填充了空间,那么组件从何处开始并不重要。关键是各种属性和值之间的相互作用。“提示:在调试布局时,我发现将每个组件设置为不同的背景色很有用。”我将阅读您的其余答案,但您会对“教人钓鱼”启用注释投赞成票。很好的一个:)许多布局问题归结到OP,假设组件将被拉伸