GUI 02:布局管理器相关知识,AWT 的 3 种布局管理器应用,以及嵌套布局的使用

news2024/11/24 10:48:21

一、前言

记录时间 [2024-05-31]

前置文章
GUI 01:GUI 编程概述,AWT 相关知识,Frame 窗口,Panel 面板,及监听事件的应用

本文讲述了 GUI 编程种布局管理器的相关知识,以及 AWT 的 3 种布局管理器——流式布局、边界布局(东西南北中)、网格布局。搭配面板使用,可以实现布局嵌套功能。


二、布局管理器

1. 相关概念

布局管理器,是 GUI 编程中的一个重要概念,它负责安排容器中组件的大小和位置。使用布局管理器可以使得 GUI 在不同的窗口大小、屏幕分辨率以及国际化的文本长度变化时,能够自适应地调整其布局,保持界面的整洁和一致性。

Java 提供了多种内置的布局管理器来满足不同场景的需求。下面是一些常用的布局管理器:

  • FlowLayout(流式布局):组件按照添加顺序从左到右排列,行满后换行。适合简单的菜单或按钮排列。
  • BorderLayout(边界布局):将容器划分为五个区域:北、南、东、西和中心。每个区域只能放置一个组件,常用于主窗口的基本布局。
  • GridLayout(网格布局):将容器分割成一个矩形网格,每个网格中放置一个组件。所有网格大小相等,适用于需要均匀分布组件的场景,如棋盘界面。
  • GridBagLayout(网格包布局):提供更复杂的网格布局功能,允许每个组件跨越多行或多列,以及设置组件的权重来控制空间分配。非常灵活,但配置也相对复杂。
  • BoxLayout(盒式布局):是 Swing 中提供的,它可以沿容器的一个轴(水平或垂直)排列组件,类似于流式布局,但提供了更精细的对齐和填充控制。
  • CardLayout(卡片布局):允许在同一个空间内堆叠多个组件(像卡片一样),但每次只有一个组件可见。常用于实现选项卡或向导式的界面。

2. 使用步骤

使用布局管理器的一般步骤包括:

  • 创建一个容器(如 Frame、Panel 等);
  • 为这个容器选择并设置一个合适的布局管理器;
  • 向容器中添加组件,并根据需要调整组件的约束条件(某些布局管理器需要);
  • 调整容器的大小或使用 pack() 方法让容器自动调整到最适合其内容的大小。

三、流式布局

1. 相关概念

在 Java 的 AWT(Abstract Window Toolkit,抽象窗口工具包)中,流式布局(FlowLayout)是一种布局管理器,它按照组件添加到容器的顺序从左到右排列组件。当一行排满时,后续的组件会自动换行到下一行继续排列。流式布局非常适合于创建菜单、按钮栏等简单界面元素的布局。

流式布局的主要特点包括:

  • 组件顺序:组件按照添加到容器的顺序依次排列。
  • 对齐方式:默认情况下,组件在每一行中居左对齐,但可以通过构造函数指定居中对齐 FlowLayout.CENTER 或居右对齐 FlowLayout.RIGHT
  • 水平和垂直间隙:可以设置组件之间的水平和垂直间隙,以调整布局的紧凑度或宽松度。
  • 自动换行:一行排满后自动换到下一行显示,无需手动处理换行逻辑。

2. 案例分析

编写代码

例如,将 3 个按钮按照流式布局添加到窗口中。

public class TestFlowLayout {

    public static void main(String[] args) {

        Frame frame = new Frame("TestFlowLayout");

        // 组件 - 按钮
        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button3");

        // 设置为流式布局
        frame.setLayout(new FlowLayout());

        frame.setSize(400, 400);

        // 把按钮添加上去
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);

        frame.setVisible(true);
    }
}

效果查看

三个按钮在窗口中的位置如图所示,流式布局默认是居中的

在这里插入图片描述


居左居右

