快捷搜索:  汽车  科技

java图形化界面开发笔记(Java-GUI编程之布局类型)

java图形化界面开发笔记(Java-GUI编程之布局类型)Window:Container作为容器根类,提供了如下方法来访问容器中的组件AWT中还有一个非常重要的接口叫LayoutManager ,如果一个容器中有多个组件,那么容器就需要使用LayoutManager来管理这些组件的布局方式。 Container继承体系:Component作为基类,提供了如下常用的方法来设置组件的大小、位置、可见性等。

java使用AWT和Swing相关的类可以完成图形化界面编程,其中AWT的全称是抽象窗口工具集(Abstract Window Toolkit) 它是sun公司最早提供的GUI库,这个GUI库提供了一些基本功能,但这个GUI库的功能比较有限,所以后来sun公司又提供了Swing库。通过使用AWT和Swing提供的图形化界面组件库,java的图形化界面编程非常简单,程序只需要依次创建所需的图形组件,并以合适的方式将这些组件组织在一起,就可以开发出非常美观的用户界面。

AWT简介

当 JDK 1.0发布时, Sun 提供了 一套基本的GUI类库,这个GUI类库希望可以在所有平台下都能运行 ,这套基本类库被称为"抽象窗口工具集 CAbstract Window Toolkit )",它为Java应用程序提供了基本的图形组件 。AWT是窗口框架,它从不同平台的窗口系统中抽取出共同组件 , 当程序运行时,将这些组件的创建和动作委托给程序所在的运行平台 。简而言之 ,当使用 AWT 编写图形界面应用 时,程序仅指定了界面组件的位置和行为,并未提供真正的实现,JVM调用操作系统本地的图形界面来创建和平台 一致的对等体 。

使用AWT创建的图形界面应用和所在的运行平台有相同的界面风格 ,比如在 Windows 操作系统上,它就表现出 Windows 风格 ; 在 UNIX 操作系统上,它就表现出UNIX 风格 。Sun 希望采用这种方式来实现 " Write Once Run Anywhere " 的目标 。

AWT继承体系
  • Component:代表一个能以图形化方式显示出来,并可与用户交互的对象,例如 Button 代表一个按钮,TextField 代表 一个文本框等;
  • MenuComponent:则代表图形界面的菜单组件,包括 MenuBar (菜单条)、 Menultem (菜单项)等子类。

java图形化界面开发笔记(Java-GUI编程之布局类型)(1)

其中 Container 是一种特殊的 Component,它代表一种容器,可以盛装普通的 Component。

AWT中还有一个非常重要的接口叫LayoutManager ,如果一个容器中有多个组件,那么容器就需要使用LayoutManager来管理这些组件的布局方式。

java图形化界面开发笔记(Java-GUI编程之布局类型)(2)

Container容器

Container继承体系:

java图形化界面开发笔记(Java-GUI编程之布局类型)(3)

  • Winow是可以独立存在的顶级窗口 默认使用BorderLayout管理其内部组件布局;
  • Panel可以容纳其他组件,但不能独立存在,它必须内嵌其他容器中使用,默认使用FlowLayout管理其内部组件布局;
  • ScrollPane 是 一个带滚动条的容器,它也不能独立存在,默认使用 BorderLayout 管理其内部组件布局;
常见API

Component作为基类,提供了如下常用的方法来设置组件的大小、位置、可见性等。

java图形化界面开发笔记(Java-GUI编程之布局类型)(4)

Container作为容器根类,提供了如下方法来访问容器中的组件

java图形化界面开发笔记(Java-GUI编程之布局类型)(5)

容器演示

Window:

java图形化界面开发笔记(Java-GUI编程之布局类型)(6)

