12.6Swing控件4 JSplitPane JTabbedPane

JSplitPane

JSplitPane 是 Java Swing 中用于创建分隔面板的组件,支持两个可调整大小组件的容器。它允许用户通过拖动分隔条来调整两个组件的相对大小,适合用于需要动态调整视图比例的场景。

  • 常用方法
    • setLeftComponent(Component comp):设置左侧组件。
    • setRightComponent(Component comp) 或 setBottomComponent(Component comp):根据方向设置另一侧组件。
    • setDividerLocation(int location):设置分割条的位置。

1. 基本概念与特点

  • 分隔方向:支持水平分隔(HORIZONTAL_SPLIT)和垂直分隔(VERTICAL_SPLIT)。
  • 子组件:只能包含两个组件(左 / 右或上 / 下),通过 setLeftComponent()setRightComponent() 或 setTopComponent()setBottomComponent() 设置。
  • 分隔条(Divider):可自定义宽度、颜色和样式,支持拖动调整大小。
  • 连续布局:拖动分隔条时是否实时更新布局(setContinuousLayout(true))。
  • 一键折叠:支持通过 setOneTouchExpandable(true) 添加快速折叠按钮。

2. 常用构造方法

构造方法描述
JSplitPane()创建默认水平分隔的面板,使用 FlowLayout,无初始组件。
JSplitPane(int orientation)指定分隔方向(HORIZONTAL_SPLIT 或 VERTICAL_SPLIT)。
JSplitPane(int orientation, boolean continuousLayout)指定分隔方向和是否启用连续布局。
JSplitPane(int orientation, Component leftComponent, Component rightComponent)指定分隔方向和初始子组件。

3. 核心方法

方法描述
setDividerLocation(double proportionalLocation)设置分隔条位置(0.0~1.0 表示比例)。
setDividerLocation(int location)设置分隔条的绝对位置(像素值)。
setDividerSize(int newSize)设置分隔条的宽度。
setOneTouchExpandable(boolean newValue)启用 / 禁用一键折叠功能。
setContinuousLayout(boolean newContinuousLayout)启用 / 禁用连续布局(拖动时分隔条是否实时更新)。
setLeftComponent(Component comp) / setTopComponent(Component comp)设置左侧 / 顶部组件。
setRightComponent(Component comp) / setBottomComponent(Component comp)设置右侧 / 底部组件。

4. 简单示例:水平分隔面板

import javax.swing.*;
import java.awt.*;public class JSplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("JSplitPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 创建左侧面板(列表)JList<String> list = new JList<>(new String[]{"项目1", "项目2", "项目3", "项目4"});JScrollPane leftPanel = new JScrollPane(list);// 创建右侧面板(文本区域)JTextArea textArea = new JTextArea("这是右侧面板内容...");JScrollPane rightPanel = new JScrollPane(textArea);// 创建水平分隔面板JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,  // 水平分隔leftPanel,                    // 左侧组件rightPanel                    // 右侧组件);// 设置分隔条初始位置(比例)splitPane.setDividerLocation(0.3);// 启用一键折叠功能splitPane.setOneTouchExpandable(true);// 启用连续布局splitPane.setContinuousLayout(true);frame.add(splitPane);frame.setVisible(true);}
}

5. 嵌套分隔面板示例

通过嵌套 JSplitPane 可创建复杂的布局:

import javax.swing.*;
import java.awt.*;public class NestedSplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("嵌套 JSplitPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(800, 600);// 创建顶部面板(文本区域)JTextArea topTextArea = new JTextArea("这是顶部面板...");JScrollPane topPanel = new JScrollPane(topTextArea);// 创建左侧面板(列表)JList<String> leftList = new JList<>(new String[]{"选项1", "选项2", "选项3"});JScrollPane leftPanel = new JScrollPane(leftList);// 创建右侧上部面板(表格)String[] columnNames = {"ID", "名称"};Object[][] data = {{1, "项目A"}, {2, "项目B"}, {3, "项目C"}};JTable table = new JTable(data, columnNames);JScrollPane rightTopPanel = new JScrollPane(table);// 创建右侧下部面板(文本区域)JTextArea bottomTextArea = new JTextArea("这是底部面板...");JScrollPane rightBottomPanel = new JScrollPane(bottomTextArea);// 创建右侧垂直分隔面板JSplitPane rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,rightTopPanel,rightBottomPanel);rightSplitPane.setDividerLocation(0.5);// 创建主水平分隔面板JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftPanel,rightSplitPane);mainSplitPane.setDividerLocation(0.3);// 创建最终的垂直分隔面板(顶部面板和主分隔面板)JSplitPane finalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,topPanel,mainSplitPane);finalSplitPane.setDividerLocation(0.2);frame.add(finalSplitPane);frame.setVisible(true);}
}

