JavaSwing界面设计(所有控件及示例).ppt

上传人:牧羊曲112 文档编号:5436006 上传时间:2023-07-06 格式:PPT 页数:133 大小:880KB
返回 下载 相关 举报
JavaSwing界面设计(所有控件及示例).ppt_第1页
第1页 / 共133页
JavaSwing界面设计(所有控件及示例).ppt_第2页
第2页 / 共133页
JavaSwing界面设计(所有控件及示例).ppt_第3页
第3页 / 共133页
JavaSwing界面设计(所有控件及示例).ppt_第4页
第4页 / 共133页
JavaSwing界面设计(所有控件及示例).ppt_第5页
第5页 / 共133页
点击查看更多>>
资源描述

《JavaSwing界面设计(所有控件及示例).ppt》由会员分享,可在线阅读,更多相关《JavaSwing界面设计(所有控件及示例).ppt(133页珍藏版)》请在三一办公上搜索。

1、张蕾,界面设计,概述用户界面组件介绍布局管理事件处理菜单和表格,主要内容,本章基本要求,了解AWT和Swing熟悉4个顶层容器掌握JFrame熟悉常用的中间容器会对组件进行布局熟悉常用基本组件的创建和操作会设置组件的颜色和字体会处理组件上发生的事件会创建菜单和表格,用户界面的类型字符用户界面(CUI):例如,MS-DOS图形用户界面(GUI):例如,Microsoft WindowsGUI的组件,用户界面概述,组件继承它的父容器的性质,AWTAWT(Abstract Window Toolkit)是在Swing出现之前用来设计界面的工具包用awt包中的类创建的用户界面在不同的操作平台上有不同的

2、表现。使用不灵活import java.awt.*;SwingSwing是对AWT的扩展,它是Java 2中的一个标准包组件都以J开头,例如:JFrame、JButton等。swing界面在不同的平台上外观完全一样,真正做到平台独立import javax.swing.*;,基本概述,界面设计中常用组件类的体系结构,用户界面,一个顶层容器(即主窗口)顶层容器包含若干个中间容器每个中间容器包含若干个基本组件按照合理的布局方式将它们组织在一起基本组件可响应发生在其上的事件,Java程序界面的构成,容器 容器是用来容纳和管理一组界面元素的对象。基本组件必须被安排在某个容器中,否则就无法使用。,有边框

3、容器,无边框容器,顶层容器,顶层容器,JFrame,JApplet,JDialog,JWindow 作用:创建初始界面,为其他组件提供一个容器,以构建满足用户需求的操作界面JFrame用来创建application,最常用的JApplet用来创建appletJDialog用来创建对话框,常用JWindow不常用,JPanel,JScrollPane,JSplitPane,JTabbedPane、JInternalFrame、Box 这些容器提供将有关组件按照某种布局组合在一起,然后放入中间容器或顶层容器的功能JPanel提供一个面板JScrollPane是具有滚动条的窗格JSplitPane是

4、具有拆分功能的窗格JTabbedPane是带有若干标签的分类窗格JInternalFrame用于创建内嵌于JFrame中的内部框架Box提供创建横向/纵向盒子容器的功能,中间容器,JLabelJButton、JCheckBox、JRadioButtonJList、JComboBoxJTextField、JPasswordField、JTextAreaJToolBar、JToolTip、JProgressBarJSlider、JSpinnerJFileChooser、JColorChooserJMenuBar、JMenu、JMenuItem、JCheckBoxMenuItem、JRadioBut

5、tonMenuItem、JPopupMenuJTableJTreeJOptionPane、JSeparator,基本组件,类 JFrame 是的子类在Swing的组件中,JFrame 并不全是由Java编写的是一种与平台关系比较密切的组件(Heavyweight component)|+-|+-|+-|+-|+-,创建用户主窗口-JFrame,构造方法JFrame()创建无标题窗口。JFrame(String s)创建标题名字是字符串s的窗口。例如:JFrame f=new JFrame(“Hello”);常用方法setTitle(String title)设置JFrame标题文本get/se

