使用 GridBagLayout 将 jButton 相对于 JTable 水平居中

centering jButton horizontally in relation to JTable with GridBagLayout

我有一个 JTable,我在它下面放了 3 个 JButton。我设法将左按钮放在左角,将右按钮放在右角,但我不知道如何将中间按钮放在中间。我已经尝试使用 .weightx.anchor 但没有任何结果。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class AccessView extends JPanel{
  String[] columnNames = {"Date","Time","Type of access"};
  DefaultTableModel tableModel;
  JTable tAccesses;
  JScrollPane scrollPane;
  JButton bAdd, bMod, bDel;

  public AccessView(){
    createGUI();
  }

   public void createGUI(){
    this.setBorder(BorderFactory.createTitledBorder("Accesses"));
    this.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    bAdd = new JButton("Add");
    bMod = new JButton("Mod");
    bDel = new JButton("Del");

    tableModel = new DefaultTableModel(25,columnNames.length);
    tableModel.setColumnIdentifiers(columnNames);   
    tAccesses = new JTable(tableModel);
    scrollPane = new JScrollPane(tAccesses);

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    this.add(scrollPane, c);

    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    c.anchor = GridBagConstraints.LAST_LINE_START;
    this.add(bAdd, c);

    c.gridx = 1;
    c.gridy = 1;
    this.add(bMod, c);

    c.gridx = 2;
    c.gridy = 1;
    c.anchor = GridBagConstraints.LAST_LINE_END;
    this.add(bDel, c);
  }  
}

有一些方法可以做到这一点:

  • 因为你扩展了 JPanel 并且整个 GridBagLayout 面板,您可以为按钮添加额外的行。看起来像 table Web 中的布局 - 确实如此。有正有反 使用 table 布局。主要缺点是很难在长期项目中维护。特别是,您不能在其他地方重复使用按钮。
  • 您可以按照@Izruo 的建议创建带有按钮的附加面板。关键功能是您可以轻松地将此面板从网格的底部移动到左侧,添加到另一个类似的 panel/menu 等。最简单的 FlowLayout 就足够了。创建 ButtonPanel 后,您可以
    • 将其添加到您的网格中。它比 table-only layout
    • 稍微好一点
    • 创建 CompositePanel,它将包含 GridPanelButtonPanel

学习 Oracle tutorial 我注意到最后一个选项更可取。根据我的个人经验,这是最佳做法

如以上评论中所建议,您可以使用另一个 JPanel 作为 3 JButton

JPanel 使用 BoxLayout,每个 JButton 之间将包含 3 个 JButtonBox.createHorizontalGlue(),您可以获得以下输出:

在这种情况下:

  1. 新建一个JPanel

    JPanel buttonsPane;
    
  2. 对其进行初始化并将其布局设置为BoxLayout

    buttonsPane = new JPanel();
    buttonsPane.setLayout(new BoxLayout(buttonsPane, BoxLayout.LINE_AXIS));
    
  3. 添加按钮以及它们之间的 Box.createHorizontalGlue()

    buttonsPane.add(bAdd);
    buttonsPane.add(Box.createHorizontalGlue());
    buttonsPane.add(bMod);
    buttonsPane.add(Box.createHorizontalGlue());
    buttonsPane.add(bDel);
    
  4. buttonsPane 添加到您的 JFrameSOUTH 对齐中(或将其与当前的 JPanel 一起添加并编辑其约束(我用的是前者)):

    frame.add(this);
    frame.add(buttonsPane, BorderLayout.SOUTH);
    

获得类似结果的另一种方法(根据下面的@MadProgrammer 评论)是更改约束并在 JButton 之间添加 "empty" 组件:

c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.weightx = 1;
this.add(bAdd, c);

c.gridx = 1;
this.add(new JLabel(""), c); //Empty component just for the extra space

c.gridx = 2;
this.add(bMod, c);

c.gridx = 3;
this.add(new JLabel(""), c); //Empty component just for the extra space

c.gridx = 4;
this.add(bDel, c);

产生: