【问题标题】:BorderLayout, GridLayout, GridBagLayout? Which should I use?边框布局、网格布局、网格包布局?我应该使用哪个?
【发布时间】:2014-06-07 02:47:36
【问题描述】:

我正在尝试创建这个基本的 GUI,但无法正确设置我的面板。(数字是像素大小)

我尝试使用本教程作为参考 (http://www.youtube.com/watch?v=Kl3klve_rmQ),但是我的教程从来没有这样的效果。

我的代码在类的顶部声明变量,然后创建一个构造函数来添加组件(面板、按钮等),然后在 main 方法中调用构造函数。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

公共类 FinalProject 扩展 JPanel {

private static final long serialVersionUID = 1L;

static JPanel nav;
static JPanel queue;
static JPanel menu;

GridBagConstraints gbc = new GridBagConstraints();

public FinalProject() 
{

    nav = new JPanel();
    nav.setLayout(new GridBagLayout());
    nav.setBackground(Color.RED);
    gbc.gridy = 0;
    gbc.gridx = 0;
    gbc.gridheight = 1;
    gbc.gridwidth = 1;
    add(nav, gbc);

    queue = new JPanel();
    queue.setLayout(new GridBagLayout());
    queue.setBackground(Color.GREEN);
    gbc.gridy = 1;
    gbc.gridx = 1;
    gbc.gridheight = 1;
    gbc.gridwidth = 1;
    add(queue, gbc);

    menu = new JPanel();
    menu.setLayout(new GridBagLayout());
    menu.setBackground(Color.BLUE);
    gbc.gridy = 2;
    gbc.gridx = 2;
    gbc.gridheight = 1;
    gbc.gridwidth = 1;
    add(menu, gbc);
}

public static void main(String[] args) 
{       
    FinalProject p = new FinalProject();
    JFrame f = new JFrame();

    f.add(nav);
    f.add(queue);
    f.add(menu);

    f.setTitle("Subway");
    f.setSize(800, 500);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
    f.setResizable(false);
    f.add(p);
}

}

我应该如何让这个布局正确?面板中的面板、面板相互独立等?

【问题讨论】:

  • 我的建议:您最需要的是一个 BorderLayout,但话虽如此,我的主要建议是让您尝试一下,如果仍然有问题,请显示代码。否则,我们将很难猜测您可能做错了什么。
  • 我已经发布了我的代码 :)
  • 您只添加一个按钮...尝试添加其他按钮,一个在 NORTH,一个在中心。
  • .....................更好的尝试

标签: java swing jframe jpanel


【解决方案1】:

GridLayout我从来没有真正使用过,但我不确定它是否可以做到这一点。

BorderLayout 可以做到这一点,并且比GridBagLayout 更易于使用。

GridBagLayout 可以做到这一点。

一般来说,GridBagLayout 是最灵活的LayoutManagers 之一,非常值得学习,所以我建议在这里使用它来适应一个简单的情况,然后再需要它来处理更复杂的事情。

如果您熟悉 HTML,则可以将 GridBagLayout 视为 HTML 表格。

非常快 - 创建三个面板并设置大小/边框/您需要的任何内容。

在单元格 0,0 中添加一个,colspan 为 2。 在单元格 1,0 中添加一个 在单元格 1,1 中添加一个

之后你就完成了,尽管你可能想要指定调整大小/锚定/等行为。

【讨论】:

  • 我对 GridBagLayout 和 Constraints 有点熟悉。知道如何让 3 个面板按照我想要的方式与适当的约束对齐吗? css 做float: left,gridbag 里面有没有类似的东西?
  • 我将添加一个非常简短的摘要。
  • 我已经在上面发布了更新。我的框架上什么都没有显示,我认为我的 gridx 和 gridy 设置有点接近。
  • @MikeMilla:您没有将 JPanel 添加到 JFrame。
  • 我用 gridbag 添加了它们,但它仍然一团糟……只看到蓝色。
【解决方案2】:

不,不要为此使用 GridBagLayout,因为您将增加比实际需要的复杂性更多的复杂性。我自己,我尽量避免使用这种布局及其所有潜在的陷阱,通常您可以通过嵌套 JPanel 来获得所需的一切,每个 JPanel 都使用自己更简单的布局。例如这里,你只需要一个 BorderLayout:

  • 将顶部 JPanel 放在 BorderLayout.NORTH 位置
  • 将左侧 JPanel 置于 BorderLayout.WEST 位置
  • 将中心 JPanel 放在 BorderLayout.CENTER 位置。

就是这样。

再次,请查看 Swing 和布局管理器教程,因为那里提供了很好的信息。


编辑
请注意,您的 JFrame 上没有显示任何内容,因为您没有将 JPanel 添加到 JFrame!


编辑 2
例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;

import javax.swing.*;

public class SimpleLayout {
   private static final Color GREEN = new Color(200, 255, 200);
   private static final Color BLUE = new Color(200, 200, 255);

   private static void createAndShowGui() {
      JFrame frame = new JFrame("SimpleLayout");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      // note that a JFrame's contentPane uses BorderLayout by default
      frame.getContentPane().add(new ColorPanel(Color.pink, 800, 80), BorderLayout.NORTH);
      frame.getContentPane().add(new ColorPanel(GREEN, 300, 420), BorderLayout.WEST);
      frame.getContentPane().add(new ColorPanel(BLUE, 500, 420), BorderLayout.CENTER);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ColorPanel extends JPanel {
   private static final float FONT_POINTS = 24f;
   private int prefW;
   private int prefH;

   public ColorPanel(Color color, int prefW, int prefH) {
      setBackground(color);
      this.prefW = prefW;
      this.prefH = prefH;

      // GBL can be useful for simply centering components
      setLayout(new GridBagLayout()); 
      String text = String.format("%d x %d", prefW, prefH);
      JLabel label = new JLabel(text, SwingConstants.CENTER);
      label.setFont(label.getFont().deriveFont(FONT_POINTS));
      label.setForeground(Color.gray);
      add(label);
   }



   @Override
   public Dimension getPreferredSize() {
      return new Dimension(prefW, prefH);
   }
}

这显示为:

【讨论】:

  • 我添加了它们,但现在一切都是蓝色的。我已经尝试过这个边界布局,但是使用 gridbag 我至少可以显示一些东西。
  • 哇,谢谢。获取标签名称的非常​​聪明的方法。