Java小应用程序(Applet).ppt_第1页
Java小应用程序(Applet).ppt_第2页
Java小应用程序(Applet).ppt_第3页
Java小应用程序(Applet).ppt_第4页
Java小应用程序(Applet).ppt_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第12章Java小应用程序(Applet)的设计,12.1编写一个Applet12.2Applet的通信,12.1编写一个Applet,要编写一个Applet,必须首先从java.applet.Applet派生一个类:importjava.applet.*;publicclassSimpleAppletextendsApplet需要注意的是,派生出的Applet的类必须定义为public类型。java.applet.Applet类实际上是java.awt.Panel的子类。Applet和AWT类的继承关系如图12.1所示。,图12.1,这种层次关系显示,一个Applet可直接用作一个AWT布局的容器。因为Applet是Panel的子类,所以它有一个缺省的流(Flow)布局管理器。Component,Container和Panel类的方法被Applet类继承了下来。12.1.1Applet的执行框架在Java出现之前,人们就已经开始使用HTML(超文本标记语言)进行Web页面的设计了。然而,对HTML稍有了解的人都知道,HTML所提供的设计能力是极其有限的。Java率先提供了让Web页面实现更丰富的GUI和逻辑运算能力的方法,这种方法是通过将一个Java的类插入到Web页面中来实现的。,如何编写一个Applet并令它在浏览器中执行呢?方法很简单,只要继承java.applet包下的Applet类,并实现一些必要的方法即可。下面我们来看一个最简单的Applet的例子,并学会怎样在浏览器中令它运行。例12.1SimpleApplet.javaimportjava.applet.*;importjava.awt.*;publicclassSimpleAppletextendsApplet,Stringtext=null;publicvoidinit()text=Asimpleappletdemo!;setBackground(Color.YELLOW);publicvoidstart()System.out.println(starting.);publicvoidstop(),System.out.println(stopping.);publicvoiddestroy()System.out.println(preparingtounload.);publicvoidpaint(Graphicsg)System.out.println(Paint);,g.drawString(text,15,25);上面是一个最简单的Applet例子,大家可能已经发现,这个程序没有main()方法,的确,我们前面所学到的Java应用程序都必须由main()方法处进入,而在一个Applet中却不是这样。Applet的生命周期稍微有些复杂,它需要通过浏览器来运行,所以为了执行它,还必须有一个HTML编写的Web页面。,例12.2SimpleApplet.html,这里将不准备详细讨论有关HTML的问题,如果不太了解,可以自己查阅相关资料。我们只稍微解释一下上面的HTML代码。它通过标记和参数告诉浏览器下载执行一个Applet。其中,name这个参数表示Applet的名字;codebase表示编译好的Applet字节码的路径;code表示Applet文件的文件名;width和height指定了该Applet的宽度和高度。name和codebase这两个参数并不是必须的,如果Applet字节码文件和html文件在同一路径下,则可以不加codebase参数。width和height这两个参数一定要加,所以在Applet程序中可以不需要设置Applet的Panel的大小。,把这个HTML文件和编译好的Applet保存在同一个目录下(HTML文件并不一定要和Applet同名),然后用浏览器打开这个HTML文件,将看到这个最简单的小应用程序的运行结果。除了通过浏览器来运行Applet,Java平台本身也提供了一个调试Applet的方法。在JDK包中带有一个小应用程序观察器AppletViewer.exe,只要在Windows命令行窗口中输入:appletviewerSimpleApplet.html就会看到和在浏览器中运行基本相同的输出结果。图12.2和图12.3分别列出了通过两种方式运行例子SimpleApplet的输出结果。,现在我们来看看这个Applet到底是如何运作的。大家可能已经注意到,在上面的例子SimpleApplet中,没有main()方法。一般的Java应用程序都是由main()方法处进入,而在Applet中却不是这样。在构造函数完成了它的任务后,浏览器将自动调用init()方法,所以通常把Applet的基本初始化操作放在这里。init()结束后,浏览器调用另一个称为start()的方法,start()通常在Applet成为可见时被调用。,start()方法结束后,piant()方法会紧接着被调用来向Applet的Panel上绘图。这样,一个Applet就已经运行起来了。用户离开了Applet所在的页面时,stop()方法被调用停止Applet的一些工作。直到浏览器关闭时,destroy()方法才被调用来完成最后的清除工作。当然Applet的生命周期比上面所讨论的要稍微复杂一些。,图12.2,图12.3,12.1.2Applet的安全机制我们已经知道,Applet是通过浏览器下载并自动运行的,这听起来好像有些可怕,通过浏览器自动运行,这不正是病毒制造者的梦想吗。Applet的设计者可能会把Applet设计成一个病毒,并借助浏览器让它进入用户的计算机。听起来很可怕,但Java的设计者们也考虑到了这一点,所以对Applet的能力做了种种限制,只要一个Applet试图违反安全条例,小应用程序安全管理器(AppletSecurityManager)就会发出一个SecurityException(安全违例)消息。,那么到底哪些是Applet可以做的,哪些是不可以做的呢?小应用程序所能够控制的安全程度是在浏览器层次上实现的,小应用程序的安全机制通过沙箱(sandbox)控制。在大多数浏览器上,在沙箱内运行时,缺省地禁止以下操作:运行时执行另一程序:小应用程序绝不能运行任何一个本地可执行程序。任何文件的输入/输出:小应用程序不能读/写本地计算机的文件系统。,调用任何本地方法:除了所用Java版本号,操作系统名和版本号,小应用程序不能获取任何与本地计算机有关的信息,也不能通过调用任何本地方法、API等方法获得。特别是,小应用程序不能获得用户名、电子邮件地址等等信息。尝试打开除提供Applet的主机之外的任何系统的Socket:除了下载它的服务器之外,小应用程序不能和任何一台主机通信。,这些限制的关键在于:通过限制Applet对系统文件的存取来阻止它侵犯一个远程系统的隐私或破坏该系统;禁止执行另一程序和不允许调用本地方法限制了Applet启动未经JVM检查的代码;对Socket的限制则禁止了与另一个可能有危害性的程序的通信。由于小应用程序是由JVM(JavaVirtualMachine)解释执行的字节码,而非由CPU直接执行的机器码,所以只要在JVM中检查了小应用程序的指令和程序区域,就可以确定,小应用程序不会对用户计算机系统造成较大的危害。表12.1显示了小应用程序在沙箱中运行时的功能。,表12.1小应用程序的功能,在这些限制下,小应用程序的能力似乎大打折扣了,这对那些恶意的设计者是有效的措施,但是也给开发者们造成了限制。如果没有办法打破这些限制,那么小应用程序所能做的就太有限了。对此,Java的设计者也提供了解决办法,那就是签名类。小程序提供者可以编写一个带有签名的Applet,当浏览器下载并运行这个Applet的时候,会提示用户这是一个签名Applet类,并询问用户是否信任该设计者。如果取得用户的信任,那么这个Applet就可以突破所有的限制,像一个普通应用程序那样在用户的计算机上运行了。,12.1.3Applet的主要方法Applet类的一些主要方法有:publicvoidinit()该方法在Applet被浏览器载入内存后自动调用,通常用来初始化数据的值。本方法只在Applet首次装入时被调用,并在调用start()方法前完成。假如要创建一个Applet生存期内的线程,就可以在该方法中创建,在destory方法中结束。,publicvoidstart()当init()方法完成后,浏览器会自动调用start()方法。它的执行使得Applet成为活动的。并且每次Applet成为可见的时,它都要执行一次,如:当浏览器在被最小化后又恢复时,或者从其他web页返回含有这个Applet的页面时。通常我们把主要程序代码写在这里,这一方法的典型用法是启动动画和播放声音。,publicvoidstop()当浏览器切换到另一个web页面或将要关闭时,会自动调用stop()方法。通常在该方法中加入一些暂停动作,例如暂停音乐或动画的播放,以便用户从其他Web页面切换回包含该Applet的页面时,可以通过调用start()方法继续播放下去。,publicvoiddestroy()用户关闭浏览器时,必须终止Applet的运行,并回收资源。此时,destroy()方法会自动被调用。该方法是Applet在生存期中执行的最后一个方法,所以通常在这里释放一些在init()中分配的资源,如创建的线程等。浏览器在调用destory()方法时,会先调用一次stop()方法。,publicAudioClipgetAudioClip(URLurl)返回由参数url所指定的AudioClip对象。AudioClip是一个音频剪辑对象的接口,它提供了音频对象的抽象控制。无论url指定的音乐文件是否存在,getAudioClip()方法都会很快返回值,因为音频文件要等到播放的时候才下载。url参数指定的必须是一个绝对地址。publicURLgetCodeBase()返回Applet所在网址。publicURLgetDocumentBase()返回包含该Applet对象的Web页面的地址。,publicImagegetImage(URLurl)返回参数url所指定的图片文件的Image对象。和getAudioClip()方法类似,不管指定地址的文件是否存在,getImage()方法都会立即返回值。图片文件在Applet显示在屏幕上时才会下载。url参数指定的必须是一个绝对地址。publicStringgetParameter(Stringname)返回由HTML文件所提供的参数信息。Applet提供了从Web页面文件中提取参数的方法,可以在HTML文件中通过标记设置一些参数供Applet使用,例如有如下的HTML代码:,调用getParameter(Color)将返回blue。注意参数名是不区分大小写的。publicBooleanisActive()检查Applet是否处于活动状态。当浏览器调用start()方法时,Applet即进入活动状态,而一旦stop()方法被调用,即进入非活动状态。,publicvoidplay(URLurl)播放由参数url指定的音频剪辑,如果该音频剪辑不存在,则不做任何事情。url参数指定的必须是一个绝对地址publicvoidshowStatus(Stringmsg)在浏览器的状态栏上显示由参数msg指定的文字信息,以便通知用户Applet的当前状态。通过第一节的例子,我们已经明白了Applet运行的方式和它的生命周期。下面我们通过实例来学习如何运用以上方法写出有趣的Applet。,例12.3ShowImageApplet.javaimportjava.applet.*;importjava.awt.*;.*;publicclassShowImageAppletextendsAppletStringImageName=null;StringAudioName=null;Imageimg=null;AudioClipaudio=null;,publicvoidinit()ImageName=getParameter(image);img=getImage(getDocumentBase(),ImageName);AudioName=getParameter(audio);audio=getAudioClip(getDocumentBase(),AudioName);publicvoidstart()audio.play();,publicvoidpaint(Graphicsg)g.drawImage(img,0,0,this);ShowImageApplet.html,图12.4,这个例子展示了如何通过getImage()方法载入一个图片对象,并将它显示在浏览器中以及在启动Applet的时候播放一段音乐。首先,通过getParameter()方法从HTML代码中提取出参数,即Image和Audio文件的文件名。然后通过getImage()方法和getAudioClip()方法取得Image和Audio文件的对象。它们包括两个参数,getDocument()返回包含Applet的Web页所在的地址,第二个参数getJava.gif指定图片文件名。最后在start()方法中播放音乐。这样,Applet每次启动时都会伴随着一段音乐。在paint()方法中调用drawImage()方法显示图片,运行时图片getJava.gif和windowsstart.wav两个文件必须和ShowImageApplet.html文件在同一目录下,其运行结果如图12.4所示。,运行结果如图12.4所示。值的注意的是,如果通过图片来源地址,12.1.4Applet标记以下为Applet标记的完整句法:archive=archiveListcode=appletFile.classwidth=pixelsheight=pixelscodebase=codebaseURLalt=alternateTextname=appletInstanceNamealign=alignmentvspace=pixelshspace=pixels,.alternateHTML这些标记的意义如下:archive=archiveList这一可选属性描述了一个或多个含有将被预装的类和其他资源的archives。类的装载由带有给定codebase的AppletClassLoader的一个实例来完成。ArchiveList中的archives以逗号(,)分隔。,code=appletFile.class这是一个必需的属性,它给定了含有已编译好的Applet子类的文件名。也可用package.appletFile.class的格式来表示。注:这个文件与你要装入的HTML文件的基URL有关,它不能含有路径名。要改变Applet的基URL,可使用。width=pixelsheight=pixels这些必需的属性给出了Applet显示区域的初始宽度和高度(以像素为单位),不包括Applet所产生的任何窗口或对话框。,codebase=codebaseURL这一可选属性指定了Applet的基URL包含有Applet代码的目录。如果这一属性未指定,则采用文档的URL。alt=alternateText这一可选属性指定了当浏览器能读取Applet标记,但不能执行JavaApplet时要显示的文本。name=appletInstanceName这个可选属性为Applet实例指定有关名称,从而使得在同一页面上的Applet可找到彼此(以及互相通信)。,align=alignment这个可选属性指定了Applet的对齐方式。它的可取值与基本的HTML中IMG标记的相应属性相同,为left,right,top,texttop,middle,absmiddle,baseline,bottom和absbottom等。vspace=pixelshspace=pixels这些可选属性指定了在Applet上下(vspace)及左右(hspace)的像素数目。其用法与IMG标记的vspace和hspace属性相同。,这个标记提供了一种可带有由外部指定的数值的Applet,它对一个Java应用程序的作用与命令行参数相同。Applet用getParameter()方法来存取它们的属性,该方法将在稍后作更详细的讨论。不支持Java程序执行的浏览器将显示被包括在和标记之间的任何常规的HTML;而可支持Java技术的浏览器则忽略介于这两个标记之间的HTML代码。,12.1.5从Applet中弹出窗口有时候我们可能觉得浏览器的界面不利于布局管理,一个浮在顶端的窗口或对话框更能引人注目。实际上,确实可以从Applet程序中弹出一个如同应用程序一般的窗口来。这有时也有利于我们将现成的应用程序转成小应用程序,如果我们只是仅仅想它通过浏览器下载运行,而不需要做太多功能上的调整,从Applet程序中弹出一个窗口也许是个好的解决办法,也就是给它披上一个Applet的外壳。下面这个例子是一个小型的计算器的程序,它通过Applet的一个按键弹出一个Frame,而计算器功能的实现都在Frame中。Applet的功能仅仅是从浏览器启动它,仅仅是它的一层外壳。,例12.4CalculatorApplet.javaimportjava.applet.*;importjava.awt.*;importjava.awt.event.*;publicclassCalculatorAppletextendsAppletimplementsActionListener/弹出的窗口privateFramecalcFrame=newCalculatorFrame();publicvoidinit(),/弹出的按键ButtoncalcButton=newButton(Calculator);calcButton.addActionListener(this);add(calcButton);publicvoidactionPerformed(ActionEventevt)/弹出窗口如果没有被显示,则显示它,否则关闭它if(calcFrame.isVisible()calcFrame.setVisible(false);,elsecalcFrame.setVisible(true);classCalculatorFrameextendsFrameimplementsActionListenerprivateTextFielddisplay=null;privatedoublearg1=0;privateStringBufferarg2=newStringBuffer();privatecharop=;,publicCalculatorFrame()setTitle(Calculator);setSize(200,200);setLayout(newBorderLayout();/输出窗口display=newTextField(0);display.setEditable(false);add(display,North);/数字按键盘Panelkeypad=newPanel();,Panelkeypad=newPanel();keypad.setLayout(newGridLayout(4,4);/添加数字和运算符按键Stringkeys=789/456*123-0.=+;for(inti=0;i=0,elsecalculate(Double.parseDouble(arg2.toString();op=c;arg2.setLength(0);if(c=)arg2.append(arg1);publicvoidcalculate(doublearg2),/计算switch(op)case+:arg1+=arg2;break;case-:arg1-=arg2;break;case*:arg1*=arg2;break;case/:arg1/=arg2;break;case=:arg1=arg2;break;default:break;,display.setText(+arg1);这个窗口是一个功能简陋的计算器面板。由于只需给它配上最简单的HTML代码,所以这里不再列出。图12.5是该程序的运行结果。,图12.5,弹出窗口,Applet,我们注意到,在弹出窗口的最底下有一行字JavaAppletWindow,这是对这个窗口的一个说明,也是所有浏览器都具备的一个安全特性。它提示用户这是一个由运行于浏览器的Applet弹出的窗口,而不是从机器上运行的一个程序。试想如你运行了一个恶意的Applet程序,它可能会弹出一个窗口,这个窗口与你本地某个需要输入账号、密码的应用程序有着相同的界面,也许你会被它蒙蔽而错误性的输入了信息,这个Applet就会把这些信息送回主机。,为了避免这种恶作剧出现,所有的弹出窗口都在底端显示一个标签,警告用户这是一个小应用程序,而不是本地应用程序。当然,如果你制作一个签名的小应用程序并得到了用户的信任,则可以不显示这个警告标签。值的一题的是,正如前面所说,这个小应用程序只是通过Applet来启动了一个弹出窗口,如果在CalculatorApplet类中为它加入一个mian()方法的话,它就可以同时作为Applet和应用程序来运行,大家可以自己试试。,12.1.6基于Swing与AWT的Applet的区别我们已经知道,Applet类是从AWT包中的Panel类派生的,而Java2提供的新一代GUI设计包Swing也提供了支持Applet设计的类:javax.swing.Japplet。注意,JApplet类并不是从JPanel类派生的,而是直接从java.applet.Applet类派生出来的。用AWT设计小应用程序时,我们从java.applet.Applet类派生一个子类,现在为了使用Swing包,就必须从javax.swing.JApplet类派生子类。让我们先来看一个基于JApplet类的小应用程序的实例,然后再分析二者的区别。,例12.5JAppletTest.javaimportjava.awt.*;importjavax.swing.*;publicclassJAppletTestextendsJAppletprivateJMenuBarmenuBar=newJMenuBar();publicvoidinit(),ContainercontentPane=getContentPane();Imageimg=getImage(getDocumentBase(),getJava.GIF);Iconicon=newImageIcon(getImage(getDocumentBase(),getJava.GIF);JLabellabel=newJLabel(Swing!,icon,SwingConstants.CENTER);,contentPane.add(label,BorderLayout.CENTER);JMenufileMenu=newJMenu(File);StringfileItems=New,Open,Save,Exit;for(inti=0;ifileItems.length;i+)fileMenu.add(fileItemsi);JMenuhelpMenu=newJMenu(Help);StringhelpItems=Helpofhelp,About;for(inti=0;ihelpItems.length;i+)helpMenu.add(helpItemsi);,menuBar.add(fileMenu);menuBar.add(helpMenu);setJMenuBar(menuBar);该程序的运行结果如图12.6所示。在该程序中,为小应用程序加入了一个菜单条,这也是基于Swing的小应用程序的一种新特性。,图12.6,从上面的例子来看,基于Swing的小应用程序和基于AWT的小应用程序在架构上没有什么分别,它们的生存方式也是相同的,所以上述例子中也没有给出start(),stop(),destory()这些方法,而是使用了默认的方法,但是,有几点需要注意:(1)JApplet类默认使用BorderLayout作为其容器的布局管理器,其默认约束条件是BordenLayout.CENTER,而Applet的缺省的布局管理器是FlowLayout,且FlowLayout的缺省约束条件是FlowLayout.LEFT,这是二者最显著的区别之一。,(2)JApplet是只包含一个组件的容器,这个组件就是JRootPane的一个实例,而JRootPane包含了一个称作内容窗格的容器。(3)内容窗格包含与特定的小应用程序有关的所有内容,可通过getContentPane()方法获得。即是说,小应用程序必须把所有的组件添加到内容窗格中,而Applet则是把它们直接添加到小应用程序中。(4)我们不能直接为小应用程序设置布局管理器,而只能对它的内容窗格设置布局管理。(5)JApplet的实例可以有一个菜单栏,它是由setJMenuBar()方法指定的,而AWT小应用程序却不能。,基于Swing的小应用程序比基于AWT的小应用程序有更多的优势,它可以使用Swing提供的更多界面元素和性能。但是它也有一个很大的缺陷,那就是很多浏览器都不能支持Swing编写的小应用程序,而必须依靠安装JavaPlug-in包。虽然可以让浏览器在运行Swing小应用程序时自动下载这个包,但是由于JavaPlug-in包并不小,所以对于非宽带上网的用户来说是不可忍受的。,12.2Applet的通信,12.2.1Applet与浏览器的通信我们已经学习过如何通过getParameter()方法从浏览器的Web页中获取信息,同时,Applet也可以要求浏览器为自己做事,例如我们可以让浏览器打开一个指定的Web页。为了与浏览器通信,需调用Applet的getAppletContext()方法。这个方法返回一个实现了AppletContext接口的对象,这个接口是实现Applet和浏览器通信的一座桥梁。,除了getAudioClip()和getImage()外,AppletContext接口还提供了四个有用的方法,它们是get-Applet()、getStream()、showDocument()和showStatus(),我们将在本节和下面的小节中讲述它们的用法。在小应用程序中可以访问浏览器的两个区:状态行和页面显示区,但都必须通过调用AppletContext接口中的方法来实现。通过调用showStatus(Stringstatus)方法,可以在浏览器底部的状态行中显示一行字符串提示信息,例如:showStatus(LoadingDatapleasewait);,但是,遗憾的是,使用showStatus()显示提示信息的功能很有限,因为浏览器自己也在使用状态行,而且经常使用。它总是用新的提示信息改写前一次的信息,用户往往无法注意到某一条信息,所以不能用该方法来显示一些重要信息。在浏览器页面显示区显示信息的方法是showDocument(),它可以通知浏览器打开一个指定的URL资源。showDocument()方法的定义如下:showDocument(URLurl);showDocument(URLurl,Stringtarget);,第一种格式的调用可以让浏览器直接打开一个新的URL资源,并将它显示在当前浏览器显示区中,替换原来显示的Web页面。第二种格式的调用多了一个String类型的参数,第一个参数依然是指定要显示的URL资源,第二个参数则用于指明浏览器打开页面的方式。如果指定值为_blank,浏览器就会另外打开一个新窗口,在新的浏览器窗口中显示指定的Web页。如果使用HTML3.2以上版本提供的帧特性,则可以将一个浏览器的窗口分成多个帧,并给每个帧指定一个名字。用户可以把自己的Applet放入一个帧中,并利用它来控制其他帧的页面显示。表12.2展示了可以用作ShowDocument()方法的第二个参数的所有字符串及其功能。,表12.2showDocument参数,例12.6Bookmark.javaimportjava.applet.*;importjava.awt.*;importjava.awt.event.*;.*;publicclassBookmarkextendsAppletimplementsItemListener,privateListlinks=newList();publicvoidinit()inti=1;Strings;while(s=getParameter(link+i)!=null)links.add(s);i+;add(links);,publicvoiditemStateChanged(ItemEventevt)Listsource=(List)evt.getSource();Stringlink=source.getSelectedItem();tryAppletContextcontext=getAppletContext();URLurl=newURL(link);context.showDocument(url,right);,catch(Exceptione)showStatus(Error+e);Bookmark.html,BookmarkApplet/Left.html,ABookmarApplet,这个小应用程序利用了HTML3.2以上版本的窗口分帧的特性,将浏览器的页面显示区垂直地分成了两个帧。左边的帧包含了上面的Bookmark小应用程序,它在一个列表框中列出了一列网址。点击其中任何一个网址,就会在右边的帧中显示出相应的Web页来。这个功能类似收藏夹的小应用程序在浏览器中运行,结果如图12.7所示。,图12.7,12.2.2同页Applet之间的通信我们已经学习了如何在一个Web页面中嵌入Applet,实际上,完全可以在同一个Web页上嵌入一个以上的小应用程序,甚至还可以让这些Applet互相通信,互相控制。要实现Web页中的不同Applet之间的通信,这些Applet的codebase必须是相同的,即它们的class文件放在服务器上的同一路径下。,Applet之前的通信是一个高级技巧。我们还记得在嵌入小应用程序的标记中有一个name参数,我们可以通过这个参数为嵌入的小应用程序赋予一个名字。然后调用AppletContext接口的getApplet()方法,获得对这个小应用程序的一个引用。利用这个应用,就可以调用小应用程序中任何public的方法。请看如下例子。,例12.7ListApplet.javai

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论