图形用户界面设计课件.ppt

上传人:小飞机 文档编号:3968586 上传时间:2023-03-30 格式:PPT 页数:99 大小:1.02MB
返回 下载 相关 举报
图形用户界面设计课件.ppt_第1页
第1页 / 共99页
图形用户界面设计课件.ppt_第2页
第2页 / 共99页
图形用户界面设计课件.ppt_第3页
第3页 / 共99页
图形用户界面设计课件.ppt_第4页
第4页 / 共99页
图形用户界面设计课件.ppt_第5页
第5页 / 共99页
点击查看更多>>
资源描述

《图形用户界面设计课件.ppt》由会员分享,可在线阅读,更多相关《图形用户界面设计课件.ppt(99页珍藏版)》请在三一办公上搜索。

1、图形用户界面设计,NCEPU,Contents,1.图形用户界面概述,NCEPU,图形用户界面概述,之前我们所编写的Java程序都是在DOS方式下运行的而Windows平台通过窗口式的图形界面实现人机对话,因此编写图形方式的Java程序也是必须的。,NCEPU,设计一个图形用户界面,界面如图所示:,例1,所需要的知识点图形用户界面基础知识布局管理器的使用,NCEPU,多行文本框,图形用户界面的组成,组件,单选按钮,单行文本框,标签,复选按钮,按钮,组合框,窗口,面板,容器,NCEPU,图形用户界面设计概述,图形用户界面(Graphics User Interface,GUI)是程序与用户交互的

2、方式,利用它系统可以接收用户的输入并向用户输出程序运行的结果。,NCEPU,GUI支持包,java.awt包:java.awt包中提供了大量的进行GUI设计所使用的类和接口,是Java语言进行GUI程序设计的基础。javax.swing包:swing是由100%纯Java实现的,没有本地代码,不依赖操作系统的支持,它的出现使得Java的图形用户界面上了一个台阶。,NCEPU,抽象窗口工具集AWT,AWT是Java基础类库(JFC,Java Foundation Class)的一部分,它为大规模的GUI开发提供了丰富的基础结构。AWT的核心软件包java.awtjava.awt主要由组件类(Co

3、mponent)、事件类(Event)、布局类(FlowLayout等)、菜单类(MenuComponet)等组成。,NCEPU,抽象窗口工具集AWT,java.awt包中的主要类 以及组件类的继承关系,java.lang.Object,Java中有两种主要容器:窗口和面板窗口(Window)是可以自由移动的,不依赖其他容器而存在的容器面板(Panel)与窗口类似,但不能独立存在,必须包含在另外一个容器里,如包含在Frame或Web中,窗口(Window)有两个主要组件:框架和对话框在Java应用程序中,一般独立应用程序主要使用框架(Frame)做容器,在框架上通过放置面板(Panel)来控制

4、图形界面的布局。如果应用到浏览器中,则主要使用面板的一个子类Applet来做容器,它能嵌入浏览器运行。,NCEPU,第一节 抽象窗口工具集AWT,java.awt包中的主要类 以及组件类的继承关系,java.lang.Object,NCEPU,Swing的类层次结构,Swing组件都是AWT的Container类的直接子类或间接子类。,NCEPU,Swing的类层次结构,NCEPU,创建可视化界面的一般步骤,选择外观,NCEPU,Swing外观,Swing采用MVC的设计范式,Swing外观感觉采用可插入的外观感觉(Pluggable Look and Feel,PL&F)。使得程序在一个平台

5、上运行时能够有不同的外观。,NCEPU,Metal风格,Swing外观,NCEPU,Motif风格,Swing外观,NCEPU,Windows风格,Swing外观,NCEPU,import javax.swing.*;import java.awt.event.*;public class HelloWorldSwing public static void main(String args)JFrame frame=new JFrame(HelloWorldSwing);final JLabel label=new JLabel(Hello World!);frame.getContentP

6、ane().add(label);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(200,70);frame.setVisible(true);,基于Swing的GUI构建方法,NCEPU,(1)引入Swing包及其他程序包import javax.swing.*;import java.awt.event.*;(2)设置外观风格UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName();(3)创建并设置窗口容器(4)创建

7、与添加Swing组件(5)显示顶层容器,基于Swing的GUI构建方法,NCEPU,图形用户界面设计概述,java程序的GUI设计主要包括下述三个概念:组件Component容器Container布局管理器-LayoutManager,NCEPU,Swing 中的容器,容器分两类:-顶级容器:一般是一个顶层窗口(框架)。-中间容器:需要包含在顶层容器中使用的容器。顶级容器JFrame:用于框架窗口的类,应用程序至少使用一个框架窗口。JDialog:用于对话框的类。JApplet:用于使用 Swing 组件的Java Applet的类。中间容器JPanel:面板,是最灵活、最常用的中间容器。JS

8、crollPane:与JPanel类似,但还可在大的组件或可扩展组件周围提供滚动条。JTabbedPane:包含多个组件,但一次只显示一个组件。用户可在组件之间方便地切换。JToolBar:按行或列排列一组组件(通常是按钮)。,NCEPU,Swing 容器组件,主窗口,Swing 应用程序,创建容器,设置容器大小(对框架及面板而言),设置容器可见度(对框架及面板而言),创建顶层容器,顶层容器(每个应用程序中至少有一个),内容面板,主要显示区域,包含 GUI 中的可视组件,NCEPU,在Java中,顶层窗口称为框架。窗口有边界、标题、关闭按钮等。,注意:每个图形用户界面应用程序必须有一个框架,框

9、架,NCEPU,框架,框架(Frame)类是窗口(Window)类的子类,它是一种带标题框并且可以改变大小的窗口。框架类的许多方法是从它的父类Window或更上层的类Container和Component继承过来的下面介绍框架类的构造方法和常用方法,NCEPU,框架,框架(Frame)类的构造方法public Frame()public Frame(String title)其中,title指定框架的标题,NCEPU,框架,组件(Component)类方法public void setSize(int width,int height)设置组件的宽度和高度public void setVisi

10、ble(boolean b)设置组件是否显示public void setLocation(int x,int y)设置组件的位置,NCEPU,框架,框架(Frame)类方法public void setTitle(String title)设置或修改框架的标题public String getTitle()获取框架的标题Public void setBackground(Color c)设置框架的背景颜色,NCEPU,框架,框架是一个带有标题框的窗口,窗口的大小可以改变。框架在实例化时默认为是不可见的,最小化的,必须通过setSize方法来设定框架的大小,并使用setVisible(true

11、)使框架可见。,NCEPU,第二节 框架,import java.awt.*;public class UserLogin public static void main(String args)Frame f=new Frame(User Login);f.setSize(280,150);f.setBackground(Color.LIGHT_GRAY);f.setVisible(true);,输出为:,import java.awt.*;public class TestMultiFramepublic static void main(String args)MyFrame f1=ne

12、w MyFrame(100,100,200,200,Color.BLUE);MyFrame f2=new MyFrame(300,100,200,200,Color.YELLOW);MyFrame f3=new MyFrame(100,300,200,200,Color.GREEN);MyFrame f4=new MyFrame(300,300,200,200,Color.MAGENTA);,class MyFrame extends Framestatic int id=0;MyFrame(int x,int y,int w,int h,Color color)super(MyFrame+(

13、+id);setBackground(color);setLayout(null);setBounds(x,y,w,h);setVisible(true);,NCEPU,与AWT组件不同,Swing组件不能直接添加到顶层容器中,它必须添加到一个与Swing顶层容器相关联的内容面板(content pane)上。getContentPane(),JFrame的使用,NCEPU,对JFrame添加组件有两种方式:(1)用getContentPane()方法获得JFrame的内容面板,再对其加入组件:frame.getContentPane().add(childComponent),如何添加组件,

14、NCEPU,import javax.swing.*;import java.awt.event.*;public class HelloWorldSwing public static void main(String args)JFrame frame=new JFrame(HelloWorldSwing);final JLabel label=new JLabel(Hello World!);frame.getContentPane().add(label);frame.setSize(200,70);frame.setVisible(true);,NCEPU,JFrame的使用,为了在

15、选择框架的关闭按钮时能退出程序,应添加WindowListener监听器或书写下列代码:frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);,NCEPU,JFrame的使用,组件(Component)类方法public void setLocation(int x,int y)设置组件的位置,NCEPU,第二节 框架,import javax.swing.*;public class JFrameDemo public static void main(String args)JFrame fr=new JFrame(学生信息管理系统);S

