




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Java開發(fā)綜合實(shí)戰(zhàn)STYLEREFbt1a項(xiàng)目六STYLEREFbt1bGUI事件處理項(xiàng)目六GUI事件處理思政目標(biāo)把握客觀事物之間的聯(lián)系和發(fā)展規(guī)律,具體問題具體分析。遵循實(shí)事求是的原則,構(gòu)建包含防范機(jī)制、處置機(jī)制和善后機(jī)制在內(nèi)的教育應(yīng)對機(jī)制。技能目標(biāo)掌握J(rèn)ava的事件處理模式。能夠?qū)UI中的常用事件進(jìn)行處理。項(xiàng)目導(dǎo)讀創(chuàng)建了圖形用戶界面后,由于組件本身并沒有實(shí)現(xiàn)任何交互功能,因此要實(shí)現(xiàn)用戶與應(yīng)用程序的交互,還要處理組件上發(fā)生的事件。Java采用事件處理機(jī)制響應(yīng)用戶的操作請求,即程序的運(yùn)行過程是不斷地響應(yīng)各種事件的過程,事件的產(chǎn)生順序決定了程序的執(zhí)行順序,事件處理是圖形用戶界面應(yīng)用程序的重要組成部分,是實(shí)現(xiàn)各種操作功能的重要途徑。任務(wù)1認(rèn)識事件處理機(jī)制任務(wù)引入小白創(chuàng)建了進(jìn)銷存管理系統(tǒng)的操作界面,但單擊界面上的按鈕沒有反應(yīng)。在Java中,該怎樣響應(yīng)用戶在圖形用戶界面的操作呢?知識準(zhǔn)備事件處理機(jī)制專門用于響應(yīng)用戶的操作,例如,響應(yīng)用戶的單擊鼠標(biāo)、按下鍵盤鍵、選擇列表項(xiàng)等操作。一、事件處理模式在學(xué)習(xí)如何使用事件處理機(jī)制之前,首先必須很好地掌握事件對象、事件源、事件監(jiān)聽器、事件處理器這4個(gè)概念。1.事件對象封裝GUI組件上發(fā)生的特定事件的類對象,通常是用戶的一次操作,如單擊按鈕、按下按鍵等。2.事件源能夠產(chǎn)生事件的對象都可以稱為事件源,通常是產(chǎn)生事件的組件,如文本框、按鈕、下拉式列表等。3.事件監(jiān)聽器負(fù)責(zé)監(jiān)聽事件源上發(fā)生的事件,以便對發(fā)生的事件進(jìn)行處理。事件源通過調(diào)用相應(yīng)的方法將某個(gè)對象注冊為自己的監(jiān)聽器。例如,對于文本框,這個(gè)方法是addActionListener(監(jiān)聽器)。對于注冊了監(jiān)聽器的文本框,在文本框獲得輸入焦點(diǎn)后,如果用戶按回車鍵,Java運(yùn)行環(huán)境就自動(dòng)用ActionEvent類創(chuàng)建一個(gè)對象,即發(fā)生了ActionEvent事件。也就是說,事件源注冊監(jiān)聽器之后,相應(yīng)的操作就會導(dǎo)致相應(yīng)事件的發(fā)生,并通知監(jiān)聽器,監(jiān)聽器就會做出相應(yīng)的處理。4.事件處理器負(fù)責(zé)接收事件對象并進(jìn)行相應(yīng)處理的方法,包含在一個(gè)事件監(jiān)聽器類中。事件監(jiān)聽器實(shí)質(zhì)上就是一個(gè)實(shí)現(xiàn)特定類型監(jiān)聽器接口的類對象,為了處理事件源發(fā)生的事件,監(jiān)聽器這個(gè)對象會自動(dòng)調(diào)用一個(gè)方法來處理事件。那么監(jiān)聽器去調(diào)用哪個(gè)方法呢?創(chuàng)建監(jiān)聽器對象的類必須聲明實(shí)現(xiàn)相應(yīng)的接口,即必須在類體中重寫接口中所有方法,那么當(dāng)事件源發(fā)生事件時(shí),監(jiān)聽器就自動(dòng)調(diào)用被類重寫的接口方法處理事件。上述4個(gè)概念彼此之間聯(lián)系緊密,在整個(gè)事件處理機(jī)制中起著非常重要的作用。事件處理模式如圖6-1所示。圖6-1事件處理模式綜上,在程序中,如果要實(shí)現(xiàn)事件的監(jiān)聽處理機(jī)制,首先要定義一個(gè)實(shí)現(xiàn)了事件監(jiān)聽器接口的類,例如ActionListener。然后通過addActionListener()方法為事件源注冊事件監(jiān)聽器對象。當(dāng)事件源發(fā)生事件產(chǎn)生事件對象時(shí),便會觸發(fā)事件監(jiān)聽器對象,由事件監(jiān)聽器調(diào)用相應(yīng)的方法來處理相應(yīng)的事件。二、事件類當(dāng)發(fā)生一個(gè)事件時(shí),該事件用一個(gè)事件對象表示,事件對象有對應(yīng)的事件類。不同的事件類描述不同類型的用戶動(dòng)作。Java將事件分為兩個(gè)類別:低級事件與語義事件。絕大部分與圖形用戶界面有關(guān)的事件類都位于java.awt.event包中,其中包含了各種事件類別的監(jiān)聽接口。javax.swing.event包中定義了與Swing事件有關(guān)的事件類,例如DocumentEvent類。1.低級事件低級事件是指來自鍵盤、鼠標(biāo)和與窗口操作有關(guān)的事件。例如,關(guān)閉窗口、移動(dòng)鼠標(biāo)、獲取焦點(diǎn)或敲擊鍵盤等。java.awt.event包中的低級事件類如表6-1所示。表6-1低級事件類事件類名說明FocusEvent組件獲得或失去焦點(diǎn)時(shí)產(chǎn)生的事件MouseEvent鼠標(biāo)按下、釋放、拖動(dòng)、移動(dòng)時(shí)產(chǎn)生的事件KeyEvent鍵盤按鍵按下或釋放時(shí)產(chǎn)生的事件WindowEvent對窗口操作產(chǎn)生的事件2.語義事件語義事件是指與組件有關(guān)的事件。例如,單擊按鈕、在文本域中輸入文本、拖動(dòng)滾動(dòng)條、選擇列表項(xiàng)等。java.awt.event包中常用的語義事件類如表6-2所示。表6-2常用的語義事件類事件類名說明ActionEvent單擊按鈕、選中菜單項(xiàng)、在文本框中按Enter鍵時(shí)產(chǎn)生的事件AdjustmentEvent調(diào)節(jié)滾動(dòng)條位置時(shí)產(chǎn)生的事件ItemEvent選擇復(fù)選框、單擊列表框、選擇列表項(xiàng)時(shí)產(chǎn)生的事件任務(wù)2常用事件任務(wù)引入大致了解了事件處理的基本流程之后,勤于思考的小白又有了新的問題:Java提供了哪些事件,這些事件如何觸發(fā)呢?如果只需要對某個(gè)事件監(jiān)聽類中的單個(gè)事件進(jìn)行監(jiān)聽,而不關(guān)心其他的事件,能不能只重寫該事件對應(yīng)的方法呢?知識準(zhǔn)備Java中的常用事件包括窗體事件、鼠標(biāo)事件、鍵盤事件、動(dòng)作事件、選項(xiàng)事件、焦點(diǎn)事件和文檔事件。每個(gè)事件類都對應(yīng)著一個(gè)監(jiān)聽器接口,比如窗體事件類WindowEvent對應(yīng)著WindowListener接口。一個(gè)類只要實(shí)現(xiàn)了某個(gè)監(jiān)聽器接口就是一個(gè)監(jiān)聽器類了。監(jiān)聽器接口中定義了一些方法,監(jiān)聽器類可以具體實(shí)現(xiàn)其中部分或是所有的方法,事件被引發(fā)后就會執(zhí)行這些方法。一、窗體事件(WindowEvent)大部分GUI應(yīng)用程序都需要使用Window(窗體)對象作為最外層的容器,窗體對象都可以發(fā)生窗體事件,如窗體的打開、關(guān)閉、激活、圖標(biāo)化等。在應(yīng)用程序中,觸發(fā)窗體事件時(shí),WindowEvent類創(chuàng)建一個(gè)窗體事件對象。該對象調(diào)用getWindow()方法可以獲取發(fā)生窗體事件的窗口。在對窗體事件進(jìn)行處理時(shí),首先需要定義一個(gè)實(shí)現(xiàn)了WindowListener接口的類作為窗體監(jiān)聽器,然后通過addWindowListener()方法將窗體對象與窗體監(jiān)聽器綁定。WindowListener接口中有7個(gè)不同的方法,如表6-3所示,不同的窗體事件觸發(fā)時(shí),窗體監(jiān)聽器調(diào)用不同的方法。
表6-3WindowListener接口的方法方法說明publicvoidwindowActivated(WindowEvente)窗口從非激活狀態(tài)到激活時(shí)調(diào)用publicvoidwindowDeactivated(WindowEvente)窗口從激活狀態(tài)到非激活狀態(tài)時(shí)調(diào)用publicvoidwindowClosing(WindowEvente)窗口被關(guān)閉時(shí)調(diào)用publicvoidwindowClosed(WindowEvente)窗口關(guān)閉后調(diào)用publicvoidwindowIconified(WindowEvente)窗口圖標(biāo)化(最小化)時(shí)調(diào)用publicvoidwindowDeiconified(WindowEvente)窗口從最小化恢復(fù)到正常狀態(tài)時(shí)調(diào)用publicvoidwindowOpened(WindowEvente)窗口打開時(shí)調(diào)用案例——關(guān)閉窗口本案例創(chuàng)建一個(gè)窗口,首先定義一個(gè)實(shí)現(xiàn)了WindowListener接口的類作為窗體監(jiān)聽器,然后為“關(guān)閉”按鈕注冊監(jiān)聽器,實(shí)現(xiàn)單擊“關(guān)閉”按鈕關(guān)閉窗口的操作。通過本案例,幫助讀者進(jìn)一步了解事件處理模式和流程。(1)在Eclipse中新建一個(gè)名為EventDemo的Java項(xiàng)目。在其中添加一個(gè)名為MyWindowListener的類,用作窗口監(jiān)聽器類。(2)在編輯器中編寫代碼,使類MyWindowListener實(shí)現(xiàn)WindowListener接口,并實(shí)現(xiàn)windowClosing()方法,用于處理關(guān)閉窗口的事件。具體代碼如下:importjava.awt.Window;importjava.awt.event.WindowEvent;importjava.awt.event.WindowListener;publicclassMyWindowListenerimplementsWindowListener{ publicvoidwindowClosing(WindowEvente){//實(shí)現(xiàn)windowClosing()方法 Windowwin=e.getWindow(); win.setVisible(false); win.dispose(); } //實(shí)現(xiàn)WindowListener接口中的其他方法,由于不需要,所以留空 publicvoidwindowActivated(WindowEvente){} publicvoidwindowClosed(WindowEvente){} publicvoidwindowDeactivated(WindowEvente){ } publicvoidwindowDeiconified(WindowEvente){ } publicvoidwindowIconified(WindowEvente){} publicvoidwindowOpened(WindowEvente){ }}上述的代碼在實(shí)現(xiàn)WindowListener接口的windowClosing()方法時(shí),首先接受事件源產(chǎn)生并傳遞的WindowEvent類創(chuàng)建的窗體事件對象e,該對象調(diào)用getWindow()方法獲取發(fā)生窗體事件的窗口。然后調(diào)用setVisible()方法設(shè)置窗口不可見,調(diào)用dispose()方法釋放窗口資源。這里要再次提請讀者注意的是,在實(shí)現(xiàn)WindowListener接口時(shí),應(yīng)實(shí)現(xiàn)該接口中的所有方法,即使不需要所有的方法。本實(shí)例將其他方法體留空,但不能省略。(3)在項(xiàng)目中添加一個(gè)名為WindowEventTest的類,用于將窗體對象與窗體監(jiān)聽器進(jìn)行綁定,并測試觸發(fā)窗體事件的效果。(4)在類體中編寫主方法,實(shí)例化一個(gè)JFrame窗體對象,設(shè)置窗體位置和大小以及可見性,然后為窗體對象注冊監(jiān)聽器。具體代碼如下:importjavax.swing.JFrame;publicclassWindowEventTest{ publicstaticvoidmain(String[]args){ JFramejf=newJFrame("測試窗口"); //建立新窗體 jf.setBounds(300,200,260,160); //設(shè)置窗體的位置和大小 jf.setVisible(true); //設(shè)置窗體可見 //為窗口組件注冊監(jiān)聽器 MyWindowListenerwl=newMyWindowListener(); jf.addWindowListener(wl); }}在上面的代碼中,使用addWindowListener()方法為事件源jf注冊事件監(jiān)聽器對象wl。當(dāng)事件源發(fā)生事件時(shí),便會觸發(fā)事件監(jiān)聽器對象,由事件監(jiān)聽器調(diào)用相應(yīng)的方法來處理相應(yīng)的事件。(5)運(yùn)行WindowEventTest.java,即可在指定位置彈出一個(gè)指定大小的窗口,如圖6-2所示。單擊窗口右上角的“關(guān)閉”按鈕,即可關(guān)閉窗口。圖6-2運(yùn)行結(jié)果提示:本例沒有指定“關(guān)閉”按鈕的處理方式。默認(rèn)情況下,會調(diào)用setDefaultCloseOperation(HIDE_ON_CLOSE)方法,調(diào)用任意已注冊的WindowListener對象后隱藏當(dāng)前窗體。二、事件適配器在Java中,當(dāng)一個(gè)類實(shí)現(xiàn)一個(gè)接口時(shí),必須實(shí)現(xiàn)接口中所有的方法,即使不需要其中的某些方法也需要實(shí)現(xiàn),這在實(shí)際應(yīng)用中會導(dǎo)致很多代碼多余但又無法省略,如上例所示。這種情況下,可以使用適配器的設(shè)計(jì)模式代替接口處理事件,在實(shí)現(xiàn)類和接口之間增加一個(gè)過渡的抽象類,子類繼承抽象類就可以根據(jù)自己的需要重寫需要的方法。Java在事件處理中提供了很多的Adapter(適配器)類,處理事件的接口多于一個(gè)方法時(shí),Java相應(yīng)地就提供一個(gè)適配器類,方便用戶進(jìn)行事件處理的實(shí)現(xiàn),例如WindowAdapter、MouseAdapter、KeyAdapter、MouseMotionAdapter和FocusAdapter。適配器已經(jīng)實(shí)現(xiàn)了相應(yīng)的接口,因此,可以使用適配器的子類創(chuàng)建的對象作為監(jiān)聽器,在子類中重寫所需要的接口方法即可。案例——使用WindowAdapter本案例修改上一個(gè)案例,使用適配器做監(jiān)聽器,只處理窗口關(guān)閉事件,因此只需重寫windowClosing()方法即可。(1)打開MyWindowListener.java,引入java.awt.event.WindowAdapter包,然后修改代碼,使MyWindowListener類繼承WindowAdapter,然后刪除其他重寫的方法。修改后的代碼如下所示:importjava.awt.Window;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;//繼承WindowAdapter類publicclassMyWindowListenerextendsWindowAdapter{ //重寫windowClosing()方法 publicvoidwindowClosing(WindowEvente){ Windowwin=e.getWindow(); win.setVisible(false); win.dispose(); }}(2)運(yùn)行WindowEventTest.java,即可在指定位置彈出一個(gè)指定大小的窗口。單擊窗口右上角的“關(guān)閉”按鈕,即可關(guān)閉窗口。三、鼠標(biāo)事件(MouseEvent)在圖形用戶界面中,用戶會經(jīng)常使用鼠標(biāo)在組件上進(jìn)行各種操作,例如鼠標(biāo)按下、釋放、單擊、拖動(dòng)等,這些操作被定義為鼠標(biāo)事件。幾乎所有的組件都可以產(chǎn)生鼠標(biāo)事件,JDK中使用MouseEvent類表示鼠標(biāo)事件,該事件會導(dǎo)致MouseEvent類自動(dòng)創(chuàng)建一個(gè)事件對象。處理鼠標(biāo)事件時(shí),首先需要實(shí)現(xiàn)MouseListener接口(或MouseMotionListener接口)或繼承適配器MouseAdapter類(或MouseMotionAdapter類)定義監(jiān)聽器,然后調(diào)用addMouseListener()方法(或addMouseMotionListener()方法)將監(jiān)聽器綁定到事件源對象。MouseListener接口中有5個(gè)不同的方法,如表6-4所示,用于處理5種不同的鼠標(biāo)事件。表6-4MouseListener接口的方法方法說明publicvoidmousePressed(MouseEvente)在組件上按下鼠標(biāo)鍵時(shí)調(diào)用publicvoidmouseReleased(MouseEvente)在組件上釋放鼠標(biāo)鍵時(shí)調(diào)用publicvoidmouseEntered(MouseEvente)鼠標(biāo)進(jìn)入組件時(shí)調(diào)用publicvoidmouseExited(MouseEvente)鼠標(biāo)離開組件時(shí)調(diào)用publicvoidmouseClicked(MouseEvente)在組件上單擊鼠標(biāo)時(shí)調(diào)用鼠標(biāo)的操作分為左鍵單擊、雙擊、右鍵點(diǎn)擊和中鍵(滾輪)點(diǎn)擊。MouseEvent類中定義了很多常量和方法來標(biāo)識鼠標(biāo)動(dòng)作,如表6-5所示。表6-5MouseEvent類的常用方法及常量方法說明publicintgetButton()以數(shù)字形式返回按下的鼠標(biāo)鍵publicintgetClickCount()獲取鼠標(biāo)被單擊的次數(shù)publicstaticStringgetMouseModifiersText(intmodifiers)以字符串形式返回鼠標(biāo)按下的鍵信息publicintgetX()獲取鼠標(biāo)指針在事件源坐標(biāo)系中的x坐標(biāo)publicintgetY()獲取鼠標(biāo)指針在事件源坐標(biāo)系中的y坐標(biāo)publicstaticfinalintBUTTON1表示鼠標(biāo)左鍵的常量publicstaticfinalintBUTTON2表示鼠標(biāo)滾軸的常量publicstaticfinalintBUTTON3表示鼠標(biāo)右鍵的常量MouseMotionListener接口中有2個(gè)不同的方法,如表6-6所示,分別用于處理拖動(dòng)鼠標(biāo)和移動(dòng)鼠標(biāo)事件。表6-6MouseMotionListener接口中的方法方法說明publicvoidmouseDragged(MouseEvente)拖動(dòng)鼠標(biāo)時(shí)(不必在事件源上)調(diào)用publicvoidmouseMoved(MouseEvente)在事件源上移動(dòng)鼠標(biāo)時(shí)調(diào)用案例——拖動(dòng)按鈕本案例定義一個(gè)繼承JFrame并實(shí)現(xiàn)MouseMotionListener接口的類作為窗體監(jiān)聽器,通過重寫mouseDragged()方法,實(shí)現(xiàn)鼠標(biāo)拖動(dòng)按鈕的操作。(1)在項(xiàng)目EventDemo中新建一個(gè)類MyMouseListener,該類繼承JFrame創(chuàng)建窗體,并實(shí)現(xiàn)MouseMotionListener接口。(2)在類體中定義類MyMouseListener的構(gòu)造方法,構(gòu)造一個(gè)窗體和按鈕,并為按鈕注冊鼠標(biāo)事件監(jiān)聽器。然后重寫mouseDragged()方法和mouseMoved()方法。具體代碼如下:importjava.awt.Component;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionListener;importjavax.swing.JButton;importjavax.swing.JFrame;publicclassMyMouseListenerextendsJFrameimplementsMouseMotionListener{privatestaticfinallongserialVersionUID=1L;publicJButtonbutton=newJButton("拖動(dòng)我"); //實(shí)例化按鈕intx,y,a,b; //坐標(biāo)變量publicMyMouseListener(){ super.setTitle("測試按鈕"); //設(shè)置窗口標(biāo)題 super.setLayout(null); //取消使用布局管理器 button.setSize(80,40); //設(shè)置按鈕尺寸 super.add(button); //在窗口中添加按鈕 button.addMouseMotionListener(this); //注冊監(jiān)聽器 super.setBounds(300,300,280,160); //設(shè)置窗口位置和大小 super.setVisible(true); //設(shè)置窗口可見}publicvoidmouseDragged(MouseEvente){//重寫拖動(dòng)鼠標(biāo)觸發(fā)的鼠標(biāo)事件 Componentcom=null; //定義一個(gè)空組件 //判斷事件源是否為組件實(shí)例,如果是,則賦值給com if(e.getSource()instanceofComponent){ com=(Component)e.getSource(); //獲取組件的坐標(biāo) a=com.getBounds().x; b=com.getBounds().y; //獲取鼠標(biāo)在事件源中的位置坐標(biāo) x=e.getX(); y=e.getY(); //將按鈕坐標(biāo)設(shè)置為鼠標(biāo)指針?biāo)谖恢? a=a+x; b=b+y; com.setLocation(a,b); }}publicvoidmouseMoved(MouseEvente){ } }上面的代碼重寫mouseDragged()方法時(shí),使用坐標(biāo)變換實(shí)現(xiàn)組件的拖動(dòng)。先獲得組件的左上角在容器坐標(biāo)系統(tǒng)中的坐標(biāo)(a,b),再獲得鼠標(biāo)指針在組件坐標(biāo)系中的坐標(biāo)(x,y),然后計(jì)算得到鼠標(biāo)指針在容器坐標(biāo)系統(tǒng)中的位置,并設(shè)置組件的位置。(3)在項(xiàng)目EventDemo中新建一個(gè)類MouseEventTest,在該類中定義主方法,實(shí)例化MyMouseListener類對象。具體代碼如下所示:publicclassMouseEventTest{ publicstaticvoidmain(String[]args){ newMyMouseListener(); }}(4)運(yùn)行MouseEventTest.java,彈出如圖6-3所示的窗口。在按鈕上按下鼠標(biāo)左鍵拖動(dòng),即可將按鈕拖動(dòng)到鼠標(biāo)指針?biāo)谖恢茫鐖D6-4所示。圖6-3運(yùn)行窗口圖6-4拖動(dòng)按鈕四、鍵盤事件(KeyEvent)鍵盤操作也是很常用的用戶交互方式,例如按下、釋放或敲擊鍵盤按鍵等,這些操作被定義為鍵盤事件。JDK使用KeyEvent類表示鍵盤事件,處理KeyEvent事件的監(jiān)聽器對象需要實(shí)現(xiàn)KeyListener接口或者繼承KeyAdapter類。KeyListener接口中有3個(gè)方法,如表6-7所示。表6-7KeyListener接口中的方法方法說明publicvoidkeyPressed(KeyEvente)組件處于激活狀態(tài)時(shí),按下鍵盤上某個(gè)鍵時(shí)調(diào)用publicvoidKeyReleased(KeyEvente)釋放鍵盤上按下的鍵時(shí)調(diào)用publicvoidkeyTyped(KeyEvente)鍵被按下又釋放時(shí)調(diào)用鍵盤上的按鍵眾多,KeyEvent類提供了一些方法用于標(biāo)識觸發(fā)鍵盤事件的鍵,如表6-8所示。表6-8KeyEvent類的常用方法方法說明publicchargetKeyChar()返回觸發(fā)keyTyped事件的字符publicintgetKeyCode()返回輸入字符的鍵碼值publicstaticStringgetKeyText(intkeycode)返回描述指定鍵碼值的信息鍵盤按鍵的鍵碼值可參見API文檔中KeyEvent類的說明。案例——字符轉(zhuǎn)碼本案例通過監(jiān)聽鍵盤事件,在文本區(qū)中輸出在文本框中輸入的字符的鍵碼。(1)在項(xiàng)目EventDemo中新建一個(gè)名為MyKeyListener的類。該類繼承JFrame并實(shí)現(xiàn)KeyListener接口。(2)引入包,在類體中定義一個(gè)標(biāo)簽,一個(gè)文本框,一個(gè)文本區(qū)域以及一個(gè)滾動(dòng)面板。接下來編寫構(gòu)造方法創(chuàng)建窗體,然后重寫KeyListener接口中的keyPressed()方法和keyReleased()方法。具體代碼如下:importjava.awt.FlowLayout;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMyKeyListenerextendsJFrameimplementsKeyListener{privatestaticfinallongserialVersionUID=1L;//創(chuàng)建標(biāo)簽和文本框JLabellabel_1=newJLabel("字符:");JTextFieldtext=newJTextField(6);//創(chuàng)建帶滾動(dòng)條的文本區(qū)JTextAreacode=newJTextArea(6,20);JScrollPanesp=newJScrollPane(code);//構(gòu)造方法publicMyKeyListener(){ super.setTitle("測試鍵盤事件"); //設(shè)置窗口標(biāo)題 super.setBounds(300,300,280,200); //設(shè)置窗口位置和大小 super.setLayout(newFlowLayout()); //設(shè)置布局管理器 //在窗體中添加組件 super.add(label_1); super.add(text); text.addKeyListener(this); //注冊監(jiān)聽器 //設(shè)置總是顯示滾動(dòng)條 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); code.setEditable(false); //設(shè)置文本區(qū)不可編輯 //設(shè)置窗口可見和關(guān)閉方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE);}//重寫keyPressed()方法,在文本區(qū)輸出按下的鍵及對應(yīng)的鍵碼publicvoidkeyPressed(KeyEvente){ code.append("鍵"+e.getKeyChar()+"的鍵碼是:"+e.getKeyCode()+"\n");}//重寫keyReleased()方法,釋放按鍵時(shí)清空文本框publicvoidkeyReleased(KeyEvente){ text.setText(null);}publicvoidkeyTyped(KeyEvente){}}(3)在項(xiàng)目中新建一個(gè)類KeyEventTest,在該類中定義主方法,實(shí)例化MyKeyListener類對象。具體代碼如下所示:publicclassKeyEventTest{ publicstaticvoidmain(String[]args){ newMyKeyListener(); }}(4)運(yùn)行KeyEventTest.java,彈出窗口。按下鍵盤上的按鍵,即可在文本區(qū)中看到輸出的鍵碼信息,如圖6-5所示。圖6-5運(yùn)行結(jié)果五、動(dòng)作事件(ActionEvent)動(dòng)作事件不代表某個(gè)具體的動(dòng)作,只是表示一個(gè)動(dòng)作發(fā)生了,而不需要關(guān)心使用哪種方式觸發(fā)事件。例如,觸發(fā)一個(gè)按鈕的單擊事件時(shí),可以使用鼠標(biāo)單擊,也可以按鍵盤上的Enter鍵,不管使用哪種方式,只要對按鈕進(jìn)行了操作,就會觸發(fā)動(dòng)作事件。JDK使用ActionEvent類表示動(dòng)作事件,文本框、按鈕、菜單項(xiàng)、密碼框和單選按鈕都成為ActionEvent事件的事件源,觸發(fā)ActionEvent事件。處理動(dòng)作事件時(shí),首先需要實(shí)現(xiàn)ActionListener接口定義監(jiān)聽器,然后調(diào)用addActionListener()方法將實(shí)現(xiàn)ActionListener接口的類的實(shí)例注冊為事件源的監(jiān)聽器。ActionListener接口中只定義了一個(gè)方法publicvoidactionPerformed(ActionEvente),在發(fā)生操作時(shí)調(diào)用。ActionEvent類常用的方法如表6-9所示。表6-9ActionEvent類的常用方法方法說明publicObjectgetSource()返回產(chǎn)生這個(gè)事件的事件源對象publicStringgetActionCommand()返回與此動(dòng)作相關(guān)的命令字符串案例——大小寫轉(zhuǎn)換本案例通過監(jiān)聽文本框和按鈕的動(dòng)作事件,將文本框中輸入的字符全部轉(zhuǎn)換為大寫字母后,在文本區(qū)中輸出。(1)在項(xiàng)目EventDemo中新建一個(gè)名為MyActionListener的類。該類繼承JFrame并實(shí)現(xiàn)ActionListener接口。(2)引入包,在類體中定義一個(gè)文本框,一個(gè)按鈕,一個(gè)文本區(qū)以及一個(gè)滾動(dòng)面板。接下來編寫構(gòu)造方法創(chuàng)建窗體,然后重寫ActionListener接口中的actionPerformed()方法。具體代碼如下:importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMyActionListenerextendsJFrameimplementsActionListener{privatestaticfinallongserialVersionUID=1L;//創(chuàng)建文本框和按鈕JTextFieldtext=newJTextField(20);JButtonbutton=newJButton("轉(zhuǎn)換");//創(chuàng)建帶滾動(dòng)條的文本區(qū)JTextAreashow=newJTextArea(6,25);JScrollPanesp=newJScrollPane(show);publicMyActionListener(){ super.setTitle("測試動(dòng)作事件"); //設(shè)置窗口標(biāo)題 super.setBounds(300,300,320,200); //設(shè)置窗口位置和大小 super.setLayout(newFlowLayout()); //設(shè)置布局管理器 //在窗體中添加組件 super.add(text); text.addActionListener(this); //注冊監(jiān)聽器 button.addActionListener(this); //注冊監(jiān)聽器 super.add(button); //設(shè)置總是顯示滾動(dòng)條 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); show.setEditable(false); //設(shè)置文本區(qū)不可編輯 //設(shè)置窗口可見和關(guān)閉方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE);}publicvoidactionPerformed(ActionEvente){ Stringstr_in=text.getText(); //獲取文本框中的字符串 Stringstr_out=str_in.toUpperCase(); //將字符串轉(zhuǎn)換為大寫 show.append(str_in+"大寫:"+str_out+"\n"); //將轉(zhuǎn)換結(jié)果追加到文本區(qū)}}(3)在項(xiàng)目中新建一個(gè)類ActionEventTest,在該類中定義主方法,實(shí)例化MyActionListener類對象。具體代碼如下所示:publicclassActionEventTest{ publicstaticvoidmain(String[]args){ newMyActionListener(); }}(4)運(yùn)行ActionEventTest.java,彈出如圖6-6(a)所示的窗口。在文本框中輸入字符,然后按Enter鍵,或單擊“轉(zhuǎn)換”按鈕,即可在文本區(qū)中看到轉(zhuǎn)換為大寫的字符串,如圖6-6(b)所示。(a)(b)圖6-6運(yùn)行結(jié)果六、選項(xiàng)事件(ItemEvent)在應(yīng)用程序中,勾選復(fù)選框或取消選中復(fù)選框,就會觸發(fā)選項(xiàng)事件。JDK使用ItemEvent類表示選項(xiàng)事件。除了復(fù)選框,下拉列表框、菜單項(xiàng)等組件都可以觸發(fā)ItemEvent事件。處理選項(xiàng)事件時(shí),首先需要實(shí)現(xiàn)ItemListener接口定義監(jiān)聽器,然后調(diào)用addItemListener()方法將實(shí)現(xiàn)ItemListener接口的類的實(shí)例注冊為事件源的監(jiān)聽器。ItemListener接口中只有一個(gè)方法publicvoiditemStateChanged(ItemEvente),在選擇項(xiàng)發(fā)生改變時(shí)調(diào)用。ItemEvent類常用的方法如表6-10所示。表6-10ItemEvent類的常用方法方法說明publicObjectgetSource()返回產(chǎn)生這個(gè)事件的事件源對象publicObjectgetItem()返回受事件影響的對象publicintgetStateChange()返回狀態(tài)更改的類型,值為常量值。SELECTED值為1,表示選擇項(xiàng)改變;DESELECTED值為2,表示選擇項(xiàng)未改變publicStringparamString()返回標(biāo)識此項(xiàng)事件的參數(shù)字符串,常用于程序調(diào)試案例——錄入用戶信息本案例通過監(jiān)聽下拉列表框的ItemEvent事件和按鈕的ActionEvent事件,將用戶界面輸入、選擇的信息在文本區(qū)中輸出。(1)在項(xiàng)目EventDemo中新建一個(gè)名為UserInfo的類。該類繼承JFrame并使用網(wǎng)格包布局管理器(GridBagLayout)排布組件,制作用戶界面。具體代碼如下:importjava.awt.GridBagConstraints;importjava.awt.GridBagLayout;importjava.awt.Insets;importjavax.swing.ButtonGroup;importjavax.swing.JButton;importjavax.swing.JComboBox;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JRadioButton;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassUserInfoextendsJFrame{ //創(chuàng)建組件 JLabellabel=newJLabel("姓名:"); JTextFieldname=newJTextField(10); JRadioButtonrb1=newJRadioButton("男"); JRadioButtonrb2=newJRadioButton("女"); ButtonGroupgender=newButtonGroup();//創(chuàng)建一個(gè)按鈕組gender,用于管理單選按鈕 //創(chuàng)建下拉列表框 JLabellabel_edu=newJLabel("學(xué)歷:"); String[]edu_list={"本科","大專","碩士","博士","其他"}; JComboBox<String>edu=newJComboBox<String>(edu_list); //創(chuàng)建按鈕和帶滾動(dòng)條的文本框 JButtonbutton=newJButton("確定"); JTextAreashow=newJTextArea(5,20); JScrollPanesp=newJScrollPane(show); //構(gòu)造方法 publicUserInfo(){ super.setTitle("測試選項(xiàng)事件"); //設(shè)置窗口標(biāo)題 super.setBounds(300,300,300,300); //設(shè)置窗口位置和大小 init(); //調(diào)用成員方法初始化界面 } voidinit(){ //定義監(jiān)聽器類,實(shí)現(xiàn)ItemListener接口,用于監(jiān)聽下拉列表框的選項(xiàng)事件 MyItemListenerselect=newMyItemListener(); //定義監(jiān)聽器類,實(shí)現(xiàn)ActionListener接口,用于監(jiān)聽按鈕的動(dòng)作事件 PrintListenersubmit=newPrintListener(); //調(diào)用監(jiān)聽器類中的成員方法,傳遞組件參數(shù) select.setJComboBox(edu); select.setButton(submit); submit.setJTextField(name); submit.setJTextArea(show); submit.setRadioButtons(rb1,rb2); //創(chuàng)建GridBagLayout布局管理器 GridBagLayoutlayout=newGridBagLayout(); super.setLayout(layout); //在窗體中添加組件 super.add(label); super.add(name); gender.add(rb1); gender.add(rb2); super.add(rb1); super.add(rb2); super.add(label_edu); super.add(edu); //設(shè)置總是顯示滾動(dòng)條 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); edu.addItemListener(select); //注冊監(jiān)聽器 super.add(button); super.add(label_edu); super.add(edu); super.add(button); button.addActionListener(submit); //注冊監(jiān)聽器 //使用GridBagLayout布局管理器排列組件 GridBagConstraintsconstraints=newGridBagConstraints(); constraints.gridx=0;//起始點(diǎn)為第1列 constraints.gridy=0;//起始點(diǎn)為第1行 layout.setConstraints(label,constraints); constraints.gridx=1;//起始點(diǎn)為第2列 constraints.gridy=0;//起始點(diǎn)為第1行 layout.setConstraints(name,constraints); constraints.gridx=1; constraints.gridy=1; layout.setConstraints(rb1,constraints); constraints.gridx=2; constraints.gridy=1; layout.setConstraints(rb2,constraints); constraints.gridx=0; constraints.gridy=2; layout.setConstraints(label_edu,constraints); constraints.gridx=1; constraints.gridy=2; layout.setConstraints(edu,constraints); constraints.gridx=1;//起始點(diǎn)為第2列 constraints.gridy=3;//起始點(diǎn)為第4行 constraints.insets=newInsets(10,0,0,0);//設(shè)置組件上方留白 layout.setConstraints(button,constraints); constraints.gridx=0;//起始點(diǎn)為第1列 constraints.gridy=4;//起始點(diǎn)為第5行 constraints.gridwidth=3; //占據(jù)3列 constraints.insets=newInsets(10,0,0,0);//設(shè)置組件上方留白 layout.setConstraints(sp,constraints); //設(shè)置窗口可見和關(guān)閉方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE); }}(2)在項(xiàng)目中添加一個(gè)名為MyItemListener.java的類,該類作為下拉列表框組件的監(jiān)聽器類,實(shí)現(xiàn)ItemListener接口。具體代碼如下:importjava.awt.event.ItemEvent;importjava.awt.event.ItemListener;importjavax.swing.JComboBox;publicclassMyItemListenerimplementsItemListener{ //定義變量,用于傳遞組件參數(shù) JComboBox<String>choice; PrintListeneroutput; publicvoidsetJComboBox(JComboBox<String>box){ choice=box; } publicvoidsetButton(PrintListenersubmit){ output=submit; } //實(shí)現(xiàn)itemStateChanged()方法 publicvoiditemStateChanged(ItemEvente){ Stringedu=choice.getSelectedItem().toString(); output.setEdu(edu); }}(3)在項(xiàng)目中添加一個(gè)名為PrintListener.java的類,該類作為按鈕組件的監(jiān)聽器類,實(shí)現(xiàn)ActionListener接口。具體代碼如下:importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.JRadioButton;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassPrintListenerimplementsActionListener{ JTextFieldname; JTextAreaoutput; JRadioButtonrb1,rb2; Stringedu; publicvoidsetJTextField(JTextFieldtxt){ name=txt; } publicvoidsetRadioButtons(JRadioButtonrb_m,JRadioButtonrb_w){ rb1=rb_m; rb2=rb_w; } publicvoidsetJTextArea(JTextAreaarea){ output=area; } publicvoidsetEdu(Strings){ edu=s; } //實(shí)現(xiàn)actionPerformed()方法,獲取界面信息并輸出 publicvoidactionPerformed(ActionEvente){ output.append("用戶名:"+name.getText()+"\n"); //判斷單選按鈕的選中狀態(tài)并輸出對應(yīng)的按鈕標(biāo)簽 if(rb1.isSelected()) output.append("性別:"+rb1.getText()+"\n"); elseif(rb2.isSelected()) output.append("性別:"+rb2.getText()+"\n"); output.append("學(xué)歷:"+edu+"\n"); }}(4)在項(xiàng)目中添加一個(gè)名為ItemEventTest的測試類,編寫主方法實(shí)例化UserInfo類對象,測試界面效果。具體代碼如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newUserInfo(); }}(5)運(yùn)行ItemEventTest.java,即可彈出圖形用戶界面。在文本框中輸入字符串,選中某個(gè)單選按鈕,在下拉列表框中選擇某個(gè)列表項(xiàng),然后單擊“確定”按鈕,即可在界面下方的文本區(qū)中顯示用戶輸入、選擇的信息,如圖6-7所示。圖6-7運(yùn)行結(jié)果七、焦點(diǎn)事件(FocusEvent)FocusEvent類表示焦點(diǎn)事件,每個(gè)GUI組件都能夠作為焦點(diǎn)事件的事件源,也就是每個(gè)組件在獲得焦點(diǎn)或者失去焦點(diǎn)時(shí)都會產(chǎn)生焦點(diǎn)事件。例如將光標(biāo)焦點(diǎn)移出一個(gè)文本框,或者將焦點(diǎn)返回給文本框,等等。處理焦點(diǎn)事件時(shí),首先需要實(shí)現(xiàn)FocusListener接口定義監(jiān)聽器,然后調(diào)用addFocusListener()方法將實(shí)現(xiàn)FocusListener接口的類的實(shí)例注冊為事件源的監(jiān)聽器。FocusListener接口中有2個(gè)方法,用于處理焦點(diǎn)改變的事件,如表6-11所示。表6-11FocusListener接口中的方法方法說明publicvoidfocusGained(FocusEvente)組件焦點(diǎn)從無到有時(shí)調(diào)用publicvoidfocusLost(FocusEvente)組件焦點(diǎn)從有到無時(shí)調(diào)用通過單擊組件可以使得該組件有輸入焦點(diǎn),同時(shí)也使得其他組件變成無輸入焦點(diǎn)。一個(gè)組件也可調(diào)用publicbooleanrequestFocusInWindow()方法獲得輸入焦點(diǎn)。焦點(diǎn)事件有持久性和暫時(shí)性兩個(gè)級別。當(dāng)焦點(diǎn)直接從一個(gè)組件移動(dòng)到另一個(gè)組件時(shí),會發(fā)生持久性焦點(diǎn)變更事件;如果失去焦點(diǎn)是暫時(shí)的,例如窗口拖放時(shí)失去焦點(diǎn),拖放結(jié)束后就會自動(dòng)恢復(fù)焦點(diǎn),這就是暫時(shí)性焦點(diǎn)變更事件。利用FocusEvent類中的publicBooleanisTemporary()方法可以返回焦點(diǎn)變更的級別,返回true表示暫時(shí)性的,返回false表示持久性的。案例——輸入序列號本案例通過監(jiān)聽文本框的焦點(diǎn)事件,模擬某些軟件輸入序列號。序列號要在3個(gè)文本框中依次輸入,每個(gè)文本框中只能輸入4個(gè)字符,多出4個(gè)字符時(shí)光標(biāo)自動(dòng)定位到下一個(gè)文本框中。(1)在項(xiàng)目EventDemo中新建一個(gè)名為SerialNumber的類。該類繼承JFrame并使用流式布局管理器(FlowLayout)排布組件,制作用戶界面。具體代碼如下:importjava.awt.FlowLayout;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JTextField;publicclassSerialNumberextendsJFrame{ privatestaticfinallongserialVersionUID=1L; //聲明窗口組件:3個(gè)文本框,2個(gè)標(biāo)簽和1個(gè)按鈕 JTextFieldtext[]=newJTextField[3]; JLabellabel[]=newJLabel[2]; JButtonbutton; FListenerfocus; //聲明監(jiān)聽器 //構(gòu)造方法初始化用戶界面 publicSerialNumber(){ setTitle("測試焦點(diǎn)事件"); //設(shè)置窗口標(biāo)題 setBounds(300,300,300,120); //設(shè)置窗口位置和大小 setLayout(newFlowLayout()); //設(shè)置窗口布局 focus=newFListener(); //創(chuàng)建監(jiān)聽器對象 //創(chuàng)建文本框和標(biāo)簽組件,并為每個(gè)文本框注冊監(jiān)聽器 for(inti=0;i<3;i++){ text[i]=newJTextField(6); text[i].addFocusListener(focus); text[i].addKeyListener(focus); add(text[i]); if(i<2){ label[i]=newJLabel("-"); add(label[i]); } } button=newJButton("確定"); add(button); //設(shè)置窗口可見及關(guān)閉方式 setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); }}(2)在項(xiàng)目中添加一個(gè)名為FListener的類,實(shí)現(xiàn)FocusListener接口和KeyListener接口。在類體中重寫focusGained()方法和keyPressed()方法,分別用于處理文本框獲得焦點(diǎn)的事件和在文本框中鍵入字符的事件。具體代碼如下:importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjavax.swing.JTextField;publicclassFListenerimplementsFocusListener,KeyListener{ publicvoidfocusGained(FocusEvente){ JTextFieldtxt=(JTextField)e.getSource(); //文本框獲取事件源 txt.setText(null); //文本框獲取焦點(diǎn),則清空文本框 } publicvoidfocusLost(FocusEvente){ } publicvoidkeyPressed(KeyEvente){ JTextFieldtxt=(JTextField)e.getSource(); //文本框獲取事件源 intlen=txt.getText().length(); if(len>=3) //達(dá)到指定長度,就將焦點(diǎn)轉(zhuǎn)移到下一個(gè)組件 txt.transferFocus(); } publicvoidkeyReleased(KeyEvente){} publicvoidkeyTyped(KeyEvente){} }(3)在項(xiàng)目中添加一個(gè)名為FocusEventTest的測試類,編寫主方法實(shí)例化SerialNumber類對象,測試界面效果。具體代碼如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newSerialNumber(); }}(4)運(yùn)行SerialNumber.java,即可彈出圖形用戶界面,焦點(diǎn)默認(rèn)位于第一個(gè)文本框中,如圖6-8(a)所示。在第一個(gè)文本框中輸入字符達(dá)到4個(gè)時(shí),光標(biāo)自動(dòng)轉(zhuǎn)移到第二個(gè)文本框,同樣的方法進(jìn)入第三個(gè)文本框,如圖6-8(b)所示。(a)(b)圖6-8運(yùn)行結(jié)果八、文檔事件(DocumentEvent)DocumentEvent接口用于處理文檔事件。能夠產(chǎn)生文檔事件的事件源有文本框(JTextField)、密碼框(JPasswordField)、文本區(qū)(JTextArea),但這些組件不能直接觸發(fā)DocumentEvent事件。用戶進(jìn)行文本編輯操作時(shí),文本內(nèi)容發(fā)生變化,使得這些組件所維護(hù)的文檔模型中的數(shù)據(jù)發(fā)生變化,從而觸發(fā)DocumentEvent事件。也就是說,是文本編輯組件所維護(hù)的文檔觸發(fā)DocumentEvent事件,組件對象調(diào)用getDocument()方法可以獲取文本區(qū)所維護(hù)的文檔。處理文檔事件時(shí),首先需要實(shí)現(xiàn)DocumentListener接口定義監(jiān)聽器,然后調(diào)用addDocumentListener()方法將實(shí)現(xiàn)DocumentListener接口的類的實(shí)例注冊為事件源的監(jiān)聽器。DocumentListener接口包含在javax.swing.event包中,定義了3個(gè)方法,用于處理文檔內(nèi)容改變的事件,如表6-12所示。表6-12DocumentListener接口中的方法方法說明publicvoidchangedUpdate(DocumentEvente)文本編輯區(qū)的內(nèi)容改變時(shí)調(diào)用publicvoidremoveUpdate(DocumentEvente)刪除文本編輯區(qū)的內(nèi)容時(shí)調(diào)用publicvoidinsertUpdate(DocumentEvente)在文本編輯區(qū)插入內(nèi)容時(shí)調(diào)用案例——實(shí)時(shí)排序本案例通過監(jiān)聽文本區(qū)所維護(hù)的文檔模型中的數(shù)據(jù)的焦點(diǎn)事件,對輸入的字符串進(jìn)行實(shí)時(shí)排序。(1)在項(xiàng)目EventDemo中新建一個(gè)名為SortString的類。該類繼承JFrame并使用流式布局管理器(FlowLayout)排布組件,制作用戶界面。具體代碼如下:importjava.awt.FlowLayout;importjavax.swing.JFrame;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;publicclassSortStringextendsJFrame{ privatestaticfinallongserialVersionUID=1L;JTextAreainput,output; DocListenertextChanged; publicSortString(){ init(); //調(diào)用成員方法初始化界面 setTitle("測試文檔事件"); //設(shè)置窗口標(biāo)題 setBounds(300,300,500,240); //設(shè)置窗口位置和大小 //設(shè)置窗口可見及關(guān)閉方式 setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } publicvoidinit(){ setLayout(newFlowLayout()); //設(shè)置布局管理器 input=newJTextArea(10,20); output=newJTextArea(10,20); output.setLineWrap(true); //文本自動(dòng)換行 output.setWrapStyleWord(true); //以單詞為界自動(dòng)換行 output.setEditable(false); //文本區(qū)不可編輯 //添加滾動(dòng)條 add(newJScrollPane(input)); add(newJScrollPane(output)); textChanged=newDocListener(); //創(chuàng)建監(jiān)聽器 //調(diào)用方法傳遞組件參數(shù) textChanged.setInput(input); textChanged.setOutput(output); //為文本區(qū)input的維護(hù)文檔注冊監(jiān)聽器 (input.getDocument()).addDocumentListener(textChanged); }}(2)在項(xiàng)目中添加一個(gè)名為DocListener的類,實(shí)現(xiàn)DocumentListener接口。在類體中編寫成員方法傳遞組件參數(shù),并實(shí)現(xiàn)DocumentListener接口的所有方法。具體代碼如下:importjava.util.Arrays;importjavax.swing.JTextArea;importjavax.swing.event.DocumentEvent;importjavax.swing.event.DocumentListener;publicclassDocListenerimplementsDocumentListener{ JTextAreain,out; publicvoidsetInput(JTextAreainput){ in=input; } publicvoidsetOutput(JTextAreaoutput){ out=output; } //重寫DocumentListener接口的所有方法 publicvoidchangedUpdate(DocumentEvente){ Stringstr=in.getText(); //獲取第一個(gè)文本區(qū)的內(nèi)容 //以逗號為分隔符,拆分文本區(qū)的字符串并保存到字符串?dāng)?shù)組中 Stringwords[]=str.split(","); Arrays.sort(words); //對數(shù)組元素按字典序排序 out.setText(null); //清空第二個(gè)文本區(qū)的內(nèi)容 //在文本區(qū)中輸出排序后的數(shù)組元素 for(inti=0;i<words.length;i++) out.append(words[i]+"\n"); } publicvoidremoveUpdate(DocumentEvente){ changedUpdate(e); //調(diào)用方法 } publicvoidinsertUpdate(DocumentEvente){ changedUpdate(e); //調(diào)用方法 }}(3)在項(xiàng)目中添加一個(gè)名為DocumentEventTest的測試類,編寫主方法實(shí)例化SortString類對象,測試界面效果。具體代碼如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newSortString(); }}(4)運(yùn)行DocumentEventTest.java,即可彈出圖形用戶界面。在左側(cè)文本區(qū)中字符串,右側(cè)文本區(qū)中即可實(shí)時(shí)顯示輸入的字符串(去除分隔符“,”),如圖6-9所示。繼續(xù)輸入或修改輸入的字符串,右側(cè)的文本區(qū)中將實(shí)時(shí)拆分字符串,并將拆分后的字符子串按字典序進(jìn)行升序排列,如圖6-10所示。圖6-9運(yùn)行結(jié)果1圖6-10運(yùn)行結(jié)果2項(xiàng)目總結(jié)項(xiàng)目實(shí)戰(zhàn)在上一章的項(xiàng)目實(shí)戰(zhàn)中已實(shí)現(xiàn)了進(jìn)銷存管理系統(tǒng)的圖形用戶界面,本節(jié)將為主操作界面、商品入庫界面、商品出庫界面以及商品查詢界面的組件注冊監(jiān)聽器、編寫事件處理程序,監(jiān)聽并處理組件的各種事件。修改商品信息界面的組件操作讀者可參照本節(jié)的實(shí)現(xiàn)代碼自行完成。(1)復(fù)制并粘貼“進(jìn)銷存管理系統(tǒng)V5.0”,在CopyProject對話框中修改項(xiàng)目名稱為“進(jìn)銷存管理系統(tǒng)V6.0”,然后單擊Copy按鈕關(guān)閉對話框。(2)打開MainFrame.java,為各個(gè)功能按鈕注冊監(jiān)聽器,處理單擊該按鈕進(jìn)入相應(yīng)界面的操作。相關(guān)代碼如下:……//為“商品入庫”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理按鈕單擊事件 inBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ InFrameaddGoods=newInFrame(); addGoods.setVisible(true); //顯示商品入庫界面 MainFrame.this.dispose(); //退出主界面,并釋放相應(yīng)的屏幕資源 }});……//為“商品出庫”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理按鈕單擊事件 outBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ OutFrameoutGoods=newOutFrame(); outGoods.setVisible(true); //顯示商品出庫界面 MainFrame.this.dispose(); //退出主界面,并釋放相應(yīng)的屏幕資源 }});……//為“修改商品”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理按鈕單擊事件 modifyBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ //讀者自行完成 }});……//為“查詢商品”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理按鈕單擊事件 searchBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ SearchFramesearchGoods=newSearchFrame(); searchGoods.setVisible(true); //顯示查詢商品界面 MainFrame.this.dispose(); //退出主界面,并釋放相應(yīng)的屏幕資源 }});……//為“退出”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理按鈕單擊事件 exitBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ MainFrame.this.dispose(); //退出主界面,并釋放相應(yīng)的屏幕資源 }});……為便于代碼維護(hù),將各種操作的功能代碼放在一個(gè)單獨(dú)的文件中。(3)在PackageExplorer窗格中右擊項(xiàng)目名稱,從彈出的快捷菜單中選擇New→Package命令,新建一個(gè)名為controller的包。然后在該包中添加一個(gè)名為Controllers的類,用于管理商品入庫、出庫、修改和查詢的操作代碼。具體代碼如下所示:packagecontroller;importjavax.swing.JOptionPane;importmodel.Goods;publicclassControllers{ staticfinalintMAXNUM=100;//最大容量 staticintproductNum=0; //商品種類 staticGoods[]products=newGoods[MAXNUM]; //商品名稱列表 //商品入庫 publicbooleanaddGoods(Goodsgoods){ try{ products[productNum++]=goods; //商品信息入庫 returntrue; }catch(ArrayIndexOutOfBoundsExceptione){ JOptionPane.showMessageDialog(null,"超出庫存容量上限,不能入庫!"); productNum--; } returnfalse; } //商品出庫 publicbooleanoutGoods(Goodsgoods){ //查找要修改信息的商品 inti=findProduct(goods.getName()); //商品索引號 if(i==productNum){ //沒有找到指定的商品 JOptionPane.showMessageDialog(null,"指定的商品不存在!"); returnfalse; } else{ intpro_num=goods.getNum(); //如果出庫量大于等于庫存,則輸出提示,并刪除對應(yīng)的記錄 if(pro_num>=products[i].getNum()){ JOpt
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 水電水電施工合同范本
- 建筑廉潔合同范本
- 電影主題公園的營銷策略與品牌建設(shè)
- 科技創(chuàng)新在農(nóng)業(yè)領(lǐng)域的成果轉(zhuǎn)化應(yīng)用
- 科技企業(yè)如何應(yīng)對負(fù)面網(wǎng)絡(luò)輿情
- 電子商務(wù)背景下的現(xiàn)代物流管理創(chuàng)新
- 科技企業(yè)戰(zhàn)略投資與管理案例
- 縱膈腫瘤中醫(yī)護(hù)理方案
- 科技發(fā)展與辦公效率的飛躍提升
- 科技醫(yī)療與視覺健康激光眼手術(shù)的術(shù)后保養(yǎng)
- 上海市建設(shè)工程施工圖設(shè)計(jì)文件勘察設(shè)計(jì)質(zhì)量疑難問題匯編(2024 版)
- 《康復(fù)工程學(xué)》課件-第一講 康復(fù)工程概論
- 2025年度智慧醫(yī)療服務(wù)平臺建設(shè)合同范本
- 2024項(xiàng)目管理人員安全培訓(xùn)考試題(審定)
- 2025四川宜賓市高縣縣屬國企業(yè)第一次招聘3人易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2024 年國家公務(wù)員考試《申論》(地市級)真題及答案
- 南京2025年中國醫(yī)學(xué)科學(xué)院皮膚病醫(yī)院招聘13人第二批筆試歷年典型考點(diǎn)(頻考版試卷)附帶答案詳解
- 2024年沈陽職業(yè)技術(shù)學(xué)院高職單招語文歷年參考題庫含答案解析
- 《榜樣9》觀后感心得體會一
- 2024年上海普陀區(qū)司法局招聘人民調(diào)解員考試真題
- 駕照考試題庫及答案(完整版)
評論
0/150
提交評論