Java程序設(shè)計之swt教程_第1頁
Java程序設(shè)計之swt教程_第2頁
Java程序設(shè)計之swt教程_第3頁
Java程序設(shè)計之swt教程_第4頁
Java程序設(shè)計之swt教程_第5頁
免費預(yù)覽已結(jié)束,剩余40頁可下載查看

付費下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第4章SWT圖形用戶界面本章要點1.SWT程序開發(fā)步驟。2.SWT常用組件的使用。3.SWT勺布局。4.SWT勺事件處理。5.SWTDesigner簡介。本章難點1.SWT常用組件的使用。2.SWT勺布局。3.SWT勺事件處理。4.1SWT/JFace簡介SWT(StandardWidgetToolkit)即標(biāo)準(zhǔn)小窗口工具箱, 是IBM公司推出的一種在Eclipse中使用的集成開發(fā)環(huán)境,SWT提供可移植的API,并與底層本機OSGUI平臺緊密集成,它是一個與本地窗口系統(tǒng)集成在一起的小部件集和圖形庫。 SWT由JNI(JavaNativeInterface,Java本機接口)調(diào)用操作系統(tǒng)的內(nèi)部API,因此運行速度快,能夠獲得與操作系統(tǒng)的內(nèi)部應(yīng)用程序相同的外觀。JFace是一個用戶界面工具箱,也是一個易用、功能強大的圖形包,它簡化了常見的圖形用戶界面的編程任務(wù)。SWT和JFace都是Eclipse平臺上的主要組件。JFace是在SWT的基礎(chǔ)上創(chuàng)建的,但JFace并不能完全覆蓋SWT的功能,JFace和SWT的關(guān)系如圖4.1所示。由于JFace的功能更強大,因此做圖形界面開發(fā)時一般優(yōu)先選用JFace。圖4.1JFace和SWT的關(guān)系4.1.1SWT程序開發(fā)步驟在eclipse的plugins目錄下,找到文件,文件名中中3.2.1是eclipse的版本號,v3235是SWT的序列號,不同的eclipse版本這兩個數(shù)字也不同。在DOS狀態(tài)下,用jar命令將該文件解壓,命令格式如下:jarxf該命令將指定的文件解壓到當(dāng)前目錄下。解壓后得到四個DLL文件:swt-win32-3235.dll,swt-awt-win32-3235.dll,swt-gdip-win32-3235.dll和swt-wgl-win32-3235.dll。這四個文件就是SWT的原生庫文件。原生庫文件為SWT通過JNI訪問windows本地API提供了接口,為使Java程序在啟動時能夠訪問這些文件,可以通過以下方法進(jìn)行設(shè)置:方法一:將這四個DLL文件復(fù)制到j(luò)re的bin目錄下。方法二:設(shè)置環(huán)境變量,在PATH中加入這幾個dll文件所在的目錄。方法三:在eclipse的Java項目中導(dǎo)入原生庫文件。操作方法是:在eclipse的包資源管理器中,右單擊項目名-導(dǎo)入-常規(guī)-文件系統(tǒng)-下一步-瀏覽-選擇 DLL文件所在目錄—確定—勾選DLL文件—完成。導(dǎo)入SWT的原生庫文件后,還要在eclipse的Java項目中配置構(gòu)建路徑,添加外部 JAR,將文件加入到項目中,操作方法是:在eclipse的包資源管理器中,右單擊項目名 -構(gòu)建路徑-配置構(gòu)建路徑-庫(L)-添加外部JAFH在eclipse的plugins文件夾中找到該jar文件-打開-確定。例4.1在Java應(yīng)用程序中使用SWT的組件。操作步驟:新建一個Java項目,項目名為:sample4_1。采用方法三在項目中導(dǎo)入原生庫文件。