16、ystem.out.println(“已经创建JFrame实例);fr.setSize(400,300);System.out.println(“调用了setSize();fr.setLocation(200,200);fr.setVisible(true);System.out.println(“调用了setVisible();fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);,NCEPU,面板,面板(JPanel)与框架类似,也是一种容器,可以容纳其他GUI组件。与框架不同的是,面板没有标题,不能独立存在,实例化以后必须使用Containe

17、r类的add方法装入到Window对象或Frame对象中,这样它才可见。,NCEPU,Swing常用的容器JPanel,JPanel面板是一种添加到其他容器使用的容器组件。JPanel的构造方法:public JPanel()public JPanel(LayoutManager layout)JPanel可指定边界,可用JComponent类的setBorder()方法设置边界。其用法如下:public void setBorder(Border border),NCEPU,第二节 框架,import java.awt.*;import javax.swing.*;public class

18、FrameWithPanel extends JFrame public static void main(String args)FrameWithPanel fr=new FrameWithPanel(Hello!);fr.setSize(200,200);fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel pan=new JPanel();pan.setSize(200,100);,NCEPU,第二节 框架,pan.setBackground(Color.yellow);pan.setLayout(new GridLayout

19、(2,1);pan.add(new JButton(确定);fr.setContentPane(pan);fr.setVisible(true);public FrameWithPanel(String str)super(str);,NCEPU,布局管理器(LayoutManager),所谓布局,就是各组件在容器中如何摆放。为了实现跨平台的特性并获得动态的布局效果,Java将 容器内的所有组件安排给“布局管理器”负责管理。布局管理器管理当窗口移动或调整大小后组件如何变化 等功能。,NCEPU,布局管理器的分类FlowLayout(流式布局):Panel和Applet的缺省布局管理器Borde

20、rLayout(边界布局):JDialog和JFrame的缺省布局管理器GridLayout(网格布局)GridBagLayout(网格组布局)CardLayout(卡片布局)BoxLayout(箱式布局)SpringLayout(弹簧布局)每个容器都有缺省的布局管理器。在没有设置新的布局前,在容器中添加组件都按照该容器的缺省布局排列。可通过setLayout(LayoutManager m)方法为容器设置新布局。,布局管理器(LayoutManager),NCEPU,布局管理器,FlowLayout(流式布局)将组件逐个放到容器的一行上一行放满后就重新起一个新行BorderLayout(边界

21、布局)容器被划分为东(East)、南(South)、西(West)、北(North)、中(Center),NCEPU,布局管理器,GridLayout(网格式布局)将容器分为大小相等的若干行乘若干列的网格,组件从左至右,从上到下放入网格中,每个组件占一格(表格式)CardLayout(卡片式布局)将容器中的组件处理成一组卡片,每一时刻只显示一张卡片,可以在卡片间切换,NCEPU,FlowLayout布局管理器,FlowLayout布局管理器FlowLayout是Panel类的默认布局管理器布局方式:将组件逐个地放在容器的一行上,一行放满就另起一个新行。其中,一行的长度取决于容器的宽度,NCEP

22、U,FlowLayout布局管理器,FlowLayout布局管理器构造方法:public FlowLayout();public FlowLayout(int align);public FlowLayout(int align,int hgap,int vgap);,其中,align表示对齐方式,hgap和vagp表示组件的水平和垂直间距,单位是像素。若没有指定align,则默认让组件居中摆放,align的取值为常量:FlowLayout.LEFT,FlowLayout.RIGHT 和 FlowLayout.CENTER 例如:new FlowLayout(FlowLayout.LEFT),

23、NCEPU,FlowLayout布局管理器,FlowLayout布局管理器设置FlowLayout 布局FlowLayout flow=new FlowLayout();Frame fr=new Frame();fr.setLayout(flow);由于一个容器只要设置了布局通常就不会再改变,因此上面的语句可以简化成:fr.setLayout(new FlowLayout();,NCEPU,FlowLayout布局管理器,FlowLayout布局管理器可以设置框架fr为组件左对齐的FlowLayout布局:fr.setLayout(new FlowLayout(FlowLayout.LEFT)

24、;还可以设置框架fr为组件左对齐的FlowLayout布局,并且组件的水平间距为20像素,垂直间距为40像素:fr.setLayout(new FlowLayout(FlowLayout.LEFT,20,40);,NCEPU,import java.awt.*;import javax.swing.*;class FlowLayoutDemo extends JFrame JButton jb1,jb2,jb3,jb4,jb5;public FlowLayoutDemo(String title)super(title);void init()this.setVisible(true);thi

25、s.setSize(300,200);Container c=this.getContentPane();jb1=new JButton(第一个按钮);jb2=new JButton(第二个按钮);jb3=new JButton(第三个按钮);jb4=new JButton(第四个按钮);jb5=new JButton(第五个按钮);c.setLayout(new FlowLayout();/设置布局管理器 c.add(jb1);c.add(jb2);c.add(jb3);c.add(jb4);c.add(jb5);public static void main(String args)Flo

26、wLayoutDemo f=new FlowLayoutDemo(FowLayoutDemo);f.init();,FlowLayout使用示例,NCEPU,BorderLayout布局管理器,BorderLayout布局管理器BorderLayout是Frame类和Dialog类的默认布局管理器布局方式:容器被划分为东(East)、南(South)、西(West)、北(North)、中(Center)五个区域变化规律为:组件的相对位置不变,大小发生变化。,NCEPU,水平拉宽我们可以看到:南、北、中控件大小会有变化,东、西控件大小不变化。,BorderLayout布局管理器,BorderLa

27、yout布局管理器,NCEPU,上下拉长可以看到:东、西、中控件大小会有变化,南、北控件大小不变化。,BorderLayout布局管理器,BorderLayout布局管理器,NCEPU,BorderLayout布局管理器,BorderLayout布局管理器构造方法:public BorderLayout();public BorderLayout(int hgap,int vgap);,其中,hgap和vagp表示组件的水平和垂直间距,单位是像素,默认为0,NCEPU,BorderLayout布局管理器,BorderLayout布局管理器Container容器类放置组件的方法:public C

28、omponent add(Component comp,int index)其中,index 指明组件放置的区域,分别为:BorderLayout.EAST 或 East BorderLayout.WEST 或 West BorderLayout.SOUTH 或 South BorderLayout.NORTH 或 North BorderLayout.CENTER 或 Center,NCEPU,import java.awt.*;import javax.swing.*;class BLExample extends JFrame public BLExample(String title)

29、super(title);Container contentPane=getContentPane();contentPane.setLayout(new BorderLayout(2,2);contentPane.add(BorderLayout.NORTH,new JButton(North);contentPane.add(BorderLayout.SOUTH,new JButton(South);contentPane.add(BorderLayout.EAST,new JButton(East);contentPane.add(BorderLayout.WEST,new JButto

30、n(West);contentPane.add(BorderLayout.CENTER,new JButton(Center);public static void main(String args)BLExample frame=new BLExample(Example);frame.setDefaultCloseOperation(EXIT_ON_CLOSE);frame.setSize(500,300);frame.setVisible(true);,NCEPU,第四节 布局管理器,import javax.swing.*;public class ExGui2 private JFr

31、ame f;private JButton be,bs,bw,bn,bc;public static void main(String args)ExGui2 that=new ExGui2();that.go();,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South

32、);f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South);f.add(bw,West

33、);f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,Frame类默认的布局管理器就是BorderLayout因此不用再使用f.setLayout(new BorderLayout(),区域的默认值是BorderLayout.CENTER因此 f.add(bc,BorderLayout.CENTER)与f.add(bc)是等价的。,若将多个组件放在了同一个区域内,最后一个放入的组件将覆盖前面的组件,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout)

34、;be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,East);f.add(bw,North);f.add(bn,North);f.add(bc);f.setSize(350,200);f.setVisible(true);,若将多个组件放在了同一个区域内,最后一个放入的组件将覆盖前面的组件,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Bo

35、rder Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South);f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,对于East、South、West、North四个边界区域,若其中的某个区域没有放置组件,则这个区域将变为0,同时Cen

36、ter区域的组件将会扩展到这个区域,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);/f.add(be,East);f.add(bs,South);f.add(bw,West);/f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,

37、对于East、South、West、North四个边界区域,若其中的某个区域没有放置组件,则这个区域将变为0,同时Center区域的组件将会扩展到这个区域,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);/f.add(bs,South);/f.add(bw,West);f.add(b

38、n,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,对于East、South、West、North四个边界区域,若其中的某个区域没有放置组件,则这个区域将变为0,同时Center区域的组件将会扩展到这个区域,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButto

39、n(Center);f.add(be,East);/f.add(bs,South);/f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,对于East、South、West、North四个边界区域,若其中的某个区域没有放置组件,则这个区域将变为0,同时Center区域的组件将会扩展到这个区域,若四个边界区域都没有组件,则Center区域的组件将充满整个容器,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new

40、 JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);/f.add(be,East);/f.add(bs,South);/f.add(bw,West);/f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,若四个边界区域都没有组件,则Center区域的组件将充满整个容器,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame

41、(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);/f.add(be,East);/f.add(bs,South);/f.add(bw,West);/f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,若四个边界区域都没有组件,则Center区域的组件将充满整个容器,对于Center区域,如果不放置组件,则

42、容器中间将会空白,边界区域的组件不会扩展过来,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South);f.add(bw,West);f.add(bn,North);/f.add(bc,Center);f.setSize(350,200);f.setVisible(tru

43、e);,对于Center区域,如果不放置组件,则容器中间将会空白,边界区域的组件不会扩展过来,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South);f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSi

44、ze(550,300);f.setVisible(true);,当容器大小发生改变的时候,各组件的大小也发生变化。但不管容器大小如何改变,North和South区域的高度保持不变,East和West区域的宽度保持不变,输出为:,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(South);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,

45、South);f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSize(550,300);f.setVisible(true);,当容器大小发生改变的时候,各组件的大小也发生变化。但不管容器大小如何改变,North和South区域的高度保持不变,East和West区域的宽度保持不变,因此,实际上真正变化的主要是Center区域的组件将随容器的大小变化而变化。,NCEPU,第四节 布局管理器,void go()f=new JFrame(Border Layout);be=new JButton(East);bs=new JButton(S

46、outh);bw=new JButton(West);bn=new JButton(North);bc=new JButton(Center);f.add(be,East);f.add(bs,South);f.add(bw,West);f.add(bn,North);f.add(bc,Center);f.setSize(350,200);f.setVisible(true);,可以使用BorderLayout的构造方法来设置各个区域组件的间距。例如,在程序中加入:f.setLayout(new BorderLayout(10,20),输出为:,NCEPU,布局管理器,3.GridLayout布

47、局管理器布局方式:这是一种网格式布局,它将容器分为大小相等的若干行和若干列的网格,组件从左至右从上到下依次放入网格中,每个组件占一格实际上,这种布局方式就是一个表格,NCEPU,使容器中的各组件呈网格状分布。各组件的排列方式为:从上到下,从左到右。组件放入容器的次序决定了它在容器中的位置。网格每列宽度相同,等于容器的宽度除以网格的列数。网格每行高度相同,等于容器的高度除以网格的行数。容器大小改变时,组件的相对位置不变,大小会改变。若组件数超过网格设定的个数,则布局管理器会自动增加网格个数,原则是保持行数不变。,布局管理器,NCEPU,布局管理器,3.GridLayout布局管理器构造方法:pu

48、blic GridLayout();public GridLayout(int rows,int cols);public GridLayout(int rows,int cols,int hgap,int vgap);,其中,rows和cols表示行数和列数;hgap和vagp表示组件的水平和垂直间距,单位是像素,默认为0,当没有rows和cols时,将构造一个只有一行的网格,列数由组件的个数而定,NCEPU,import java.awt.*;class GridEx private JFrame f;private JButton b1,b2,b3,b4,b5;public static

49、 void main(String args)GridEx that=new GridEx();that.go();void go()f=new JFrame(Grid Layout);f.setLayout(new GridLayout(3,2);,NCEPU,b1=new JButton(b1);b2=new JButton(b2);b3=new JButton(b3);b4=new JButton(b4);b5=new JButton(b5);f.add(b1);f.add(b2);f.add(b3);f.add(b4);f.add(b5);f.setSize(200,200);f.se

50、tVisible(true);,NCEPU,import java.awt.*;class GridEx private JFrame f;private JButton b1,b2,b3,b4,b5;public static void main(String args)GridEx that=new GridEx();that.go();void go()f=new JFrame(Grid Layout);f.setLayout(new GridLayout(2,2);,若放置的组件超过网格设定的个数,则布局管理器会自动增加网格个数,原则是保持行数不变,NCEPU,import java.

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

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


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号