6、tSize():获取/设置JFrame的大小。add(Object a):将组件添加到JFrame中。dispose()关闭JFrame并回收用于创建窗口的任何资源。setVisible(boolean b)设置JFrame的可见性。setLocation(x,y)设置JFrame在屏幕的位置,创建用户主窗口-JFrame,常用方法void setExtendedState(int);/设置扩展的状态,取值:NORMAL ICONIFIED MAXIMIZED_HORIZ MAXIMIZED_VERT MAXIMIZED_BOTH/最大化void setDefaultCloseOperatio

7、n(int);/设置默认的关闭时的操作,取值:DO_NOTHING_ON_CLOSE HIDE_ON_CLOSE DISPOSE_ON_CLOSE EXIT_ON_CLOSE/关闭,创建用户主窗口-JFrame,import javax.swing.*;public class FirstJFrame public static void main(String args)JFrame f=new JFrame();f.setTitle(My First JFrame);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setSize(300

8、,300);f.setVisible(true);,示例:直接使用JFrame创建,import javax.swing.*;public class SecondJFrame extends JFrame public SecondJFrame()super(“My Second JFrame”);setDefaultCloseOperation(EXIT_ON_CLOSE);setExtendedState(MAXIMIZED_BOTH);setVisible(true);public static void main(String args)SecondJFrame f=new Seco

9、ndJFrame();,示例:扩展JFrame创建,相关类图标类:图像类:创建图标和图像对象ImageIcon ii=new ImageIcon(“x.gif”);Image image=ii.getImage();设置setIconImage(image);,设置JFrame的图标,由JFrame创建初始的用户界面由JPanel、JScrollPane、JTabbedPane、JSplitPane、JInternalFrame、Box等创建中间容器由基本组件类创建有关的组件将基本组件按照某种布局添加到中间容器中,根据需要可能会用到容器的嵌套将中间容器按照某种布局添加到顶层容器中,形成满足用户

10、需求的操作界面,界面的基本组织方式,Container con=getContentPane();JPanel panel=new JPanel();JButton butt=new JButton(Press Me);panel.add(butt);con.add(panel);,获得JFrame的容器并添加组件,学生基本信息录入界面的设计设计一个用户界面,用于输入学生的下列信息:姓名JTextField密码JPasswordField 性别JRadioButton党否JCheckBox 年龄JSpinner颜色 JColorChooser 加分JSlider系别JComboBox 选课JL

11、ist确认JButton 保存JFileChooser结果JTextArea要求输入完毕按“确认”将该学生的信息记录到“结果”中;按“保存”将结果保存到一个指定的文件中;基本信息与结果界面上下分布在一个JSplitPane中;屏幕下方显示当前时间,示例:学生信息管理系统,步骤一:由JFrame创建初始的用户界面,获得JFrame的容器,添加中间容器JPanel,示例:学生信息管理系统,JFrame f=new JFrame();f.setTitle(学生信息管理系统);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setExtendedS

12、tate(MAXIMIZED_BOTH);/f.setSize(800,600);/f.setLocation(200,200);Container con=f.getContentPane();JPanel pan=new JPanel();con.add(pan);f.setVisible(true);,基本组件,标签 标签(JLabel)是最简单的组件,用于显示单行静态文本。用户只能查看其内容而不能对其进行修改。标签类没有事件响应。构造方法JLabel label1=new JLabel(“姓名”);ImageIcon ii=new ImageIcon(“java.gif”);JLabe

13、l label2=new JLabel(ii);JLabel label3=new JLabel(“姓名”,ii,JLabel.CENTER);标签内容一般不需要改变,但也可以使用setText和setIcon方法进行改变例如当使用同一标签显示不同的图片时,就可使用setIcon方法实现,基本组件标签,步骤二:添加标签(要录入的基本信息的名称),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel l_xm=new JLabel(姓名);pan.add(

14、l_xm);JLabel l_xb=new JLabel(性别);pan.add(l_xb);con.add(pan);f.setVisible(true);,按钮是常用的功能组件,表示按钮的类为JButton。构造方法JButton button1=new JButton(“姓名”);ImageIcon ii=new ImageIcon(“java.gif”);JButton button2=new JButton(ii);JButton button3=new JButton(“姓名”,ii);常用方法void setActionCommand(String);void addAction

