




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
6.1GUI程序框架
6.2容器布局ContainerLayout
6.3事件處理
6.4基本Swing組件編程
6.5高級Swing組件編程
6.6小結(jié)
6.7習(xí)題
6.1.1GUI類層次圖
如圖6-1所示,GUI(GraphicsUserInterface)編程主要以java.awt.Component包為主,要建立GUI程序還必須包含容器類Container,而Container又包括Panel、Window和javax.swing.JComponent。Panel容器包括Applet和JApplet的子類,Window容器分為Frame和Dialog,由這兩種類再派生出JFrame和JDialog。java.awt.Component包含各種Swing組件,諸如JButton、JTextArea、JTabel等。6.1GUI程序框架圖6-1GUI類層次圖6.1.2程序框架
GUI圖形用戶界面用于編寫基于圖形化的界面,便于用戶與計算機(jī)進(jìn)行交互,它比前面講述的基于命令行窗口的Application更加友好。要進(jìn)行GUI編程,就要掌握AWT(AbstractWindowToolkit,抽象窗口工具包),它是Java為了適應(yīng)各種不同操作的圖形化編程而抽象出的若干圖形化的窗口組件的工具集合。AWT提供了各種容器、布局管理以及各種組件,其類層次如圖6-1所示。AWT在編程實踐中又有一定局限性,因此輕量級組件包javax.swing應(yīng)運而生。與AWT組件相比,Swing組件具有更加優(yōu)秀的特性(將在后續(xù)章節(jié)中講述),因此我們主要以Swing組件為基礎(chǔ)來講述。要建立GUI程序,就需要將各種各樣的組件組合在一起,按照一定的排列方式排列起來,這就需要一個能夠容納組件的對象——容器。容器可對各種組件的布局進(jìn)行管理。
常見的容器如圖6-1所示,有Panel、javax.swing.JComponent和Window。Window類的子類Dialog和Frame又派生出了JDialog和JFrame。JDialog是特殊的容器,其位置可以移動,但不能改變其大小,我們在后續(xù)章節(jié)講述。本節(jié)主要介紹JFrame。
JFrame是一個大小可以調(diào)整、位置可以移動的窗體。Panel類派生出了JPanel、Applet及JApplet,Applet和JApplet是一種特殊的程序,主要運行在Web上,我們在后續(xù)章節(jié)中講述,本節(jié)我們主要講述JPanel。因此,本節(jié)我們主要講述構(gòu)成程序框架的兩個關(guān)鍵容器JPanel和JFrame。
1.?JPanel
JPanel不能獨立存在,只能加在別的容器中使用,如JFrame、JDialog等。JPanel類由Panel派生而得到,Panel還有一個Applet子類和JApplet(Applet的子類),JApplet和Applet是運行在Web上的小應(yīng)用程序,下一章節(jié)將詳細(xì)介紹。一個JPanel區(qū)域是一個矩形的區(qū)域,因為它本身是一個容器類,因此在其中可以添加其他組件對象,諸如JButton、JLabel等。
JPanel()直接構(gòu)造一個空的JPanel對象,應(yīng)用add(object)方法可以將其他組件加入到JPanel容器中。JPanel通常不可視,只有當(dāng)其添加到JFrame中后,才可顯示。
如例6-1所示,先構(gòu)造一個JFrame對象、一個JPanel對象和一個JLabel對象,將JLabel對象lb加入到容器JPanel的對象jp中,再將jp對象添加到JFrame的對象frm中。程序運行結(jié)果如圖6-2所示。圖6-2JPanel的使用【例6-1】JPanel示例程序。
importjavax.swing.*;
publicclassMyJPanelextendsJFrame
{
publicstaticvoidmain(String[]args)
{
Iconicn=newImageIcon("images/Student1.jpg");
JLabellb=newJLabel(icn);
JPaneljp=newJPanel();
JFramefrm=newJFrame("JPanel測試示例");
jp.add(lb);
frm.add(jp);
frm.setSize(200,160);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2.?JFrame圖6-3JFrame的使用
應(yīng)用JFrame()可以構(gòu)造一個空的窗口對象;應(yīng)用JFrame(Stringtitle)可以構(gòu)造一個窗口標(biāo)題為title的窗口;應(yīng)用add(object)方法可以將各種組件添加到窗口中,應(yīng)用setSize(intwindth,intheigh)可以設(shè)置JFrame窗口的寬度和高度;應(yīng)用frameobject.pack()方法,可以使窗口自動調(diào)整尺寸,以適應(yīng)其中組件的大小;應(yīng)用setVisable()可以使窗口顯示(true)或隱藏(false);應(yīng)用setDefaultCloseOperation()方法,其中參數(shù)為靜態(tài)常量“JFrame.EXIT_ON_CLOSE”,可以設(shè)置窗體響應(yīng)關(guān)閉命令。
JFrame的使用如例6-2所示,其運行結(jié)果如圖6-3所示。
【例6-2】JFrame應(yīng)用示例。
importjavax.swing.*;
publicclassMyJFrameextendsJFrame
{
publicstaticvoidmain(String[]args)
{
JFramef=newJFrame("JFrame測試示例");
JButtonbtn=newJButton("PleaseClickme!");
f.add(btn); f.setSize(200,100);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
JFrame程序中若沒有事件偵聽處理Window退出事件,或沒有setDefaltCloseOperation,則點擊窗口的“×”時,無法完全退出系統(tǒng),必須按“Ctrl?+?C”鍵才能中斷退出當(dāng)前運行程序。圖6-3JFrame的使用在GUI編程時,所有的組件必須盛放在一個容器中,這些組件的排列方式、大小都由布局管理器來控制。每個容器Container(如Panel或Frame)都有一個與它相關(guān)的缺省布局管理器,它可以通過調(diào)用setLayout()來改變?nèi)萜髦薪M件的布局方式。
6.2容器布局ContainerLayout
Java中常用的幾種布局格式如下:
FlowLayout:流布局格式,一般在Panel或Applet中是缺省的布局格式。
BorderLayout:邊界布局格式,一般在Window、Frame中是缺省的布局格式。
此外還有GridLayout布局格式、CardLayout布局格式和GridBagLayout布局格式。6.2.1FlowLayout布局
采用FlowLayout布局時,所有的組件按照順序排列,逐行定位,當(dāng)一行上放置不下時轉(zhuǎn)到新一行再進(jìn)行放置組件。當(dāng)用戶對一個采用FlowLayout布局的區(qū)域進(jìn)行縮放時,布局也會發(fā)生變化,如原本為一行三個組件,當(dāng)Window縮小時可能只能放置兩個組件,第三個組件便會順序推至下一行。與其它布局管理器不同的是,F(xiàn)lowLayout布局管理器不限制它所管理的組件的大小,而是允許它們有自己的最佳大小。可以通過參數(shù)來設(shè)置組件之間的間隔,也可以通過參數(shù)來設(shè)定組件的對齊格式,如左右對齊、居中對齊等。
例6-3是通過setLayout(newFlowLayout(intalign,inthgap,intvgap));來設(shè)置布局的,setLayout()中的內(nèi)容為一個匿名的流布局管理器對象,intalign參數(shù)用來設(shè)置組件對齊格式,通常有FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING或FlowLayout.TRAILING幾個常量;inthgap整型參數(shù)為組件間的水平間距(像素值);intvgap為組件間的垂直間距。【例6-3】FlowLayout布局示例。
importjava.awt.*;
publicclassMyFlowLayout
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame(“FlowLayout布局示例”);
f.setLayout(new
FlowLayout(FlowLayout.CENTER,5,5));
Buttonbutton1=newButton("Ok");
Buttonbutton2=newButton("Open");
Buttonbutton3=newButton("Close"); f.add(button1);
f.add(button2);
f.add(button3);
f.setSize(100,100);
f.setVisible(true);
}
}其中,F(xiàn)ramef=newFrame("FlowLayout布局示例")語句創(chuàng)建一個Title是“FlowLayout布局示例”的框架;f.setLayout(newFlowLayout(FlowLayout.CENTER,5,5))語句用于設(shè)置該框架內(nèi)部組件以Flow布局方式放置,居中對齊,水平和垂直間距都為5個像素值;newButton("Ok")語句用于創(chuàng)建一個顯示“OK”的按鈕并通過f.add(button1)將該按鈕添加到Frame中;f.setVisible(true)使該框架變?yōu)榭梢晝?nèi)容。這些語句將在本章下一節(jié)詳細(xì)講解。FlowLayout布局結(jié)果見圖6-4。圖6-4FlowLayout布局及區(qū)域變化后的FlowLayout布局6.2.2BorderLayout布局
采用BorderLayout布局管理器時,其布局稍稍復(fù)雜一些,它把整個容器分為北、南、西、東、中(North、South、West、East、Center)五個區(qū)域,這五個區(qū)域按照地圖的布局“上北下南左西右東”分布,中間是“Center”區(qū)域。
BorderLayout布局格式是Frame或Dialog容器的缺省布局格式。
采用BorderLayout布局時其位置保持相對不變,而區(qū)域中組件的大小隨著區(qū)域的變化而變化,例6-4運行后的結(jié)果如圖6-5所示。當(dāng)區(qū)域縮小時,五個按鈕的位置相對不變,而按鈕大小發(fā)生變化。圖6-5BorderLayout布局格式及其區(qū)域變化后布局【例6-4】BorderLayout布局示例。
importjava.awt.*;
publicclassMyBorderLayout
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("BorderLayout布局示例"); f.setLayout(newBorderLayout());
Buttonbn=newButton("B1");
Buttonbs=newButton("B2");
Buttonbe=newButton("B3");
Buttonbw=newButton("B4");
Buttonbc=newButton("B5");
f.add(bn,BorderLayout.NORTH); f.add(bs,BorderLayout.SOUTH);
f.add(be,BorderLayout.EAST);
f.add(bw,BorderLayout.WEST);
f.add(bc,BorderLayout.CENTER);
f.setSize(150,150);
f.setVisible(true);
}
}其中,f.setLayout(newBorderLayout())行代碼設(shè)定區(qū)域布局為Border布局;f.add(bn,BorderLayout.NORTH)等五行程序?qū)⑽鍌€按鈕添加進(jìn)North等五個不同區(qū)域。一般情況下,五個區(qū)域中每個區(qū)域只能添加一個組件,若添加多個組件,則最后添加的一個組件可視。如果要實現(xiàn)每個區(qū)域添加多個組件,則可對每個區(qū)域再設(shè)置布局(如Flow布局)來實現(xiàn)。6.2.3GridLayout布局
采用GridLayout布局管理器時,它把容器分為若干行和列的單元格,每個單元格中可以添加組件。若例6-5中,把區(qū)域分成2行3列或者3行2列,然后將6個按鈕添加到每個單元格中,添加時順序遵從先行后列,即從第一行第一列開始,然后第一行第二列,依次當(dāng)?shù)谝恍袧M時轉(zhuǎn)至第二行,如圖6-6(b)所示。采用GridLayout布局時,組件的大小與布局的行列數(shù)有關(guān),GridLayout布局管理器依據(jù)行數(shù)來平均分配整個容器的垂直高度,依據(jù)列來平均分配水平寬度。
當(dāng)在GridLayout布局管理器中添加超過行數(shù)和列數(shù)的組件時,最后添加的組件是可視的,一般對列進(jìn)行擴(kuò)展,而行數(shù)保持不變,如圖6-6(c)所示,行列數(shù)設(shè)置為3行2列,而實際添加組件數(shù)為9個,則列進(jìn)行擴(kuò)展。圖6-6GridLayout布局格式及行列變化后的布局(a)
(b)
(c)【例6-5】GridLayout布局示例。
importjava.awt.*;
publicclassMyGridLayout
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("GridLayout布局示例"); f.setLayout(newGridLayout(3,2));
Buttonb1=newButton("1");
Buttonb2=newButton("2");
Buttonb3=newButton("3");
Buttonb4=newButton("4");
Buttonb5=newButton("5");
Buttonb6=newButton("6");
f.add(b1);f.add(b2);f.add(b3);
f.add(b4);f.add(b5);f.add(b6);
f.pack();
f.setSize(150,150);
f.setVisible(true);
}
}6.2.4CardLayout布局
CardLayout布局格式就像卡片一樣,可以疊放多個頁面,但界面中每次只能顯示一個頁面。例6-6中,疊放了五個Panel,每個Panel的背景顏色不同,且上面顯示的文字也不同,當(dāng)調(diào)用f.add添加時,每個Panel有一個別名;當(dāng)調(diào)用myCard.show(f,“First”)時,則顯示具體的每個Panel。
【例6-6】CardLayout布局示例。importjava.awt.*;
importjava.awt.event.*;
publicclassMyCardLayout
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("CardLayout布局示例");
CardLayoutmyCard=newCardLayout();
f.setLayout(myCard);f.add(p1,“First”);f.add(p2,“Second”);f.add(p3,“Third”);
f.add(p4,“Fourth”);f.add(p5,“Fifth”);
myCard.show(f,“First”);
//myCard.show(f,“Fourth”);
f.setSize(150,150);
f.setVisible(true);
}
}
圖6-7為CardLayout布局及顯示不同的Panel。圖6-7CardLayout布局及顯示不同的Panel(a)
(b)6.2.5GridBagLayout布局
與前幾種布局管理器不同,GridBagLayout的網(wǎng)格包布局管理器提供了更加復(fù)雜的布局管理格式,前幾種組件的大小都可以隨區(qū)域變化而改變,GridBagLayout布局使得組件大小更趨優(yōu)化。GridBagLayout布局無需讓組件占滿一個布局區(qū)域,而是使用更加合理的尺寸,同時在GridBagLayout布局時,一個組件還可以同時占據(jù)若干個布局區(qū)域,這是前幾種布局管理器所不具有的特點。例6-7中,使用GridBagLayout布局首先創(chuàng)建GridBagLayout的布局管理器對象,然后將容器設(shè)置為GridBagLayout布局,GridBagLayoutgb=newGridBagLayout();
Container.setLayout(gb);隨后創(chuàng)建GridBagConstraints對象。然后設(shè)置第一個組件的GridBagConstraints屬性,并告知布局管理器第一個組件的GridBagConstraints屬性(即layout.setConstraints(Component1,Constraints);語句),再在容器中添加第一個組件。同理加入第二個、第三個組件,依次類推。其中Constraints有四個屬性:constraints.gridx、constraints.gridy、constraints.gridwidth、constraints.gridheight,分別是組件的頂點橫、縱坐標(biāo)以及組件占用網(wǎng)格的行數(shù)和列數(shù)。如圖6-8所示,按鈕“一”的gridheight=2,則占據(jù)2行;按鈕“四”的gridwigth=2,則占據(jù)2列。(a)(b)圖6-8GridbagLayout布局及fill屬性設(shè)置效果此外,fill屬性可設(shè)置水平、垂直位置的空區(qū)域填充,如圖6-8(b)所示;weightx和weighty屬性分別設(shè)置水平和垂直填充空白區(qū)域的權(quán)值。其他屬性請查閱JDK1.6API文檔。
【例6-7】GridBagLayout布局示例。
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
publicclassMyGridBagLayoutextendsJPanel
{GridBagConstraintsconstraints=newGridBagConstraints();
publicMyGridBagLayout()
{
setLayout(newGridBagLayout());
//constraints.weightx=1.0;
//constraints.weighty=1.0;
constraints.fill=GridBagConstraints.BOTH;
intx,y;constraints.gridheight=2;
addGB(newJButton("一"),x=0,y=0);
constraints.gridheight=1;
addGB(newJButton("二"),x=1,y=0);
addGB(newJButton("三"),x=2,y=0);
constraints.gridwidth=2;
addGB(newJButton("四"),x=1,y=1);
constraints.gridwidth=1;
}voidaddGB(Componentcomponent,intx,inty){
constraints.gridx=x;
constraints.gridy=y;
add(component,constraints);
}
publicstaticvoidmain(String[]args){
JFramef=newJFrame("GridBag布局示例");
f.addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){System.exit(0);}});
f.setSize(200,150);
f.setContentPane(newMyGridBagLayout());
f.setVisible(true);
}
}
例6-7中,f.addWindowListener(newWindowAdapter()…});語句是為當(dāng)前JFrame添加一個事件偵聽器,作為鼠標(biāo)關(guān)閉窗體使用。事件偵聽內(nèi)容將在6.3節(jié)詳細(xì)講述。6.2.6復(fù)雜布局
前面講述的五種布局格式功能比較單一,單獨使用時會有種種限制,但如果將這五種布局格式綜合起來使用,即在一種布局格式中嵌套其他的布局格式,這樣會使得布局更趨合理。
例6-8中,在屏幕左邊是工具欄區(qū)域,中間是工作區(qū)域,上面是菜單區(qū)域。要實現(xiàn)這樣的布局,就要在BorderLayout布局的North區(qū)域放置兩個按鈕,即采用布局的嵌套方式。【例6-8】復(fù)雜布局格式示例。
importjava.awt.*;
publicclassMutLayout
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("復(fù)雜布局格式示例");
Buttonbw=newButton("工具欄");
Buttonbc=newButton("工作區(qū)域");
f.add(bw,BorderLayout.WEST); f.add(bc,BorderLayout.CENTER);
Panelp=newPanel();
Buttonbfile=newButton("文件(F)");
Buttonbhelp=newButton("幫助(H)");
p.add(bfile);
p.add(bhelp);
f.add(p,BorderLayout.NORTH);
f.setSize(200,150);
f.setVisible(true);
}
}如圖6-9所示,整個Frame的布局為BorderLayout布局,West中加入“工具欄”,Center中加入“工作區(qū)域”,North中加入菜單,即兩個按鈕分別是“文件”和“幫助”;同時在North中放置一個Panel,再將Panel設(shè)置為FlowLayout布局,然后將兩個按鈕按順序加入Panel。圖6-9復(fù)雜布局格式6.3.1委托事件模型
所謂事件源就是一個事件的產(chǎn)生者。如在Button組件上點擊鼠標(biāo)會產(chǎn)生以這個Button為源的一個ActionEvent,這個ActionEvent實例是一個對象,它是包含關(guān)于剛才所發(fā)生的那個事件的信息的對象。
事件處理器就是一個接收事件、解釋事件并處理用戶交互的方法。6.3事件處理在JDK1.0中采用的是層次模型,層次模型是基于容器的。事件先發(fā)送到組件,然后沿容器層次向上傳播。沒有被組件處理的事件會自動地繼續(xù)傳播到組件的容器。例如在Frame中嵌入一個Panel,在Panel中添加一Button對象,當(dāng)鼠標(biāo)點擊此按鈕時就會發(fā)送一個事件,如果事件沒有被Button處理,這個事件會被送往Panel,如果仍然沒有被處理,這個事件會被送往Frame,這樣逐層上行就形成一種層次處理的事件模型。層次處理模型存在于早期版本中,從JDK1.1至后續(xù)版本采用的都是委托事件模型,這里我們不深入討論層次模型而是主要講述委托事件模型。委托事件模型下,每個可以觸發(fā)事件的組件被當(dāng)作事件源,每一種事件都有單獨的事件偵聽器,該事件偵聽器只負(fù)責(zé)接收和處理這一種事件。一個事件源可以觸發(fā)多個事件,只有當(dāng)該事件源注冊了幾種事件偵聽器時,這幾種事件才會被接收和處理。因為事件源自身不處理事件,觸發(fā)的事件交由事件偵聽器來處理,所以這種事件處理模式被稱為委托事件模型。
圖6-10就是一個典型的委托事件模型。事件源是Frame,對Frame注冊了KeyListener的鍵盤事件偵聽器,則當(dāng)Frame觸發(fā)鍵盤事件時,就由KeyListener來處理鍵盤事件。雖然Frame也能觸發(fā)鼠標(biāo)事件,但由于事件源Frame并沒有注冊鼠標(biāo)事件偵聽器,因此Frame的鼠標(biāo)事件就不發(fā)送。
委托事件模型如例6-9所示,運行結(jié)果如圖6-11所示。圖6-10委托事件模型實例圖6-11委托事件模型【例6-9】委托事件模型示例。
importjava.awt.*;
publicclassEventModel
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("委托事件模型示例"); Buttonb=newButton("請點擊按鈕!");
b.addActionListener(newButtonHandler());
f.add(b,"Center");
f.setSize(200,100);
f.setVisible(true);
}
}例6-9中,b.addActionListener()為按鈕b添加了一個行為事件偵聽器,這個事件偵聽器類作如下定義:
importjava.awt.event.*;
publicclassButtonHandlerimplementsActionListener
{
publicvoidactionPerformed(ActionEvente)
{ System.out.println("產(chǎn)生事件");
System.out.println("按鈕的標(biāo)簽是:"+e.getActionCommand());
}
}
當(dāng)我們點擊圖6-11中的左窗口按鈕時,其響應(yīng)按鈕的鼠標(biāo)點擊事件,在事件中輸出結(jié)果,見圖6-11右窗口。6.3.2事件偵聽接口
Java中大部分事件類集中在java.awt.event的包中,也有一些特殊事件存在于其它包中。每類事件都由一個接口來實現(xiàn),這個接口不僅需由相應(yīng)接收這個事件的對象來實現(xiàn),同時還需要定義一個或多個方法來做各種處理。當(dāng)事件發(fā)生時,就會調(diào)用這些方法。表6-1是Java中常見的事件源、實現(xiàn)的接口即事件偵聽接口、觸發(fā)事件后執(zhí)行的方法。表6-1事件源、偵聽接口和方法表6-1中,例如Action事件,其事件偵聽接口為ActionListener,使用addActionListener方法就可以為某個組件添加Action類事件的偵聽接口;當(dāng)事件偵聽接口偵聽到事件發(fā)生時,就會執(zhí)行ActionPerformed()方法;在ActionPerformed中添加代碼即可實現(xiàn)對Action類事件的處理。其余類型事件相似,這里不再詳述。
委托事件模型允許同一個組件可以有多個偵聽接口。編程通過多次調(diào)用addXXXlistener方法來實現(xiàn)。6.3.3事件適配器
Java語言中,為了減小編程的工作量,提供了一個Adapter類,用于實現(xiàn)Listener偵聽接口,編程時只需重寫Adapter適配器類所提供的方法即可。例如,MouseListener接口定義了如下方法:mouseClicked()、mouseEntered()、mouseExited()、mousePressed()和mouseReleased()等方法,要實現(xiàn)MouseListener偵聽接口,編程時可以繼承鼠標(biāo)事件的適配器MouseAdapter類,然后重寫該類所需要的方法就可以了。上述實現(xiàn)過程如例6-10所示。【例6-10】事件適配器示例。
importjava.awt.*;
importjava.awt.event.*;
publicclassAdapterTest
{
publicstaticvoidmain(Stringargs[])
{ Framef=newFrame("適配器測試示例"");
Buttonb=newButton("1");
b.addMouseListener(newMyMouseListener());
f.add(b,"Center");
f.setSize(150,100);
f.setVisible(true);
}
}classMyMouseListenerextendsMouseAdapter
{
intcount;
publicvoidmouseClicked(MouseEvente)
{
Buttonbtn=(Button)e.getSource();
btn.setLabel(newInteger(Integer.parseInt(btn.getLabel())+1).toString());
}
}在實現(xiàn)MyMouseListener接口時,繼承了MouseAdapter的類并覆蓋了其MouseClicked方法。在主程序中給按鈕添加此MyMouseListener的偵聽器,當(dāng)點擊按鈕時,其Label數(shù)組隨點擊次數(shù)的增加而增加。運行結(jié)果如圖6-12所示。
常用的事件適配器如表6-2所示。圖6-12事件適配器實現(xiàn)事件偵聽表6-2常用的事件適配器6.3.4匿名內(nèi)部類實現(xiàn)事件偵聽
在例6-10中,覆蓋方法時,我們不能直接訪問外部類的成員變量和方法,所以需添加一行語句Buttonbtn=(Button)e.getSource()來取得事件源,然后再對事件源進(jìn)行操作。這種方法顯得比較繁瑣,而Java事件偵聽大多采用匿名的內(nèi)部類來直接訪問外部類的成員屬性和方法。例6-11中,b.addActionLiserer添加了一個匿名對象newActionListener(),在編寫這個匿名內(nèi)部類的方法actionPerformed()時,無需再獲取事件源(例中語句標(biāo)識),而是直接對按鈕對象b實施操作。【例6-11】匿名內(nèi)部類實現(xiàn)事件偵聽示例。
importjava.awt.*;
importjava.awt.event.*;
publicclassAnonymousclassextendsFrame
{
Buttonb=newButton("1");
publicAnonymousclass(Stringtitle)
{ super(title);
b.addActionListener
(
newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
//Buttonb=(Button)e.getSource();
b.setLabel(newInteger(Integer.parseInt(b.getLabel())+1).toString()); }
}
);
add(b);
setSize(150,80);
setVisible(true); }
publicstaticvoidmain(String[]args)
{
newAnonymousclass("匿名內(nèi)部類接口實現(xiàn)示例");
}
}
運行結(jié)果如圖6-13所示。圖6-13匿名內(nèi)部類實現(xiàn)事件偵聽為了能夠?qū)崿F(xiàn)GUI編程,JDK提供了AWT,用于在各種不同的操作系統(tǒng)平臺下實現(xiàn)圖形用戶程序的編寫。AWT提供了諸如Frame、Button、Label等各種組件,可以進(jìn)行一些圖形窗口界面的程序設(shè)計。
6.4基本Swing組件編程隨著技術(shù)的發(fā)展,原有的AWT組件已經(jīng)不能滿足需要,于是在AWT組件的基礎(chǔ)上產(chǎn)生了Swing組件。由圖6-1可知,Swing組件是基于AWT組件的,AWT組件是Swing組件的父類。例如JFrame類,我們查看其源文件,首先導(dǎo)入java.awt.*的包,同時其類定義(如publicclassJframeextendsFrameimplementsWindowConstants{})繼承了Frame類,因此這兩種組件包的功能基本相似。
AWT是為了支持小應(yīng)用程序Applet而設(shè)計的,早期的版本不支持打印、剪貼板等,其功能受到一定限制;此外,AWT是基于對等組件的體系結(jié)構(gòu),這都使得AWT具有局限性。因此,Swing組件應(yīng)運而生。
Swing組件是純Java語言編寫的GUI組件,它與本地系統(tǒng)無關(guān),可以跨平臺使用。獨立于本地平臺的Swing組件稱為輕量級組件,而依賴于本地操作系統(tǒng)平臺的AWT組件稱為重量級組件。
Swing組件與重量級組件相比,沒有本地的對等組件,不像重量級組件那樣要在本地不透明窗體中繪制,而輕量級組件在重量級組件的窗口上繪制。
下面主要以編程中最常使用的Swing組件為例來介紹GUI的圖形編程。6.4.1按鈕與標(biāo)簽
1.?JButton組件
JButton組件提供了這樣一種機(jī)制,即當(dāng)點擊按鈕后執(zhí)行一定的操作。
常用JButton的構(gòu)造方法包括:
JButton():構(gòu)造一個沒有任何標(biāo)記的空按鈕。
JButton(Iconicon):構(gòu)造一個顯示有Icon對象指定圖標(biāo)的按鈕。
JButton(Stringtext):構(gòu)造一個顯示有text指定文字的按鈕。
JButton(Stringtext,Iconicon):構(gòu)造一個既顯示文字text又顯示圖標(biāo)icon的按鈕。
getIcon()和setIcon(IcondefaultIcon):獲取按鈕上的圖標(biāo)和設(shè)置按鈕上所要顯示的圖標(biāo)。
getText()和setText(Stringtext):獲取按鈕上顯示的文字和設(shè)置按鈕上所要顯示的文字。
setEnabled(booleanb):設(shè)置按鈕可用(true)或按鈕不可用(false)。
此外還有setHorizontalAlignment(intalignment)、setVerticalAlignment(intalignment)、setHorizontalTextPosition(inttextPosition)、setVerticalTextPosition(inttextPosition)等構(gòu)造方法,分別用于設(shè)置水平和垂直對齊方式以及按鈕顯示文字的水平和垂直位置。
操作按鈕可以產(chǎn)生多種事件,不過程序通常只需響應(yīng)點擊按鈕時產(chǎn)生的動作事件(ActiveEvent)。可使用addActionListener(ActionListenerl)方法給按鈕添加事件偵聽器。
2.?JLabel標(biāo)簽
一個標(biāo)簽對象顯示一行靜態(tài)文本。程序可以改變文本,但用戶不能改變。在編程時JLabel一般用作提示信息,它不會產(chǎn)生任何事件,所以使用相對簡單。
常用JLabel的構(gòu)造方法包括:
JLabel():構(gòu)造一個空的JLabel。
JLabel(Iconimage):構(gòu)造一個帶圖標(biāo)的JLabel。
JLabel(Stringtext):構(gòu)造一個顯示文字內(nèi)容為text的標(biāo)簽。
JLabel(Stringtext,Iconicon,inthorizontalAlignment):構(gòu)造一個既顯示文字又顯示圖標(biāo)的標(biāo)簽。【例6-12】按鈕和標(biāo)簽的使用。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
publicclassButtonLabelextendsJFrame{
Icon[]icons={
newImageIcon(“images/Student1.jpg”),
newImageIcon(“images/Student2.jpg”),
newImageIcon("images/Student3.jpg")
}; String[]name={“學(xué)生甲”,“學(xué)生乙”,“學(xué)生丙”};
JLabeljl;
JButton
b1=newJButton
(“下一學(xué)生”,newImageIcon(“images/right.gif”)),
b2=newJButton("上一學(xué)生",newImageIcon("images/left.gif"));
intn=0,i=icons.length;
publicButtonLabel()
{setLayout(newBorderLayout());
jl=newJLabel(name[n],icons[n],SwingConstants.CENTER);
add(jl,BorderLayout.CENTER);
JPaneljp=newJPanel();
jp.setLayout(newFlowLayout());
b2.setEnabled(false);
b1.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){ n++;
jl.setIcon(icons[n]);
jl.setText(name[n]);
if(n==1)
b2.setEnabled(true);
if(n==i-1)
b1.setEnabled(false);
}
});
b2.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){ n--;
jl.setIcon(icons[n]);
jl.setText(name[n]);
if(n==i-2)
b1.setEnabled(true);
if(n==0)
b2.setEnabled(false);
}
});
jp.add(b1);jp.add(b2); add(jp,BorderLayout.SOUTH);
}
publicstaticvoidmain(String[]args){
ButtonLabelf=newButtonLabel();
f.setTitle(“測試JButton和JLabel”);
f.setSize(300,250);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運行結(jié)果如圖6-14所示。圖6-14JButton和JLabel示例例6-12中創(chuàng)建了兩個按鈕b1、b2,它們既有文字顯示又有圖標(biāo)(對應(yīng)圖形文件為left.gif和right.gif)。采用匿名內(nèi)部類的方法給兩個按鈕添加事件驅(qū)動,當(dāng)點擊按鈕時,JLabel上的文字和圖標(biāo)內(nèi)容也隨之改變。
學(xué)生照片的顯示可通過JLabel的圖標(biāo)顯示功能來實現(xiàn),JPanel上既有圖標(biāo)又有文字的顯示。6.4.2文本域與文本區(qū)域
文本域與文本區(qū)域都是允許用戶輸入字符的區(qū)域,文本域只允許用戶輸入一行字符,而文本區(qū)域允許用戶輸入多行字符。文本域類還可以派生出JPasswordField的子類,用于輸入用戶口令字所輸入的口令字以特定的字符顯示而使口令不可視。
1.文本域
文本域常使用JTextField(文本字段)構(gòu)造方法:JTextField()可以構(gòu)造一個列數(shù)為0、初始字符串為空的文本輸入域;JTextField(Stringtext)可以構(gòu)造一個列數(shù)為0、初始字符串為text的文本輸入域;JTextField(intcolumns)可以構(gòu)造一個初始字符串為空、列數(shù)為columns的文本輸入域;JTextField(Stringtext,intcolumns)可以構(gòu)造一個初始字符串為text、列數(shù)為columns的文本輸入域。
在文本域中按回車鍵會引發(fā)ActionEvent事件。我們可以使用addActionListener
(ActionListenerl)給文本輸入域設(shè)置一個事件偵聽器。
此外,getColumns()方法可以獲取文本輸入域的列數(shù),setColumns(intcolumns)可以設(shè)置文本輸入域的列數(shù)。應(yīng)用setFont(Fontf)還可以設(shè)置文本輸入域中文字的字體。
2.文本區(qū)域
文本區(qū)域常使用JTextArea構(gòu)造方法:JTextArea()可以構(gòu)造一個行、列數(shù)為0,初始字符串為空的文本輸入?yún)^(qū)域;JTextArea(Stringtext)可以構(gòu)造一個指定初始字符串為text的文本輸入?yún)^(qū)域;JTextArea(introws,intcolumns)可以構(gòu)造一個指定行、列數(shù)分別為rows和columns的文本輸入?yún)^(qū)域;JTextArea(Stringtext,introws,intcolumns)可以構(gòu)造一個指定行、列數(shù)和初始字符串的文本輸入?yún)^(qū)域。
應(yīng)用setEditable(boolean)方法還可以將文本輸入?yún)^(qū)域的內(nèi)容設(shè)置為只讀(false),用于顯示一段說明性文字。與文本域不同,文本區(qū)域不會引發(fā)ActionEvent事件。
【例6-13】文本域與文本區(qū)域。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
publicclassMyTextextendsJFrame{
publicMyText()
{ setLayout(newBorderLayout());
JLabellabel1=newJLabel("學(xué)生姓名:");
finalJTextFieldtextField=newJTextField(30);
JLabellabel2=newJLabel("學(xué)生簡介:");
finalJTextAreatxtArea=newJTextArea(6,30);
JButtonbtn1=newJButton("確定");
textField.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){ txtArea.requestFocusInWindow();
}
});
btn1.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
textField.setText(null);
txtArea.setText(null);
}
});
JPaneljpTextField=newJPanel();
jpTextField.setLayout(newFlowLayout()); add(jpTextField,BorderLayout.NORTH);
JPaneljpTextArea=newJPanel();
jpTextArea.setLayout(newFlowLayout());
jpTextArea.add(label2);jpTextArea.add(newJScrollPane(txtArea));
add(jpTextArea,BorderLayout.CENTER);
add(btn1,BorderLayout.SOUTH);
} publicstaticvoidmain(String[]args){
MyTextf=newMyText();
f.setTitle("測試JTextField和JTextArea");
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運行結(jié)果如圖6-15所示。圖6-15文本域與文本區(qū)域例6-13中添加了一個輸入學(xué)生姓名的textField文本域,以及一個輸入學(xué)生基本情況簡介的文本區(qū)域。文本域添加了一個ActionListener的匿名內(nèi)部類實現(xiàn)事件偵聽,鍵入回車鍵后,將光標(biāo)移到文本區(qū)域即可輸入學(xué)生的基本簡介。同時,在SOUTH區(qū)添加一個按鈕,當(dāng)按鈕響應(yīng)事件后,即清空文本域和文本區(qū)域中的內(nèi)容。6.4.3復(fù)選框與單選按鈕
1.復(fù)選框
復(fù)選框可通過JCheckBox來實現(xiàn)。JCheckBox是一個很小的方框,框旁邊可以標(biāo)有文字或圖標(biāo)。它有兩種狀態(tài),即被選或未被選。即當(dāng)用戶點擊某個復(fù)選框時,該復(fù)選框會從一種狀態(tài)轉(zhuǎn)變?yōu)榱硪环N狀態(tài)。
常見的JCheckBox構(gòu)造方法包括:JCheckBox()可以構(gòu)造一個空的復(fù)選框;JCheckBox(Iconicon)可以構(gòu)造一個帶圖標(biāo)的復(fù)選框;
JCheckBox(Iconicon,boolean selected)可以構(gòu)造一個帶圖標(biāo)、初始狀態(tài)為被選擇(true)的復(fù)選框;JCheckBox(Stringtext,Booleanselected)可以構(gòu)造一個顯示文字為text且初始被選擇的復(fù)選框(true);JCheckBox(Stringtext,Iconicon,booleanselected)可以構(gòu)造一個既顯示文字又顯示圖標(biāo)的且可以設(shè)置初始狀態(tài)的復(fù)選框。此外,應(yīng)用isSelected()方法可以獲取當(dāng)前復(fù)選框的選擇狀態(tài),應(yīng)用setSelected(booleanb)可以設(shè)置復(fù)選框的狀態(tài)為被選擇(true)或者不被選擇(false)。
由于點擊復(fù)選框可以引發(fā)ActiveEvent和ItemEvent事件,因此可以給復(fù)選框添加ActiveListener和ItemListener的偵聽器來偵聽復(fù)選框發(fā)生的事件。
2.單選按鈕
單選按鈕可通過JRadioButton來實現(xiàn)。JRadioButton是一個很小的圓,圓旁邊可以標(biāo)有文字或圖標(biāo)。與復(fù)選框相同,每個單選按鈕有兩種狀態(tài):被選或未被選。用戶點擊某個單選按鈕時,該單選按鈕會從一種狀態(tài)轉(zhuǎn)變?yōu)榱硪环N狀態(tài)。與復(fù)選框不同的是,在某一時刻同一組中的單選按鈕只有一個被選擇,選擇某個單選按鈕時,同一組中的其他單選按鈕都會變?yōu)槲幢贿x;而同一組中的復(fù)選框同時可以有0個、1個或多個被選。常見的JRadioButton構(gòu)造方法包括:JRadioButton()可以構(gòu)造一個空的單選按鈕;JRadioButton(Iconicon)可以構(gòu)造一個帶圖標(biāo)顯示的單選按鈕;JRadioButton(Iconicon,booleanselected)可以構(gòu)造一個帶圖標(biāo)且設(shè)置初始狀態(tài)的單選按鈕;JRadioButton(Stringtext,Booleanselected)可以構(gòu)造一個顯示文字為text且可以設(shè)置初始態(tài)是否被選擇的單選按鈕;JRadioButton(Stringtext,Iconicon,booleanselected)可以構(gòu)造一個既有文字顯示又有圖標(biāo)顯示的且可以設(shè)置初始狀態(tài)的單選按鈕。單選按鈕一般是兩個或兩個以上存在,沒有單獨存在的單選按鈕,這些單選按鈕存在于一個組中,且組中的單選按鈕同時有且只能有一個被選擇。添加組時我們首先創(chuàng)建一個javax.swing.ButtonGroup類的對象,然后調(diào)用add(AbstractButtonb)方法將單選按鈕添加到ButtonGroup組中來。
點擊單選按鈕也會引發(fā)ActiveEvent和ItemEvent事件,可以給單選按鈕添加ActiveListener和ItemListener的偵聽器來偵聽它們所引發(fā)的事件。【例6-14】單選按鈕和復(fù)選框的使用。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
publicclassMyJCheckBoxRadioextendsJFrame{
privateJLabeljl1=newJLabel("姓名");
privateJTextFieldtf=newJTextField(10);
privateJLabeljl2=newJLabel("性別");
privateJRadioButtonrb1=newJRadioButton("男",true);
privateJRadioButtonrb2=newJRadioButton("女",false); privateButtonGroupbg=newButtonGroup();
privateJLabeljl3=newJLabel("參加社團(tuán)");
privateJCheckBoxcb1=newJCheckBox("書畫");
privateJCheckBoxcb2=newJCheckBox("文學(xué)");
privateJCheckBoxcb3=newJCheckBox("體育");
publicMyJCheckBoxRadio()
{ frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運行結(jié)果如圖6-16所示。圖6-16單選按鈕和復(fù)選框例6-14中,學(xué)生的性別選擇使用單選按鈕rb1和rb2,其JRadioButton添加在一個ButtonGroup組中,每次只能選擇一個。學(xué)生參加社團(tuán)的選擇使用復(fù)選框,每個JCheckBox選項都可以選擇。6.4.4組合框與列表框
1.組合框
JComboBox組合框與單選按鈕有些類似,用戶點擊組合框右側(cè)下三角,展開后會出現(xiàn)一些可選項目,這些可選項目中只能選擇其中一個,而不能多選。
JComboBox(組合框)常見的構(gòu)造方法包括:JComboBox()可以構(gòu)造一個選項為空的組合框;JComboBox(Object[]items)可以構(gòu)造一個選項為items數(shù)組項的組合框。其中ietms是Object類型的,因此它支持很多格式的選項數(shù)組,譬如文字、圖像等。此外,應(yīng)用addItem(ObjectanObject)可以向組合框中添加一個選項;應(yīng)用removeItem
(ObjectanObject)可以刪除一個選項;應(yīng)用removeItem(IntanIndex)可以刪除位置為anIndex的選項;應(yīng)用removeAllItems()可以移除所有選項。
JComboBox可以觸發(fā)ActionEvent和ItemEvent事件,通過給JComboBox添加ActionListener和ItemListener來實現(xiàn)事件偵聽。
2.列表框
JList在屏幕上顯示為若干行數(shù)的選項。列表框與復(fù)選框有些類似,可以實現(xiàn)多個選項的選擇,JList和JComboBox的外觀不同,JComboBox只有點擊下拉小三角后才能顯示若干個選項,而JList可直接列出所有選項。JList要實現(xiàn)多選時,按“Ctrl”鍵,點擊不連續(xù)的選項實現(xiàn)不連續(xù)項的選擇,或者按“Shift”鍵,點擊首選項和末選項實現(xiàn)一段連續(xù)選項的選擇。應(yīng)用JList()可以構(gòu)造一個空的JList的列表框;應(yīng)用JList(Object[]listData)可以構(gòu)造一個有l(wèi)istData對象數(shù)組指定選項的列表框。
應(yīng)用getSelectedIndexes()可以獲取JList中所選擇項的索引值;應(yīng)用getSelectedValues()可以獲取JList中選中選項的值;應(yīng)用setVisibleRowCount(intvisibleRowCount)可以設(shè)置JList中可視選項的行數(shù)。
選擇了JList選項時,將引發(fā)ListSelectionEvent事件,通過對JList添加ListSelectionListener事件偵聽器來編寫響應(yīng)的事件處理程序。【例6-15】組合框和列表框應(yīng)用示例。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
importjavax.swing.event.*;
publicclassMyJComboBoxJListextendsJFrame
{ String[]comboStrings={"中共黨員","共青團(tuán)員","群眾","民主黨派"};
String[]listStrings={"書畫協(xié)會","文學(xué)社","籃球協(xié)會","電腦協(xié)會"};
JTextAreata=newJTextArea(8,20);
JComboBoxcombo=newJComboBox(comboStrings);
JListlst=newJList(listStrings);
JTextFieldtf=newJTextField(10);
JLabeljl1=newJLabel("政治面貌"); JLabeljl2=newJLabel("參加社團(tuán)");
JLabeljl3=newJLabel("學(xué)生姓名");
JPaneljp1=newJPanel();
JPaneljp2=newJPanel();
JPaneljp3=newJPanel();
publicMyJComboBoxJList()
{
combo.addItemListener(newItemListener(){ ta.setText("");
inti=combo.getSelectedIndex();
ta.append("學(xué)生姓名:"+tf.getText()+"\n"+"政治面貌是:"+comboStrings[i]);
}
});
lst.addListSelectionListener(newListSelectionListener(){
publicvoidvalueChanged(ListSelectionEvente){
ta.setText(null); ta.append("參加的社團(tuán)是"+"\n");
Object[]items=lst.getSelectedValues();
for(inti=0;i<items.length;i++)
ta.append((String)items[i]+"\n");
}
});
ta.setEditable(false);
setLayout(newBorderLayout()); jp1.add(jl3);jp1.add(tf);
jp2.add(jl1);jp2.add(combo);
jp3.add(jl2);jp3.add(lst);jp3.add(ta);
add(jp1,BorderLayout.NORTH);
add(jp2,BorderLayout.CENTER);
add(jp3,BorderLayout.SOUTH);
}
publicstaticvoidmain(String[]args)
{ MyJComboBoxJListframe=newMyJComboBoxJList();
frame.setTitle("測試JComboBox&JList");
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運行結(jié)果如圖6-17所示。圖6-17JComboBox和JList的使用例6-15中,學(xué)生政治面貌的填寫是一個組合框,只能選擇四個選項中的一個。當(dāng)選擇了組合框中的選項后,觸發(fā)組合框事件偵聽的響應(yīng),即可在右下文本區(qū)域框中填寫學(xué)生的姓名和政治面貌。學(xué)生參加社團(tuán)通過列表框來實現(xiàn),可以同時選擇多個選項,選擇后響應(yīng)其事件并在右下文本區(qū)域內(nèi)填寫學(xué)生所選擇的社團(tuán)組織。6.5.1菜單
1.菜單JMenu
Java菜單的組成一般是一個菜單條JMenuBar包含多個菜單JMenu,菜單JMenu又包含若干個菜單項JMenuItem,菜單項JMenuItem又分為兩個子類JCheckBoxMenuItem和JRadioButtonMenuItem。JcheckBoxMenuItem實現(xiàn)復(fù)選框菜單的選項,JRadioButtonMenuItem實現(xiàn)單選菜單的選項。菜單條JMenuBar必須加入到一個支持JMenuBar的容器中去,如JFrame、JDialog和JApplet等。6.5高級Swing組件編程當(dāng)用戶選擇某個菜單項時會引發(fā)ActionEvent事件,因此,通過添加ActionListener偵聽器的方法來處理菜單事件。
【例6-16】菜單的使用。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
publicclassMyJMenuextendsJFrame
{
publicMyJMenu()
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 動物行為觀察與養(yǎng)殖效率優(yōu)化試題及答案
- 提升關(guān)鍵2025年特許金融分析師考試試題及答案
- 理財咨詢與客戶關(guān)系管理的進(jìn)階試題及答案
- 網(wǎng)絡(luò)編輯師證書考試獨家試題及答案
- 未來趨勢網(wǎng)絡(luò)編輯師證書考試試題及答案分析
- 企業(yè)在線進(jìn)銷存管理系統(tǒng)V1.0介紹
- 畜牧師職稱考試全面解析與試題答案
- 銀行風(fēng)險審計與內(nèi)控試題及答案2025年總結(jié)
- 2025年特許金融分析師備考支持資源試題及答案
- 把握2024年小語種證書考試試題及答案趨勢
- GB/T 311.2-2013絕緣配合第2部分:使用導(dǎo)則
- 科技公司涉密計算機(jī)軟件安裝審批表
- GA 1517-2018金銀珠寶營業(yè)場所安全防范要求
- C語言期末考試試題南昌航空大學(xué)
- 取消訂單協(xié)議模板(5篇)
- 東風(fēng)天錦5180勾臂式垃圾車的改裝設(shè)計
- 浦發(fā)銀行個人信用報告異議申請表
- 施工進(jìn)度計劃網(wǎng)絡(luò)圖-練習(xí)題知識講解
- 防孤島測試報告
- 按摩常用英語
- midas NFX使用指南(八)
評論
0/150
提交評論