GUI初步建立
新建窗口JFrame
用Swing搭建GUI,首先需要建立窗口。窗口类组件属于顶层容器。像这样新建窗口并初始化:
// 新建以title为标题的窗口 JFrame frame = new JFrame(title); // 设置窗口大小 frame.setSize(1150, 600); // 设置默认关闭方式 frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
代码中,JFrame
是普通窗口类。绝大多数 swing 图形界面程序都使用JFrame
作为顶层容器。
添加面板JPanel
有了顶层容器,接下来需要新建中间容器,用以承载、管理具体组件。这里选用普通的轻量级 面板容器组件JPanel
:
// 新建面板并设置Layout为null(绝对布局) JPanel panel = new JPanel(null); // 向窗口中添加panel frame.add(panel);
在新建面板的时候,需要指明采用何种布局方式。以我个人愚见,Java swing所提供的布局方式基本都很难用,想做更新和修改也要费很大力气。因此,不如直接采用绝对布局,通过指定各个组件的绝对坐标来布局页面。再加上一些小技巧(如使用变量储存横纵坐标值,以便移动和修改等),绝对布局反而是省心省力的了。其他的布局方式可以参看教程。
添加基本组件
接下来,就需要往面板中添加组件。简单起见,我们只使用三种最基本、最常用的组件:
组件 | 描述 | 功能 |
---|---|---|
JLabel |
标签 | 展示文字或图片 |
JTextField |
文本框 | 编辑单行文本 |
JButton |
按钮 | 用户点击时触发特定的事件 |
其他的大部分组件都是大同小异的。这三个组件的详细教程在此:标签教程;文本框教程;按钮教程。
添加标签JLabel
标签JLabel
用于展示文字或图片。刚开始用swing的时候,我花了好些时间寻找如何让文字换行。事实上,不同于某些图文编辑软件中的「文本框」,JLabel
是不能让其内容主动换行的,且其中所有内容都应用一个格式。要想实现多行、多格式效果,只能用多个JLabel
实现。
// 新建标签,文字内容为“Add a new person” JLabel addPersonLabel = new JLabel("Add a new person"); // 设置位置和大小 addPersonLabel.setBounds(xCoord, yCoord, 200, 25); // 设置字体 addPersonLabel.setFont(functionTitleFont); // 向面板添加这个JLabel panel.add(addPersonLabel);
添加文本框JTextField
文本框JTextField
用以让用户编辑单行的文本。在本应用中,用户需要输入新结点的名称等。向面板中添加文本框的代码如下:
// 新建文本框,宽度为20 JTextField personNameText = new JTextField(20); // 设置位置和大小 personNameText.setBounds(70, yCoord, 125, 25); // 向面板添加这个JTextField panel.add(personNameText);
添加按钮JButton
按钮JButton
在用户点击时触发特定的事件。下面是向面板添加用于新建结点的「Add」按钮的代码:
// 新建按钮,设置文字为“Add” JButton addPersonButton = new JButton("Add"); // 设置位置和大小 addPersonButton.setBounds(210, yCoord, 80, 25); // 添加动作监听器,设置点击按钮时要做的事 addPersonButton.addActionListener(e -> { // 获取文本框中的文本字符串,命名为name String name = personNameText.getText(); // 若输入为空,忽略此次点击 if (name.length() > 0) { // 调用FriendshipGraph类的API,尝试在图中新建名为name的结点 if (graph.addVertex(name)) { // 若新建成功,改变那些显示反馈信息的标签中的文字 addPersonInfoLabel.setText("Successfully added a person named '" + name + "' !"); printPersonLabel.setText("Total: " + graph.getVerticesNum() + " People"); } else { // 若新建失败,显示错误信息 addPersonInfoLabel.setText("Error: Cannot add the person."); } // 清空文本框 personNameText.setText(""); } }); // 向面板添加这个JButton panel.add(addPersonButton);