Swing中的布局控件简介

  布局控件主要用于将控件按指定的方式进行排列。在Swing中,有11种布局控件,相比之下Visual Studio(C#语言,下文简称VS)中的布局控件就要少的多。下面对Swing中的11种布局控件进行简要的说明。
在这里插入图片描述

Absolute layout

  Swing中有专门的绝对布局控件,所谓绝对布局,是指用户可以在任意位置放置任意大小的控件,绝对布局控件不会对控件做任何操作。VS中没有专门的布局控件,但是新建一个窗口(Form)后,用户可以在窗口的任意位置放置控件,相当于是任意布局了。Absolute layout中的坐标原点在控件左上角,这点与VS中的窗口坐标系相同。
在这里插入图片描述

FlowLayout

  FlowLayout控件按指定的规则顺序排列控件。该控件在Swing和VS中都存在,VS中的名称是FlowLayoutPanel,但是这两者间的规则不太一样。Swing中FlowLayout的排列方式有五种:LEFT(从左向右排列)、CENTER(居中排列)、RIGHT(从右向左排列)、LEADING(从容器的开始边方向开始排列)和TRAILING(从容器的结束边方向开始排列),而在VS中FlowLayout有四种排列方式:LeftToRight(从左向右)、TopDown(从上往下)、RightToLeft(从右向左)和BottomUp(从下往上)。
在这里插入图片描述

BorderLayout

  BorderLayout控件将界面划分为5个区域,每个区域只能放一个控件,VS中没有对应功能的布局控件。示例代码及程序示意图如下所示(代码来自参考文献2):

         JFrame jf=new JFrame("测试程序");
         jf.setSize(300,200);
         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         jf.setVisible(true);
         JPanel contentPane=new JPanel();
         jf.setContentPane(contentPane);
         JButton b1=new JButton("区域1");
         JButton b2=new JButton("区域2");
         JButton b3=new JButton("区域3");
         JButton b4=new JButton("区域4");
         JButton b5=new JButton("区域5");
         BorderLayout lay=new BorderLayout();
         jf.setLayout(lay);
         contentPane.add(b1,"North");
         contentPane.add(b2,"South");
         contentPane.add(b3,"East");
         contentPane.add(b4,"West");
         contentPane.add(b5,"Center");

在这里插入图片描述

GridLayout

  GridLayout将区域划分为m行n列的网格,每个小格的大小相同,且仅能放置一个控件,每个控件只能占据一个格子,无法横跨几个格子。VS中的TableLayoutPanel控件的功能像是GridLayout和GridLayout两个布局控件的组合。
在这里插入图片描述

GridBagLayout

  GridBagLayout是GridLayout的功能扩大版,除了每个格子可以放置一个控件外,控件还是横向、纵向占据多个格子。GraidBagLayout控件使用专门的类GridBagConstraints 来指定要添加的控件的位置及占用的格子数。也可以直接在WindowBuilder界面中用鼠标拖动控件到GridBagLayout中,然后选中控件,用拖拽的方式设置控件占用多少格子。

CardLayout

  CardLayout功能类似于VS中的TabControl,但是用法要比TabControl要复杂的多。理论来说,CardLayout将它包含的每个控件都在单独的卡片上显示,每个只显示一个卡片,这点类似于TabPage,但是TabPage上面可以随意的方式控件,而CardLayout要想达到类似的效果,应该首先方式JPanel控件,然后再在JPanel中随意放置控件。CardLayout控件使用比较麻烦,这里列出参考文献2中的示例代码,感兴趣的朋友可以在Eclipse中进行测试。

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class Test extends JFrame 
{
    private JPanel pane = null; // 主要的JPanel,该JPanel的布局管理将被设置成CardLayout
    private JPanel p = null; // 放按钮的JPanel
    private CardLayout card = null; // CardLayout布局管理器
    private JButton button_1 = null; // 上一步
    private JButton button_2 = null; // 下一步
    private JButton b_1 = null, b_2 = null, b_3 = null; // 三个可直接翻转到JPanel组件的按钮
    private JPanel p_1 = null, p_2 = null, p_3 = null; // 要切换的三个JPanel
    public Test() 
    {
        super("CardLayout Test");
        try 
        {
        	// 将LookAndFeel设置成Windows样式
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } 
        catch (Exception ex) 
        {
          ex.printStackTrace();
        }
        card = new CardLayout(5, 5); //创建一个具有指定的水平和垂直间隙的新卡片布局
        pane = new JPanel(card); // JPanel的布局管理将被设置成CardLayout
        p = new JPanel(); // 构造放按钮的JPanel
        button_1 = new JButton("< 上一步");
        button_2 = new JButton("下一步 >");
        b_1 = new JButton("1");
        b_2 = new JButton("2");
        b_3 = new JButton("3");
        b_1.setMargin(new Insets(2,2,2,2));
        b_2.setMargin(new Insets(2,2,2,2));
        b_3.setMargin(new Insets(2,2,2,2));
        p.add(button_1);
        p.add(b_1);
        p.add(b_2);
        p.add(b_3);
        p.add(button_2);
        p_1 = new JPanel();
        p_2 = new JPanel();
        p_3 = new JPanel();
        p_1.setBackground(Color.RED);
        p_2.setBackground(Color.BLUE);
        p_3.setBackground(Color.GREEN);
        p_1.add(new JLabel("JPanel_1"));
        p_2.add(new JLabel("JPanel_2"));
        p_3.add(new JLabel("JPanel_3"));
        pane.add(p_1, "p1");
        pane.add(p_2, "p2");
        pane.add(p_3, "p3");
         //下面是翻转到卡片布局的某个组件的动作事件处理,当单击某个普通按钮组件,就会触发出现下一个组件
        button_1.addActionListener(new ActionListener()
        { 
         /// 上一步的按钮动作
            public void actionPerformed(ActionEvent e) {
                card.previous(pane);
            }
        });
        button_2.addActionListener(new ActionListener()
        {
        // 下一步的按钮动作
            public void actionPerformed(ActionEvent e) {
                card.next(pane);
            }
        });
        b_1.addActionListener(new ActionListener() 
        {
        // 直接翻转到p_1
            public void actionPerformed(ActionEvent e) {
                card.show(pane, "p1");
            }
        });
        b_2.addActionListener(new ActionListener() 
        { 
        // 直接翻转到p_2
            public void actionPerformed(ActionEvent e) {
                card.show(pane, "p2");
            }
        });
        b_3.addActionListener(new ActionListener() 
        { 
         // 直接翻转到p_3
            public void actionPerformed(ActionEvent e) {
                card.show(pane, "p3");
            }
        });
        this.getContentPane().add(pane);
        this.getContentPane().add(p, BorderLayout.SOUTH);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(300, 200);
        this.setVisible(true);
    }
    public static void main(String[] args)
    {
        new Test();
    }    
}

在这里插入图片描述

BoxLayout

  VS中不存在箱式布局,这属于Swing中的布局方式。该布局的用法是使用Box类的createHorizontalBox函数和createVerticalBox函数创建水平箱和垂直箱,这两类箱都可以容纳控件,也可以相互容纳,开发者根据需要使用这两类箱的组合排列出需要的界面。Box类中还可以创建几类分隔器,用于分隔箱中的控件,主要有以下几类(类型说明来自参考文献6):

  • Rigid area 可以定义水平和垂直尺寸的透明组件,该类对象使用createRigidArea函数创建;
  • strut 与 rigid area 类似,但只能定义一个方向的尺寸,即水平方向或者垂直方向,不能同时定义水平和垂直尺寸,该类对象使用createHorizontalStrut或createVerticalStrut创建;
  • glue位于两个控件之间时,它会尽可能的占据两个控件之间的多余空间,从而将两个控件挤到两边,该类对象使createGlue、createHorizontalGlue或createVerticalGlue创建;

  BoxLayout的示例代码可以在参考文献2的第五章代码test9中获取,这里仅列出使用了BoxLayout控件的窗口示例截图。
在这里插入图片描述

SpringLayout

  SpringLayout的功能与VS中控件的Anchor属性类似,但是要更复杂,需要设置的属性更多。将控件的边分为EAST、WEST、SOUTH和NORTH,即东西南北四条边,使用putConstraint函数设置控件与控件间的距离,具体设置可以参考参考文献2和7。在WindowBuilder中,如果使用的是SpringLayout控件,选中的控件会自动显示与其它控件的距离设置,在控件的属性中有专门的Constraints属性,可以在面板中直接设置当前控件与其它控件的距离。
在这里插入图片描述

GroupLayout

  GroupLayout中将控件按组管理、按组排列展示。每个组可以包含任意数量的控件,其中元素有 Group、Component 或间隙 (gap)。该控件详细用法请参考参考文献8,本文仅列出参考文献2中的示例代码及运行结果截图。

import java.awt.Container;
import java.awt.HeadlessException;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Test extends JFrame 
{
	private static final long serialVersionUID = 1L;
	public Test() throws HeadlessException 
	{
	   Container c = getContentPane();//创建一个中间容器,并且创建一个GroupLayout布局管理器对象
	   GroupLayout layout = new GroupLayout(c);
	   JButton b1 = new JButton("按钮 1");//创建两个普通按钮组件、文本框组件
	   JButton b2 = new JButton("按钮 2");
	   JTextField text = new JTextField("文本"); 
	   GroupLayout.SequentialGroup hsg = layout.createSequentialGroup();//创建一个hsg组,将两个按钮一个一个的添加到组里面
	   hsg.addComponent(b1);
	   hsg.addComponent(b2);
	   GroupLayout.ParallelGroup hpg = 
	   layout.createParallelGroup(GroupLayout.Alignment.CENTER); //创建一个hpg组,将文本框组件和上面的那个组添加到其中,并且居中排列
	   hpg.addComponent(text).addGroup(hsg); 
	   layout.setHorizontalGroup(hpg); //沿水平线来确定hpg组中两个按钮组件的位置
	   GroupLayout.ParallelGroup vpg = layout.createParallelGroup();//创建一个vpg组,按照水平线来排列两个按钮组件的位置  
	   vpg.addComponent(b1); 
	   vpg.addComponent(b2); 
	   GroupLayout.SequentialGroup vsg = layout.createSequentialGroup();// 将文本框组件和前面的容纳两个按钮组件的组同时添加到vsg组中
	   vsg.addComponent(text).addGroup(vpg);
	   layout.setVerticalGroup(vsg); //沿垂直线来确定vsg中vpg和文本框组件的位置
	   this.setLayout(layout); 
	   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	   pack();
	}
	public static void main(String[] args) 
	{
		Test demo = new Test();
		demo.setVisible(true);
	}
}

在这里插入图片描述

FormLayout

  FormLayout与VS中的TableLayoutPanel控件功能最像,它功能强大、使用灵活,FormLayout使用时也将区域划分为m行n列的格子,但格子的大小可以不一致,每个控件可以放在一个或多个格子中。在WindowBuilder中,如果使用的是FormLayout控件,可以首先在Panel的属性Layout中设置行数和列数,然后鼠标拖拽控件到布局控件的某个格子上,然后根据需要拖拽控件占据一到多个格子的位置。详细使用方法可以参考文献9-12。
在这里插入图片描述

MigLayout

  MigLayout的功能与FormLayout类似,用起来稍微简单一些。可以在Panel的Layout属性中首先设置几行几列,然后将控件拖动到某个格子中,再选中控件,拖拽控件占据一到多个格子。具体的用法可以参考文献13-15。
在这里插入图片描述

参考文献:
[1]Java Swing图形界面开发与案例详解
[2]Java Swing图形界面开发与案例详解随书实例代码,http://www.okbase.net/file/item/19034
[3]JavaTM Platform Standard Edition 6 API 规范,http://tool.oschina.net/uploads/apidocs/jdk-zh/overview-summary.html
[4]JavaSwing_1.4: BoxLayout(箱式布局),https://blog.csdn.net/xietansheng/article/details/72814557
[5]运用 BoxLayout 进行 Swing 控件布局,https://www.ibm.com/developerworks/cn/java/j-lo-boxlayout/
[6]Java Swing组件BoxLayout布局用法示例,https://www.jb51.net/article/128319.htm
[7],Java SpringLayout布局(弹簧布局),https://blog.csdn.net/qq_36761831/article/details/81539307
[8]JavaSwing_1.5: GroupLayout(分组布局),https://blog.csdn.net/xietansheng/article/details/72862660
[9]swing的jgoodies FormLayout,https://www.iteye.com/blog/fansofjava-1144353
[10]https://www.formdev.com/jformdesigner/doc/layouts/formlayout/
[11]http://www.blogjava.net/javagui/archive/2007/11/24/FormLayout.html
[12]https://yq.aliyun.com/articles/377635
[13]https://blog.csdn.net/kungfu_star/article/details/9064083
[14]https://www.iteye.com/blog/icarusliu-1197336
[15]http://www.migcalendar.com/miglayout/whitepaper.html

发布了157 篇原创文章 · 获赞 102 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/gc_2299/article/details/102645664
今日推荐