import java.awt.*; public class FrameDemo { public static void main(String[] args) { //1.创建窗口对象 Frame frame = new Frame("这是第一个窗口容器"); //设置窗口的位置和大小 frame.setBounds(100 100 500 300); //设置窗口可见 frame.setVisible(true); } }Panel

java图形化界面开发笔记(Java-GUI编程之布局类型)(7)

import java.awt.*; public class PanelDemo { public static void main(String[] args) { //1.创建Frame容器对象 Frame frame = new Frame("这里在测试Panel"); //2.创建Panel容器对象 Panel panel = new Panel(); //3.往Panel容器中添加组件 panel.add(new TextField("这是一个测试文本")); panel.add(new Button("这是一个测试按钮")); //4.把Panel添加到Frame中 frame.add(panel); //5.设置Frame的位置和大小 frame.setBounds(30 30 500 300); //6.设置Frame可见 frame.setVisible(true); } }ScrollPane

java图形化界面开发笔记(Java-GUI编程之布局类型)(8)

import java.awt.*; public class ScrollPaneDemo { public static void main(String[] args) { //1.创建Frame窗口对象 Frame frame = new Frame("这里测试ScrollPane"); //2.创建ScrollPane对象,并且指定默认有滚动条 ScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); //3.往ScrollPane中添加组件 scrollPane.add(new TextField("这是测试文本")); scrollPane.add(new Button("这是测试按钮")); //4.把ScrollPane添加到Frame中 frame.add(scrollPane); //5.设置Frame的位置及大小 frame.setBounds(30 30 500 300); //6.设置Frame可见 frame.setVisible(true); } }

程序命名向 ScrollPane 容器中添加了 一个文本框和一个按钮,但只能看到 一个按钮,却看不到文本框 ,这是为什么 呢?这是因为ScrollPane 使用 BorderLayout 布局管理器的缘故,而 BorderLayout 导致了该容器中只有一个组件被显示出来 。

4LayoutManager布局管理器

之前,我们介绍了Component中有一个方法 setBounds() 可以设置当前容器的位置和大小,但是我们需要明确一件事,如果我们手动地为组件设置位置和大小的话,就会造成程序的不通用性,例如:

Label label = new Label("你好,世界");

创建了一个lable组件,很多情况下,我们需要让lable组件的宽高和“你好,世界”这个字符串自身的宽高一致,这种大小称为最佳大小。由于操作系统存在差异,例如在windows上,我们要达到这样的效果,需要把该Lable组件的宽和高分别设置为100px 20px 但是在Linux操作系统上,可能需要把Lable组件的宽和高分别设置为120px,24px,才能达到同样的效果。

如果要让我们的程序在不同的操作系统下,都有相同的使用体验,那么手动设置组件的位置和大小,无疑是一种灾难,因为有太多的组件,需要分别设置不同操作系统下的大小和位置。为了解决这个问题,Java提供了LayoutManager布局管理器,可以根据运行平台来自动调整组件大小,程序员不用再手动设置组件的大小和位置了,只需要为容器选择合适的布局管理器即可。

java图形化界面开发笔记(Java-GUI编程之布局类型)(9)

FlowLayout

在 FlowLayout 布局管理器 中,组件像水流一样向某个方向流动 (排列) ,遇到障碍(边界)就折回,重头开始排列 。在默认情况下, FlowLayout 布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。

java图形化界面开发笔记(Java-GUI编程之布局类型)(10)

FlowLayout 组件的排列方向(从左向右、从右向左、从中间向两边等) , 该参数应该使用FlowLayout类的静态常量 : FlowLayout. LEFT 、 FlowLayout. CENTER 、 FlowLayout. RIGHT ,默认是左对齐。

FlowLayout 中组件中间距通过整数设置,单位是像素,默认是5个像素。

代码演示:

java图形化界面开发笔记(Java-GUI编程之布局类型)(11)

import java.awt.*; public class FlowLayoutDemo { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试FlowLayout"); //2.修改Frame容器的布局管理器为FlowLayout frame.setLayout(new FlowLayout(FlowLayout.LEFT 20 20)); //3.往Frame中添加100个button for (int i = 0; i < 100; i ) { frame.add(new Button("按钮" i)); } //4.设置Frame为最佳大小 frame.pack(); //5.设置Frame可见 frame.setVisible(true); } }BorderLayout

BorderLayout 将容器分为 EAST 、 SOUTH 、 WEST 、 NORTH 、 CENTER五个区域,普通组件可以被放置在这 5 区域的任意一个中 。BorderLayout布局 管理器的布局示意图如图所示 。

java图形化界面开发笔记(Java-GUI编程之布局类型)(12)

当改变使用 BorderLayout 的容器大小时, NORTH 、 SOUTH 和 CENTER区域水平调整,而 EAST 、 WEST 和 CENTER 区域垂直调整。使用BorderLayout 有如下两个注意点:

  1. 当向使用 BorderLayout 布局管理器的容器中添加组件时 , 需要指定要添加到哪个区域中 。如果没有指定添加到哪个区域中,则默认添加到中间区域中;
  2. 如果向同一个区域中添加多个组件时 , 后放入的组件会覆盖先前放入的组件;

java图形化界面开发笔记(Java-GUI编程之布局类型)(13)

代码演示1:

java图形化界面开发笔记(Java-GUI编程之布局类型)(14)

import java.awt.*; public class BorderLayoutDemo1 { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试BorderLayout"); //2.指定Frame对象的布局管理器为BorderLayout frame.setLayout(new BorderLayout(30 5)); //3.往Frame指定东南西北中各添加一个按钮组件 frame.add(new Button("东侧按钮") BorderLayout.EAST); frame.add(new Button("西侧按钮") BorderLayout.WEST); frame.add(new Button("南侧按钮") BorderLayout.SOUTH); frame.add(new Button("北侧按钮") BorderLayout.NORTH); frame.add(new Button("中间按钮") BorderLayout.CENTER); //4.设置Frame为最佳大小 frame.pack(); //5.设置Frame可见 frame.setVisible(true); } }

如果不往某个区域中放入组件,那么该区域不会空白出来,而是会被其他区域占用

代码演示2:

java图形化界面开发笔记(Java-GUI编程之布局类型)(15)

import java.awt.*; public class BorderLayoutDemo2 { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试BorderLayout"); //2.指定Frame对象的布局管理器为BorderLayout frame.setLayout(new BorderLayout(30 5)); //3.往Frame指定南,北,放入一个按钮,往中间区域放入一个Panel frame.add(new Button("南侧按钮") BorderLayout.SOUTH); frame.add(new Button("北侧按钮") BorderLayout.NORTH); Panel panel = new Panel(); panel.add(new TextField("测试文本")); panel.add(new Button("中间按钮")); frame.add(panel BorderLayout.CENTER); //4.设置Frame为最佳大小 frame.pack(); //5.设置Frame可见 frame.setVisible(true); } }2.4.3 GridLayout

GridLayout 布局管理器将容器分割成纵横线分隔的网格 , 每个网格所占的区域大小相同。当向使用 GridLayout 布局管理器的容器中添加组件时, 默认从左向右、 从上向下依次添加到每个网格中 。与 FlowLayout不同的是,放置在 GridLayout 布局管理器中的各组件的大小由组件所处的区域决定(每 个组件将自动占满整个区域) 。

java图形化界面开发笔记(Java-GUI编程之布局类型)(16)

案例:

使用Frame Panel,配合FlowLayout和GridLayout完成一个计算器效果。

java图形化界面开发笔记(Java-GUI编程之布局类型)(17)

代码:

import java.awt.*; public class GridLayoutDemo{ public static void main(String[] args) { //1.创建Frame对象,并且标题设置为计算器 Frame frame = new Frame("计算器"); //2.创建一个Panel对象,并且往Panel中放置一个TextField组件 Panel p1 = new Panel(); p1.add(new TextField(30)); //3.把上述的Panel放入到Frame的北侧区域 frame.add(p1 BorderLayout.NORTH); //4.创建一个Panel对象,并且设置其布局管理器为GridLayout Panel p2 = new Panel(); p2.setLayout(new GridLayout(3 5 4 4)); //5.往上述Panel中,放置15个按钮,内容依次是:0 1 2 3 4 5 6,7 8 9, ,-,*,/ . for (int i = 0; i < 10; i ) { p2.add(new Button(i "")); } p2.add(new Button(" ")); p2.add(new Button("-")); p2.add(new Button("*")); p2.add(new Button("/")); p2.add(new Button(".")); //6.把上述Panel添加到Frame的中间区域中国 frame.add(p2); //7.设置Frame为最佳大小 frame.pack(); //8.设置Frame可见 frame.setVisible(true); } }GridBagLayout

GridBagLayout 布局管理器的功能最强大 , 但也最复杂,与 GridLayout 布局管理器不同的是, 在GridBagLayout 布局管理器中,一个组件可以跨越一个或多个网格 , 并且可以设置各网格的大小互不相同,从而增加了布局的灵活性 。当窗口的大小发生变化时 , GridBagLayout 布局管理器也可以准确地控制窗口各部分的拉伸 。

java图形化界面开发笔记(Java-GUI编程之布局类型)(18)

由于在GridBagLayout 布局中,每个组件可以占用多个网格,此时,我们往容器中添加组件的时候,就需要具体地控制每个组件占用多少个网格,java提供的GridBagConstaints类,与特定的组件绑定,可以完成具体大小和跨越性的设置。

GridBagConstraints API:

java图形化界面开发笔记(Java-GUI编程之布局类型)(19)

GridBagLayout使用步骤:

1.创建GridBagLaout布局管理器对象,并给容器设置该布局管理器对象; 2.创建GridBagConstraints对象,并设置该对象的控制属性: gridx: 用于指定组件在网格中所处的横向索引; gridy: 用于执行组件在网格中所处的纵向索引; gridwidth: 用于指定组件横向跨越多少个网格; gridheight: 用于指定组件纵向跨越多少个网格; 3.调用GridBagLayout对象的setConstraints(Component c GridBagConstraints gbc )方法,把即将要添加到容器中的组件c和GridBagConstraints对象关联起来; 4. 把组件添加到容器中;

案例:

使用Frame容器,设置GridBagLayout布局管理器,实现下图中的效果:

java图形化界面开发笔记(Java-GUI编程之布局类型)(20)

演示代码:

import java.awt.*; public class GridBagLayoutDemo { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里是GridBagLayout测试"); //2.创建GridBagLayout对象 GridBagLayout gbl = new GridBagLayout(); //3.把Frame对象的布局管理器设置为GridBagLayout frame.setLayout(gbl); //4.创建GridBagConstraints对象 GridBagConstraints gbc = new GridBagConstraints(); //5.创建容量为10的Button数组 Button[] bs = new Button[10]; //6.遍历数组,初始化每一个Button for (int i = 0; i < bs.length; i ) { bs[i] = new Button("按钮" (i 1)); } //7.设置所有的GridBagConstraints对象的fill属性为GridBagConstraints.BOTH 当有空白区域时,组件自动扩大占满空白区域 gbc.fill=GridBagConstraints.BOTH; //8.设置GridBagConstraints对象的weightx设置为1 表示横向扩展比例为1 gbc.weightx=1; //9.往frame中添加数组中的前3个Button addComponent(frame bs[0] gbl gbc); addComponent(frame bs[1] gbl gbc); addComponent(frame bs[2] gbl gbc); //10.把GridBagConstraints的gridwidth设置为GridBagConstraints.REMAINDER 则表明当前组件是横向最后一个组件 gbc.gridwidth=GridBagConstraints.REMAINDER; //11.把button数组中第四个按钮添加到frame中 addComponent(frame bs[3] gbl gbc); //12.把GridBagConstraints的weighty设置为1,表示纵向扩展比例为1 gbc.weighty=1; //13.把button数组中第5个按钮添加到frame中 addComponent(frame bs[4] gbl gbc); //14.把GridBagConstaints的gridheight和gridwidth设置为2,表示纵向和横向会占用两个网格 gbc.gridheight=2; gbc.gridwidth=2; //15.把button数组中第6个按钮添加到frame中 addComponent(frame bs[5] gbl gbc); //16.把GridBagConstaints的gridheight和gridwidth设置为1,表示纵向会占用1个网格 gbc.gridwidth=1; gbc.gridheight=1; //17.把button数组中第7个按钮添加到frame中 addComponent(frame bs[6] gbl gbc); //18.把GridBagConstraints的gridwidth设置为GridBagConstraints.REMAINDER 则表明当前组件是横向最后一个组件 gbc.gridwidth=GridBagConstraints.REMAINDER; //19.把button数组中第8个按钮添加到frame中 addComponent(frame bs[7] gbl gbc); //20.把GridBagConstaints的gridwidth设置为1,表示纵向会占用1个网格 gbc.gridwidth=1; //21.把button数组中第9、10个按钮添加到frame中 addComponent(frame bs[8] gbl gbc); addComponent(frame bs[9] gbl gbc); //22.设置frame为最佳大小 frame.pack(); //23.设置frame可见 frame.setVisible(true); } public static void addComponent(Container container Component c GridBagLayout gridBagLayout GridBagConstraints gridBagConstraints){ gridBagLayout.setConstraints(c gridBagConstraints); container.add(c); } } CardLayout

CardLayout 布局管理器以时间而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的那个 Component 才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌才可见.

java图形化界面开发笔记(Java-GUI编程之布局类型)(21)

案例:

使用Frame和Panel以及CardLayout完成下图中的效果,点击底部的按钮,切换卡片

java图形化界面开发笔记(Java-GUI编程之布局类型)(22)

演示代码:

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class CardLayoutDemo { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试CardLayout"); //2.创建一个String数组,存储不同卡片的名字 String[] names = {"第一张" "第二张" "第三张" "第四张" "第五张"}; //3.创建一个Panel容器p1,并设置其布局管理器为CardLayout 用来存放多张卡片 CardLayout cardLayout = new CardLayout(); Panel p1 = new Panel(); p1.setLayout(cardLayout); //4.往p1中存储5个Button按钮,名字从String数组中取 for (int i = 0; i < 5; i ) { p1.add(names[i] new Button(names[i])); } //5.创建一个Panel容器p2 用来存储5个按钮,完成卡片的切换 Panel p2 = new Panel(); //6.创建5个按钮,并给按钮设置监听器 ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); switch (command){ case "上一张": cardLayout.previous(p1); break; case "下一张": cardLayout.next(p1); break; case "第一张": cardLayout.first(p1); break; case "最后一张": cardLayout.last(p1); break; case "第三张": cardLayout.show(p1 "第三张"); break; } } }; Button b1 = new Button("上一张"); Button b2 = new Button("下一张"); Button b3 = new Button("第一张"); Button b4 = new Button("最后一张"); Button b5 = new Button("第三张"); b1.addActionListener(listener); b2.addActionListener(listener); b3.addActionListener(listener); b4.addActionListener(listener); b5.addActionListener(listener); //7.把5个按钮添加到p2中 p2.add(b1); p2.add(b2); p2.add(b3); p2.add(b4); p2.add(b5); //8.把p1添加到frame的中间区域 frame.add(p1); //9.把p2添加到frame的底部区域 frame.add(p2 BorderLayout.SOUTH); //10设置frame最佳大小并可见 frame.pack(); frame.setVisible(true); } } BoxLayout

为了简化开发,Swing 引入了 一个新的布局管理器 : BoxLayout 。BoxLayout 可以在垂直和 水平分两个方向上摆放 GUI 组件, BoxLayout 提供了如下一个简单的构造器:

java图形化界面开发笔记(Java-GUI编程之布局类型)(23)

案例1:

使用Frame和BoxLayout完成下图效果:

java图形化界面开发笔记(Java-GUI编程之布局类型)(24)

演示代码1:

import javax.swing.*; import java.awt.*; public class BoxLayoutDemo1 { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试BoxLayout"); //2.创建BoxLayout布局管理器,并指定容器为上面的frame对象,指定组件排列方向为纵向 BoxLayout boxLayout = new BoxLayout(frame BoxLayout.Y_AXIS); frame.setLayout(boxLayout); //3.往frame对象中添加两个按钮 frame.add(new Button("按钮1")); frame.add(new Button("按钮2")); //4.设置frame最佳大小,并可见 frame.pack(); frame.setVisible(true); } }

在java.swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout 大多数情况下,使用Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成整体窗口布局。

java图形化界面开发笔记(Java-GUI编程之布局类型)(25)

案例2:

使用Frame和Box,完成下图效果:

java图形化界面开发笔记(Java-GUI编程之布局类型)(26)

演示代码2:

import javax.swing.*; import java.awt.*; public class BoxLayoutDemo2 { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试BoxLayout"); //2.创建一个横向的Box 并添加两个按钮 Box hBox = Box.createHorizontalBox(); hBox.add(new Button("水平按钮一")); hBox.add(new Button("水平按钮二")); //3.创建一个纵向的Box,并添加两个按钮 Box vBox = Box.createVerticalBox(); vBox.add(new Button("垂直按钮一")); vBox.add(new Button("垂直按钮二")); //4.把box容器添加到frame容器中 frame.add(hBox BorderLayout.NORTH); frame.add(vBox); //5.设置frame最佳大小并可见 frame.pack(); frame.setVisible(true); } }

通过之前的两个BoxLayout演示,我们会发现,被它管理的容器中的组件之间是没有间隔的,不是特别的美观,但之前学习的几种布局,组件之间都会有一些间距,那使用BoxLayout如何给组件设置间距呢?

其实很简单,我们只需要在原有的组件需要间隔的地方,添加间隔即可,而每个间隔可以是一个组件,只不过该组件没有内容,仅仅起到一种分隔的作用。

java图形化界面开发笔记(Java-GUI编程之布局类型)(27)

Box类中,提供了5个方便的静态方法来生成这些间隔组件:

java图形化界面开发笔记(Java-GUI编程之布局类型)(28)

案例3:

使用Frame和Box,完成下图效果:

java图形化界面开发笔记(Java-GUI编程之布局类型)(29)

演示代码3:

import javax.swing.*; import java.awt.*; public class BoxLayoutDemo3 { public static void main(String[] args) { //1.创建Frame对象 Frame frame = new Frame("这里测试BoxLayout"); //2.创建一个横向的Box 并添加两个按钮 Box hBox = Box.createHorizontalBox(); hBox.add(new Button("水平按钮一")); hBox.add(Box.createHorizontalGlue());//两个方向都可以拉伸的间隔 hBox.add(new Button("水平按钮二")); hBox.add(Box.createHorizontalStrut(10));//水平间隔固定,垂直间方向可以拉伸 hBox.add(new Button("水平按钮3")); //3.创建一个纵向的Box,并添加两个按钮 Box vBox = Box.createVerticalBox(); vBox.add(new Button("垂直按钮一")); vBox.add(Box.createVerticalGlue());//两个方向都可以拉伸的间隔 vBox.add(new Button("垂直按钮二")); vBox.add(Box.createVerticalStrut(10));//垂直间隔固定,水平方向可以拉伸 vBox.add(new Button("垂直按钮三")); //4.把box容器添加到frame容器中 frame.add(hBox BorderLayout.NORTH); frame.add(vBox); //5.设置frame最佳大小并可见 frame.pack(); frame.setVisible(true); } }

公众号文章链接:Java-GUI编程之布局类型

猜您喜欢: