swing206界面线程与工作线程

[MFC]界面线程和工作线程 1.前言MFC提供了2中线程的实现方式,一种是界面线程,可以处理来自系统的消息,比如窗口的点击事件;一种是工作线程,用于处理繁琐的计算或者长时间的任务,例如后台打印,计算等。2.界面线程界限线程的创建需要继承父类CWinThread,并继承与重写部分父类方法。见下表所示: 方法 说明 ExitInstance 线程退出所需的工作 InitInstance 线程创建的时候需要的工 阅读详情

事件循环

在这里插入图片描述

package my;

import java.awt.Container;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Swing2
{
	private static void createGUI()
	{
		// JFrame指一个窗口,构造方法的参数为窗口标题
		// 语法:因为MyFrame是JFrame的子类,所以可以这么写
		JFrame frame = new MyFrame("Swing Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		// 设置窗口的其他参数,如窗口大小
		frame.setSize(500, 300);
		
		// 显示窗口
		frame.setVisible(true);
		
		
	}
	
	public static void main(String[] args)
	{
		// 此段代码间接地调用了 createGUI(),具体原理在 Swing高级篇 里讲解
		// 初学者先照抄此代码框架即可
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run()
			{
				createGUI();
			}
		});

	}
}

package my;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyFrame extends JFrame
{
	JTextField textField = new JTextField(20);
	JButton okButton = new JButton("OK");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new FlowLayout());

		root.add(textField);
		root.add(okButton);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{
				textField.setText("2019-02-14");
			}			
		});
	}

	
}

界面卡顿

在这里插入图片描述

package my;

import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyFrame extends JFrame
{
	JTextField textField = new JTextField(20);
	JButton okButton = new JButton("OK");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new FlowLayout());

		root.add(textField);
		root.add(okButton);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{				
				onMouseClicked();				
			}			
		});
	}

	// 按钮点击事件处理
	private void onMouseClicked()
	{
		try
		{
			System.out.println("Ma");
			Thread.sleep(3000); 
			
			System.out.println("Mi");
			Thread.sleep(3000); 
			
			System.out.println("Hong");
			Thread.sleep(3000);
			
		} catch (Exception e1){} 
	}
}

创建工作线程

在这里插入图片描述

package my;

import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyFrame extends JFrame
{
	JTextField textField = new JTextField(20);
	JButton okButton = new JButton("OK");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new FlowLayout());

		root.add(textField);
		root.add(okButton);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{				
				onMouseClicked();				
			}			
		});
	}

	// 按钮点击事件处理
	private void onMouseClicked()
	{
		MyWorkThread th = new MyWorkThread();
		th.start();
	}
	
	private class MyWorkThread extends Thread
	{

		@Override
		public void run()
		{
			try
			{
				System.out.println("Ma");
				Thread.sleep(3000); 
				
				System.out.println("Mi");
				Thread.sleep(3000); 
				
				System.out.println("Hong");
				Thread.sleep(3000);
				
			} catch (Exception e1){} 
		}
		
	}
}

更新界面

在这里插入图片描述

package my;

import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class MyFrame extends JFrame
{
	JTextField textField = new JTextField(20);
	JButton okButton = new JButton("OK");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new FlowLayout());

		root.add(textField);
		root.add(okButton);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{				
				onMouseClicked();				
			}			
		});
	}

	// 按钮点击事件处理
	private void onMouseClicked()
	{
		MyWorkThread th = new MyWorkThread();
		th.start();
	}
	
	private class MyWorkThread extends Thread
	{

		@Override
		public void run()
		{
			try
			{
				updateUI("Ma");
				Thread.sleep(3000); 
				
				updateUI("Mi");
				Thread.sleep(3000); 
				
				updateUI("Hong");
				Thread.sleep(3000);
				
			} catch (Exception e1){} 
		}
		
		// 更新界面
		private void updateUI(String progress)
		{
			SwingUtilities.invokeLater( new Runnable() {				
				@Override
				public void run()
				{
					// 在匿名类里,也可以直接访问上层方法里的局部变量
					// 比如, progress就是一个局部变量
					// 这个语法真要解释起来比较复杂,大家直接用就行,先不要管那么多
					textField.setText( progress );
				}
			});
		}
	}
}

倒计时练习

在这里插入图片描述

