Java-GUI 编程之 Swing

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位

进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。

入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

Swing概述

实际使用 Java 开发图形界面程序时 ,很少使用 AWT 组件,绝大部分时候都是用 Swing 组件开发的 。 Swing是由100%纯 Java实现的,不再依赖于本地平台的 GUI, 因此可以在所有平台上都保持相同的界面外观。独立于本地平台的Swing组件被称为 轻量级组件;而依赖于本地平台的 AWT 组件被称为 重量级组件
由于 Swing 的所有组件完全采用 Java 实现,不再调用本地平台的 GUI,所以导致 Swing 图形界面的显示速度要比 AWT 图形界面的显示速度慢一些,但相对于快速发展的硬件设施而言,这种微小的速度差别无妨大碍。

使用Swing的优势:

Swing的特征:

1.Swing 组件采用 MVC(Model-View-Controller, 即模型一视图一控制器)设计模式:

  • 模型(Model): 用于维护组件的各种状态;
  • 视图(View): 是组件的可视化表现;
  • 控制器(Controller):用于控制对于各种事件、组件做出响应 。

当模型发生改变时,它会通知所有依赖它的视图,视图会根据模型数据来更新自己。Swing使用UI代理来包装视图和控制器, 还有一个模型对象来维护该组件的状态。例如,按钮JButton有一个维护其状态信息的模型ButtonModel对象 。 Swing组件的模型是自动设置的,因此一般都使用JButton,而无须关心ButtonModel对象。

2.Swing在不同的平台上表现一致,并且有能力提供本地平台不支持的显示外观 。由于 Swing采用 MVC 模式来维护各组件,所以 当组件的外观被改变时,对组件的状态信息(由模型维护)没有任何影响 。因 此,Swing可以使用插拔式外观感觉 (Pluggable Look And Feel, PLAF)来控制组件外观,使得 Swing图形界面在同一个平台上运行时能拥有不同的外观,用户可以选择自己喜欢的外观 。相比之下,在 AWT 图形界面中,由于控制组件外观的对等类与具体平台相关 ,因此 AWT 组件总是具有与本地平台相同的外观 。

Swing组件层次

Swing组件继承体系图:

​ 大部分Swing 组件都是 JComponent抽象类的直接或间接子类(并不是全部的 Swing 组件),JComponent 类定义了所有子类组件的通用方法 ,JComponent 类是 AWT 里 java.awt. Container 类的子类 ,这也是 AWT 和 Swing 的联系之一。 绝大部分 Swing 组件类继承了 Container类,所以Swing 组件都可作为 容器使用 ( JFrame继承了Frame 类)。

Swing组件和AWT组件的对应关系:

​ 大部分情况下,只需要在AWT组件的名称前面加个J,就可以得到其对应的Swing组件名称,但有几个例外:

​ 1. JComboBox: 对应于 AWT 里的 Choice 组件,但比 Choice 组件功能更丰富 。
2. JFileChooser: 对应于 AWT 里的 FileDialog 组件 。
3. JScrollBar: 对应于 AWT 里的 Scrollbar 组件,注意两个组件类名中 b 字母的大小写差别。
4. JCheckBox : 对应于 AWT 里的 Checkbox 组件, 注意两个组件类名中 b 字母的大小 写差别 。
5. JCheckBoxMenultem: 对应于 AWT 里的 CheckboxMenuItem 组件,注意两个组件类名中 b字母的大小写差别。

Swing组件按照功能来分类:

AWT组件的Swing实现

​ Swing 为除 Canvas 之外的所有 AWT 组件提供了相应的实现,Swing 组件比 AWT 组件的功能更加强大。相对于 AWT 组件, Swing 组件具有如下 4 个额外的功能 :

​ 每个 Swing 组件都有一个对应的UI 类,例如 JButton组件就有一个对应的 ButtonUI 类来作为UI代理 。每个 Swing组件的UI代理的类名总是将该 Swing 组件类名的 J 去掉,然后在后面添加 UI 后缀 。 UI代理类通常是一个抽象基类 , 不同的 PLAF 会有不同的UI代理实现类 。 Swing 类库中包含了几套UI代理,分别放在不同的包下, 每套UI代理都几乎包含了所有 Swing组件的 ComponentUI实现,每套这样的实现都被称为一种PLAF 实现 。以 JButton 为例,其 UI 代理的继承层次下图:

​ 如果需要改变程序的外观风格, 则可以使用如下代码:

//容器:
JFrame jf = new JFrame();

try {

 //设置外观风格
 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

 //刷新jf容器及其内部组件的外观
 SwingUtilities.updateComponentTreeUI(jf);
} catch (Exception e) {
 e.printStackTrace();
}

​ 使用Swing组件,实现下图中的界面效果:

演示代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;

public class SwingComponentDemo {

 JFrame f = new JFrame("测试swing基本组件");

 // 定义一个按钮,并为其指定图标
 JButton ok = new JButton("确定",new ImageIcon("ok.png"));

 // 定义一个单选按钮,初始处于选中的状态
 JRadioButton male = new JRadioButton("男", true);
 // 定义一个单选按钮,初始处于选中状态
 JRadioButton female = new JRadioButton("女", false);

 // 定义一个ButtonGroup,把male和female组合起来,实现单选
 ButtonGroup bg = new ButtonGroup();

 // 定义一个复选框,初始处于没有选中状态
 JCheckBox married = new JCheckBox("是否已婚?", false);

 // 定义一个数组存储颜色
 String[] colors = { "红色", "绿色 ", "蓝色 " };

 // 定义一个下拉选择框,展示颜色
 JComboBox colorChooser = new JComboBox(colors);

 // 定一个列表框,展示颜色
 JList colorList = new JList(colors);

 // 定义一个8行20列的多行文本域
 JTextArea ta = new JTextArea(8, 20);

 // 定义一个40列的单行文本域
 JTextField name = new JTextField(40);

 // 定义菜单条
 JMenuBar mb = new JMenuBar();

 // 定义菜单
 JMenu file = new JMenu("文件");
 JMenu edit = new JMenu("编辑");

 // 创建菜单项,并指定图标
 JMenuItem newItem = new JMenuItem("新建", new ImageIcon("new.png"));
 JMenuItem saveItem = new JMenuItem("保存", new ImageIcon("save.png"));
 JMenuItem exitItem = new JMenuItem("退出", new ImageIcon("exit.png"));

 JCheckBoxMenuItem autoWrap = new JCheckBoxMenuItem("自动换行");
 JMenuItem copyItem = new JMenuItem("复制", new ImageIcon("copy.png"));
 JMenuItem pasteItem = new JMenuItem("粘贴", new ImageIcon("paste.png"));

 // 定义二级菜单,将来会添加到编辑中
 JMenu format = new JMenu("格式");
 JMenuItem commentItem = new JMenuItem("注释");
 JMenuItem cancelItem = new JMenuItem("取消注释");

 // 定义一个右键菜单,用于设置程序的外观风格
 JPopupMenu pop = new JPopupMenu();

 // 定义一个ButtongGroup对象,用于组合风格按钮,形成单选
 ButtonGroup flavorGroup = new ButtonGroup();

 // 定义五个单选按钮菜单项,用于设置程序风格
 JRadioButtonMenuItem metalItem = new JRadioButtonMenuItem("Metal 风格", true);
 JRadioButtonMenuItem nimbusItem = new JRadioButtonMenuItem("Nimbus 风格", true);
 JRadioButtonMenuItem windowsItem = new JRadioButtonMenuItem("Windows 风格", true);
 JRadioButtonMenuItem classicItem = new JRadioButtonMenuItem("Windows 经典风格", true);
 JRadioButtonMenuItem motifItem = new JRadioButtonMenuItem("Motif 风格", true);

 // 初始化界面
 public void init() {

 // ------------------------组合主区域------------------------
 // 创建一个装载文本框和按钮的JPanel
 JPanel bottom = new JPanel();
 bottom.add(name);
 bottom.add(ok);

 f.add(bottom, BorderLayout.SOUTH);

 // 创建一个装载下拉选择框、三个JChekBox的JPanel
 JPanel checkPanel = new JPanel();
 checkPanel.add(colorChooser);
 bg.add(male);
 bg.add(female);

 checkPanel.add(male);
 checkPanel.add(female);
 checkPanel.add(married);

 // 创建一个垂直排列的Box,装载checkPanel和多行文本域
 Box topLeft = Box.createVerticalBox();

 // 使用JScrollPane作为普通组件的JViewPort
 JScrollPane taJsp = new JScrollPane(ta);
 topLeft.add(taJsp);
 topLeft.add(checkPanel);

 // 创建一个水平排列的Box,装载topLeft和colorList
 Box top = Box.createHorizontalBox();
 top.add(topLeft);
 top.add(colorList);

 // 将top Box 添加到窗口的中间
 f.add(top);

 // ---------------------------组合菜单条----------------------------------------------
 // 为newItem添加快捷键 ctrl+N
 newItem.setAccelerator(KeyStroke.getKeyStroke('N', InputEvent.CTRL\_MASK));
 newItem.addActionListener(new ActionListener() {

 public void actionPerformed(ActionEvent e) {
 ta.append("用户点击了“新建”菜单\n");
 }
 });

 // 为file添加菜单项
 file.add(newItem);
 file.add(saveItem);
 file.add(exitItem);

 // 为edit添加菜单项
 edit.add(autoWrap);
 edit.addSeparator();
 edit.add(copyItem);
 edit.add(pasteItem);
 // 为commentItem添加提示信息
 commentItem.setToolTipText("将程序代码注释起来");

 // 为format菜单添加菜单项
 format.add(commentItem);
 format.add(cancelItem);

 // 给edit添加一个分隔符
 edit.addSeparator();

 // 把format添加到edit中形成二级菜单
 edit.add(format);

 // 把edit file 添加到菜单条中
 mb.add(file);
 mb.add(edit);

 // 把菜单条设置给窗口
 f.setJMenuBar(mb);

 // ------------------------组合右键菜单-----------------------------

 flavorGroup.add(metalItem);
 flavorGroup.add(nimbusItem);
 flavorGroup.add(windowsItem);
 flavorGroup.add(classicItem);
 flavorGroup.add(motifItem);

 // 给5个风格菜单创建事件监听器
 ActionListener flavorLister = new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 String command = e.getActionCommand();
 try {
 changeFlavor(command);
 } catch (Exception e1) {
 e1.printStackTrace();
 }
 }
 };

 // 为5个风格菜单项注册监听器
 metalItem.addActionListener(flavorLister);
 nimbusItem.addActionListener(flavorLister);
 windowsItem.addActionListener(flavorLister);
 classicItem.addActionListener(flavorLister);
 motifItem.addActionListener(flavorLister);

 pop.add(metalItem);
 pop.add(nimbusItem);
 pop.add(windowsItem);
 pop.add(classicItem);
 pop.add(motifItem);

 // 调用ta组件的setComponentPopupMenu即可设置右键菜单,无需使用事件
 ta.setComponentPopupMenu(pop);

 // 设置关闭窗口时推出程序
 f.setDefaultCloseOperation(JFrame.EXIT\_ON\_CLOSE);

 // 设置jFrame最佳大小并可见
 f.pack();
 f.setVisible(true);

 }

 // 定义一个方法,用于改变界面风格
 private void changeFlavor(String command) throws Exception {
 switch (command) {
 case "Metal 风格":
 UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
 break;
 case "Nimbus 风格":
 UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
 break;
 case "Windows 风格":
 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
 break;
 case "Windows 经典风格":
 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
 break;
 case "Motif 风格":
 UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
 break;
 }

 // 更新f窗口内顶级容器以及所有组件的UI
 SwingUtilities.updateComponentTreeUI(f.getContentPane());
 // 更新mb菜单条及每部所有组件UI
 SwingUtilities.updateComponentTreeUI(mb);
 // 更新右键菜单及内部所有菜单项的UI
 SwingUtilities.updateComponentTreeUI(pop);
 }

 public static void main(String[] args) {
 new SwingComponentDemo().init();
 }

}

注意细节:

1.Swing菜单项指定快捷键时必须通过 组件名.setAccelerator(keyStroke.getKeyStroke("大写字母",InputEvent.CTRL_MASK))方法来设置,其中KeyStroke代表一次击键动作,可以直接通过按键对应字母来指定该击键动作 。

2.更新JFrame的风格时,调用了 SwingUtilities.updateComponentTreeUI(f.getContentPane());这是因为如果直接更新 JFrame 本身 ,将会导致 JFrame 也被更新, JFrame 是一个特殊的容器 , JFrame 依然部分依赖于本地平台的图形组件 。如果强制 JFrame 更新,则有可能导致该窗口失去标题栏和边框 。

3.给组件设置右键菜单,不需要使用监听器,只需要调用setComponentPopupMenu()方法即可,更简单。

5.如果需要让某个组件支持滚动条,只需要把该组件放入到JScrollPane中,然后使用JScrollPane即可。

EOF

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqakFjtd-1651468033923)(https://blog.csdn.net/kohler21/p/16214218.html)]愚生浅末 本文链接:https://blog.csdn.net/kohler21/p/16214218.html关于博主:评论和私信会在第一时间回复。或者直接私信我。版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【[推荐](javascript:void(0)😉】一下。您的鼓励是博主的最大动力!

Original: https://blog.csdn.net/www_xuhss_com/article/details/124539719
Author: www_xuhss_com
Title: Java-GUI 编程之 Swing

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/746844/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 初识Flask——轻量级框架

    1 什么是flask? Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务,在介绍Flask之前首先来聊下它和Django…

    Python 2023年8月15日
    052
  • IS-IS的报文类型

    SNP 序列号报文SNP(Sequence Number PDUs)通过 描述全部&…

    Python 2023年6月10日
    073
  • 【Python】Python第三方库概览

    前两天我安装第三方库的功能出现了点问题,断断续续修复了一天,修好之后我就在想Python的第三方库有多少,都能用来做什么,于是我展开了探索。 ​21天打卡最后一篇活动地址:CSDN…

    Python 2023年8月23日
    077
  • TypeScript

    文章目录 TypeScript开发环境搭建 TypeScript新增数据类型 TypeScript怎么做到优雅的配置编译 WebPack 与 TypeScript Babel Ty…

    Python 2023年10月11日
    056
  • 6.1 文本情感倾向性分析

    是日常生活中最常用的两类自然语言处理任务, 一、自然语言情感分析 人类自然语言具有高度的复杂性,相同的对话在不同的情景,不同的情感,不同的人演绎,表达的效果往往也会迥然不同。例如&…

    Python 2023年9月28日
    060
  • python scrapy框架爬虫当当图书网

    最近在复习scrapy框架,就随便找了个网站做了一下爬虫,当当网,说实话这种网站还是比较好做爬虫的,我没加代理,也没限速,没写多线程,就直接搞下来了,数据量还是比较可观的。接下来进…

    Python 2023年10月3日
    055
  • 人工神经网络的发展现状,神经网络未来发展趋势

    人工神经网络的发展 现代意义上对神经网络(特指人工神经网络)的研究一般认为从1943年美国芝加哥大学的生理学家W.S.McCulloch和W.A.Pitts提出M-P神经元模型开始…

    Python 2023年9月29日
    051
  • 机器学习实战|使用K-临近算法改进约会网站的配对效果

    1 准备数据:从文本文件中解析数据 datingTestSet.txt:每列分别代表每年获得的飞行常客里程数、玩游戏视频所耗时间百分比、每周消费的冰淇淋公升数、不喜欢/魅力一般/极…

    Python 2023年9月5日
    036
  • 超强视频超分AI算法,从此只看高清视频

    最近发现一个特别强的视频超分算法————BasicVSR,在真实世界数据集中,实现了前所未有的视觉重建效果,最近它还拿下了超分比赛NTIRE 2021三冠一亚的优异成绩,登上了CV…

    Python 2023年10月26日
    044
  • python数据可视化第四章图标样式的美化

    一、图标样式的概述matplotlib在绘图的过程中会读取储存在本地的的配置文件matplotlibrc,通过matplotlibrc文件中的缺省配置信息指定图表元素的默认样式,完…

    Python 2023年9月3日
    058
  • ShowDialog

    Private Sub BT_DPNO1_Click(sender As Object, e As EventArgs) Handles BT_DPNO1.ClickDim LJP…

    Python 2023年6月10日
    064
  • Python之文件操作

    Python之文件操作 原创 wx62d12289ce45b2022-08-10 17:26:06博主文章分类:Python ©著作权 文章标签 github 文件名 复制文件 文…

    Python 2023年5月24日
    077
  • 7 款殿堂级的开源 CMS(内容管理系统)

    最近,有读者留言让我推荐开源 CMS。我本想直接回复 WordPress,但是转念一想我玩 WordPress 是 2010 年左右的事情了,都过去十年了,它会不会有些过时呢?有没…

    Python 2023年10月15日
    059
  • Matplotlib 设置支持中文的默认字体

    Matplotlib 设置支持中文的默认字体 问题描述 python 3.7 使用 matplotlib 时汉字显示为方框,如下: ; 问题原因 matplotlib 使用的默认字…

    Python 2023年8月31日
    0112
  • python django 切换生产开发配置(规范常用)

    使用django项目进行开发,可以在setting文件中直接写死指定的数据库,但是一旦项目需要上线就需要切换相应的配置,如果每次本地调试提交代码手动去修改配置的话就特别麻烦,可能有…

    Python 2023年8月4日
    062
  • python ean13条形码的验证_在Matplotlib中显示EAN13条形码

    我想在Matplotlib中显示EAN条形码。我试图使用包作为条形码,但这只打印到.svg和.png,这对我的应用程序来说是相当不方便的。如何放置EAN条形码,如下例所示: 打印中…

    Python 2023年9月6日
    078
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球