流式布局默认是居中的,当然也可以实现居左居右。

// 流式布局默认居中
frame.setLayout(new FlowLayout());

// 设置靠左
frame.setLayout(new FlowLayout(FlowLayout.LEFT));

// 设置靠右
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));

四、边界布局

1. 相关概念

边界布局(BorderLayout)将容器划分为五个区域:北(North)、南(South)、东(East)、西(West)和中心(Center)。每个区域可以放置一个组件,这样的设计非常适合创建具有标准框架结构的窗口,比如带有菜单栏、工具栏、状态栏和主要内容区域的窗口布局。

边界布局的特点包括:

  • 五个区域:每个区域都有特定的含义和默认的行为。中心区域通常占据最大的空间,而北、南、东、西区域则作为边缘区域,通常放置辅助性的控件如按钮、标签等。
    • North:位于容器顶部,通常用于放置标题栏、菜单栏等。
    • South:位于容器底部,常用于放置状态栏、确认/取消按钮等。
    • East:位于容器右侧,适合放置侧边栏或较小的控制面板。
    • West:位于容器左侧,用途与东区相似,也是放置辅助控件的好位置。
    • Center:占据容器剩余的所有空间,主要用于放置主要的内容或控件。
  • 组件大小:除了中心区域会填充剩余空间外,其他区域的大小默认为所包含组件的最佳大小,但也可以通过设置组件的首选大小来影响它们的尺寸。
  • 单一组件:边界布局的每个区域只能放置一个组件。如果需要在同一区域内放置多个组件,应该先将这些组件放入一个容器(如Panel),再将该容器添加到相应的区域。

2. 案例分析

编写代码

例如,在东西南北中 5 个位置分别添加一个按钮。

public class TestBorderLayout {

    public static void main(String[] args) {
        Frame frame = new Frame("TestBorderLayout");

        Button east = new Button("East");
        Button west = new Button("West");
        Button south = new Button("South");
        Button north = new Button("North");
        Button center = new Button("Center");

        // 添加到布局中
        frame.add(east, BorderLayout.EAST);
        frame.add(west, BorderLayout.WEST);
        frame.add(south, BorderLayout.SOUTH);
        frame.add(north, BorderLayout.NORTH);
        frame.add(center, BorderLayout.CENTER);
        
        frame.setSize(400, 400);

        frame.setVisible(true);
    }
}

效果查看

窗口效果如图所示,呈现出东西南北中的架构。

在这里插入图片描述


五、网格布局

1. 相关概念

网格布局(GridLayout)将容器划分为一个二维的网格结构,每个网格中可以放置一个组件。组件在网格中均匀分布,每个网格的大小相同,由其中最大的组件决定。

网格布局适用于需要将界面元素组织成规则矩阵的情况,如计算器、棋盘或表格布局等。

使用网格布局的特点包括:

  • 行列数量:在创建 GridLayout 时,可以指定行数和列数,或者只指定一个参数。
    • new GridLayout(3, 2) 表示 3 行 2 列;
    • new GridLayout(2) 表示 2 行,每行的列数由添加的组件自动决定。
  • 组件大小:所有网格的大小一致,自动调整以适应容器的大小,且所有组件在网格中大小相等。这意味着较大的组件可能会挤压其他组件的空间。
  • 填充顺序:组件按照添加到容器的顺序填充网格,从左到右,从上到下
  • 空白空间:网格布局不考虑组件间的空白空间,所有组件紧密相邻。

2. 案例分析

编写代码

例如,设置一个 3 行 2 列的网格,分别在每个网格中放置一个按钮。

使用 pack() 方法让容器自动调整到最适合其内容的大小。

public class TestGridLayout {

    public static void main(String[] args) {

        Frame frame = new Frame("TestGridLayout");

        Button btn1 = new Button("btn1");
        Button btn2 = new Button("btn2");
        Button btn3 = new Button("btn3");
        Button btn4 = new Button("btn4");
        Button btn5 = new Button("btn5");
        Button btn6 = new Button("btn6");

        frame.setLayout(new GridLayout(3, 2));

        frame.add(btn1);
        frame.add(btn2);
        frame.add(btn3);
        frame.add(btn4);
        frame.add(btn5);
        frame.add(btn6);

        // java 函数,网格自适应窗口布局
        frame.pack();

        frame.setVisible(true);
    }
}

效果查看

窗口效果如图所示,六个按钮按从左到右,从上到下的次序添加到窗口中。

在这里插入图片描述


六、综合案例

1. 案例要求

接下来完成嵌套布局案例,具体要求如下:

  • 将按钮摆放成如图所示模样;
  • 设置关闭按钮监听事件。

在这里插入图片描述


2. 案例分析

  • 对上述布局进行大致划分,首先可以上下结构——2 行 1 列的网格布局(p1 和 p3);
  • p1 设置为边界布局(东西南北中)布局,中间嵌入 p2,p2 为 2 行 1 列的网格布局;
  • p3 设置为边界布局(东西南北中)布局,中间嵌入 p4,p4 为 2 行 2 列的网格布局。

在这里插入图片描述


3. 代码实现

设置顶层窗口

设置顶层 Frame 窗口的一系列参数:可见性、宽高、初始位置、背景颜色,以及布局。

// 总 Frame
Frame frame = new Frame("布局嵌套");
frame.setSize(400, 300);         // 设置宽高
frame.setLocation(300, 400);            // 设置初始位置
frame.setBackground(Color.blue);             // 设置背景颜色
frame.setVisible(true);                      // 设置可见
frame.setLayout(new GridLayout(2, 1));  // 设置网格布局

设置 4 个面板

设置 4 个面板 Panel,以完成布局的嵌套。

// 4 个面板
Panel p1 = new Panel(new BorderLayout());       // 边界布局(东西南北中)布局
Panel p2 = new Panel(new GridLayout(2, 1));
Panel p3 = new Panel(new BorderLayout());
Panel p4 = new Panel(new GridLayout(2, 2));

// p1 p3 添加到主窗口
frame.add(p1);
frame.add(p3);

完成上半部分

上半部分 p1 设置为边界布局(东西南北中)布局,中间嵌入 p2,p2 为 2 行 1 列的网格布局。

把 p2 添加到 p1 中。

// 上半部分
p1.add(new Button("East-1"), BorderLayout.EAST);
p1.add(new Button("West-1"), BorderLayout.WEST);
p2.add(new Button("p2-btn-1"));
p2.add(new Button("p2-btn-2"));
p1.add(p2, BorderLayout.CENTER);    // 把 p2 添加到 p1 中

完成下半部分

下半部分 p3 设置为边界布局(东西南北中)布局,中间嵌入 p4,p2 为 2 行 2 列的网格布局。

把 p4 添加到 p3 中。

// 下半部分
p3.add(new Button("East-2"), BorderLayout.EAST);
p3.add(new Button("West-2"), BorderLayout.WEST);
for (int i = 0; i < 4; i++) {
    p4.add(new Button("for" + i));
}
p3.add(p4, BorderLayout.CENTER);    // 把 p4 添加到 p3 中

设置按钮监听

设置关闭按钮监听——点击关闭按钮时,关闭窗口。

// 设置按钮监听
frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
});

七、总结

本文讲述了 GUI 编程种布局管理器的相关知识,以及 AWT 的 3 种布局管理器——流式布局、边界布局(东西南北中)、网格布局。搭配面板使用,可以实现布局嵌套功能。


要点整理

  • Frame 是顶层窗口;
  • Panel 无法单独显示,必须添加到某个容器中;
  • 3 种布局管理器:流式布局、边界布局(东西南北中)、网格布局;
  • 参数:大小、定位、布局、背景颜色、可见性、监听。

一些参考资料

狂神说 GUI 编程:https://www.bilibili.com/video/BV1DJ411B75F
IDEA 官网:https://www.jetbrains.com.cn/idea/
Java 开发手册:https://developer.aliyun.com/ebook/394
Java 8 帮助文档:https://docs.oracle.com/javase/8/docs/api/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1718411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL中list的模拟实现

目录 list模拟实现 list节点 list的push_back()函数 list的迭代器操作&#xff08;非const&#xff09; list的迭代器操作&#xff08;const&#xff09; list迭代器const 非const优化 list的insert()函数 list的erase()函数 list的pop_back() push_front() pop_front(…

【Python】解决Python报错:AttributeError: ‘int‘ object has no attribute ‘xxx‘

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

使用element的提示框并修改css

使用el-tooltip来做提示框&#xff1a; <el-tooltip popper-class"popper" content"敬请期待" placement"right"><div><i class"iconfont icon-lianjie-01"></i><span>输入链接</span></div&…

从头开始构建GPT标记器

从头开始构建GPT标记器 对于GPT Tokenizer&#xff0c;论文《Language Models are Unsupervised Multitask Learners》中介绍了一种字节级编码作为LLM的标记化机制&#xff1a; The vocabulary is expanded to 50,257. We also increase the context size from 512 to 1024 to…

LAMP分布式安全方案搭建网页 (LinuxCentOS7+Apache+Mariadb+PHP)包括服务端口及防火墙规则配置

目录 一、实验目的 二、设计方案及规划 三、实验内容及步骤 &#xff08;1&#xff09;实验前基础配置 &#xff08;2&#xff09;Test配置&#xff0c;安装Firefox浏览器和图形界面 &#xff08;3&#xff09;Web安装Apache &#xff08;4&#xff09;Database安装Mari…

变现实谈,我要的不是灵光一现,而是真实的实现!——感悟篇

变现要的是行动不是想法 正文时代奇点奇迹 点题以己及人 正文 每当我看到了一个有趣的事情 我会在脑中构思一些想法 会贴合我当下的想要做的事情 比如 在我写下这篇文章之前 我看到了 二战期间的诞生的一个奇迹 可口可乐 我就思考 咦 原来可口可乐居然是在这么个时间点成长…

【React】函数式组件的 ref 结果为 undefined(useRef)

函数式组件不能直接应用 ref。 class ClassComp extends Component {render() {return ;} }function FuncComp(props) {return ; }function App() {let refClass useRef();let refFunc useRef();return (<div><ClassComp ref{refClass} /><FuncComp ref{refF…

计算机网络-BGP路由通告原则

前面一章我们学习了BGP的路由产生方式以及查看路由表信息。BGP自身并不会发现并计算产生路由。BGP通过network、import-route、aggregate聚合方式生成BGP路由后&#xff0c;通过Update报文将BGP路由传递给对等体。那BGP向邻居通告路由时遵循哪些原则呢&#xff1f; BGP通告遵循…

将局部变量指针传递给某个c++类,离开类时数据发生变化

最近遇到一个c的问题&#xff0c;将一个局部变量的值传递给某个类&#xff0c;类中没有对该数据进行任何显式修改&#xff0c;结果该变量的值发生变化并且不可访问。 我开始很奇怪为何会发生这样的事情&#xff0c;后来经过调试&#xff0c;发现原来是该类发生了异常&#xff…

【vue】v-for只显示前几个数据,超出显示查看更多

v-for只显示前几个数据&#xff0c;超出显示查看更多 如图 <div v-for"(item,index) in list.slice(0,3)" :key"index"><div class"degreeNo" :class"index0?noOne:index1?noTwo:index2?noThree:"> NO{{index1}}:<…

基于springboot的-仓库 管理系统(附:源码+课件)

项目介绍002&#xff1a; 管理员system 123456 客户表&#xff08;ID 客户名称 邮编 客户地址 客户电话 联系人 联系人电话 开户行账号 邮箱&#xff09; 供应商表&#xff08;ID 供应商名称 邮编 供应商地址 供应商电话 联系人 联系人电话 开户行 账号 邮箱&#xff09; 商品…

go 针对 time类型字段,前端查询,后端返回数据格式为UTC时间

测试代码 package mainimport ("context""log""net/http""time""github.com/gin-gonic/gin""go.mongodb.org/mongo-driver/bson""go.mongodb.org/mongo-driver/bson/primitive""go.mongodb.org/m…

控制障碍函数CBF详解(附带案例实现)

控制障碍函数CBF详解&#xff08;附带案例实现&#xff09; 文章目录 控制障碍函数CBF详解&#xff08;附带案例实现&#xff09;1. Control Affine System2. Lyapunov Theory, Nagumos Theory, Invariance Principle3. Control Lyapunov Function (CLF) and CLF-QP4. Control …

[openwrt-21.02]openwrt-21.02 make menuconfig不显示luci-app-firewall问题分析及解决方案

问题描述 make menuconfig在 在applications界面没有luci-app-firewall 问题分析 首先重新执行 ./scripts/feeds update -a ./scripts/feeds install -a 然后再次执行make menuconfig&#xff0c;依然不显示&#xff0c;所以不是feeds安装的问题 最后看到log有个openmptc…

字符串匹配算法(二)BM算法

文章目录 算法简介坏字符规则坏字符的定义坏字符的移动 好后缀规则好后缀的定义好后缀的移动 算法实现 算法简介 BM算法也就是Boyer Moore算法&#xff0c;它是一种非常高效的字符串匹配算法&#xff0c;是一种滑动算法。什么是滑动&#xff1f; 下面例子中&#xff0c;主串中…

vcruntime140_1.dll在哪个文件夹?详细修复vcruntime140_1.dll缺失的方法

vcruntime140_1.dll文件是什么&#xff1f;相信很多人都对它很陌生吧&#xff1f;毕竟大部分人对于dll文件还是了解得太少了&#xff0c;当突发情况出现vcruntime140_1.dll文件丢失&#xff1f;你要怎么办&#xff1f;不要担心&#xff0c;下面我们就来给大家详细的讲解一下修复…

出吉林大学计算机考研资料适用于计专966/计学941/软专967

本人是24上岸吉大计算机专硕的考生&#xff0c;先上成绩&#xff1a; 出专业课备考过程的相关笔记资料&#xff0c;也可以提供经验分享等&#xff1a; 吉林大学计算机数据结构基础算法ADL汇总&#xff0c;适用于计专966/计学941/软专967综合整理小绿书以及期末题上重难点算法…

LLVM入门教学——Code Coverage插桩

1、简介 LLVM的Code Coverage工具集提供了一系列工具和库&#xff0c;帮助开发者收集和分析代码覆盖率数据&#xff0c;从而评估测试的有效性和代码的执行情况。LLVM的Code Coverage工具集包括以下主要组件&#xff1a; Clang编译器&#xff1a;用于编译源代码并生成覆盖率信息…

Linux下配置Pytorch

1.Anaconda 1.1虚拟环境创建 2.Nvidia驱动 3.CUDA驱动安装 4.Pytorch安装 具体的步骤如上&#xff1a;可参考另一位博主的博客非常详细&#xff1a; Linux服务器配置PythonPyTorchCUDA深度学习环境_linux cuda环境配置-CSDN博客https://blog.csdn.net/NSJim/article/detai…

官方小游戏项目

一 项目原理&#xff1a;看广告&#xff0c;操作简单&#xff0c;时间自由&#xff0c;适合利用业余时间来做&#xff0c;一个广告大概在15s-30s之间。 二 介绍&#xff1a;给你开代理权限&#xff0c;你就有独立后台管理系统&#xff0c;监测每台手机每条广告的情况&#xff0…