版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
6.1GUI程序框架
6.2容器布局ContainerLayout
6.3事件處理
6.4基本Swing組件編程
6.5高級(jí)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圖形用戶界面用于編寫(xiě)基于圖形化的界面,便于用戶與計(jì)算機(jī)進(jìn)行交互,它比前面講述的基于命令行窗口的Application更加友好。要進(jìn)行GUI編程,就要掌握AWT(AbstractWindowToolkit,抽象窗口工具包),它是Java為了適應(yīng)各種不同操作的圖形化編程而抽象出的若干圖形化的窗口組件的工具集合。AWT提供了各種容器、布局管理以及各種組件,其類層次如圖6-1所示。AWT在編程實(shí)踐中又有一定局限性,因此輕量級(jí)組件包javax.swing應(yīng)運(yùn)而生。與AWT組件相比,Swing組件具有更加優(yōu)秀的特性(將在后續(xù)章節(jié)中講述),因此我們主要以Swing組件為基礎(chǔ)來(lái)講述。要建立GUI程序,就需要將各種各樣的組件組合在一起,按照一定的排列方式排列起來(lái),這就需要一個(gè)能夠容納組件的對(duì)象——容器。容器可對(duì)各種組件的布局進(jìn)行管理。
常見(jiàn)的容器如圖6-1所示,有Panel、javax.swing.JComponent和Window。Window類的子類Dialog和Frame又派生出了JDialog和JFrame。JDialog是特殊的容器,其位置可以移動(dòng),但不能改變其大小,我們?cè)诤罄m(xù)章節(jié)講述。本節(jié)主要介紹JFrame。
JFrame是一個(gè)大小可以調(diào)整、位置可以移動(dòng)的窗體。Panel類派生出了JPanel、Applet及JApplet,Applet和JApplet是一種特殊的程序,主要運(yùn)行在Web上,我們?cè)诤罄m(xù)章節(jié)中講述,本節(jié)我們主要講述JPanel。因此,本節(jié)我們主要講述構(gòu)成程序框架的兩個(gè)關(guān)鍵容器JPanel和JFrame。
1.?JPanel
JPanel不能獨(dú)立存在,只能加在別的容器中使用,如JFrame、JDialog等。JPanel類由Panel派生而得到,Panel還有一個(gè)Applet子類和JApplet(Applet的子類),JApplet和Applet是運(yùn)行在Web上的小應(yīng)用程序,下一章節(jié)將詳細(xì)介紹。一個(gè)JPanel區(qū)域是一個(gè)矩形的區(qū)域,因?yàn)樗旧硎且粋€(gè)容器類,因此在其中可以添加其他組件對(duì)象,諸如JButton、JLabel等。
JPanel()直接構(gòu)造一個(gè)空的JPanel對(duì)象,應(yīng)用add(object)方法可以將其他組件加入到JPanel容器中。JPanel通常不可視,只有當(dāng)其添加到JFrame中后,才可顯示。
如例6-1所示,先構(gòu)造一個(gè)JFrame對(duì)象、一個(gè)JPanel對(duì)象和一個(gè)JLabel對(duì)象,將JLabel對(duì)象lb加入到容器JPanel的對(duì)象jp中,再將jp對(duì)象添加到JFrame的對(duì)象frm中。程序運(yùn)行結(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測(cè)試示例");
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)造一個(gè)空的窗口對(duì)象;應(yīng)用JFrame(Stringtitle)可以構(gòu)造一個(gè)窗口標(biāo)題為title的窗口;應(yīng)用add(object)方法可以將各種組件添加到窗口中,應(yīng)用setSize(intwindth,intheigh)可以設(shè)置JFrame窗口的寬度和高度;應(yīng)用frameobject.pack()方法,可以使窗口自動(dòng)調(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所示,其運(yùn)行結(jié)果如圖6-3所示。
【例6-2】JFrame應(yīng)用示例。
importjavax.swing.*;
publicclassMyJFrameextendsJFrame
{
publicstaticvoidmain(String[]args)
{
JFramef=newJFrame("JFrame測(cè)試示例");
JButtonbtn=newJButton("PleaseClickme!");
f.add(btn); f.setSize(200,100);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
JFrame程序中若沒(méi)有事件偵聽(tīng)處理Window退出事件,或沒(méi)有setDefaltCloseOperation,則點(diǎn)擊窗口的“×”時(shí),無(wú)法完全退出系統(tǒng),必須按“Ctrl?+?C”鍵才能中斷退出當(dāng)前運(yùn)行程序。圖6-3JFrame的使用在GUI編程時(shí),所有的組件必須盛放在一個(gè)容器中,這些組件的排列方式、大小都由布局管理器來(lái)控制。每個(gè)容器Container(如Panel或Frame)都有一個(gè)與它相關(guān)的缺省布局管理器,它可以通過(guò)調(diào)用setLayout()來(lái)改變?nèi)萜髦薪M件的布局方式。
6.2容器布局ContainerLayout
Java中常用的幾種布局格式如下:
FlowLayout:流布局格式,一般在Panel或Applet中是缺省的布局格式。
BorderLayout:邊界布局格式,一般在Window、Frame中是缺省的布局格式。
此外還有GridLayout布局格式、CardLayout布局格式和GridBagLayout布局格式。6.2.1FlowLayout布局
采用FlowLayout布局時(shí),所有的組件按照順序排列,逐行定位,當(dāng)一行上放置不下時(shí)轉(zhuǎn)到新一行再進(jìn)行放置組件。當(dāng)用戶對(duì)一個(gè)采用FlowLayout布局的區(qū)域進(jìn)行縮放時(shí),布局也會(huì)發(fā)生變化,如原本為一行三個(gè)組件,當(dāng)Window縮小時(shí)可能只能放置兩個(gè)組件,第三個(gè)組件便會(huì)順序推至下一行。與其它布局管理器不同的是,F(xiàn)lowLayout布局管理器不限制它所管理的組件的大小,而是允許它們有自己的最佳大小??梢酝ㄟ^(guò)參數(shù)來(lái)設(shè)置組件之間的間隔,也可以通過(guò)參數(shù)來(lái)設(shè)定組件的對(duì)齊格式,如左右對(duì)齊、居中對(duì)齊等。
例6-3是通過(guò)setLayout(newFlowLayout(intalign,inthgap,intvgap));來(lái)設(shè)置布局的,setLayout()中的內(nèi)容為一個(gè)匿名的流布局管理器對(duì)象,intalign參數(shù)用來(lái)設(shè)置組件對(duì)齊格式,通常有FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING或FlowLayout.TRAILING幾個(gè)常量;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布局示例")語(yǔ)句創(chuàng)建一個(gè)Title是“FlowLayout布局示例”的框架;f.setLayout(newFlowLayout(FlowLayout.CENTER,5,5))語(yǔ)句用于設(shè)置該框架內(nèi)部組件以Flow布局方式放置,居中對(duì)齊,水平和垂直間距都為5個(gè)像素值;newButton("Ok")語(yǔ)句用于創(chuàng)建一個(gè)顯示“OK”的按鈕并通過(guò)f.add(button1)將該按鈕添加到Frame中;f.setVisible(true)使該框架變?yōu)榭梢晝?nèi)容。這些語(yǔ)句將在本章下一節(jié)詳細(xì)講解。FlowLayout布局結(jié)果見(jiàn)圖6-4。圖6-4FlowLayout布局及區(qū)域變化后的FlowLayout布局6.2.2BorderLayout布局
采用BorderLayout布局管理器時(shí),其布局稍稍復(fù)雜一些,它把整個(gè)容器分為北、南、西、東、中(North、South、West、East、Center)五個(gè)區(qū)域,這五個(gè)區(qū)域按照地圖的布局“上北下南左西右東”分布,中間是“Center”區(qū)域。
BorderLayout布局格式是Frame或Dialog容器的缺省布局格式。
采用BorderLayout布局時(shí)其位置保持相對(duì)不變,而區(qū)域中組件的大小隨著區(qū)域的變化而變化,例6-4運(yùn)行后的結(jié)果如圖6-5所示。當(dāng)區(qū)域縮小時(shí),五個(gè)按鈕的位置相對(duì)不變,而按鈕大小發(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ū)⑽鍌€(gè)按鈕添加進(jìn)North等五個(gè)不同區(qū)域。一般情況下,五個(gè)區(qū)域中每個(gè)區(qū)域只能添加一個(gè)組件,若添加多個(gè)組件,則最后添加的一個(gè)組件可視。如果要實(shí)現(xiàn)每個(gè)區(qū)域添加多個(gè)組件,則可對(duì)每個(gè)區(qū)域再設(shè)置布局(如Flow布局)來(lái)實(shí)現(xiàn)。6.2.3GridLayout布局
采用GridLayout布局管理器時(shí),它把容器分為若干行和列的單元格,每個(gè)單元格中可以添加組件。若例6-5中,把區(qū)域分成2行3列或者3行2列,然后將6個(gè)按鈕添加到每個(gè)單元格中,添加時(shí)順序遵從先行后列,即從第一行第一列開(kāi)始,然后第一行第二列,依次當(dāng)?shù)谝恍袧M時(shí)轉(zhuǎn)至第二行,如圖6-6(b)所示。采用GridLayout布局時(shí),組件的大小與布局的行列數(shù)有關(guān),GridLayout布局管理器依據(jù)行數(shù)來(lái)平均分配整個(gè)容器的垂直高度,依據(jù)列來(lái)平均分配水平寬度。
當(dāng)在GridLayout布局管理器中添加超過(guò)行數(shù)和列數(shù)的組件時(shí),最后添加的組件是可視的,一般對(duì)列進(jìn)行擴(kuò)展,而行數(shù)保持不變,如圖6-6(c)所示,行列數(shù)設(shè)置為3行2列,而實(shí)際添加組件數(shù)為9個(gè),則列進(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布局格式就像卡片一樣,可以疊放多個(gè)頁(yè)面,但界面中每次只能顯示一個(gè)頁(yè)面。例6-6中,疊放了五個(gè)Panel,每個(gè)Panel的背景顏色不同,且上面顯示的文字也不同,當(dāng)調(diào)用f.add添加時(shí),每個(gè)Panel有一個(gè)別名;當(dāng)調(diào)用myCard.show(f,“First”)時(shí),則顯示具體的每個(gè)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布局無(wú)需讓組件占滿一個(gè)布局區(qū)域,而是使用更加合理的尺寸,同時(shí)在GridBagLayout布局時(shí),一個(gè)組件還可以同時(shí)占據(jù)若干個(gè)布局區(qū)域,這是前幾種布局管理器所不具有的特點(diǎn)。例6-7中,使用GridBagLayout布局首先創(chuàng)建GridBagLayout的布局管理器對(duì)象,然后將容器設(shè)置為GridBagLayout布局,GridBagLayoutgb=newGridBagLayout();
Container.setLayout(gb);隨后創(chuàng)建GridBagConstraints對(duì)象。然后設(shè)置第一個(gè)組件的GridBagConstraints屬性,并告知布局管理器第一個(gè)組件的GridBagConstraints屬性(即layout.setConstraints(Component1,Constraints);語(yǔ)句),再在容器中添加第一個(gè)組件。同理加入第二個(gè)、第三個(gè)組件,依次類推。其中Constraints有四個(gè)屬性:constraints.gridx、constraints.gridy、constraints.gridwidth、constraints.gridheight,分別是組件的頂點(diǎn)橫、縱坐標(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)值。其他屬性請(qǐng)查閱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()…});語(yǔ)句是為當(dāng)前JFrame添加一個(gè)事件偵聽(tīng)器,作為鼠標(biāo)關(guān)閉窗體使用。事件偵聽(tīng)內(nèi)容將在6.3節(jié)詳細(xì)講述。6.2.6復(fù)雜布局
前面講述的五種布局格式功能比較單一,單獨(dú)使用時(shí)會(huì)有種種限制,但如果將這五種布局格式綜合起來(lái)使用,即在一種布局格式中嵌套其他的布局格式,這樣會(huì)使得布局更趨合理。
例6-8中,在屏幕左邊是工具欄區(qū)域,中間是工作區(qū)域,上面是菜單區(qū)域。要實(shí)現(xiàn)這樣的布局,就要在BorderLayout布局的North區(qū)域放置兩個(gè)按鈕,即采用布局的嵌套方式。【例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所示,整個(gè)Frame的布局為BorderLayout布局,West中加入“工具欄”,Center中加入“工作區(qū)域”,North中加入菜單,即兩個(gè)按鈕分別是“文件”和“幫助”;同時(shí)在North中放置一個(gè)Panel,再將Panel設(shè)置為FlowLayout布局,然后將兩個(gè)按鈕按順序加入Panel。圖6-9復(fù)雜布局格式6.3.1委托事件模型
所謂事件源就是一個(gè)事件的產(chǎn)生者。如在Button組件上點(diǎn)擊鼠標(biāo)會(huì)產(chǎn)生以這個(gè)Button為源的一個(gè)ActionEvent,這個(gè)ActionEvent實(shí)例是一個(gè)對(duì)象,它是包含關(guān)于剛才所發(fā)生的那個(gè)事件的信息的對(duì)象。
事件處理器就是一個(gè)接收事件、解釋事件并處理用戶交互的方法。6.3事件處理在JDK1.0中采用的是層次模型,層次模型是基于容器的。事件先發(fā)送到組件,然后沿容器層次向上傳播。沒(méi)有被組件處理的事件會(huì)自動(dòng)地繼續(xù)傳播到組件的容器。例如在Frame中嵌入一個(gè)Panel,在Panel中添加一Button對(duì)象,當(dāng)鼠標(biāo)點(diǎn)擊此按鈕時(shí)就會(huì)發(fā)送一個(gè)事件,如果事件沒(méi)有被Button處理,這個(gè)事件會(huì)被送往Panel,如果仍然沒(méi)有被處理,這個(gè)事件會(huì)被送往Frame,這樣逐層上行就形成一種層次處理的事件模型。層次處理模型存在于早期版本中,從JDK1.1至后續(xù)版本采用的都是委托事件模型,這里我們不深入討論層次模型而是主要講述委托事件模型。委托事件模型下,每個(gè)可以觸發(fā)事件的組件被當(dāng)作事件源,每一種事件都有單獨(dú)的事件偵聽(tīng)器,該事件偵聽(tīng)器只負(fù)責(zé)接收和處理這一種事件。一個(gè)事件源可以觸發(fā)多個(gè)事件,只有當(dāng)該事件源注冊(cè)了幾種事件偵聽(tīng)器時(shí),這幾種事件才會(huì)被接收和處理。因?yàn)槭录醋陨聿惶幚硎录?,觸發(fā)的事件交由事件偵聽(tīng)器來(lái)處理,所以這種事件處理模式被稱為委托事件模型。
圖6-10就是一個(gè)典型的委托事件模型。事件源是Frame,對(duì)Frame注冊(cè)了KeyListener的鍵盤(pán)事件偵聽(tīng)器,則當(dāng)Frame觸發(fā)鍵盤(pán)事件時(shí),就由KeyListener來(lái)處理鍵盤(pán)事件。雖然Frame也能觸發(fā)鼠標(biāo)事件,但由于事件源Frame并沒(méi)有注冊(cè)鼠標(biāo)事件偵聽(tīng)器,因此Frame的鼠標(biāo)事件就不發(fā)送。
委托事件模型如例6-9所示,運(yùn)行結(jié)果如圖6-11所示。圖6-10委托事件模型實(shí)例圖6-11委托事件模型【例6-9】委托事件模型示例。
importjava.awt.*;
publicclassEventModel
{
publicstaticvoidmain(Stringargs[])
{
Framef=newFrame("委托事件模型示例"); Buttonb=newButton("請(qǐng)點(diǎn)擊按鈕!");
b.addActionListener(newButtonHandler());
f.add(b,"Center");
f.setSize(200,100);
f.setVisible(true);
}
}例6-9中,b.addActionListener()為按鈕b添加了一個(gè)行為事件偵聽(tīng)器,這個(gè)事件偵聽(tīng)器類作如下定義:
importjava.awt.event.*;
publicclassButtonHandlerimplementsActionListener
{
publicvoidactionPerformed(ActionEvente)
{ System.out.println("產(chǎn)生事件");
System.out.println("按鈕的標(biāo)簽是:"+e.getActionCommand());
}
}
當(dāng)我們點(diǎn)擊圖6-11中的左窗口按鈕時(shí),其響應(yīng)按鈕的鼠標(biāo)點(diǎn)擊事件,在事件中輸出結(jié)果,見(jiàn)圖6-11右窗口。6.3.2事件偵聽(tīng)接口
Java中大部分事件類集中在java.awt.event的包中,也有一些特殊事件存在于其它包中。每類事件都由一個(gè)接口來(lái)實(shí)現(xiàn),這個(gè)接口不僅需由相應(yīng)接收這個(gè)事件的對(duì)象來(lái)實(shí)現(xiàn),同時(shí)還需要定義一個(gè)或多個(gè)方法來(lái)做各種處理。當(dāng)事件發(fā)生時(shí),就會(huì)調(diào)用這些方法。表6-1是Java中常見(jiàn)的事件源、實(shí)現(xiàn)的接口即事件偵聽(tīng)接口、觸發(fā)事件后執(zhí)行的方法。表6-1事件源、偵聽(tīng)接口和方法表6-1中,例如Action事件,其事件偵聽(tīng)接口為ActionListener,使用addActionListener方法就可以為某個(gè)組件添加Action類事件的偵聽(tīng)接口;當(dāng)事件偵聽(tīng)接口偵聽(tīng)到事件發(fā)生時(shí),就會(huì)執(zhí)行ActionPerformed()方法;在ActionPerformed中添加代碼即可實(shí)現(xiàn)對(duì)Action類事件的處理。其余類型事件相似,這里不再詳述。
委托事件模型允許同一個(gè)組件可以有多個(gè)偵聽(tīng)接口。編程通過(guò)多次調(diào)用addXXXlistener方法來(lái)實(shí)現(xiàn)。6.3.3事件適配器
Java語(yǔ)言中,為了減小編程的工作量,提供了一個(gè)Adapter類,用于實(shí)現(xiàn)Listener偵聽(tīng)接口,編程時(shí)只需重寫(xiě)Adapter適配器類所提供的方法即可。例如,MouseListener接口定義了如下方法:mouseClicked()、mouseEntered()、mouseExited()、mousePressed()和mouseReleased()等方法,要實(shí)現(xiàn)MouseListener偵聽(tīng)接口,編程時(shí)可以繼承鼠標(biāo)事件的適配器MouseAdapter類,然后重寫(xiě)該類所需要的方法就可以了。上述實(shí)現(xiàn)過(guò)程如例6-10所示?!纠?-10】事件適配器示例。
importjava.awt.*;
importjava.awt.event.*;
publicclassAdapterTest
{
publicstaticvoidmain(Stringargs[])
{ Framef=newFrame("適配器測(cè)試示例"");
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());
}
}在實(shí)現(xiàn)MyMouseListener接口時(shí),繼承了MouseAdapter的類并覆蓋了其MouseClicked方法。在主程序中給按鈕添加此MyMouseListener的偵聽(tīng)器,當(dāng)點(diǎn)擊按鈕時(shí),其Label數(shù)組隨點(diǎn)擊次數(shù)的增加而增加。運(yùn)行結(jié)果如圖6-12所示。
常用的事件適配器如表6-2所示。圖6-12事件適配器實(shí)現(xiàn)事件偵聽(tīng)表6-2常用的事件適配器6.3.4匿名內(nèi)部類實(shí)現(xiàn)事件偵聽(tīng)
在例6-10中,覆蓋方法時(shí),我們不能直接訪問(wèn)外部類的成員變量和方法,所以需添加一行語(yǔ)句Buttonbtn=(Button)e.getSource()來(lái)取得事件源,然后再對(duì)事件源進(jìn)行操作。這種方法顯得比較繁瑣,而Java事件偵聽(tīng)大多采用匿名的內(nèi)部類來(lái)直接訪問(wèn)外部類的成員屬性和方法。例6-11中,b.addActionLiserer添加了一個(gè)匿名對(duì)象newActionListener(),在編寫(xiě)這個(gè)匿名內(nèi)部類的方法actionPerformed()時(shí),無(wú)需再獲取事件源(例中語(yǔ)句標(biāo)識(shí)),而是直接對(duì)按鈕對(duì)象b實(shí)施操作。【例6-11】匿名內(nèi)部類實(shí)現(xiàn)事件偵聽(tīng)示例。
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)部類接口實(shí)現(xiàn)示例");
}
}
運(yùn)行結(jié)果如圖6-13所示。圖6-13匿名內(nèi)部類實(shí)現(xiàn)事件偵聽(tīng)為了能夠?qū)崿F(xiàn)GUI編程,JDK提供了AWT,用于在各種不同的操作系統(tǒng)平臺(tái)下實(shí)現(xiàn)圖形用戶程序的編寫(xiě)。AWT提供了諸如Frame、Button、Label等各種組件,可以進(jìn)行一些圖形窗口界面的程序設(shè)計(jì)。
6.4基本Swing組件編程隨著技術(shù)的發(fā)展,原有的AWT組件已經(jīng)不能滿足需要,于是在AWT組件的基礎(chǔ)上產(chǎn)生了Swing組件。由圖6-1可知,Swing組件是基于AWT組件的,AWT組件是Swing組件的父類。例如JFrame類,我們查看其源文件,首先導(dǎo)入java.awt.*的包,同時(shí)其類定義(如publicclassJframeextendsFrameimplementsWindowConstants{})繼承了Frame類,因此這兩種組件包的功能基本相似。
AWT是為了支持小應(yīng)用程序Applet而設(shè)計(jì)的,早期的版本不支持打印、剪貼板等,其功能受到一定限制;此外,AWT是基于對(duì)等組件的體系結(jié)構(gòu),這都使得AWT具有局限性。因此,Swing組件應(yīng)運(yùn)而生。
Swing組件是純Java語(yǔ)言編寫(xiě)的GUI組件,它與本地系統(tǒng)無(wú)關(guān),可以跨平臺(tái)使用。獨(dú)立于本地平臺(tái)的Swing組件稱為輕量級(jí)組件,而依賴于本地操作系統(tǒng)平臺(tái)的AWT組件稱為重量級(jí)組件。
Swing組件與重量級(jí)組件相比,沒(méi)有本地的對(duì)等組件,不像重量級(jí)組件那樣要在本地不透明窗體中繪制,而輕量級(jí)組件在重量級(jí)組件的窗口上繪制。
下面主要以編程中最常使用的Swing組件為例來(lái)介紹GUI的圖形編程。6.4.1按鈕與標(biāo)簽
1.?JButton組件
JButton組件提供了這樣一種機(jī)制,即當(dāng)點(diǎn)擊按鈕后執(zhí)行一定的操作。
常用JButton的構(gòu)造方法包括:
JButton():構(gòu)造一個(gè)沒(méi)有任何標(biāo)記的空按鈕。
JButton(Iconicon):構(gòu)造一個(gè)顯示有Icon對(duì)象指定圖標(biāo)的按鈕。
JButton(Stringtext):構(gòu)造一個(gè)顯示有text指定文字的按鈕。
JButton(Stringtext,Iconicon):構(gòu)造一個(gè)既顯示文字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è)置水平和垂直對(duì)齊方式以及按鈕顯示文字的水平和垂直位置。
操作按鈕可以產(chǎn)生多種事件,不過(guò)程序通常只需響應(yīng)點(diǎn)擊按鈕時(shí)產(chǎn)生的動(dòng)作事件(ActiveEvent)??墒褂胊ddActionListener(ActionListenerl)方法給按鈕添加事件偵聽(tīng)器。
2.?JLabel標(biāo)簽
一個(gè)標(biāo)簽對(duì)象顯示一行靜態(tài)文本。程序可以改變文本,但用戶不能改變。在編程時(shí)JLabel一般用作提示信息,它不會(huì)產(chǎn)生任何事件,所以使用相對(duì)簡(jiǎn)單。
常用JLabel的構(gòu)造方法包括:
JLabel():構(gòu)造一個(gè)空的JLabel。
JLabel(Iconimage):構(gòu)造一個(gè)帶圖標(biāo)的JLabel。
JLabel(Stringtext):構(gòu)造一個(gè)顯示文字內(nèi)容為text的標(biāo)簽。
JLabel(Stringtext,Iconicon,inthorizontalAlignment):構(gòu)造一個(gè)既顯示文字又顯示圖標(biāo)的標(biāo)簽?!纠?-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(“測(cè)試JButton和JLabel”);
f.setSize(300,250);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運(yùn)行結(jié)果如圖6-14所示。圖6-14JButton和JLabel示例例6-12中創(chuàng)建了兩個(gè)按鈕b1、b2,它們既有文字顯示又有圖標(biāo)(對(duì)應(yīng)圖形文件為left.gif和right.gif)。采用匿名內(nèi)部類的方法給兩個(gè)按鈕添加事件驅(qū)動(dòng),當(dāng)點(diǎn)擊按鈕時(shí),JLabel上的文字和圖標(biāo)內(nèi)容也隨之改變。
學(xué)生照片的顯示可通過(guò)JLabel的圖標(biāo)顯示功能來(lái)實(shí)現(xiàn),JPanel上既有圖標(biāo)又有文字的顯示。6.4.2文本域與文本區(qū)域
文本域與文本區(qū)域都是允許用戶輸入字符的區(qū)域,文本域只允許用戶輸入一行字符,而文本區(qū)域允許用戶輸入多行字符。文本域類還可以派生出JPasswordField的子類,用于輸入用戶口令字所輸入的口令字以特定的字符顯示而使口令不可視。
1.文本域
文本域常使用JTextField(文本字段)構(gòu)造方法:JTextField()可以構(gòu)造一個(gè)列數(shù)為0、初始字符串為空的文本輸入域;JTextField(Stringtext)可以構(gòu)造一個(gè)列數(shù)為0、初始字符串為text的文本輸入域;JTextField(intcolumns)可以構(gòu)造一個(gè)初始字符串為空、列數(shù)為columns的文本輸入域;JTextField(Stringtext,intcolumns)可以構(gòu)造一個(gè)初始字符串為text、列數(shù)為columns的文本輸入域。
在文本域中按回車鍵會(huì)引發(fā)ActionEvent事件。我們可以使用addActionListener
(ActionListenerl)給文本輸入域設(shè)置一個(gè)事件偵聽(tīng)器。
此外,getColumns()方法可以獲取文本輸入域的列數(shù),setColumns(intcolumns)可以設(shè)置文本輸入域的列數(shù)。應(yīng)用setFont(Fontf)還可以設(shè)置文本輸入域中文字的字體。
2.文本區(qū)域
文本區(qū)域常使用JTextArea構(gòu)造方法:JTextArea()可以構(gòu)造一個(gè)行、列數(shù)為0,初始字符串為空的文本輸入?yún)^(qū)域;JTextArea(Stringtext)可以構(gòu)造一個(gè)指定初始字符串為text的文本輸入?yún)^(qū)域;JTextArea(introws,intcolumns)可以構(gòu)造一個(gè)指定行、列數(shù)分別為rows和columns的文本輸入?yún)^(qū)域;JTextArea(Stringtext,introws,intcolumns)可以構(gòu)造一個(gè)指定行、列數(shù)和初始字符串的文本輸入?yún)^(qū)域。
應(yīng)用setEditable(boolean)方法還可以將文本輸入?yún)^(qū)域的內(nèi)容設(shè)置為只讀(false),用于顯示一段說(shuō)明性文字。與文本域不同,文本區(qū)域不會(huì)引發(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é)生簡(jiǎn)介:");
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("測(cè)試JTextField和JTextArea");
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運(yùn)行結(jié)果如圖6-15所示。圖6-15文本域與文本區(qū)域例6-13中添加了一個(gè)輸入學(xué)生姓名的textField文本域,以及一個(gè)輸入學(xué)生基本情況簡(jiǎn)介的文本區(qū)域。文本域添加了一個(gè)ActionListener的匿名內(nèi)部類實(shí)現(xiàn)事件偵聽(tīng),鍵入回車鍵后,將光標(biāo)移到文本區(qū)域即可輸入學(xué)生的基本簡(jiǎn)介。同時(shí),在SOUTH區(qū)添加一個(gè)按鈕,當(dāng)按鈕響應(yīng)事件后,即清空文本域和文本區(qū)域中的內(nèi)容。6.4.3復(fù)選框與單選按鈕
1.復(fù)選框
復(fù)選框可通過(guò)JCheckBox來(lái)實(shí)現(xiàn)。JCheckBox是一個(gè)很小的方框,框旁邊可以標(biāo)有文字或圖標(biāo)。它有兩種狀態(tài),即被選或未被選。即當(dāng)用戶點(diǎn)擊某個(gè)復(fù)選框時(shí),該復(fù)選框會(huì)從一種狀態(tài)轉(zhuǎn)變?yōu)榱硪环N狀態(tài)。
常見(jiàn)的JCheckBox構(gòu)造方法包括:JCheckBox()可以構(gòu)造一個(gè)空的復(fù)選框;JCheckBox(Iconicon)可以構(gòu)造一個(gè)帶圖標(biāo)的復(fù)選框;
JCheckBox(Iconicon,boolean selected)可以構(gòu)造一個(gè)帶圖標(biāo)、初始狀態(tài)為被選擇(true)的復(fù)選框;JCheckBox(Stringtext,Booleanselected)可以構(gòu)造一個(gè)顯示文字為text且初始被選擇的復(fù)選框(true);JCheckBox(Stringtext,Iconicon,booleanselected)可以構(gòu)造一個(gè)既顯示文字又顯示圖標(biāo)的且可以設(shè)置初始狀態(tài)的復(fù)選框。此外,應(yīng)用isSelected()方法可以獲取當(dāng)前復(fù)選框的選擇狀態(tài),應(yīng)用setSelected(booleanb)可以設(shè)置復(fù)選框的狀態(tài)為被選擇(true)或者不被選擇(false)。
由于點(diǎn)擊復(fù)選框可以引發(fā)ActiveEvent和ItemEvent事件,因此可以給復(fù)選框添加ActiveListener和ItemListener的偵聽(tīng)器來(lái)偵聽(tīng)復(fù)選框發(fā)生的事件。
2.單選按鈕
單選按鈕可通過(guò)JRadioButton來(lái)實(shí)現(xiàn)。JRadioButton是一個(gè)很小的圓,圓旁邊可以標(biāo)有文字或圖標(biāo)。與復(fù)選框相同,每個(gè)單選按鈕有兩種狀態(tài):被選或未被選。用戶點(diǎn)擊某個(gè)單選按鈕時(shí),該單選按鈕會(huì)從一種狀態(tài)轉(zhuǎn)變?yōu)榱硪环N狀態(tài)。與復(fù)選框不同的是,在某一時(shí)刻同一組中的單選按鈕只有一個(gè)被選擇,選擇某個(gè)單選按鈕時(shí),同一組中的其他單選按鈕都會(huì)變?yōu)槲幢贿x;而同一組中的復(fù)選框同時(shí)可以有0個(gè)、1個(gè)或多個(gè)被選。常見(jiàn)的JRadioButton構(gòu)造方法包括:JRadioButton()可以構(gòu)造一個(gè)空的單選按鈕;JRadioButton(Iconicon)可以構(gòu)造一個(gè)帶圖標(biāo)顯示的單選按鈕;JRadioButton(Iconicon,booleanselected)可以構(gòu)造一個(gè)帶圖標(biāo)且設(shè)置初始狀態(tài)的單選按鈕;JRadioButton(Stringtext,Booleanselected)可以構(gòu)造一個(gè)顯示文字為text且可以設(shè)置初始態(tài)是否被選擇的單選按鈕;JRadioButton(Stringtext,Iconicon,booleanselected)可以構(gòu)造一個(gè)既有文字顯示又有圖標(biāo)顯示的且可以設(shè)置初始狀態(tài)的單選按鈕。單選按鈕一般是兩個(gè)或兩個(gè)以上存在,沒(méi)有單獨(dú)存在的單選按鈕,這些單選按鈕存在于一個(gè)組中,且組中的單選按鈕同時(shí)有且只能有一個(gè)被選擇。添加組時(shí)我們首先創(chuàng)建一個(gè)javax.swing.ButtonGroup類的對(duì)象,然后調(diào)用add(AbstractButtonb)方法將單選按鈕添加到ButtonGroup組中來(lái)。
點(diǎn)擊單選按鈕也會(huì)引發(fā)ActiveEvent和ItemEvent事件,可以給單選按鈕添加ActiveListener和ItemListener的偵聽(tīng)器來(lái)偵聽(tīng)它們所引發(fā)的事件?!纠?-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("書(shū)畫(huà)");
privateJCheckBoxcb2=newJCheckBox("文學(xué)");
privateJCheckBoxcb3=newJCheckBox("體育");
publicMyJCheckBoxRadio()
{ frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運(yùn)行結(jié)果如圖6-16所示。圖6-16單選按鈕和復(fù)選框例6-14中,學(xué)生的性別選擇使用單選按鈕rb1和rb2,其JRadioButton添加在一個(gè)ButtonGroup組中,每次只能選擇一個(gè)。學(xué)生參加社團(tuán)的選擇使用復(fù)選框,每個(gè)JCheckBox選項(xiàng)都可以選擇。6.4.4組合框與列表框
1.組合框
JComboBox組合框與單選按鈕有些類似,用戶點(diǎn)擊組合框右側(cè)下三角,展開(kāi)后會(huì)出現(xiàn)一些可選項(xiàng)目,這些可選項(xiàng)目中只能選擇其中一個(gè),而不能多選。
JComboBox(組合框)常見(jiàn)的構(gòu)造方法包括:JComboBox()可以構(gòu)造一個(gè)選項(xiàng)為空的組合框;JComboBox(Object[]items)可以構(gòu)造一個(gè)選項(xiàng)為items數(shù)組項(xiàng)的組合框。其中ietms是Object類型的,因此它支持很多格式的選項(xiàng)數(shù)組,譬如文字、圖像等。此外,應(yīng)用addItem(ObjectanObject)可以向組合框中添加一個(gè)選項(xiàng);應(yīng)用removeItem
(ObjectanObject)可以刪除一個(gè)選項(xiàng);應(yīng)用removeItem(IntanIndex)可以刪除位置為anIndex的選項(xiàng);應(yīng)用removeAllItems()可以移除所有選項(xiàng)。
JComboBox可以觸發(fā)ActionEvent和ItemEvent事件,通過(guò)給JComboBox添加ActionListener和ItemListener來(lái)實(shí)現(xiàn)事件偵聽(tīng)。
2.列表框
JList在屏幕上顯示為若干行數(shù)的選項(xiàng)。列表框與復(fù)選框有些類似,可以實(shí)現(xiàn)多個(gè)選項(xiàng)的選擇,JList和JComboBox的外觀不同,JComboBox只有點(diǎn)擊下拉小三角后才能顯示若干個(gè)選項(xiàng),而JList可直接列出所有選項(xiàng)。JList要實(shí)現(xiàn)多選時(shí),按“Ctrl”鍵,點(diǎn)擊不連續(xù)的選項(xiàng)實(shí)現(xiàn)不連續(xù)項(xiàng)的選擇,或者按“Shift”鍵,點(diǎn)擊首選項(xiàng)和末選項(xiàng)實(shí)現(xiàn)一段連續(xù)選項(xiàng)的選擇。應(yīng)用JList()可以構(gòu)造一個(gè)空的JList的列表框;應(yīng)用JList(Object[]listData)可以構(gòu)造一個(gè)有l(wèi)istData對(duì)象數(shù)組指定選項(xiàng)的列表框。
應(yīng)用getSelectedIndexes()可以獲取JList中所選擇項(xiàng)的索引值;應(yīng)用getSelectedValues()可以獲取JList中選中選項(xiàng)的值;應(yīng)用setVisibleRowCount(intvisibleRowCount)可以設(shè)置JList中可視選項(xiàng)的行數(shù)。
選擇了JList選項(xiàng)時(shí),將引發(fā)ListSelectionEvent事件,通過(guò)對(duì)JList添加ListSelectionListener事件偵聽(tīng)器來(lái)編寫(xiě)響應(yīng)的事件處理程序。【例6-15】組合框和列表框應(yīng)用示例。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
importjavax.swing.event.*;
publicclassMyJComboBoxJListextendsJFrame
{ String[]comboStrings={"中共黨員","共青團(tuán)員","群眾","民主黨派"};
String[]listStrings={"書(shū)畫(huà)協(xié)會(huì)","文學(xué)社","籃球協(xié)會(huì)","電腦協(xié)會(huì)"};
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("測(cè)試JComboBox&JList");
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
運(yùn)行結(jié)果如圖6-17所示。圖6-17JComboBox和JList的使用例6-15中,學(xué)生政治面貌的填寫(xiě)是一個(gè)組合框,只能選擇四個(gè)選項(xiàng)中的一個(gè)。當(dāng)選擇了組合框中的選項(xiàng)后,觸發(fā)組合框事件偵聽(tīng)的響應(yīng),即可在右下文本區(qū)域框中填寫(xiě)學(xué)生的姓名和政治面貌。學(xué)生參加社團(tuán)通過(guò)列表框來(lái)實(shí)現(xiàn),可以同時(shí)選擇多個(gè)選項(xiàng),選擇后響應(yīng)其事件并在右下文本區(qū)域內(nèi)填寫(xiě)學(xué)生所選擇的社團(tuán)組織。6.5.1菜單
1.菜單JMenu
Java菜單的組成一般是一個(gè)菜單條JMenuBar包含多個(gè)菜單JMenu,菜單JMenu又包含若干個(gè)菜單項(xiàng)JMenuItem,菜單項(xiàng)JMenuItem又分為兩個(gè)子類JCheckBoxMenuItem和JRadioButtonMenuItem。JcheckBoxMenuItem實(shí)現(xiàn)復(fù)選框菜單的選項(xiàng),JRadioButtonMenuItem實(shí)現(xiàn)單選菜單的選項(xiàng)。菜單條JMenuBar必須加入到一個(gè)支持JMenuBar的容器中去,如JFrame、JDialog和JApplet等。6.5高級(jí)Swing組件編程當(dāng)用戶選擇某個(gè)菜單項(xiàng)時(shí)會(huì)引發(fā)ActionEvent事件,因此,通過(guò)添加ActionListener偵聽(tīng)器的方法來(lái)處理菜單事件。
【例6-16】菜單的使用。
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
publicclassMyJMenuextendsJFrame
{
publicMyJMenu()
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 長(zhǎng)沙商貿(mào)旅游職業(yè)技術(shù)學(xué)院《機(jī)械制圖與實(shí)驗(yàn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 配電網(wǎng)數(shù)據(jù)采集與分析
- 述職報(bào)告:技術(shù)領(lǐng)先之道模板
- 職業(yè)導(dǎo)論-2020年房地產(chǎn)經(jīng)紀(jì)人《職業(yè)導(dǎo)論》真題匯編
- 名畫(huà)欣賞與創(chuàng)作模板
- 公司年年會(huì)主持稿
- 二零二五年電子商務(wù)平臺(tái)入駐合作協(xié)議范本3篇
- 二零二五版北京車牌租賃市場(chǎng)推廣合作合同規(guī)范范本9篇
- 二零二五版基站建設(shè)場(chǎng)地使用權(quán)及通信網(wǎng)絡(luò)優(yōu)化合同2篇
- 吉林油田十二中2024-2025學(xué)年七年級(jí)上學(xué)期期末語(yǔ)文試卷(含答案)
- 分期還款協(xié)議書(shū)
- 小區(qū)住戶手冊(cè)范本
- ??低?視頻監(jiān)控原理培訓(xùn)教材課件
- 《鄭伯克段于鄢》-完整版課件
- 土壤肥料全套課件
- 畢業(yè)生延期畢業(yè)申請(qǐng)表
- 學(xué)校6S管理制度
- 肽的健康作用及應(yīng)用課件
- T.C--M-ONE效果器使用手冊(cè)
- 8小時(shí)等效A聲級(jí)計(jì)算工具
- 人教版七年級(jí)下冊(cè)數(shù)學(xué)計(jì)算題300道
評(píng)論
0/150
提交評(píng)論