package my;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class MyFrame extends JFrame
{
	JLabel display = new JLabel("准备");
	JButton okButton = new JButton("开始");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new BorderLayout());

		root.add(okButton, BorderLayout.PAGE_START);
		root.add(display, BorderLayout.CENTER);
				
		display.setFont(new Font("宋体", Font.PLAIN, 80));
		display.setHorizontalAlignment(SwingConstants.CENTER);
		display.setOpaque(true);
		display.setBackground(Color.WHITE);
		display.setForeground(Color.BLUE);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{				
				onMouseClicked();				
			}			
		});
	}

	// 按钮点击事件处理
	private void onMouseClicked()
	{
		okButton.setEnabled(false); // 禁用按钮
		
		MyWorkThread th = new MyWorkThread();
		th.start();		
	}
	
	private class MyWorkThread extends Thread
	{
		@Override
		public void run()
		{
			int n = 5;
			while(n > 0)
			{
				// 更新界面:显示倒计时
				
				// 语法:传到内部类使用的局部变量,必须为final ( 默认final)
				final String text = String.valueOf(n);
				SwingUtilities.invokeLater ( ()->{
					//在内部类里可以直接使用外部方法的final局部变量
					display.setText( text ); 
				});	
				
				n -= 1;
				try { Thread.sleep(1000);}catch(Exception e) {}					
			}
			
			// 结束时最后更新界面
			SwingUtilities.invokeLater ( ()->{
				display.setText("新年快乐");
				okButton.setEnabled(true);
			});			
		}

	}
}

匿名内部类访问局部变量

package my;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class MyFrame extends JFrame
{
	JLabel display = new JLabel("准备");
	JButton okButton = new JButton("开始");
	
	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new BorderLayout());

		root.add(okButton, BorderLayout.PAGE_START);
		root.add(display, BorderLayout.CENTER);
				
		display.setFont(new Font("宋体", Font.PLAIN, 80));
		display.setHorizontalAlignment(SwingConstants.CENTER);
		display.setOpaque(true);
		display.setBackground(Color.WHITE);
		display.setForeground(Color.BLUE);
		
		okButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{				
				onMouseClicked();				
			}			
		});
	}

	// 按钮点击事件处理
	private void onMouseClicked()
	{
		okButton.setEnabled(false); // 禁用按钮
		
		MyWorkThread th = new MyWorkThread();
		th.start();		
	}
	
	private class MyWorkThread extends Thread
	{
		@Override
		public void run()
		{
			int n = 5;
			while(n > 0)
			{
				// 更新界面:显示倒计时				
				final String text = String.valueOf(n);
				
				SwingUtilities.invokeLater ( new Runnable() {					
					@Override
					public void run()
					{							
						// 语法:匿名类可以直接访问外面的final局部变量
						display.setText( text );						
					}
				});	
				
				n -= 1;
				try { Thread.sleep(1000);}catch(Exception e) {}					
			}
		}
	}
	
	private class MyUpdater implements Runnable
	{
		String text;
		
		public MyUpdater(String text)
		{
			this.text = text;
		}

		@Override
		public void run()
		{
			display.setText( text ); 
		}
	}
}

使用 MATLAB/Simulink 对风光互补发电系统进行建模 随着全球对清洁能源的需求日益增长,风力发电和光伏发电作为两种主要的可再生能源形式,在电力供应中的占比越来越高。然而,由于风电和光伏的间歇性和不确定性,单独依赖其中任何一种能源都会给电网带来挑战。因此,风光互补发电系统(Wind-PV Hybrid System)应运而生,通过合理配置风力发电机和光伏电池板的数量,可以有效提高系统的稳定性和可靠性。此外,为了确保整个电力系统的安全稳定运行,还需要研究风光互补发电系统与主网之间的协调调度策略。本教程将详细介绍如何使用。 阅读详情

相关推荐

MinerU与Docling:智能文档处理框架对比

本文对比分析了MinerU和Docling两大智能文档处理框架。MinerU专注于高精度PDF解析,采用多模态AI技术,在学术文献、金融报表等复杂文档处理上表现优异;Docling则定位企业级多格式文档处理平台,支持10+格式转换,更适合文档管理系统等场景。技术层面,MinerU基于VLM模型实现端到端处理,Docling采用插件化多后端架构。性能测试显示MinerU精度更高(95%+),但资源消耗较大;Docling处理速度更快(1-3秒/页),部署更灵活。

轩哥的个人研究和成长记录 1916

Windows 线程漫谈——界面线程和工作者线程