15、Listener(ActionListener);,基本组件按钮,步骤二:添加按钮(确认和保存按钮),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();JPanel pan=new JPanel();JLabel l_xml_xm=new JLabel(姓名);pan.add(l_xm);JButton b_sub=new JButton(确认);pan.add(b_sub);JButton b_save=new JButton(保存);pan.add(b_save);con.add(pan);f.setVis

16、ible(true);,构造方法JTextField tf1=new JTextField(10);JTextField tf2=new TextField(“aa”);JTextField tf3=new JTextField(“aa”,8);,基本组件文本框(JTextField),其它方法 public String getText()public String getSelectedText()public void setText(String s)public void setEchoChar(char c)public void setEditable(boolean b),步骤

17、二:添加文本框(录入姓名信息),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();JPanel pan=new JPanel();JLabel l_xm=new JLabel(姓名);pan.add(l_xm);JTextField tf_name=new JTextField(20);pan.add(tf_name);con.add(pan);f.setVisible(true);,构造方法 JTextArea ta1=new JTextArea(5,5);JTextArea ta2=new JTextAre

18、a(“ab”,8,7);,基本组件文本区(JTextArea),其它方法 public getCaretPosition()public void insert(String str,int pos)public String getSelectedText()public int getSelectionStart()public int getSelectionEnd()public void replaceRange(String str,int start,int end),应用中经常将文本区对象放入一个滚动窗格中,以使用滚动条功能,方法如下:JTextArea ta=new JTex

19、tArea(10,10);JScrollPane sp=new JScrollPane(ta);,基本组件文本区(JTextArea),步骤二:添加文本域(显示录入结果信息),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();Jlabel l_jg=new JLabel(录入结果);JTextArea result=new JTextArea(10,30);JScrollPane sp=new JScrollPane(result);pan.add(sp);pan

20、.add(l_jg);con.add(pan);f.setVisible(true);,基本组件单选按钮(JRadioButton),构造方法(与JButton类似)JRadioButton rbutt1=new JRadioButton(“男”,true);ImageIcon ii=new ImageIcon(“java.gif”);JRadioButton rbutt2=new JRadioButton(ii);JRadioButton rbutt3=new JRadioButton(“女”,ii,false);常用方法void addActionListener(ActionListen

21、er);void addItemListener(ItemListener);boolean isSelected();void setSelected(boolean);,使用单选按钮时经常用到ButtonGroup类,如下创建按钮组对象ButtonGroup bg=new ButtonGroup();创建若干单选按钮对象JRadioButton b1=new JRadioButton(“x”);JRadioButton b2=new JRadioButton(“y”);将各单选按钮添加到按钮组中bg.add(b1);bg.add(b2);将单选按钮添加到其他容器中容器对象.add(b1);

22、容器对象.add(b2);注:按钮组维持只有一个单选按钮处于选择状态,基本组件单选按钮(JRadioButton),步骤二:添加单选按钮(选择性别),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JRadioButton male=new JRadioButton(男,true);JRadioButton female=new JRadioButton(女);ButtonGroup group=new ButtonGroup();group.add(male)

23、;group.add(female);pan.add(male);pan.add(female);con.add(pan);f.setVisible(true);,构造方法JCheckbox()创建一个没有标签的复选框。JCheckbox(Icon icon)创建一个有图标的复选框。JCheckbox(Icon icon,boolean sele)创建一个有图标icon的复选框,初始状态为selsJCheckbox(String s)创建一个有标签的复选框。JCheckbox(String s,boolean b)创建一个有标签的复选框,参数b设置初始状态JCheckbox(String st

24、r,Icon icon)创建一个有str文字及图标icon的复选框JCheckbox(String str,Icon icon,boolean sele)创建一个有str文字及图标icon的复选框,初始状态为sels,基本组件复选框(JCheckbox),常用方法isSelected():返回复选按钮的状态,返回类型是boolean。如果返回true,则表示该按钮处于选中状态;否则处于未选中状态。setSelected(Boolean state):设置复选按钮的状态。,基本组件复选框(JCheckbox),步骤二:添加复选框(选择爱好,多项选择),示例:学生信息管理系统,JFrame f=n