配置構(gòu)建路徑,將加入到項目中。eclipse包資源管理器可以看到導(dǎo)入的原生庫文件和引入的jar文件,如圖4.2所示。④在項目中新建一個類,文件名為HelloSWT.java。⑤在類文件中寫入代碼。圖4.2包資源管理器圖4.3程序運行結(jié)果HelloSWT.java文件內(nèi)容如下:packageedu.ch4;importimportimportimportimportclassHelloSWT{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();Shellshell=newShell(display);shell.setLayout(null);//Texthello=newText(shell,SWT.shell.setText("JavaimportclassHelloSWT{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();Shellshell=newShell(display);shell.setLayout(null);//Texthello=newText(shell,SWT.shell.setText("Java應(yīng)用程序");shell.setSize(200,100);Colorcolor=newColor(Display.//創(chuàng)建一個display對象。//shell是程序的主窗體設(shè)置shell的布局方式MULT)I; //聲明一個可以顯示多行信息的文本框//設(shè)置主窗體的標(biāo)題//設(shè)置主窗體的大小shell.setBackground(color);hello.setText(hello.pack();//shell.pack();//shell.open();getCurrent(),255,255,255);//聲明顏色對象//設(shè)置窗體的背景顏色"Hello,SWTWorld!\n\n你好,SWT世界!“);//設(shè)置文本框信息//自動調(diào)整文本框的大小自動調(diào)整主窗體的大小//打開主窗體//如果主窗體沒有關(guān)閉則一直循環(huán)//如果display不忙while(!shell.isDisposed()){if(!display.readAndDispatch()){display.sleep();}}display.dispose();////休眠銷毀display}HelloSWT.java 運行方式Java應(yīng)用程序,程序運行結(jié)果如圖HelloSWT.java 運行方式Java應(yīng)用程序,程序運行結(jié)果如圖4.3SWT應(yīng)用程序需要以下步驟:SWT應(yīng)用程序需要以下步驟:創(chuàng)建一個Display創(chuàng)建一個或多個 Shell設(shè)置Shell的布局創(chuàng)建Shell中的組件用open()方法打開Shell窗體寫一個事件轉(zhuǎn)發(fā)循環(huán)⑦銷毀displaySWT中的包SWT是Eclipse圖形API的基礎(chǔ),本節(jié)簡單介紹一下SWT中常用的包。1.dgets最常用的組件基本都在此包中,如 Button、Text、Label、Combo等。其中兩個最重要的組件是Shell和Composite。Shell相當(dāng)于應(yīng)用程序的主窗體;Composite是容納組件的容器,相當(dāng)于SWING中的Panel對象。2.主要的界面布局方式在此包中。SWT對組件的布局也采用了AWT/SWING中的Layout和LayoutData結(jié)合的方式。3.對一些基本圖形組件的擴展在此包中,比如其中的CLabel就是對標(biāo)準(zhǔn)Label組件的擴展,在CLabel上可以同時加入文字和圖片。在此包中還有一個新的布局方式 StackLayout。4.SWT采用了和AWT/SWING一樣的事件模型,在包中可以找到事件監(jiān)聽類和相應(yīng)的事件對象。比如,鼠標(biāo)事件監(jiān)聽器MouseListener,MouseMoveListener等,及對應(yīng)的事件對象MouseEvent。5.此包中包含針對圖片、光標(biāo)、字體或繪圖API。比如,可通過Image類調(diào)用系統(tǒng)中不同類型的圖片文件。6.對不同平臺,SWT有一些針對性的API。例如,在Windows平臺,可以通過此包很容易的調(diào)用OLE組件,這使得SWT程序也可以內(nèi)嵌IE瀏覽器或Word、Excel等程序。SWT/JFace常用組件SWT/JFace常用組件有按鈕(Button類)、標(biāo)簽(Label類)、文本框(Text類)、下拉框(Combo類)和列表框(List類)等。按鈕組件按鈕(Button)組件是SWT中最常用的組件,Button類的構(gòu)造方法是:Button(Compositeparent,intstyle)該方法有兩個參數(shù):第一個參數(shù)parent是指Button創(chuàng)建在哪一個容器上。Composite(面板)是最常用的容器,Shell(窗體)繼承自Composite,此參數(shù)也能接受Shell和任何繼承自Compsite的類。第二個參數(shù)style用來指定Button的式樣。SWT組件可以在構(gòu)造方法中使用式樣(style)來聲明組件的外觀形狀和文字的式樣。 SWT組件的構(gòu)造方法和Button類相似,參數(shù)的含義也相同。1.Button組件常用式樣SWT.PUSH:按鈕。SWT.CHECK:多選按鈕。SWT.RADIO:單選按鈕。SWT.ARROW:箭頭按鈕。SWT.NONE:默認(rèn)按鈕。SWT.CENTER:文字居中,與SWT.NONE相同。SWT.LEFT:文字靠左。SWT.RIGHT:文字靠右。SWT.BORDER:深陷型按鈕。SWT.FLAT:平面型按鈕。RADIdRADIdSWT.BORDER創(chuàng)建深陷型單選按鈕一個Button也可以指定多個式樣,只要將指定的各個式樣用符號“ 連接起來即可。如:Buttonbt=newButton(shell,SWT.CHECK|SWT.BORDER|SWTLEFT);表示創(chuàng)建的按鈕bt是一個復(fù)選按鈕(CHECK),深陷型(BORDER)、文字左對齊(LEFT)2.Button組件的常用方法setText(Stringstring):設(shè)置組件的標(biāo)簽文字。setBounds(intx,inty,intwidth,intheight):設(shè)置組件的坐標(biāo)位置和大小 (x軸坐標(biāo),y軸坐標(biāo),組件寬度width,組件高度height)。setEnabled(Booleanenabled):設(shè)置組件是否可用。 true:可用(默認(rèn)值), false:不可用。setFont(Fontfont):設(shè)置文字的字體。setForeground(Colorcolor):設(shè)置前景色。setBackgrount(Colorcolor):設(shè)置背景色。setlmage(lmageimage):設(shè)置顯示的圖片。setSelection(Booleanselected):設(shè)置是否選中(僅對復(fù)選框或單選框有效)。 true:選中,false:未選中(默認(rèn)值)。setToolTipText(Stringstring):設(shè)置鼠標(biāo)停留在組件上時岀現(xiàn)的提示信息。以上方法在其他組件中也可使用。例4.2按鈕示例。按照例4.1的操作步驟建立項目設(shè)置構(gòu)建路徑和引入原生庫。類 Sample4_2.java源代碼如下:packageedu.ch4;importimportpublicclassSample4_2{publicstaticvoidmain(String[]args){//創(chuàng)建一個display對象。//shell是程序的主窗體//創(chuàng)建一個display對象。//shell是程序的主窗體//設(shè)置shell的布局方式//設(shè)置主窗體的標(biāo)題NULL;//創(chuàng)建默認(rèn)按鈕NULL;//創(chuàng)建默認(rèn)按鈕設(shè)置按鈕上的文字設(shè)置按鈕顯示位置及寬度、高度PUS|SWT.BORDER/創(chuàng)建深陷型按鈕CHECK/創(chuàng)建復(fù)選按鈕CHECKWT.BORDER創(chuàng)建深陷型復(fù)選按鈕RADIO//創(chuàng)建單選按鈕Buttonbt2= newButton(shell,SWT.bt2.setText( "SWT.PUSH');bt2.setBounds(90,10,75,30);Buttoncheck1=newButton(shell,SWT.check1.setText( "SWT.CHECK):check1.setBounds(10,50,75,30);Buttoncheck2=newButton(shell,SWT.check2.setText( "SWT.CHECK)';check2.setBounds(90,50,75,30);Buttonradio1=newButton(shell,SWT.radio1.setText("SWT.RADIO");radiol.setBounds(10,90,75,30);Buttonradio2=newButton(shell,SWT.radio2.setText("SWT.RADIO");radio2.setBounds(90,90,75,30);黑體黑體",14,SWT.BOLD));//設(shè)置文字的字體字號ButtonarrowLeft=newButton(shell,SWT.ARRO|WSWT.LEFT);//創(chuàng)建箭頭按鈕(向左)arrowLeft.setBounds(10,130,75,20);ButtonarrowRight=newButton(shell,SWT.ARRO|WSWT.RIGHT|SWT.BORDE);RarrowRight.setBounds(90,130,75,20);shell.pack();shell.open();//自動調(diào)整主窗體的大小//打開主窗體while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉if(!display.readAndDispatch()){//如果display不忙display.sleep();//休眠}}display.dispose();//銷毀display}}運行結(jié)果如圖4.4所示。圖4.4按鈕圖4.5標(biāo)簽標(biāo)簽組件標(biāo)簽(Label類)組件是SWT中最簡單的組件。Label類的構(gòu)造方法和Button類相似,參數(shù)的含義與相同,格式如下:Label(Compositeparent,intstyle)Label類的常用式樣有以下幾種:Label類常用的式樣如下:SWT.CENTER:文字居中。SWT.RIGHT:文字靠右。SWT.LEFT:文字靠左。SWT.NONE:默認(rèn)式樣。SWT.WRAP:自動換行。SWT.BORDER:深陷型。SWT.SEPARATOR:分欄符,默認(rèn)為豎線分欄。SWT.HORIZONTAL:橫線分欄符。例4.3標(biāo)簽示例。packageedu.ch4;importimportimportpublicclassSample4_3{publicstaticvoidmain(String[]args){//創(chuàng)建一個//創(chuàng)建一個display對象。//shell是程序的主窗體設(shè)置shell的布局方式Shellshell=newShell(display);//shell.setLayout(null);//shell.setText( "標(biāo)簽示例");//設(shè)置主窗體的標(biāo)題Labellb1=newLabel(shell,SWT.BORDE|SRWT.RIGHT);//深陷型、文字右對齊Labellb1=newLabel(shell,SWT.lb1.setBounds(10,10,70,30);lb1.setText("標(biāo)簽1");lb1.setFont(newFont(display,lb1.setForeground(Display. lb1.setForeground(Display. getCurrent().getSystemColor(SWT. COLOR_BLU));ENONNON|ESWT.BORDE);R//帶邊框Labellb2=newLabel(shell,SWT.lb2.setBounds(90,10,70,30);CENTE)R;//文字居中的標(biāo)簽lb2.setText("標(biāo)簽2");lb2.setFont(newFont(display,Labellb3=newLabel(shell,SWT.宋體",14,SWT.NORMA))L;//設(shè)置文字的字體字號SEPARATO|SRWT.BORDE);R//豎直分欄符lb3.setBounds(10,50,70,30);Labellb4=newLabel(shell,SWT.SEPARATO|SRWT.HORIZONTA|SLWT.BORDE);R//水平分欄符lb4.setBounds(90,50,70,30);shell.pack();//自動調(diào)整主窗體的大小shell.open();//打開主窗體while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){//如果display不忙display.sleep();//休眠}}display.dispose(); //銷毀display}}程序運行結(jié)果如圖4.5所示。4.2.3文本框組件文本框(Text類)的式樣如下:SWT.NONE:默認(rèn)式樣。SWT.CENTER:文字居中。SWT.LEFT:文字靠左。SWT.RIGHT:文字靠右。SWT.MULTI:可以輸入多行,須回車換行。SWT.WRAP:可以輸入多行,到行尾后自動換行。SWT.PASSWORD:密碼型,輸入字符顯示成“*”。SWT.BORDER:深陷型。SWT.V_SCROLL:帶垂直滾動條SWT.H_SCROLL:帶水平滾動條例4.4各種文本框示例。packageedu.ch4;importimportpublicclassSample4_4{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象Shellshell=newShell(display);shell.setText("文本框示例");Texttext1=newText(shell,SWT.text1.setBounds(10,10,70,30);Texttext2=newText(shell,SWT.//shell是程序的主窗體PASSWO)R;Dtext2.setBounds(90,10,70,30);Texttext3=newText(shell,SWT.text3.setBounds(10,50,70,70);Texttext4=newText(shell,SWT.text4.setBounds(90,50,70,70);shell.pack();MULT|SWT.V_SCROLSWT.H_SCROLLWRASWT.V_SCROLLshell.open();while(!shell.isDisposed()){ //如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep(); //休眠}}display.dispose();}}運行結(jié)果如圖4.6所示。圖4.6文本框4.2.4下拉框組件//銷毀display圖4.7下拉框.下拉框(Combo類)的式樣SWT.NONE:默認(rèn)式樣。SWT.READ_ONLY:只讀。SWT.SIMPLE:無須單擊下拉框,列表會一直顯示。.下拉框(Combo類)的常用方法add(Stringstring):在Combo中增加一項。add(Stringstring,intindex):在Combo的第index項后插入一項。deselectAll():使Combo組件中的當(dāng)前選擇項置空。removeAll():將Combo中的所有選項清空。setItems(String[]items):將數(shù)組中的各項依次加入到 Combo中select(intindex):將Combo的第index+1項設(shè)置為當(dāng)前選擇項。例4.5下拉框示例。packageedu.ch4;importimportimportpublicclassSample4_5{privatestaticLabel lb;publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell=newShell(display);//shell 是程序的主窗體shell.setText( "下拉框示例");finalCombocombo=newCombo(shell,SWT.NONEcombo.setBounds(10,10,100,25);lb=newLabel(shell,SWT. WRA)P// 創(chuàng)建標(biāo)簽,可自動換行l(wèi)b.setBounds(120,10,100,35);Buttonbt1=newButton(shell,SWT. NONEbtl.setBounds(20,60,100,25);bt1.setText("設(shè)值");btl.addSelectionListener( newSelectionAdapter(){publicvoidwidgetSelected(SelectionEvente){// 按鈕的單擊事件combo.removeAll();// 清空combofor(inti=1;i<=3;i++){combo.add("第"+i+"項");// 循環(huán)添加選項}combo.select(O);// 設(shè)置默認(rèn)選項}});Buttonbt2=newButton(shell,SWT. NONEbt2.setBounds(130,60,100,25);bt2.setText("取值");bt2.addSelectionListener( newSelectionAdapter(){publicvoidwidgetSelected(SelectionEvente){// 按鈕的單擊事件lb.setText("你選擇的是:"+combo.getText());}});shell.pack();shell.open();while(!shell.isDisposed()){ //如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep(); //休眠}}display.dispose(); //銷毀display}}運行結(jié)果如圖4.7所示。本例中,按鈕bt1和bt2添加了按鈕選擇監(jiān)聽事件代碼。下拉框最初沒有值,單擊【設(shè)置】按鈕后將一組數(shù)據(jù)加入,單擊【取值】按鈕,標(biāo)簽 lb顯示取值的結(jié)果。4.2.5列表框組件列表框(List類)組件的用法和下拉框(Combo類)相似。1.列表框(List類)的式樣SWT.NONE:默認(rèn)式樣。SWT.V_SCROLL:帶垂直滾動條。SWT.MULTI:允許復(fù)選。SWT.SINGLE:允許單選。2?常用方法列表框(List類)組件的方法和下拉框(Combo類)是一樣的,但由于List可選擇多項,而Combo只能選擇一項,所以List沒有g(shù)etText()方法,List的取值是用getSelection()方法,返回一個所有選項組成的 String數(shù)組。例4.6列表框示例。packageedu.ch4;importimportimportimportimportimportimportimportpublicclassSample4_6{private staticLabel lb;publicstaticvoidmain(String[]args){Displaydisplay=newDisplay。; //創(chuàng)建一個display對象。finalShellshell=newShell(display);//shell 是程序的主窗體shell.setText("列表框示例");finalListlist=newList(shell,SWT. MULT|SWT.V_SCROLSWT.BORDE)R// 聲明一個可復(fù)選、帶垂直滾動條、有邊框的列表框。list.setBounds(10,10,100,50);lb=newLabel(shell,SWT. WRA)Plb.setBounds(120,10,90,50);Buttonbt1=newButton(shell,SWT. NONEbt1.setBounds(20,60,100,25);bt1.setText("設(shè)值");bt1.addSelectionListener( newSelectionAdapter(){publicvoidwidgetSelected(SelectionEvente){list.removeAll();for(inti=1;i<=8;i++){list.add("第"+i+"項");// 將選項循環(huán)加入到列表框中}list.select(O);}});Buttonbt2=newButton(shell,SWT. NONEbt2.setBounds(130,60,100,25);bt2.setText("取值");bt2.addSelectionListener( newSelectionAdapter(){publicvoidwidgetSelected(SelectionEvente){String[]selected=list.getSelection();// 聲明字符串?dāng)?shù)組保存選項StringoutStr= "";for(intj=O;j<selected.length;j++){outStr=outStr+""+selected[j];// 將數(shù)組中的選項加入到輸岀字符串}lb.setText("你選擇的是:"+outStr);}});shell.pack();shell.open();while(!shell.isDisposed()){ //如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep(); //休眠}}display.dispose(); //銷毀display}}本例開始運行時,列表框是空的,單擊【設(shè)置】按鈕,將選項加入到列表框中,按【 Ctrl】鍵加鼠標(biāo)左鍵選項,再按【取值】按鈕。運行結(jié)果如圖 4.8所示。圖4.8列表框4.2.6菜單菜單(Menu類,Menultem類)是常用的SWT組件,Menu是一個菜單欄,同時也是一個容器,可以容納菜單項(MenuItem)。.Menu的式樣SWT.BAR:菜單欄,用于主菜單。SWT.DROP_DOWN:下拉菜單,用于子菜單。SWT.POP_UP:鼠標(biāo)右鍵彈岀式菜單。.MenuItem的式樣SWT.CASCADE:有子菜單的菜單項。SWT.CHECK:選中后前面顯示一個小勾。SWT.PUSH:普通型菜單。SWT.RADIO:選中后前面顯示一個圓點。SWT.SEPARATOR:分隔符。?建立菜單的一般步驟:首先建立一個菜單欄,需要使用 SWT.BAR屬性。MenumainMenu=newMenu(shell,SWT.BAR在窗體中指定需要顯示的菜單欄。shell.setMenuBar(mainMenu);創(chuàng)建頂級菜單項,需要使用 SWT.CASCADE屬性。MenuItemfileltem= newMenultem(mainMenu,SWT.CASCADEfileltem.setText("文件&F");創(chuàng)建與頂級菜單項相關(guān)的下拉式菜單。MenufileMenu=newMenu(shell,SWT.DROP_DC)WN將頂級菜單項與下拉菜單關(guān)聯(lián)。fileItem.setMenu(fileMenu);二級菜單的創(chuàng)建只需重復(fù)以上步驟③?⑤。注意:本例創(chuàng)建所有 Menu對象的第一個參數(shù)都是shell;創(chuàng)建Menultem對象的第一個參數(shù)是該Menultem所在的Menu對象;如果某Menu是某MenuItem的子菜單,則還要建立關(guān)聯(lián):Menultem.setMenu(Menu)。源代碼如下:packageedu.ch4;importimportimportimportimport

publicclassSample4_7{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell=newShell(display);//shell是程序的主窗體shell.setText( "菜單示例");MenumainMenu=newMenu(shell,SWT.BARshell.setMenuBar(mainMenu);//MenumainMenu=newMenu(shell,SWT.POP_UP);// 創(chuàng)建彈岀式菜單//shell.setMenu(mainMenu);// 創(chuàng)建彈岀式菜單{//"文件“publicclassSample4_7{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell=newShell(display);//shell是程序的主窗體shell.setText( "菜單示例");MenumainMenu=newMenu(shell,SWT.BARshell.setMenuBar(mainMenu);//MenumainMenu=newMenu(shell,SWT.POP_UP);// 創(chuàng)建彈岀式菜單//shell.setMenu(mainMenu);// 創(chuàng)建彈岀式菜單{//"文件“項Menultemfileltem= newMenultem(mainMenu,S\fileItem.setText("文件&F");//"文件“菜單CASCADE////MenufileMenu=newMenu(shell,SWT.fileltem.setMenu(fileMenu);DROP_DOW/N//"新建“項MenultemnewFileItem=newMenultem(fileMenu,SWT. CASCADEnewFileItem.setText( "新建&N");//"新建“菜單MenunewFileMenu=newMenu(shell,SWT.newFileltem.setMenu(newFileMenu);{DROP_DOW/N//"新建項目“項MenuItemnewProjectltem= newMenultem(newFileMenu,SWT.PUSHnewProjectltem.setText("項目\tCtrl+Shift+N");設(shè)置快捷鍵newProjectltem.setAccelerator(SWT.添加事件監(jiān)聽CTR+SWTSHIFT+'N');newProjectltem.addSelectionListener( newSelectionAdapter(){publicvoidwidgetSelected(SelectionEvente){Texttext=newText(shell,SWT. MULTISWT.BORDESWT.WRAPtext.setBounds(10,10,100,30);text.setText("你選擇了"新建項目" ");}});newMenultem(newFileMenu,SWT.SEPARATORPUSHsetText("包");Menultem(newFileMenu,SWT.PUSHsetText("類");newMenuItem(newFileMenu,SWT.new}MenultemopenFileltem=newMenultem(fileMenu,SWT.CASCADEopenFileltem.setText( "打開&O');Menultemexitltem= newMenuItem(fileMenu,SWT. CASCADEexitItem.setText("退岀&E");}Menultemhelpltem=newMenultem(mainMenu,SWT.CASCADEhelpltem.setText("幫助&H");}shell.pack();shell.open();while(!shell.isDisposed()){ //如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep(); //休眠}}display.dispose(); //銷毀display}}程序運行結(jié)果如圖 4.9、4.10所示。當(dāng)點擊【文件】t【新建】t【項目 Ctrl+Shift+N】時,文本框中顯示“你選擇了’新建項目’”。圖4.9選擇菜單 圖4.10運行結(jié)果創(chuàng)建彈岀式菜單只需將①、②兩步的代碼改為以下兩行即可。MenumainMenu=newMenu(shell,SWT.POP_UP);// 創(chuàng)建彈岀式菜單shell.setMenu(mainMenu);// 創(chuàng)建彈岀式菜單4.3容器類通常,組件構(gòu)建在容器類中,容器構(gòu)建在主窗體( shell)中,主窗體也是容器,也就是說,容器不僅可以容納組件,也可以容納容器。有了容器,就可以通過它來對組件進(jìn)行集體操作。例如,容器在界面上移動時,其上的組件也會隨著容器移動,容器隱藏,其組件也會被隱藏,容器銷毀( dispose),其組件也會被銷毀。4.3.1面板面板(Composite類)是最常用的容器。主窗體( shell)是面板(Composite)的子類。面板的構(gòu)造方法格式如下:Composite(Compositeparent,intstyle)第一個參數(shù)表示該容器創(chuàng)建在哪個容器上,第二個參數(shù)表示容器的式樣。 Composite的式樣一般都是用SWT.NONE,這時Composite在界面是不顯示岀來的, 只是發(fā)揮著容器的作用。 如果要讓容器形成凹陷效果,可以用SWT.BORDER式樣。例如,在主窗體中創(chuàng)建一個容器:Compositecomposite=newComposite(shell,SWT.NONE);Composite的常用方法:getLayout():得到布局管理器。getLayoutData():得到布局?jǐn)?shù)據(jù)。getParent():得到容納該容器的父容器。getShell():得到容納該容器的 Shell。layout():將容器上的組件重新布局,相當(dāng)于刷新。例4.8面板示例。packageedu.ch4;importimportimportimportimportpublicclassSample4_8{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象finalShellshell=newShell(display);//shell是程序的主窗體shell.setText( "容器示例");Compositecomposite1=newComposite(shell,SWT.NON)E;composite1.setBounds(10,10,100,50);Compositecomposite2=newComposite(shell,SWT.BORDE);Rcomposite2.setBounds(120,10,100,50);Labellb1=newLabel(composite1,SWT.NON)E;lb1.setText("面板1");lb1.pack();Labellb2=newLabel(composite2,SWT.NON)E;lb2.setText("面板2");lb2.pack();shell.pack();shell.open();while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep();//休眠}}display.dispose(); //銷毀display}}運行結(jié)果如圖4.11所示。圖4.11面板圖4.12分組框4.3.2分組框Group顯示有分組框(Group類)是面板(CompositeGroup顯示有例4.9分組框示例。packageedu.ch4;importimport*;publicclassSample4_9{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell= newShell(display); //shell是程序的主窗體shell.setText( "分組框示例");Groupgroup1=newGroup(shell,SWT.NON)E;//創(chuàng)建分組框group1.setText("錄入信息");//設(shè)置分組框說明信息group1.setBounds(10,20,200,100);Labellb1=newLabel(group1,SWT.NON)E;//在分組框中加入組件lb1.setText("姓名:");

lb1.setBounds(10,20,70,20);Texttext1=newText(group1,SWT.BORDE);Rtext1.setBounds(90,20,70,20);Labellb2=newLabel(group1,SWT.NON)E;lb2.setText("地址:");lb2.setBounds(10,50,70,20);Texttext2=newText(group1,SWT.BORDE);Rtext2.setBounds(90,50,70,20);shell.pack();shell.open();while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep();//休眠}}display.dispose(); //銷毀display}}運行結(jié)果如圖4.12所示。4.3.3選項卡選項卡包括一個選項卡(TabFolder類)和一個選項頁(TabItem類),TabFolder是容器,可以容納其他容器和組件,但TabItem不是容器,可以把它看成是一個選項標(biāo)簽,TabFolder通過TabItem來對其中的組件進(jìn)行控制。每一個TabItem用setControl()方法來控制一個界面組件。例4.10選項卡示例。packageedu.ch4;importimportpublicclassSample4_10{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell= newShell(display); //shell是程序的主窗體shell.setText( "選項卡示例");TabFoldertabFolder=newTabFolder(shell,SWT. NON)E;//聲明一個選項卡容器tabFolder.setBounds(5,5,180,130);//設(shè)置選項卡的位置和大小TabItemtabItem1=newTabItem(tabFolder,SWT.NON)E;//聲明第1個選項頁tabItem1.setText("選項1");//設(shè)置選項頁的標(biāo)題//創(chuàng)建第1個分組框,建立在Groupgroup1=group1.setText(//創(chuàng)建第1個分組框,建立在Groupgroup1=group1.setText("錄入信息");tabItem1.setControl(group1);//Labellb1=newLabel(group1,SWT.lb1.setText("姓名:");lb1.setBounds(10,20,70,20);Texttext1=newText(group1,SWT.tabFoldernewGroup(tabFolder,SWT.上NON)E;//設(shè)置分組框說明信息

讓tabItem1控制group1

NON)E;//注意Label建立在group1上BORDE);Rtext1.setBounds(90,20,70,20);Labellb2=newLabel(group1,SWT.NON)E;lb2.setText("地址:");lb2.setBounds(10,50,70,20);Texttext2=newText(group1,SWT.BORDE);Rtext2.setBounds(90,50,70,20);}TabItemtabItem2=newTabItem(tabFolder,SWT. NON)E;//聲明第2個選項頁tabItem2.setText({"選項2");//創(chuàng)建第2個分組框,建立在tabFolder上Groupgroup2=newGroup(tabFolder,SWT.NON)E;tabItem2.setControl(group2);//讓tabItem2控制group2group2.setText("興趣愛好");Buttonbt1=newButton(group2,SWT.CHEC)K;bt1.setBounds(20,20,70,20);bt1.setText("音樂");Buttonbt2=newButton(group2,SWT.CHEC)K;bt2.setBounds(20,50,70,20);bt2.setText("美術(shù)");Buttonbt3=newButton(group2,SWT.CHEC)K;bt3.setBounds(20,80,70,20);bt3.setText("體育");}shell.pack();shell.open();while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){//如果display不忙display.sleep();//休眠}}display.dispose();//銷毀display}}圖4.14選項2運行結(jié)果如圖4.13、4.14所示。圖圖4.14選項24.4布局管理器在Java中,GUI程序開發(fā)的目標(biāo)之一是跨平臺,而每種類型操作系統(tǒng)對屏幕的定義不一樣,所以Swing中引入了布局的概念,對子組件的位置和大小等信息進(jìn)行定義。SWT中也采用了布局方式,用戶可使用布局來控制組件中元素的位置和大小等信息。組件可以用方法setBounds(intx,inty,intwidth,intheight) 來指定該組件相對于父組件的位置和組件的大小。組件的這種定位方式稱為絕對定位。當(dāng)組件數(shù)量較多,布局較復(fù)雜時,則要使用布局管理器LayoutManager來進(jìn)行定位,這時,每個控件的坐標(biāo) X、Y、寬度和高度都是通過 LayoutManager設(shè)置的,這種定位方式稱為托管定位。SWT提供了一些常用的布局管理器供用戶使用;在本章中,將介紹四種基本的布

局管理器:FillLayout、RowLayout、GridLayout和FormLayout。在布局管理器中,每當(dāng)重新設(shè)置復(fù)合組件的大小,都需要進(jìn)行定位。布局管理器常常是專為某一個復(fù)合組件設(shè)計的。一些布局管理器只使用它們自身的參數(shù)就可以控制,而另一些布局管理器還需要其它參數(shù)(LayoutData),該參數(shù)是在設(shè)置布局管理器的復(fù)合組件中的每個控件上指定的。SWT中常用的布局管理器有如下一些:FillLayout:充滿式布局,在容器中以相同的大小以單行或單列排列組件。RowLayout:行列式布局,以單行或多行的方式定制組件的排列方式。GridLayout:網(wǎng)格式布局,以網(wǎng)格的方式進(jìn)行布局,組件可以占用指定的一個或幾個網(wǎng)格。FormLayout:表格式布局,通過定義組件四個邊的距離來排列組件,被引用的相對的組件可以是父組件,也可以是同一容器中的其它組件。充滿式布局充滿式布局(FillLayout類)是最簡單的布局管理器。它把組件按一行或一列充滿整個容器,并強制組件的大小一致。一般,組件的高度與最高組件相同,寬度與最寬組件相同。距離和間距。如果容器中只有一個組件,則該組件會充滿整個容器。1.構(gòu)造方法:FillLayout()創(chuàng)建按一行充滿容器的對象。type)有:SWT.HORIZONTALtype)有:SWT.HORIZONTAL按FillLayout不能折行,不能設(shè)置邊界type的取值同上。type屬性,代碼如下:FillLayoutfilllayout= newFillLayout();// 創(chuàng)建FillLayoutFilllayout.type=SWT.VERTICAL;// 設(shè)置type的值FillLayout不能折行,不能設(shè)置邊界type的取值同上。type屬性,代碼如下:FillLayoutfilllayout= newFillLayout();// 創(chuàng)建FillLayoutFilllayout.type=SWT.VERTICAL;// 設(shè)置type的值shell.setLayout(filllayout);//newButton(shell,SWT.newButton(shell,SWT.newButton(shell,SWT.newButton(shell,SWT.將FillLayout對象用于shellPUSH).setText(PUSH).setText(PUSH).setText(PUSH).setText("超寬按鈕1");//在shell"按鈕2");"按鈕3");"按鈕4");對象上中創(chuàng)建按鈕例4.11充滿式布局示例。packageedu.ch4;importimportimportpublicclassSample4_11{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();finalShellshell=newShell(display);//shell"FillLayout示例importpublicclassSample4_11{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();finalShellshell=newShell(display);//shell"FillLayout示例");newFillLayout();//將FillLayout//創(chuàng)建一個display對象。是程序的主窗體shell.setText(FillLayoutfilllayout=shell.setLayout(filllayout);//newButton(shell,SWT.newButton(shell,SWT.newButton(shell,SWT.newButton(shell,SWT.創(chuàng)建FillLayout對象用于shell對象上PUSH).setText(PUSH).setText(PUSH).setText(PUSH).setText("超寬按鈕1");//在shell"按鈕2");"按鈕3");"按鈕4");中創(chuàng)建按鈕shell.pack();shell.open();while(!shell.isDisposed()){//如果主窗體沒有關(guān)閉則一直循環(huán)if(!display.readAndDispatch()){ //如果display不忙display.sleep();//休眠}}display.dispose(); //銷毀display}}運行結(jié)果如圖4.15所示。圖4.15FillLayout水平布局 圖4.16FillLayout垂直布局如果要將按鈕按豎直方向排列,也可以只修改以下一行語句:Layoutlayout=newFillLayout(SWT.VERTICAL);運行結(jié)果如圖4.16所示。行列式布局行列式布局(RowLayout類)可以使組件折行顯示,可以設(shè)置邊界距離和間距。另外,還可以對每個組件通過setLayoutData()方法設(shè)置RowData對象。RowData用來設(shè)置組件的大小。1.構(gòu)造方法:RowLayout()創(chuàng)建按行放置組件的對象。RowLayout(inttype)創(chuàng)建按指定類型放置組件的對象。指定類型( type)有:SWT.VERTICAL按列放置組件。SWT.HORIZONTAL 按行放置組件。2.常用屬性:intmarginWidth:組件距容器邊緣的寬度(像素),默認(rèn)值為0intmarginHeight:組件距容器邊緣的高度(像素),默認(rèn)值為0intmarginTop:組件距容器上邊緣的距離(像素),默認(rèn)值為3intmarginBottom:組件距容器下邊緣的距離(像素),默認(rèn)值為 3。intspacing:組件之間的距離,默認(rèn)值為 3。booleanjustify:如果該屬性為true,則組件間的距離隨容器的拉伸而變大。默認(rèn)值為 false。booleanwrap:如果該屬性為true,則當(dāng)容器空間不足時會自動折行;如果該屬性為 false,不自動折行。默認(rèn)值為true。booleanpack:如果該屬性為true,組件大小為設(shè)定值;如果該屬性為 false,則強制組件的大小相同。默認(rèn)值為type:使組件按指定式樣放置,(type=SWT.HORIZONTAL|SWT.VERTICAL),默認(rèn)為按行放置,默認(rèn)值為SWT.HORIZONTAL。3.RowData類:RowData稱為RowLayout的布局?jǐn)?shù)據(jù)類,可用于改變?nèi)萜髦薪M件的外觀形狀。其構(gòu)造方法:RowData(intwidth,intheight);例如:Buttonbt1=newButton(shell,SWT. PUSH);//創(chuàng)建按鈕bt1.setText( "按鈕1");RowDatarowdata=newRowData(60,30);//創(chuàng)建布局?jǐn)?shù)據(jù)類的對象bt1.setLayoutData(rowdata); //設(shè)置按鈕的布局?jǐn)?shù)據(jù)禾U用RowData對象設(shè)置按鈕(bt1)的寬度是60像素,高度是30像素。例4.12行列式布局。packageedu.ch4;importimportimportpublicclassSample4_12{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();//創(chuàng)建一個display對象。finalShellshell=newShell(display);//shell是程序的主窗體shell.setText("FillLayout示例");RowLayoutrowlayout=newRowLayout();//創(chuàng)建按行放置組件的對象強制組件大小相同不自動折行組件距容器邊緣的寬度為20像素組件距容器邊緣的高度為20像素組件之間的間距為10像素設(shè)置容器shell的布局方式為rowlayoutPUSH);//創(chuàng)建按鈕rowlayout.pack=false;//rowlayout.wrap=false;//rowlayout.rowlayout.rowlayout.marginWidth=20;marginHeight=20;spacing=10;//////shell.setLayout(rowlayout);Buttonbt1=newButton(shell,SWT.bt1.setText("按鈕1");RowDatarowdata=newRowData(80,30);//bt1.setLayoutData(rowdata);//newButton(shell,SWT.newButton(shell,SWT.newButton(shell,SWT.shell.pack();shell.open();//創(chuàng)建布局?jǐn)?shù)據(jù)類的對象設(shè)置按鈕的布局?jǐn)?shù)據(jù)"按鈕2");"按鈕3");"按鈕4");