6. 自定义分隔条样式

通过设置 UI 属性或子类化 BasicSplitPaneUI 可自定义分隔条外观:

import javax.swing.*;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;public class CustomDividerExample {public static void main(String[] args) {JFrame frame = new JFrame("自定义分隔条示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new JLabel("左侧面板"),new JLabel("右侧面板"));// 自定义分隔条样式splitPane.setUI(new BasicSplitPaneUI() {@Overridepublic BasicSplitPaneDivider createDefaultDivider() {return new BasicSplitPaneDivider(this) {@Overridepublic void paint(Graphics g) {// 绘制自定义分隔条g.setColor(Color.RED);g.fillRect(0, 0, getSize().width, getSize().height);super.paint(g);}};}});// 设置分隔条宽度splitPane.setDividerSize(10);frame.add(splitPane);frame.setVisible(true);}
}

7. 监听分隔条位置变化

通过 PropertyChangeListener 监听 dividerLocation 属性变化:

import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;public class DividerListenerExample {public static void main(String[] args) {JFrame frame = new JFrame("分隔条监听示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new JLabel("左侧面板"),new JLabel("右侧面板"));// 添加分隔条位置变化监听器splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {@Overridepublic void propertyChange(PropertyChangeEvent e) {System.out.println("分隔条位置变化:" + e.getOldValue() + " -> " + e.getNewValue());}});frame.add(splitPane);frame.setVisible(true);}
}

8. 注意事项

  1. 组件大小JSplitPane 会根据子组件的首选大小初始化分隔条位置,可通过 setPreferredSize() 调整。
  2. 禁用拖动:通过重写 Divider 的 mouseDragged() 方法可禁用分隔条拖动:
    splitPane.setUI(new BasicSplitPaneUI() {@Overridepublic BasicSplitPaneDivider createDefaultDivider() {return new BasicSplitPaneDivider(this) {@Overridepublic void mouseDragged(java.awt.event.MouseEvent e) {// 空实现,禁用拖动}};}
    });
    

  3. 持久化分隔条位置:可通过 getDividerLocation() 获取当前位置,并在下次启动时通过 setDividerLocation() 恢复。

JSplitPane 是 Java Swing 中创建动态分隔界面的强大组件,通过简单配置即可实现灵活的布局。其核心优势在于支持嵌套结构、实时调整和自定义样式,适用于需要动态分配空间的应用场景(如编辑器、文件管理器等)。

JTabbedPane

JTabbedPane 是 Java Swing 中用于创建选项卡式界面的组件 提供了一个选项卡式的界面,允许用户通过点击不同的选项卡来切换内容视图。每个选项卡可以包含不同的组件或信息,非常适合用于多页面的应用程序界面。

  • 常用方法
    • addTab(String title, Component component):添加一个新的选项卡。
    • setSelectedIndex(int index):选择指定索引处的选项卡。
    • setTitleAt(int index, String title):设置指定索引处选项卡的标题。

1. 基本概念与特点

  • 选项卡布局:支持顶部、底部、左侧或右侧放置标签。
  • 标签样式:可自定义标签文本、图标和工具提示。
  • 组件关联:每个标签对应一个组件(如 JPanelJTextArea 等)。
  • 动态操作:支持添加、删除和重排序标签。
  • 事件监听:可监听标签切换事件。

2. 常用构造方法

构造方法描述
JTabbedPane()创建默认标签位于顶部的选项卡面板。
JTabbedPane(int tabPlacement)指定标签位置(TOPBOTTOMLEFTRIGHT)。
JTabbedPane(int tabPlacement, int tabLayoutPolicy)指定标签位置和布局策略(WRAP_TAB_LAYOUT 或 SCROLL_TAB_LAYOUT)。

3. 核心方法

方法描述
addTab(String title, Component component)添加带标题的标签页。
addTab(String title, Icon icon, Component component)添加带标题和图标的标签页。
addTab(String title, Icon icon, Component component, String tip)添加带标题、图标和工具提示的标签页。
insertTab(String title, Icon icon, Component component, String tip, int index)在指定位置插入标签页。
removeTabAt(int index)移除指定位置的标签页。
setSelectedIndex(int index)选择指定索引的标签页。
setTabComponentAt(int index, Component component)设置标签的自定义组件(如带关闭按钮的标签)。
setTitleAt(int index, String title)修改指定标签的标题。
setIconAt(int index, Icon icon)修改指定标签的图标。
addChangeListener(ChangeListener listener)添加标签切换事件监听器。

4. 简单示例:基本选项卡面板

import javax.swing.*;
import java.awt.*;public class JTabbedPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("JTabbedPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 创建选项卡面板JTabbedPane tabbedPane = new JTabbedPane();// 添加第一个标签页JPanel panel1 = new JPanel();panel1.add(new JLabel("这是第一个标签页"));tabbedPane.addTab("标签1", panel1);// 添加第二个标签页(带图标)JPanel panel2 = new JPanel();panel2.add(new JLabel("这是第二个标签页"));Icon icon = new ImageIcon("path/to/icon.png"); // 替换为实际图标路径tabbedPane.addTab("标签2", icon, panel2, "这是第二个标签的提示");// 添加第三个标签页JPanel panel3 = new JPanel();panel3.add(new JLabel("这是第三个标签页"));tabbedPane.addTab("标签3", panel3);frame.add(tabbedPane);frame.setVisible(true);}
}

5. 标签位置与布局策略示例

import javax.swing.*;
import java.awt.*;public class TabPlacementExample {public static void main(String[] args) {JFrame frame = new JFrame("标签位置示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(800, 600);// 创建一个大的选项卡面板,包含四个方向的标签子面板JTabbedPane mainTabbedPane = new JTabbedPane();// 顶部标签JTabbedPane topTabs = new JTabbedPane(JTabbedPane.TOP);topTabs.addTab("顶部1", new JLabel("顶部标签1"));topTabs.addTab("顶部2", new JLabel("顶部标签2"));mainTabbedPane.addTab("顶部标签", topTabs);// 底部标签JTabbedPane bottomTabs = new JTabbedPane(JTabbedPane.BOTTOM);bottomTabs.addTab("底部1", new JLabel("底部标签1"));bottomTabs.addTab("底部2", new JLabel("底部标签2"));mainTabbedPane.addTab("底部标签", bottomTabs);// 左侧标签JTabbedPane leftTabs = new JTabbedPane(JTabbedPane.LEFT);leftTabs.addTab("左侧1", new JLabel("左侧标签1"));leftTabs.addTab("左侧2", new JLabel("左侧标签2"));mainTabbedPane.addTab("左侧标签", leftTabs);// 右侧标签JTabbedPane rightTabs = new JTabbedPane(JTabbedPane.RIGHT);rightTabs.addTab("右侧1", new JLabel("右侧标签1"));rightTabs.addTab("右侧2", new JLabel("右侧标签2"));mainTabbedPane.addTab("右侧标签", rightTabs);frame.add(mainTabbedPane);frame.setVisible(true);}
}

6. 动态操作与事件监听

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;public class DynamicTabExample {public static void main(String[] args) {JFrame frame = new JFrame("动态选项卡示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JTabbedPane tabbedPane = new JTabbedPane();// 添加初始标签页tabbedPane.addTab("标签1", new JLabel("初始标签页"));// 创建操作面板JPanel controlPanel = new JPanel();JButton addButton = new JButton("添加标签");JButton removeButton = new JButton("删除当前标签");controlPanel.add(addButton);controlPanel.add(removeButton);// 添加标签按钮事件addButton.addActionListener(new ActionListener() {private int tabCount = 2;@Overridepublic void actionPerformed(ActionEvent e) {tabbedPane.addTab("标签" + tabCount, new JLabel("新标签页 " + tabCount));tabCount++;}});// 删除标签按钮事件removeButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int selectedIndex = tabbedPane.getSelectedIndex();if (selectedIndex >= 0) {tabbedPane.removeTabAt(selectedIndex);}}});// 添加标签切换监听器tabbedPane.addChangeListener(e -> {int selectedIndex = tabbedPane.getSelectedIndex();if (selectedIndex >= 0) {System.out.println("切换到标签:" + tabbedPane.getTitleAt(selectedIndex));}});// 使用 BorderLayout 添加组件frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);frame.getContentPane().add(controlPanel, BorderLayout.SOUTH);frame.setVisible(true);}
}

7. 自定义标签组件(带关闭按钮)

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class ClosableTabExample {public static void main(String[] args) {JFrame frame = new JFrame("带关闭按钮的标签");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JTabbedPane tabbedPane = new JTabbedPane();// 添加初始标签页addClosableTab(tabbedPane, "标签1", new JLabel("内容 1"));addClosableTab(tabbedPane, "标签2", new JLabel("内容 2"));frame.add(tabbedPane);frame.setVisible(true);}private static void addClosableTab(JTabbedPane tabbedPane, String title, Component content) {// 添加标签页tabbedPane.addTab(title, content);// 获取标签索引int index = tabbedPane.indexOfTab(title);// 创建自定义标签组件(带文本和关闭按钮)JPanel tabComponent = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));tabComponent.setOpaque(false);JLabel titleLabel = new JLabel(title);tabComponent.add(titleLabel);JButton closeButton = new JButton("×");closeButton.setBorder(null);closeButton.setContentAreaFilled(false);closeButton.setFocusPainted(false);closeButton.setMargin(new Insets(0, 0, 0, 0));closeButton.addActionListener(e -> tabbedPane.remove(index));tabComponent.add(closeButton);// 设置自定义标签组件tabbedPane.setTabComponentAt(index, tabComponent);}
}

8. 注意事项

  1. 布局策略:当标签过多时,可使用 SCROLL_TAB_LAYOUT 启用滚动:

    JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
    
  2. 键盘导航:默认支持 Ctrl+Tab 和 Ctrl+Shift+Tab 切换标签,可通过 setMnemonicAt() 设置快捷键。

  3. 标签图标:图标应保持简洁,避免过大影响布局。

  4. 预加载与懒加载

    • 预加载:在初始化时创建所有标签页的组件。
    • 懒加载:在首次切换到标签页时创建组件(通过监听 ChangeListener 实现)。

JTabbedPane 是 Java Swing 中组织多页面界面的高效组件,通过标签切换可有效节省屏幕空间。其核心优势在于支持多种标签布局、动态操作和自定义样式,适用于需要分类展示内容

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

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

相关文章

Spark 单机模式部署与启动

&#x1f680; Spark 单机模式部署与启动教程&#xff08;适配 Hadoop 3.1.1&#xff09; 本文记录了在 Linux 环境中部署 Spark 的完整过程&#xff0c;使用 Standalone 单机模式&#xff0c;适配 Hadoop 3.1.1&#xff0c;最终可通过 Web 页面访问 Spark Master 状态界面。 …

JAVA学习 DAY2 java程序运行、注意事项、转义字符

本系列可作为JAVA学习系列的笔记&#xff0c;文中提到的一些练习的代码&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 点赞关注不迷路&#xff01;您的点赞、关注和收藏是对小编最大的支持和鼓励&#xff01; 系列文章目录…

Visual Studio 中的 MD、MTD、MDD、MT 选项详解

在Visual Studio中开发C++项目时,正确选择运行时库(runtime library)对于确保应用程序的性能、稳定性和兼容性至关重要。本文将详细介绍/MD, /MT, /MDd, 和 /MTd这些编译器选项的意义、应用场景及其区别。 MSVCRT.dll MSVCRT.dll 是 Microsoft Visual C++ Runtime Library …

EasyRTC嵌入式音视频通信SDK助力物联网/视频物联网音视频打造全场景应用

一、方案概述​ 随着物联网技术的飞速发展&#xff0c;视频物联网在各行业的应用日益广泛。实时音视频通信技术作为视频物联网的核心支撑&#xff0c;其性能直接影响着系统的交互体验和信息传递效率。EasyRTC作为一款成熟的音视频框架&#xff0c;具备低延迟、高画质、跨平台等…

栈的概念以及实现

目录: 一、栈的概念 二、栈的实现 1.栈的初始化 2.栈的销毁 3.入栈 4.出栈 5.获取栈顶数据 6.判断栈是否为空 7.获取栈的个数 三、代码 一、栈的概念 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端…

【Bluedroid】蓝牙启动之 SMP_Init 源码解析

蓝牙(安全管理协议,Security Management Protocol)是蓝牙设备安全通信的核心协议,负责配对、密钥协商和安全等级管理。本文围绕 Bluedroid SMP 协议的初始化流程展开,系统解析其核心控制块(tSMP_CB)的状态管理、与 L2CAP 层的接口注册,以及 P-256 椭圆曲线参数的初始化…

C++课设:考勤记录系统

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏介绍&#xff1a;《编程项目实战》 目录 一、项目背景与需求分析1. 传统考勤管理…

前端面试题之ES6保姆级教程

ES6 核心特性深度解析&#xff1a;现代 JavaScript 开发基石 2015 年发布的 ECMAScript 2015&#xff08;ES6&#xff09;彻底改变了 JavaScript 的编程范式&#xff0c;本文将全面剖析其核心特性及最佳实践 一、ES6 简介与背景 ECMAScript 6.0&#xff08;简称 ES6&#xff0…

CTF:网络安全的实战演练场

文章目录 每日一句正能量前言一、CTF简介&#xff08;一&#xff09;什么是CTF&#xff1f;&#xff08;二&#xff09;CTF的历史 二、CTF比赛形式&#xff08;一&#xff09;线上赛&#xff08;Online CTF&#xff09;&#xff08;二&#xff09;线下赛&#xff08;Offline CT…

如何自定义一个 Spring Boot Starter?

导语&#xff1a; 在后端 Java 面试中&#xff0c;Spring Boot 是绕不开的重点&#xff0c;而“如何自定义一个 Starter”作为进阶开发能力的体现&#xff0c;常被面试官用于考察候选人的工程架构思维与 Spring Boot 底层掌握程度。本文将带你深入理解自定义 Starter 的实现逻辑…

大学课程:计算机科学与技术专业主要课程,是否落伍了?

计算机科学与技术 计算机科学与技术&#xff08;CS&#xff09;是一门涵盖理论、系统、应用的综合学科&#xff0c;其课程体系围绕“计算机的底层原理、开发方法、技术创新”展开&#xff0c;既包含数学与理论基础&#xff0c;也涉及工程实践与前沿技术。以下是主要课程的分类…

docker-部署Nginx以及Tomcat

一、docker 部署Nginx 1、搜索镜像&#xff08;nginx&#xff09; [rootlocalhost /]# docker search nginx Error response from daemon: Get "https://index.docker.io/v1/search?qnginx&n25": dial tcp 192.133.77.133:443: connect: connection refused 简…

服务器信任质询

NSURLSession 与 NSURLAuthenticationMethodServerTrust —— 从零开始的“服务器信任质询”全流程 目标读者&#xff1a;刚接触 iOS 网络开发、准备理解 HTTPS 与证书校验细节的同学 出发点&#xff1a;搞清楚为什么会有“质询”、质询的触发时机、以及在 delegate 里怎么正确…

MCP协议重构AI Agent生态:万能插槽如何终结工具孤岛?

前言 在人工智能技术快速发展的2025年&#xff0c;MCP(Model Context Protocol&#xff0c;模型上下文协议)正逐渐成为AI Agent生态系统的关键基础设施。这一由Anthropic主导的开放协议&#xff0c;旨在解决AI模型与外部工具和数据源之间的连接难题&#xff0c;被业界形象地称…

测试 FreeSWITCH 的 mod_loopback

bgapi originate loopback/answer,park/default/inline park inline show channels as xml show calls as xml 有 2 个 channels 有 2 个 calls 比较有意思 在 loopback-a 是播放 wav 在 loopback-b 上可以录音 这就是回环 有什么用呢&#xff1f; 除了做测试&#x…

三维GIS开发cesium智慧地铁教程(4)城市白模加载与样式控制

一、添加3D瓦片 <!-- 核心依赖引入 --> <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"><!-- 模型数据路径 --> u…

Unity 中的颜色空间

一、颜色空间基本概念疑问 1、什么是颜色空间&#xff1f; 颜色空间是一个数学模型或系统&#xff0c;它定义了一套规则和方法&#xff0c;用来精确地描述、表示和组织颜色。​ 可以把它想象成一个三维坐标系​&#xff08;或者有时更多维&#xff09; 每个维度代表一…

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…

Python----目标检测(YOLO简介)

一、 YOLO简介 [YOLO](You Only Look Once&#xff09;是一种流行的物体检测和图像分割模型&#xff0c; 由华盛顿大学的约瑟夫-雷德蒙&#xff08;Joseph Redmon&#xff09;和阿里-法哈迪&#xff08;Ali Farhadi&#xff09;开发&#xff0c;YOLO 于 2015 年推出&#xff0c…

OLED(SSD306)移植全解-基于IIC

OLED&#xff08;SSD306&#xff09;移植全解-基于IIC 一&#xff0c;什么是oled?二&#xff0c;什么是IIC协议三&#xff0c;IIC通信流程&#xff1a;四&#xff0c;针对SSD1306的IIC通信流程&#xff08;结合芯片手册版&#xff09;1&#xff0c;主机发送起始信号2&#xff…