25、ew JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();Jlabel l_ah=new JLabel(爱好);JCheckBox hobby=new JCheckBox(音乐),new JCheckBox(足球),new JCheckBox(绘画);pan.add(l_ah);pan.add(hobby0);pan.add(hobby1);pan.add(hobby2);con.add(pan);f.setVisible(true);,构造方法String ss=“red”,”green”,”blue”;JLis

26、t list1=new JList(ss);JList list2=new JList(Vector);其它常用方法 void addListSelectionListener();void setVisibleRowCount(int);void setSelectionMode(int);/取值如下(在ListSelectionModel中定义)SINGLE_SELECTIONSINGLE_INTERVAL_SELECTION MULTIPLE_INTERVAL_SELECTION(默认)int getSelectedIndex();int getSelectedIndices();Obj

27、ect getSelectedValue();Object getSelectedValues();,基本组件列表框(JList),步骤二:添加列表框(选择选修课程),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel l_xk=new JLabel(选课);String coursesNames=数据结构“,操作系统“,网络原理,Java程序设计“,分布式系统开发技术,计算机导论“,密码学,计算机组成原理“,编译原理,图形学”;course=new

28、JList(coursesNames);pan.add(l_xk);pan.add(course);con.add(pan);f.setVisible(true);,构造方法String ss=“red”,”green”,”blue”;JComboBox cb1=new JComboBox(ss);JComboBox cb2=new JComboBox(Vector);常用方法addItem()添加一个项目到 JComboBox.get/setSelectedIndex()获取/设置 JComboBox 中选中项目的索引get/setSelectedItem()获取/设置选中的对象。remov

29、eAllItems()从 JComboBox 删除所有对象。removeItem()从 JComboBox 删除特定对象。setEditable把一个组合框设置为可编辑的。注意编辑只会影响当前项,它不会改变列表的内容。,基本组件下拉列表(JComboBox),步骤二:添加下拉列表(选择院系),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel l_yx=new JLabel(院系);pan.add(l_yx);String departmentName

30、s=计算机科学与技术系,电子信息与技术系,计算机工程系”;JComboBox department=new JComboBox(departmentNames);department.setEditable(false);pan.add(department);con.add(pan);f.setVisible(true);,构造方法(类似于JTextField)常用方法void addActionListener(ActionListener);char getPassword();void setEchoChar(char);char getEchoChar();,基本组件密码域(JPas

31、swordField),步骤二:添加密码(密码输入显示“*”),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel l_ma=new JLabel(密码);pan.add(l_ma);password=new JPasswordField(20);password.setEchoChar(*);pan.add(password);con.add(pan);f.setVisible(true);,构造方法JSlider slider=new JSlide

32、r(JSlider.HORIZONTAL,0,100,10);常用方法void addChangeListener(ChangeListener);void setValue(int);int getValue();void setMajorTickSpacing(int);void setMinorTickSpacing(int);void setPaintTicks(boolean);/falsevoid setPaintLabels(boolean);/falsevoid setPaintTrack(boolean);/truevoid setSnapToTicks(boolean);/

33、false,基本组件滑动条(JSlider),步骤二:添加加分选项(加分的选项采用滑动条实现),示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel l_jf=new JLabel(加分);pan.add(l_jf);addition=new JSlider(JSlider.HORIZONTAL,0,100,50);addition.setMajorTickSpacing(10);addition.setMinorTickSpacing(5);addit

34、ion.setPaintTicks(true);addition.setPaintLabels(true);addition.setSnapToTicks(true);pan.add(addition);con.add(pan);f.setVisible(true);,构造方法 JProgressBar(int,int,int);JProgressBar pb=new JProgressBar(JProgressBar.HORIZONTAL,0,100);常用方法void addChangeListener(ChangeListener);void setValue(int);/设置当前值vo