每个系统都有线程,而线程的最重要的作用就是并行处理,提高软件的并发率。针对界面来说,还能提高界面的响应力。 线程分为界面线程和工作者线程,界面实际就是一个线程画出来的东西,这个线程维护一个“消息队列”,“消息队列”也是界面线程和工作者线程的最大区别,这个词应该进到你的脑子里,根深蒂固的!如果在界面线程的某个地方停住,这说明它处理不了窗口消息了,所以有时候我们就会看到整个界面无响应了。这种问

一雨田的专栏 1万+

Unity3D用c#脚本调用前端javascript函数:H5获取unity - webgl 加载并初始化完成的消息

unity3d发布的Webgl 可以作为静态文件加载到H5页面中,并通过javascript 调用unity内置的C#脚本函数,详见Webgl调用unity api。而往往我们需要知道Webgl ready的消息,本文将给出unity 内部调用javascript函数的方案加以解决。

Bravo 2477

用户界面线程与工作者线程

<br />1、 做要用的用户界面,即对话框Dialog1,取名IDD_DIALOG1<br />2、 建立对话框对应的类,如是病人的基本信息录入,取名为CBingLi,生成BingLi.h和 BingLi.cpp<br />3、  建立要用的用户界面线程的类,为了与对话框的名字相照应,取名为CbingLiThread,会自动生成.h和.cpp文件,注意:在生成用户界面线程类的时候,基类要用CWinThread<br />4、 在BingLiThread.h中嵌入头文件#include "BingLi.h"

萝卜 白菜 1443

构建多节点AI代理网络:OpenClaw协同框架与实战部署指南

在分布式系统与AI代理技术领域,多节点协同是提升智能体能力与扩展性的核心挑战。其原理在于通过设计清晰的通信协议与数据同步机制,使分散的智能体能够共享状态、知识与技能,从而实现1+1>2的群体智能。这一技术价值在于突破了单点AI的能力上限,为构建复杂、鲁棒且可扩展的自动化系统提供了基础。典型的应用场景包括跨设备任务编排、企业级工作流自动化以及大规模AI代理集群的管理。本文聚焦于OpenClaw这一开源AI代理框架,深入探讨如何利用模块化设计(如网状网络与任务控制中心)实现记忆共享与统一调度,解决多网关协同中的

weixin_42521032的博客 298

10.嵌入式控制器EC实战 GPIO开发流程

文章目录1.General Control Register (GCR),通用控制寄存器,地址0x1602.GPDRA—GPDRJ端口数据寄存器组(共10组)3.Port Control n Registers (GPCRn, n = A0-I7),端口控制寄存器4.GPIO端口编程指导编程步骤端口初始化使用InitGPIOReg数据结构初始化所有端口默认工作模式读取输入引脚的值(STATE_ACin()): IT8502中各个引脚的描述见下表所示: 在嵌入式控制器EC的IT8502主控芯片中,通过芯片的

qq_30135687的博客 2285

MFC工作者线程和用户界面线程

MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。   工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。但对于Win32的API编程而言,这两种线程是没有区别的,它们...

Txwtech 3717

【PyTorch项目实战】之ResNet系列:resnet18、resnet34、resnet50、resnet101、resnet152

ResNet (Residual Network) :是一种深度卷积神经网络(CNN)架构,其核心思想是引入残差学习(Residual Learning)机制,通过跳跃连接(skip connections)来解决深层网络训练中的退化问题。

📷 图像处理践行者 | 传统算法 · 深度学习 · 多模态 | 分享实战经验与技术洞见,探索从像素到智能的无限可能。 6376

工作线程与界面线程

工作线程与界面线程 区别 工作线程与界面线程的区别在于:消息循环 模态对话框有自己的消息循环 非模态对话框需要其所在线程中有消息循环 MSG msg = { 0 }; while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } 在界面的操作时最好还是在界面线程中进行处理,但是如果处理的是非本线程的窗口时建议用发消息的方式! 界面线程的创建: 使用类向

qq_43630810的博客 471

【某音电商】protobuf聊天协议逆向

某音电商私信、聊天消息protobuf协议逆向分析与解析

吴秋霖的博客 2316

Flow Matching05:概率路径与插值【概率路径:线性插值路径(最简单)、高斯插值路径】【先尝试线性插值,看效果如何;若不够好,尝试高斯插值】

好的,我将从数学角度详细解释Flow Matching,从高中生能理解的基础知识开始,逐步深入到高级概念。

u013250861的博客 174