shell的大小while(!shell.isDisposed()){if(!display.readAndDispatch()){display.sleep();}}display.dispose();PUSH).setText(PUSH).setText(PUSH).setText(//自動調(diào)整容器//打開主窗體//如果主窗體沒有關(guān)閉則一直循環(huán)//如果display不忙//休眠//銷毀displayrowlayout.pack=true時,各按鈕為設(shè)定值,如圖4.17所示;當(dāng)rowlayout.pack=false時,各按鈕被強制設(shè)定為相同大小,如圖4.18所示;當(dāng)rowlayout.justify=true時,將主窗體拉伸,各按鈕間的距離也增大,但間隔均勻分布,如圖4.19所示;當(dāng)rowlayout.justify=false時,將主窗體拉伸,各按鈕間距不變,如圖4.20所示;當(dāng)rowlayout.wrap=false時,當(dāng)主窗體寬度收縮,按鈕自動折行,如圖4.21所示;當(dāng)rowlayout.wrap=false時,主窗體寬度收縮,按鈕不會折行,如圖圖4.17rowlayout.pack=true圖4.19rowlayout.justify=true圖4.21rowlayout.wrap=true4.4.3網(wǎng)格式布局4.22所示。圖4.18rowlayout.pack=false圖4.20rowlayout.justify=false圖4.22rowlayout.wrap=false網(wǎng)格式布局(GridLayout類)是實用而且功能強大的標(biāo)準(zhǔn)布局,也是較為復(fù)雜的一種布局。這種布局把容器分成網(wǎng)格,把組件放置在網(wǎng)格中。GridLayout有很多可配置的屬性,和RowLayout一樣,也有專用的布局?jǐn)?shù)據(jù)類GridData,GridLayout的強大之處在于它可以通過 GridData來設(shè)置每一個組件的外觀形狀。GridLayout的構(gòu)造方法無參數(shù),但可以通過 GfidData和設(shè)置GridLayout的屬性來設(shè)置組件的排列及組件的形狀和位置。1.GridLayout的屬性intnumColumns:設(shè)置容器的列數(shù),組件從左到右按列放置,當(dāng)組件數(shù)大于列數(shù)時,下一個組件將自動添加新的一行。默認(rèn)值為 1列。booleanmakeColumnsEqualWidth:強制使列都具有相同的寬度,默認(rèn)值為 falseintmarginWidth:設(shè)置組件與容器邊緣的水平距離,默認(rèn)值為 5<intmarginHeight:設(shè)置組件與容器邊緣的垂直距離,默認(rèn)值為 5inthorizontalSpacing:設(shè)置列與列之間的間隔,默認(rèn)值為 5。intverticalSpacing:設(shè)置行與行之間的間隔,默認(rèn)值為 5。例4.13GridLayout的屬性設(shè)置。packageedu.ch4;importimportimportpublicclassSample4_13{publicstaticvoidDisplaydisplay=Shellshell=shell.setText(GridLayoutgridLayout=main(String[]args){newDisplay();newShell(display);"GridLayout示例");newGridLayout();numColumns=3;horizontalSpacing =30;makeColumnsEqualWidth=true;newButton(shell,SWT.PUSHsetText("B1");newButton(shell,SWT.PUSHsetText("超寬按鈕2"newButton(shell,SWT.PUSHsetText("按鈕3");newButton(shell,SWT.PUSHsetText("B4");newButton(shell,SWT.PUSHsetText("按鈕5");shell.setLayout(gridLayout););shell.pack();shell.open();while(!shell.isDisposed()){if(!display.readAndDispatch())display.sleep();}display.dispose();gridLayout.numColumns分別為1、2、3時,按鈕依次按所示;當(dāng)makeColumnsEqualWidth=true時,雖然按鈕寬度不同,1列、2列和3列排列,運行結(jié)果如圖但列寬相同,如圖 4.26所示;當(dāng)4.23~4.25horizontalSpacing=30時,列間距為30,如圖4.27所示。圖4.23numColumns=1 圖4.24numColumns=2圖4.25numColumns=3圖4.26makeColumnsEqualWidth=true2.布局?jǐn)?shù)據(jù)類(GridData類)圖4.27horizontalSpacing=30GridData的配合使用,充滿GridData是GridLayout專用的布局?jǐn)?shù)據(jù)類,用 GridDataGridData的配合使用,充滿構(gòu)造方法如下:GridData();創(chuàng)建一個屬性值為默認(rèn)值的對象。GridData(inttype); 創(chuàng)建一個指定類型(type)的對象。GridData常用類型如下:GridData.FILL通常與GridData類的對象屬性horizontalAlignment和verticalAlignment對象屬性指定的空間。GridData.FILL_HORIZONTAL水平充滿,組件充滿網(wǎng)格水平方向的空間。GridData.FILL_VERTICAL垂直充滿,組件充滿網(wǎng)格垂直方向的空間。GridData.FILL_BOTH雙向充滿,組件充滿水平和垂直方向的空間。GridData.HORIZONTAL_ALIGN_BEGINNING水平對齊靠左,組件在網(wǎng)格中靠左放置。GridData.HORIZONTAL_ALIGN_CENTER水平對齊居中,組件在網(wǎng)格中居中放置。GridData.HORIZONTAL_ALIGN_END水平對齊靠右,組件在網(wǎng)格中靠右放置。GridData常用對象屬性如下:inthorizontalSpan設(shè)置組件占用的列數(shù),默認(rèn)值為1。intverticalSpan設(shè)置組件占用的行數(shù),默認(rèn)值為 1。horizontalAlignment 設(shè)置組件的對齊方式為水平方向。verticalAlignment 設(shè)置組件的對齊方式為垂直方向。grabExcessHorizontalSpace搶占額外的水平空間。grabExcessVerticalSpace搶占額外的垂直空間。horizontalAlignment和verticalAlignment可以取以下值:BEGINNING開始(水平對齊時居左;垂直對齊時居上)CENTER居中END結(jié)束(水平對齊時居右;垂直對齊時居下)FILL充滿默認(rèn)的horizontalAlignment值是BEGINNING。默認(rèn)的verticalAlignment值是CENTER例4.14使用gridData布局。packageedu.ch4;importimportimportpublicclassSample4_14{publicstaticvoidmain(String[]args){Displaydisplay=newDisplay();Shellshell= newShell(display);shell.setText( "GridData示例");GridLayoutgridLayout=newGridLayout();//創(chuàng)建網(wǎng)格布局對象gridLayout.numColumns=3; //設(shè)置網(wǎng)格布局列數(shù)為3gridLayout.makeColumnsEqualWidth=true; //強制列寬相等shell.setLayout(gridLayout); //將shell設(shè)置為指定的網(wǎng)格布局式樣GridDatagridData=newGridData();//創(chuàng)建網(wǎng)格布局?jǐn)?shù)據(jù)對象gridData.horizon

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論