35、id setString(String);/设置显示的字符串void setStringPainted(boolean);/设置是否显示字符串,默认为falsevoid setBorderPainted(boolean);/设置是否显示边框,默认为true,基本组件进度条(JProgressBar),步骤二:添加进度条,示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JProgressBar progbar=new JProgressBar(JProgressB

36、ar.HORIZONTAL,0,100);progbar.setStringPainted(true);con.add(pan);f.setVisible(true);,构造方法JFileChooser fc1,fc2;/声明两个对象变量fc1=new JFileChooser();/使用系统默认目录fc2=new JFileChooser(“d:java”);显示方法int showOpenDialog(Component);int showSaveDialog(Component);/分别用于显示标准的打开和保存对话框/参数Component指定对话框依附的父组件/返回值:APPROVE_

37、OPTION选择了确认 CANCEL_OPTION选择了取消 ERROR_OPTION出现了错误,基本组件文件选择器(JFileChooser),其他常用方法void setCurrentDirectory(File);void setMultiSelectionEnabled(boolean);File getSelectedFile();File getSelectedFiles();File getCurrentDirectory();String getName(File);/取得文件/目录名称,不含路径,可用File类的getAbsolutePath()方法获取完整路径void se

38、tFileSelectionMode(int);/FILES_ONLY 只能选择文件(默认)DIRECTORIES_ONLY 只能选择目录 FILES_AND_DIRECTORIES 文件和目录都可选void setFileFilter(FileFilter);,显示方法使用JColorChooser提供的类方法showDialogstatic Color showDialog(Component,/父组件 String,/标题 Color/初始颜色值);/返回值:新选择的颜色值Color示例Color c=JColorChooser.showDialog(this,”请选择颜色”,Color

39、.red);/得到颜色对象c后,即可在需要的地方使用,基本组件颜色选择器(JColorChooser),Confirm对话框int showConfirmDialog(Component,Object);/显示含有 Yes、No、Cancel 按钮的确认框/参数:父组件,显示信息/返回值:YES_OPTION是 NO_OPTION否 CANCEL_OPTION撤销 OK_OPTION确定 CLOSED_OPTION关闭还有其他形式的类方法,请参阅帮助文档,基本组件对话框(JOptionPane),Input对话框String showInputDialog(Component,Object);

40、/参数:父组件,显示信息/返回值:选择确认后返回 输入的字符串 选择取消或关闭后返回 null还有其他形式的类方法,请参阅帮助文档,基本组件对话框(JOptionPane),Message对话框void showMessageDialog(Component,Object);/参数:父组件,显示信息/没有返回值,只是用来显示一些信息还有其他形式的类方法,请参阅帮助文档,基本组件对话框(JOptionPane),Option对话框int showOptionDialog(Component,/父组件 Object,/显示信息 String,/标题 int,/标准选项按钮组类型 int,/标准信息

41、图标类型 Icon,/自定义信息图标 Object,/自定义选项按钮组 Object/自定义默认的选项按钮);/该方法提供了丰富且复杂的表达形式,请参阅帮助文档注:使用这些标准对话框,可以方便实现某些功能,基本组件对话框(JOptionPane),微调器(JSpinner),构造方法JSpinner spinner=new JSpinner();常用方法void addChangeListener(ChangeListener);void setValue(Object);Object getValue();Object getNextValue();Object getPreviousVal

