配色: 字号:
《Java语言编程基础立体化实用教程》2-3 登录窗体的实现
2023-05-25 | 阅:  转:  |  分享 
  
任务九 登录窗体的实现学习目标1.了解窗体绝对布局的方法;2.掌握JTextField、JPasswordField、JButton、JL
abel等控件的使用;3.掌握JFrame窗体的构造方法及属性设置。任务九 登录窗体的实现一、任务描述 通常一个系统
的登录需要输入用户名和密码才能实现。这里用户名和密码的匹配需要连接数据库比对后,根据匹配结果显示应用程序窗体,或提示用户名密码错误
等信息。在本任务中,我们对登录功能进行简化,设定用户名为“anne”,密码为“123456”时才能登录系统,否则提示错误信息。任务
九 登录窗体的实现二、任务分析操作步骤如下:步骤一:创建JFrame应用程序窗体LoginFrame;步骤二:为窗体设置合适的颜
色;步骤三:为窗体设置合适的布局;步骤四:添加标签、文本框、按钮等控件;步骤五:为按钮添加响应事件。任务九 登录窗体的实现三、任
务实施 任务概览:pubic class Log
inFrame{private JLabel lblSno;private JLabel lblSname;private JTe
xtField txtSno;private JTextField txtSname;private JButton btnSub
mit;private JButton btnClear;LoginFrame(){};initComponents(){};}图
9-1任务执行效果图任务九 登录窗体的实现三、任务实施
步骤一:创建JFrame应用程序窗体LoginFrame;1.在com.sdlg.view包上右单击,选择“new”,选
择“class”,创建新的类LoginFrame。代码如下所示:package com.sdlg.view;?import jav
ax.swing.JFrame;public class LoginFrame extends JFrame{ public
LoginFrame() { this.setTitle("登录");//设置窗体标题,这里及以后的this可以省
略 this.setVisible(true);//设置可见性,为false时,窗体不可见 this.
setSize(500,400);//设置窗体大小,width为500px,height为400px this.se
tLocation(0,0);//设置窗体位置,窗体左上角定点坐标为(0,0) } public static void m
ain(String[] args) { new LoginFrame();? }}【注意】LoginFrame需要继承JFra
me类。运行结果:图9-2 登录窗口显示任务九 登录窗体的实现三、任务实施
2.在SCMS项目上右单击,选择“new”,选择“folder”,打开新建文件夹窗口,填入文件名“i
mag”(存放图片),将“main.jpg”图片拷贝到imag文件夹中,单击确定,如下图所示:图9-3 新建文件夹菜单图9-4新建
imag文件夹任务九 登录窗体的实现三、任务实施
3.进一步改进代码,使得窗口位于屏幕的中心位置,并为窗体设置背景颜色,并为窗体添加图标,代码如下:package com.sd
lg.view;import java.awt.Image;import java.awt.Toolkit;import java
x.swing.ImageIcon;import javax.swing.JFrame;public class LoginFra
me extends JFrame{ public LoginFrame() { // 获得屏幕宽度 double wid
th = Toolkit.getDefaultToolkit().getScreenSize().getWidth(); //
获得屏幕高度 double height = Toolkit.getDefaultToolkit().getScreenSize
().getHeight(); this.setTitle("登录"); // 设置窗体的背景颜色 this.getCont
entPane().setBackground(new Color(240, 255, 255)); this.setSize(
500, 400); // 设置屏幕左上角x坐标为屏幕宽度减去窗体宽度的一半,y坐标为屏幕高度减//去窗体高度的一半 this
.setLocation((int) (width - 500) / 2, (int) (height - 400) / 2);
// 设置窗体布局为绝对布局 this.setLayout(null); // 初始化各控件,在后面的步骤完成该方法的定义
//initComponents(); // 加载窗体图标对象 this.setVisible(true); 任务九 登
录窗体的实现三、任务实施 3.进一步改进代码,使
得窗口位于屏幕的中心位置,并为窗体设置背景颜色,并为窗体添加图标,代码如下: Image image = new ImageIc
on("./imag/main.jpg").getImage(); // 设置窗体的图标和标题 setIconImage(im
age); } public static void main(String[] args) { new LoginFrame(
);? }}运行结果:图9-5 窗体居中显示图9-6 登录窗体细节图任务九 登录窗体的实现三、任务实施
步骤二:在LoginFrame的构造方法中增加如下代码和注释,为窗体设置
背景颜色。这里Color是一个类,其参数的取值范围都为0-255,分别代表红色、绿色、蓝色,是RGB模式里的分量,其次,使用Col
or类时,行首提示错误是因为未引入相关的包,在行首单击叉号,弹出修正提示,单击第一行引入java.awt.Color类可自动引入相
应的类,完成修正代码的工作。图9-7设置窗体颜色代码和注释图9-8引入相关的类 增加代码之后,发现窗体颜色发生改变。任务九 登录
窗体的实现三、任务实施 步骤三:在LoginFr
ame的构造方法中增加如下代码和注释,为窗体设置绝对布局,该语句出现在setVisible(true)之间;图9-9设置窗体为绝对
布局【注意】绝对布局模式下,可通过设置控件的位置和大小来实现窗体布局。任务九 登录窗体的实现三、任务实施
步骤四:为该类创建initComponents()方法,添加标签、文本
框、按钮等控件。initComponents方法初始化各控件,该方法的调用要放在setVisible(true)之前。代码如下所示
:package com.sdlg.view;import java.awt.Color;import java.awt.Font
;import java.awt.Image;import java.awt.Toolkit;import java.awt.ev
ent.ActionEvent;import java.awt.event.ActionListener;import javax
.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JF
rame;import javax.swing.JLabel;import javax.swing.JOptionPane;imp
ort javax.swing.JTextField;public class LoginFrame extends JFrame
{ private JLabel lblSno; private JLabel lblSname; private JTextF
ield txtSno; private JTextField txtSname; private JButton btnSubm
it; private JButton btnClear; public LoginFrame() { ... //取消上一步
骤中initComponents()前的注释符号,其余代码与上一步骤相同 initComponents(); ... }任务九
登录窗体的实现三、任务实施 步骤四:为该类创
建initComponents()方法,添加标签、文本框、按钮等控件。initComponents方法初始化各控件,该方法的调用要
放在setVisible(true)之前。代码如下所示: public void initComponents() { lblS
no = new JLabel("学号"); lblSno.setFont(new Font("微软雅黑", Font.PLAI
N, 16)); lblSno.setBounds(120, 67, 54, 15); this.add(lblSno);
lblSname = new JLabel("姓名"); lblSname.setFont(new Font("微软雅黑", F
ont.PLAIN, 16)); lblSname.setBounds(120, 133, 54, 15); this.add
(lblSname); txtSno = new JTextField(); txtSno.setFont(new Font(
"微软雅黑", Font.PLAIN, 16)); txtSno.setBounds(200, 67, 147, 28); t
xtSno.setColumns(30); this.add(txtSno); txtSname = new JTextFie
ld(); txtSname.setFont(new Font("微软雅黑", Font.PLAIN, 16)); txtSn
ame.setBounds(200, 133, 147, 28); txtSname.setColumns(30); this
.add(txtSname); btnSubmit = new JButton("登录"); btnSubmit.setFon
t(new Font("微软雅黑", Font.PLAIN, 16)); btnSubmit.setBounds(120, 20
0, 100, 28);任务九 登录窗体的实现三、任务实施
步骤四:为该类创建initComponents()方法,添加标签、文本框、按钮等控件。initComponents方
法初始化各控件,该方法的调用要放在setVisible(true)之前。代码如下所示: this.add(btnSubmit);
btnClear = new JButton("清空"); btnClear.setFont(new Font("微软雅黑"
, Font.PLAIN, 16)); btnClear.setBounds(250, 200, 100, 28); this
.add(btnClear);// 通过匿名内部类实现监听器,代码在下一步骤完成 } public static void ma
in(String[] args) { new LoginFrame(); }}运行结果:图9-10登录窗体显示任务九 登录窗
体的实现三、任务实施 步骤五:为按钮添加响应事件
。 //通过匿名内部类实现监听器btnSubmit.addActionListener(new ActionListener(
) { public void actionPerformed(ActionEvent e) { if(((txtSno.get
Text().trim()).equals("anne"))&&((txtSname.getText().trim()).equa
ls("123456")))//提示窗口的实现,第二个字符串参数显示在提示框中 JOptionPane.showMessage
Dialog(null, "您已经成功登录系统"); else JOptionPane.showMessageDialog(
null, "您的用户名或密码错误"); } });btnClear.addActionListener(new Action
Listener() { public void actionPerformed(ActionEvent e) { tx
tSno.setText("");//设置txtSno文本框为空 txtSname.setText("");//设置txtS
name文本框为空 }});运行结果:图9-11登录成功提示图9-12登录失败提示【注意】待完成应用程序主窗体后,应将“登录成
功提示”更改为“显示主窗体”,其实现代码为“new MainFrame();”。任务九 登录窗体的实现四、相关知识9.4.1 A
WT和SwingJava提供的两个处理图形用户界面的类库:java.awt包和javax.swing包,GUI的类库可分为:容器类
、布局管理器类和组件类。1.AWT简介AWT(Abstract Windows Toolkit):抽象窗口工具包。在java.aw
t包中提供了大量地进行GUI设计所使用的类和接口:绘制图形、设置字体和颜色、控制组件、处理事件等,AWT是Java语言进行GUI程
序设计的基础。缺点:组件的创建和行为是由程序所在平台的本地GUI工具处理,限制了不同平台行为效果的一致性,所以被称为抽象的工具集。
任务八 学生成绩操作接口的实现四、相关知识9.4.1 AWT和SwingJava提供的两个处理图形用户界面的类库:java.aw
t包和javax.swing包,GUI的类库可分为:容器类、布局管理器类和组件类。2.Swing简介javax.swing包是ja
va.awt包的扩展包:(1)Swing包是Java基础类库的一部分,它提供了从按钮到可分拆面板和表格的所有组件;(2)Swing
组件是Java提供的第二代GUI设计工具包,它以AWT为基础,并在此基础上新增或改进了一些GUI组件,使得GUI程序功能更强大,设
计更容易、更方便;(3)Swing的组件是“轻量级”(lightweight)组件,任一Swing组件要显示在屏幕上,都要由一个顶
层容器容纳;(4)Swing中组件的类名常以“J”开头,以与AWT相应组件区别。Swing位于javax.swing包中,java
x是java的一个扩展包。任务九 登录窗体的实现四、相关知识9.4.1 AWT和Swing3.AWT和swing的不同(1)AW
T是Swing的基础,Swing产生主要原因是AWT不能满足图形用户界面发展的需要;(2)Swing组件没有本地代码,不依赖于操作
系统平台的支持,这是它与AWT组件的最大区别;(3)Swing由百分百纯Java实现,不依赖操作系统的支持, 在不同的平台上的表现
都是一致的,比AWT组件具有更强的可移植性和灵活性。任务九 登录窗体的实现四、相关知识9.4.1 AWT和Swing【例9.1】
利用AWT包中的Frame类创建窗体import java.awt.;public class Exp91 { public
static void main(String[] args) { Frame f = new Frame("AWT"); f
.add(new Button("AWT窗体!")); f.setSize(400, 400); f.setVisible(t
rue); }}【注意】这里单击窗体按钮无法关闭窗体,需要添加窗体事件才能实现关闭窗体功能。运行结果:图9-13 AWT窗体显示
任务九 登录窗体的实现四、相关知识9.4.1 AWT和Swing【例9.2】利用Swing包中的JFrame类创建窗体impor
t java.awt.;public class Exp91 { public static void main(String
[] args) { Frame f = new Frame("AWT"); f.add(new Button("AWT窗体!
")); f.setSize(400, 400); f.setVisible(true); }}【注意】这里只有设置了大小和可
见性之后窗体才能正常显示出来。运行结果:图9-14 Swing窗体显示任务九 登录窗体的实现四、相关知识9.4.2 JFram
e1.JFrame的常用构造方法和常用方法如下表所示:表9-1 JFrame部分构造方法任务八 学生成绩操作接口的实现四、相关知
识9.4.2 JFrame1.JFrame的常用构造方法和常用方法如下表所示:表9-2 JFrame常用方法任务九 登录窗体的实
现四、相关知识9.4.2 JFrame2.创建一个窗体的两种方法1)在程序中定义一个JFrame对象,通过对象来设置相关属性,如【
例9.2】所示;2)自定义一个类继承JFrame对象,在该类的构造方法中设置窗体相关属性,最后实例化该类,形成窗体,如下面的例子所
示,它实现了和【例9.2】同样的功能。任务九 登录窗体的实现四、相关知识9.4.2 JFrame【例9.3】第二种创建窗体的方式
import java.awt.Dimension;import javax.swing.JButton;import javax
.swing.JFrame;public class Exp93 extends JFrame{ public Exp93() {
this.setTitle("Swing"); this.setSize(new Dimension(400,400));/
/setSize的第二种使用方法 this.add(new JButton("Swing窗体!")); this.setVis
ible(true);//EXIT_ON_CLOSE使用System.exit方法退出应用程序,仅在应用程序中使用 this.s
etDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static vo
id main(String[] args) { new Exp93(); }}任务九 登录窗体的实现四、相关知识9.4.3
JTextFieldJTextField即文本框控件,用来接收用户输入的单行数据。JTextFiled的常用构造方法如下表所示:表
9-3 JTextFiled构造方法任务九 登录窗体的实现四、相关知识9.4.3 JTextFieldJTextField即文本
框控件,用来接收用户输入的单行数据。JTextFiled的常用方法如下表所示:表9-4 JTextFiled常用方法任务九 登录
窗体的实现四、相关知识9.4.4 JPasswordFieldJPasswordField为密码框,它扩展了JTextFiled的
功能,特点是当用户输入数据后,数据不显示为正常字符,将会被特定字符(默认为“”)隐藏。JPasswordField jp=new
JPasswordField();//echochar设置为a,这样该密码框输入的信息将会被a隐藏jp.setEchoChar(
‘a’);任务九 登录窗体的实现四、相关知识【例9.4】文本框和密码框示例import java.awt.Dimension;i
mport java.awt.FlowLayout;import javax.swing.JFrame;import javax.
swing.JPasswordField;import javax.swing.JTextField;public class E
xp94 extends JFrame{ public Exp94() { this.setTitle("文本框测
试"); this.setSize(new Dimension(400,500)); this.setLayout(n
ew FlowLayout());//设置窗体为流式布局 JTextField txt1=new JTextField();
//创建文本框对象txt1 JTextField txt2=new JTextField();//创建文本框对象txt2
JTextField txt3=new JTextField();//创建文本框对象txt3 JPasswordFiel
d txt4=new JPasswordField();//创建密码框对象txt4 txt1.setColumns(20);
//设置文本框列数 txt2.setColumns(20);//设置文本框列数 txt3.setColumns(20)
;//设置文本框列数 txt4.setColumns(20);//设置密码框列数 txt2.setText("ok")
;//设置文本框txt2的显示文本 txt2.setEditable(false);//文本框txt2设置为非可编辑的
txt3.setEnabled(false);//设置txt3文本框为不可用 this.add(txt1);//将文本框
txt1添加到窗体上 this.add(txt2);//将密码框txt2添加到窗体上 this.add(txt3);/
/将密码框txt3添加到窗体上 this.add(txt4);//将密码框txt4添加到窗体上 txt4.setEch
oChar(''$'');//设置密码框显示字符为"$" this.setVisible(true); pac
k(); } public static void main(String[] args) { new Exp94(
); }}运行结果:图9-15 文本框和密码框示例运行结果【注意】第二个文本框为不可编辑,第三个文本框为不可
用,此时文本框都不能输入信息。任务九 登录窗体的实现四、相关知识9.4.5 JButtonButton即按钮控件,
用来与用户进行交互,响应用户的操作。JButton的常用构造方法如下表所示:表9-5 JButton构造方法任务九 登录窗体的实
现四、相关知识9.4.5 JButtonButton即按钮控件,用来与用户进行交互,响应用户的操作。JButton的常用方法如下表
所示:表9-6 JButton常用方法任务九 登录窗体的实现四、相关知识9.4.5 JButtonButton即按钮控件,用来与
用户进行交互,响应用户的操作。JButton的常用方法如下表所示:表9-6 JButton常用方法任务九 登录窗体的实现四、相关
知识9.4.5 JButton【例9.5】按钮示例程序import java.awt.FlowLayout;?import jav
ax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.JBu
tton;import javax.swing.JFrame;?public class Exp95 extends JFrame
{ private FlowLayout flowlayout1; //创建流式布局flowlayout
1 private JButton btn1; //创建按钮btn1 private
JButton btn2; //创建按钮btn2 private JButton
btn3; //创建按钮btn3 public Exp95() { thi
s.setTitle("按钮示例"); flowlayout1=new FlowLayout(); this.setL
ayout(flowlayout1); Icon icon=new ImageIcon("imag/main.jpg");
//加载imag文件夹下的图片 btn1=new JButton("文本only"); //实例化bt
n1为只有文本的按钮 btn2=new JButton(icon); //实例化btn2
为只有图片的按钮 btn3=new JButton("文本和图片",icon); //实例化btn3为含图片文本的按
钮 任务九 登录窗体的实现四、相关知识9.4.5 JButton【例9.5】按钮示例程序 this.add(btn1);
//将btn1添加到窗体 this.add(btn2);
//将btn2添加到窗体 this.add(btn3);
//将btn3添加到窗体 this.setBounds(0,0,400,300);
//设置窗体的位置和大小 pack();
this.setVisible(true); //设置窗体可见性 } public
static void main(String[] args) { new Exp95(); }}运行结果:图9-16
按钮示例运行结果任务九 登录窗体的实现四、相关知识9.4.5 JButton【例9.6】标签示例程序 import java
.awt.Color;import java.awt.FlowLayout;import javax.swing.BorderFa
ctory;import javax.swing.Icon;import javax.swing.ImageIcon;import
javax.swing.JFrame;import javax.swing.JLabel;public class Exp96
extends JFrame{ private FlowLayout flowlayout1; //创建
流式布局flowlayout1 private JLabel lbl1; //创建
标签lbl1 private JLabel lbl2; //创建标签lbl2 pr
ivate JLabel lbl3; //创建标签lbl3 private JLa
bel lbl4; //创建标签lbl4 public Exp96() {
this.setTitle("标签示例"); flowlayout1=new FlowLayout(); this
.setLayout(flowlayout1); Icon icon=new ImageIcon("imag/main.jp
g"); //加载imag文件夹下的图片 lbl1=new JLabel("文本"); //
实例化lbl1为只有文本的标签 lbl2=new JLabel(icon); //实例化l
bl2为只有图片的标签//实例化lbl3为含图片、文本、对齐方式的标签 lbl3=new JLabel("文本、图片和对齐方
式",icon,JLabel.LEFT);//实例化lbl4具有文本和对齐方式的标签 lbl4=new JLabel("文本
和对齐方式"); 任务九 登录窗体的实现四、相关知识9.4.5 JButton【例9.6】标签示例程序//为标签设置
边框,颜色为红色,宽度为3 lbl1.setBorder(BorderFactory.createLineBorder
(Color.red, 3)); lbl2.setBorder(BorderFactory.createLineBorder(Co
lor.red, 3)); lbl3.setBorder(BorderFactory.createLineBorder(Co
lor.red, 3)); lbl4.setBorder(BorderFactory.createLineBorder(Co
lor.red, 3)); this.add(lbl1); //将lbl
1添加到窗体 this.add(lbl2); //将lbl2添加到窗体
this.add(lbl3); //将lbl3添加到窗体 this
.add(lbl4); //将lbl4添加到窗体 this.setBou
nds(0,0,400,300); //设置窗体的位置和大小 pack(); //设置窗体的关闭
方式 this.setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE); //设置窗体可见性 this.setVisible(true);
} public static void main(String[] args) { ne
w Exp96(); }}运行结果:任务九 登录窗体的实现五、任务训练 1.请利用WindowBui
lder,通过控件拖放完成本任务中的登录窗体。 代码由操作自动生成,此处代码略。2.请利用JTextField、JPas
swordField、JButton、JLabel等控件制作注册页面。import java.awt.;import javax
.swing.;public class zhuce extends JFrame{ private JTextField te
xtFieldusername=new JTextField(); private JPasswordField Password
Fieldpsd=new JPasswordField(); private JPasswordField PasswordFie
ldrpsd=new JPasswordField(); private JButton button1=new JButton(
"注册"); private JButton button2=new JButton("重置"); private JLabel
labelusername=new JLabel("用户名"); private JLabel labelpsd=new JLab
el("密码"); private JLabel labelrpsd=new JLabel("确认密码"); public zhu
ce(){ super("注册"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOS
E); setSize(500,400); setLocation(400,400); setLayout(null);
button1.setLocation(120,250); button1.setSize(100,30); button2.
setLocation(270,250); button2.setSize(100,30); add(button1); a
dd(button2);任务九 登录窗体的实现五、任务训练 1.请利用WindowBuilder,通过控
件拖放完成本任务中的登录窗体。 代码由操作自动生成,此处代码略。2.请利用JTextField、JPasswordFie
ld、JButton、JLabel等控件制作注册页面。 textFieldusername.setBounds(200,50,1
50,30); add(textFieldusername); PasswordFieldpsd.setBounds(200,
100,150,30); add(PasswordFieldpsd); PasswordFieldrpsd.setBounds
(200,150,150,30); add(PasswordFieldrpsd); labelusername.setBoun
ds(150,50,150,30); add(labelusername); labelpsd.setBounds(155,1
00,150,30); add(labelpsd); labelrpsd.setBounds(140,150,150,30);
add(labelrpsd); } public static void main(String[] args) { zhu
ce frame=new zhuce(); frame.setVisible(true); frame.getContentP
ane().setBackground(new Color(240,255,255)); }}图9-18 注册页面运行结果:任
务九 登录窗体的实现六、拓展提高 (1)查看Eclipse的版本 选择“help”菜单下的“About Ecli
pse”菜单项,打开“About Eclipse”窗口,查看Eclipse的版本,如下所示:1.WindowBuilder的安装图
9-19 Help菜单下的About Eclipse菜单项图9-20 About Eclipse窗口任务九 登录窗体的实现六
、拓展提高(2)找到windowbuilder对应的下载地址打开下面的网址:http://www.eclipse.org/wind
owbuilder/download.php,如下图所示,按相应的版本选择“link”,打开网页,复制得到如下地址:http://download.eclipse.org/windowbuilder/WB/integration/4.7/1.WindowBuilder的安装图9-21 windowbuilder下载页面任务九 登录窗体的实现六、拓展提高(3)在eclipse中,单击help菜单,选择install new software。1.WindowBuilder的安装图9-22 Install New Software菜单项图9-23 弹出Install对话框任务九 登录窗体的实现六、拓展提高(5)接着选择“next”,选择“我接受协议”,如下图,单击“finish”,进入安装。安装完毕后重启。1.WindowBuilder的安装图9-25 安装协议界面任务九 登录窗体的实现六、拓展提高WindowBuilder的安装,可以使我们通过拖拽放置各个控件,而不用再写繁复的代码。使用步骤如下:(1)利用WindowBuilder新建项目,从Eclipse菜单中选择“new”,然后选择“other”,选择JFrame,如下图所示:1.WindowBuilder的使用图9-26 新建—向导选择对话框图9-27 Swing Designer向导任务九 登录窗体的实现六、拓展提高WindowBuilder的安装,可以使我们通过拖拽放置各个控件,而不用再写繁复的代码。使用步骤如下:(2)在下面的窗体中填入JFrame的名字,单击“Finish”按钮即可创建JFrame窗体,如下图所示:1.WindowBuilder的使用图9-28 新建JFrame窗体任务九 登录窗体的实现六、拓展提高WindowBuilder的安装,可以使我们通过拖拽放置各个控件,而不用再写繁复的代码。使用步骤如下:(3)在代码窗口的底部有两个选项卡Source和Design,选择Design选项卡如下图所示:1.WindowBuilder的使用图9-29 Design选项卡图9-30 JFrame设计界面(4)可以通过拖放控件,更改控件相关的属性,来构建窗体。任务九 登录窗体的实现小 结 本任务主要完成了登录窗体的实现,通过本任务的实施,我们学习了Awt、Swing、JFrame、JTextField、JPasswordField、JButton、JLabel等控件的基本使用。通过本任务的学习,读者可以了解在GUI项目中的常用控件,通过这些常用控件可以基本实现各种类型的登录窗口。通过这一任务的学习,读者基本掌握了GUI项目开发中窗体开发的步骤。
献花(0)
+1
(本文系大高老师首藏)