工作线程不要对界面操作

MFC并不是线程安全的,用子线程操作用户界面,可能导致线程主线程无法终止。 例如在子线程处理函数中进行如下操作: Ondestroy中等待子线程结束: 当关闭对话框时后,从资源管理器中依旧可以看到线程并未终止。 另外,企图在线程处理函数结束时弹出一个MessageBox进行直观确认时,不能使用MFC中的MessageBoX,因其默认以对话框作为父窗口,这样也

xiaoluo91的专栏 2081

【云原生】Docker可视化工具Portainer使用详解

Docker可视化工具Portainer使用详解

congge 1万+

java中级相关

在Swing程序的开发中,需要建立3种线程的概念 初始化线程 初始化线程用于创建各种容器,组件并显示他们,一旦创建并显示,初始化线程的任务就结束了。 事件调度线程 通过事件监听的学习,我们了解到Swing是一个事件驱动的模型,所有和事件相关的操作都放是放在事件调度线程 (Event Dispatch)中进行的。比如点击一个按钮,对应的ActionListener.actionPerform...

zoinsung_lee的博客 433

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Swing-界面线程与工作线程(创建工作线程)

工作线程: *Work Thread 如果事件处理较长时间,应当创建一个线程来处理这个任务。此线程称为“工作线程” *界面线程:一直运行,处理界面事件 *工作线程:工作完成后退出 *线程的特点:独立、并发 code: ButtonThread: package my; public class ButtonThread extends Thread { @O...

给你更好的 1205

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

java swing 多个线程_Swing中的线程并发处理

理论解释见官方的文档:一个Swing程序中一般有下面三种类型的线程:初始化线程(Initial Thread)UI事件调度线程(EDT)任务线程(Worker Thread),可以看成后台其他的线程每个程序必须有一个main方法,这是程序的入口。该方法运行在初始化或启动线程上。初始化线程读取程序参数并初始化一些对象。在许多Swing程序中,该线程主要目的是启动程序的图形用户界面(GUI)。一旦GU...

weixin_42465051的博客 692

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 295

信创环境下PageOffice文档控件适配与实践

信创适配做到文档控件这一层,拼的已经不是"有没有国产版本",而是同一个功能在两类终端上是否真的等价。等价的标准很具体:同一次点击能得到同样的结果,同一份公文能得到同样的版式,同一个项目不需要维护两套代码。这背后是三件并不轻松的工作:服务端用一套接口同时支撑两类终端,客户端把两种系统与四种芯片的安装包分发清楚,文档内核层由产品侧跟着 WPS 的版本走。浏览器这一层的压力,则被收进了产品自己的窗口里——升级节奏由产品掌握,不再交给运气。

zi_wu_xian的专栏 326

第三篇 第 6 课

前置:第三篇第 1 课(stdx 引入),第二篇第 1 课(std.regex)。环境:仓颉 SDK 1.2.0。本文所有代码与输出均逐行实测。

weixin_41618057的博客 513

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 351

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 532

Java 集合容器高频面试题全解:HashMap 树化阈值、1.7 死循环与 ConcurrentHashMap 演进(2026 招聘 JD 真题复盘)

HashMap 树化阈值 8 的泊松分布依据、退化阈值 6 的防抖设计、JDK 1.7 头插成环死循环的排查与修复、1.8 尾插后为何仍线程不安全、ConcurrentHashMap 放弃分段锁的原因与 ForwardingNode 协作扩容、computeIfAbsent 死锁陷阱、大集合找重复的场景题选型,附三层追问链自测。题目来源为 38 期公开招聘 JD 样本与字节、拼多多、建行、美团、快手公开面经。

蒙眼过河 417

spdlog 同步日志库使用详解

spdlog是一个轻量级 C++ 日志库,支持同步日志、异步日志、多线程日志、日志文件轮转和自定义日志格式。对于嵌入式 Linux 应用开发,我建议先使用。它可以帮我们完成:日志级别过滤。时间戳和线程 ID 输出。日志格式化。终端和文件输出。多线程安全写入。日志文件按大小或时间轮转。我们不需要自己实现互斥锁、文件写入、日志格式化和轮转等底层功能。

zengjiajun2006的博客 1118

JavaSE通关手册:数据类型与变量

代码无需额外处理,编译时编译器自动完成转换。

xys_678的博客 207

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 367
上一篇: swing205图表
下一篇: swing207短任务
dingpython
博客等级 码龄6年 5粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值