42、ue();,示例:学生信息管理系统,JFrame f=new JFrame();Container con=f.getContentPane();Jpanel pan=new JPanel();JLabel lb=new JLabel(年龄);JSpinner jsp=new JSpinner();jsp.setValue(new Integer(20);pan.add(lb);pan.add(jsp);con.add(pan);f.setVisible(true);,步骤二:添加年龄微调器,计时器(Timer),构造方法Timer(int,ActionListener);Timer time

43、r=new Timer(1000,this);常用方法void start();void stop();void restart();void setDelay(int);void setRepeats(boolean);boolean isRunning();,创建边框(使用BorderFactory类的类方法)Border border1=/创建一个具有指定颜色和宽度的线边框BorderFactory.createLineBorder(Color,int);Border border2=BorderFactory.createTitledBorder(String);创建一个新标题边框,采

44、用默认设置,并指定了标题文本。Border border3=BorderFactory.createLoweredBevelBorder();创建一个具有凹入斜面边缘的边框Border border4=BorderFactory.createRaisedBevelBorder();创建一个具有凸出斜面边缘的边框Border border5=BorderFactory.createEtchedBevelBorder();创建一个具有“浮雕化”外观效果的边框,将组件的当前背景色用于突出显示和阴影显示使用setBorder(border)方法设置组件的边框,组件的边框设置边框(Border),分隔线

45、(JSeparator)构造方法JSeparator separator1=new JSeparator();/默认水平JSeparator separator2=new JSeparator(JSeparator.HORIZONTAL);JSeparator separator3=new JSeparator(JSeparator.VERTICAL);使用add(JSeparator)方法加到合适的地方,组件的分隔线设置,设置颜色默认情况下,Java使用RGB颜色描述系统RGB指红/绿/蓝三基色,取值范围是0,255,一种颜色就是这三种基本颜色的组合描述颜色的类是颜色对象的创建Color c

46、=new Color(0,255,0);直接使用Color类中定义的标准颜色常量如 Color.BLACK 或 Color.black 等Color c1=Color.BLACK;/Color.blackC)颜色选择器JColorChooser直观得到一个Color对象Color c3=JColorChooser.showDialog(Component,String,Color);,组件的颜色设置,有了Color对象后,可使用setForeground(Color);setBackground(Color);设置组件的前景色和背景色,组件的颜色设置,字体类:字体对象的创建Font(Strin

47、g name,int style,int size);/名称,如“隶书”/风格,取值有 PLAIN,BOLD,ITALIC/大小,如 24,60Font f=new Font(“宋体”,Font.BOLD,24);设置组件的字体setFont(Font);,组件的字体设置,光标类:光标对象的获取Cursor.getPredefinedCursor(int);/如:DEFAULT_CURSOR、HAND_CURSOR、WAIT_CURSOR、TEXT_CORSOR、CROSSHAIR_CURSOR设置组件的光标setCursor(Cursor.HAND_CURSOR);,组件的光标设置,JPan

48、el创建对象JPanel p=new JPanel();默认布局为FlowLayout,可以改变,如p.setLayout(new GridLayout(2,3);添加组件p.add(组件对象1);p.add(组件对象2);,中间容器的使用,JScrollPaneJTextArea ta=new JTextArea(50,50);JScrollPane sp=new JScrollPane(ta);JSplitPaneJTextArea ta=new JTextArea(50,50);JPanel p=new JPanel();JSplitPane sp=new JSplitPane(JSpl

49、itPane.HORIZONTAL_SPLIT,ta,p);/另一种方式JSplitPane sp=newJSplitPane(JSplitPane.VERTICAL_SPLIT,true,ta,p);,中间容器的使用,JTabbedPaneJTabbedPane tp=new JTabbedPane();tp.setTabPlacement(int);tp.addChangeListener(ChangeListener);JPanel p1=new JPanel();JPanel p2=new JPanel();tp.addTab(“p1”,p1);tp.addTab(“p2”,p2);t

50、p.removeTabAt(0);int n=tp.getTabCount();,中间容器的使用,JInternalFrame示例:ExampleCh07_Jframe.java中class JInternalFrame_test,中间容器的使用,Java用户图形界面设计步骤根据需要往界面中添加组件通过布局管理器对容器中的组件进行组织排列如何相应用户对组件的操作,即事件处理,小结,布局管理,布局是指组件在容器中的排列方式,主要有:FlowLayout流式布局BorderLayout边界布局GridLayout网格布局CardLayout卡片布局BoxLayout盒式布局GridBagLayou

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号