Java dan pengendalian acara
Sebilangan besar program, untuk menjadi berguna, mesti bertindak balas terhadap arahan dari pengguna. Untuk melakukannya, program Java bergantung pada peristiwa yang menggambarkan tindakan pengguna.
Bulan lalu saya menunjukkan cara memasang antara muka pengguna grafik dari komponen yang disediakan oleh toolkit abstrak perpustakaan kelas Java. Setelah mengumpulkan beberapa antara muka seperti itu, saya bercakap secara ringkas mengenai topik pengendalian acara, tetapi saya berhenti daripada penerangan lengkap mengenai pengendalian acara seperti yang dilaksanakan oleh AWT. Bulan ini, kami mengambil tempat yang kami tinggalkan.
Untuk didorong oleh acara
Pada masa lalu, program yang ingin mengetahui apa yang dilakukan pengguna harus mengumpulkan maklumat itu sendiri. Dalam praktiknya ini bermaksud bahawa setelah program diinisialisasi sendiri, ia memasuki gelung besar di mana ia berulang kali melihat untuk melihat apakah pengguna melakukan sesuatu yang menarik (misalnya, menekan butang, menyentuh butang, menggerakkan slider, menggerakkan tetikus) dan kemudian mengambil tindakan yang sewajarnya. Teknik ini dikenali sebagai pengundian .
Pengundian berjaya dilakukan tetapi cenderung tidak berat sebelah apabila digunakan dalam aplikasi moden untuk dua sebab yang berkaitan: Pertama, penggunaan undian cenderung mendorong semua kod pengendalian acara ke satu lokasi (di dalam gelung besar); kedua, interaksi yang dihasilkan dalam gelung besar cenderung kompleks. Di samping itu, pengundian memerlukan program untuk terus berjalan, menghabiskan kitaran CPU, sementara menunggu pengguna melakukan sesuatu - pembaziran sumber daya yang berharga.
AWT menyelesaikan masalah ini dengan menerapkan paradigma yang berbeza, yang mendasari semua sistem tetingkap moden: pengaturcaraan berdasarkan acara. Dalam AWT, semua tindakan pengguna tergolong dalam kumpulan abstrak perkara yang disebut peristiwa . Suatu peristiwa menerangkan, dengan cukup terperinci, tindakan pengguna tertentu. Daripada program yang secara aktif mengumpulkan acara yang dihasilkan pengguna, waktu berjalan Java memberitahu program apabila peristiwa menarik berlaku. Program yang menangani interaksi pengguna dengan cara ini dikatakan berdasarkan acara .
Kelas Acara
Kelas Acara adalah pemain utama dalam permainan acara. Ia cuba menangkap ciri-ciri asas dari semua peristiwa yang dihasilkan pengguna. Jadual 1 menyenaraikan anggota data awam yang disediakan oleh Acara kelas.
Jenis | Nama | Penerangan |
Objek | sasaran | Rujukan kepada komponen yang pada mulanya menerima acara tersebut |
lama | bila | Masa di mana peristiwa itu berlaku. |
int | ID | Jenis acara (lihat bahagian Jenis Acara untuk maklumat lebih lanjut). |
int | x | Koordinat x di mana tindakan berlaku berbanding dengan komponen yang sedang memproses peristiwa tersebut. Untuk acara tertentu, koordinat x akan berubah nilainya semasa acara menaikkan hierarki komponen. Asal satah koordinat berada di sudut kiri atas komponen. |
int | y | Koordinat y di mana tindakan berlaku berbanding dengan komponen yang sedang memproses peristiwa tersebut. Untuk acara tertentu, koordinat y akan berubah nilainya semasa acara menaikkan hierarki komponen. Asal satah koordinat berada di sudut kiri atas komponen. |
int | kunci | Untuk acara papan kekunci, kekunci kekunci hanya ditekan. Nilainya biasanya akan menjadi nilai Unicode watak yang ditunjukkan oleh kunci. Kemungkinan lain termasuk nilai untuk kunci khas HOME, END, F1, F2, dan sebagainya. |
int | pengubah | Gabungan nilai-nilai SHIFT_MASK, CTRL_MASK, META_MASK, dan ALT_MASK secara aritmetik atau. Nilainya masing-masing mewakili keadaan shift, control, meta, dan alt. |
int | klikBilangan | Bilangan klik tetikus berturut-turut. Anggota data ini hanya penting dalam acara MOUSE_DOWN. |
Objek | berhujah | Hujah bergantung pada peristiwa. Untuk objek Butang, objek ini adalah objek String yang mengandungi label tekstur butang. |
Seperti yang akan saya jelaskan di bahagian yang berjudul Pengiriman dan penyebaran acara , contoh acara Kelas biasanya dibuat oleh sistem jangka waktu Java. Akan tetapi, mungkin untuk program membuat dan mengirim acara ke komponen melalui postEvent()
kaedahnya.
Jenis acara
Seperti yang disebutkan di atas, kelas Acara adalah model acara antara muka pengguna. Acara secara semula jadi tergolong dalam kategori berdasarkan jenis acara (jenis acara ditunjukkan oleh id
ahli data). Jadual 2 menyenaraikan semua peristiwa yang ditentukan oleh AWT, disusun mengikut kategori.
Ini dapat memberi pengajaran untuk melihat penjanaan peristiwa dalam tindakan. Butang dalam Gambar 1, ketika ditekan, membuat penyemak imbas acara yang memaparkan maklumat peristiwa mengenai peristiwa yang diterima oleh penyemak imbas. Kod sumber untuk penyemak imbas acara boleh didapati di sini.
Anda memerlukan penyemak imbas berkemampuan Java untuk melihat applet iniGambar 1: Penjanaan peristiwa dalam tindakan
Penghantaran dan penyebaran acara
Pertimbangkan applet dalam Rajah 2. Ini terdiri daripada dua contoh kelas Button, yang disertakan dalam instance kelas Panel. Contoh kelas Panel ini sendiri tertanam dalam contoh lain dari kelas Panel. Contoh terakhir dari kelas Panel berada di bawah contoh kelas TextArea, dan kedua-dua contoh disisipkan dalam contoh kelas Applet. Gambar 3 menunjukkan unsur-unsur yang membentuk applet ini sebagai pohon, dengan contoh TextArea dan Button sebagai daun, dan contoh Applet sebagai akar. (Untuk maklumat lebih lanjut mengenai susun atur komponen hierarki dalam antara muka pengguna, baca pengenalan AWT bulan lalu.)
Anda memerlukan penyemak imbas berkemampuan Java untuk melihat applet iniGambar 2: Kelas tertanam dalam kelas
Gambar 3: Pohon elemen applet (hierarki)
Apabila pengguna berinteraksi dengan applet dalam Gambar 2, sistem jangka masa Java membuat kejadian Event class dan mengisi anggota datanya dengan maklumat yang menerangkan tindakannya. Sistem jangka masa Java kemudian membenarkan applet untuk menangani acara tersebut. Ia dimulakan dengan komponen yang pada awalnya menerima acara (misalnya, butang yang diklik) dan bergerak ke atas pohon komponen, komponen demi komponen, hingga sampai ke wadah di bahagian atas pohon. Sepanjang perjalanan, setiap komponen berpeluang untuk mengabaikan peristiwa tersebut atau bertindak balas dengan satu (atau lebih) cara berikut:
- Ubah suai data anggota kejadian Peristiwa
- Lakukan tindakan dan lakukan beberapa pengiraan berdasarkan maklumat yang terdapat dalam acara tersebut
- Tunjukkan kepada sistem jangka masa Java bahawa acara tersebut tidak dapat disebarkan lagi
Sistem jangka masa Java menyampaikan maklumat peristiwa ke komponen melalui kaedah komponen handleEvent()
. Semua handleEvent()
kaedah yang sah mestilah dalam bentuk
acara boolean publicEvent (Acara e)
Pengendali acara memerlukan satu bahagian maklumat: rujukan ke contoh kelas Acara yang mengandungi maklumat mengenai peristiwa yang baru sahaja berlaku.
Nilai yang dikembalikan dari handleEvent()
kaedah itu penting. Ini menunjukkan kepada sistem run-time Java apakah acara telah ditangani sepenuhnya dalam pengendali acara atau tidak. Nilai benar menunjukkan bahawa acara telah ditangani dan penyebaran harus berhenti. Nilai yang salah menunjukkan bahawa peristiwa tersebut telah diabaikan, tidak dapat ditangani, atau telah ditangani dengan tidak lengkap dan harus terus berjalan di atas pohon.
Consider the following description of an imaginary user's interaction with the applet in Figure 2. The user clicks on the button labeled "One." The Java language run-time system gathers information about the event (the number of clicks, the location of the click, the time the click occurred, and the component that received the click) and packages that information in an instance of the Event class. The Java run-time system then begins at the component that was clicked (in this case, the Button labeled "One") and, via a call to the component's handleEvent()
method, offers the component a chance to react to the event. If the component does not handle the event or handles the event incompletely (indicated by a return value of false), the Java run-time system offers the Event instance to the next higher component in the tree -- in this case an instance of the Panel class. The Java run-time system continues in this manner until the event is handled or the run-time system runs out of components to try. Figure 4 illustrates the path of this event as the applet attempts to handle it.
Figure 4: The path of an event
Each component making up the applet in Figure 2 adds a line to the TextArea object that indicates it received an event. It then allows the event to propagate to the next component in the tree. Listing 1 contains the code for a typical handleEvent()
method. The complete source code for this applet is available here.
public boolean handleEvent(Event evt) { if (evt.id == Event.ACTION_EVENT) { ta.appendText("Panel " + str + " saw action...\n"); } else if (evt.id == Event.MOUSE_DOWN) { ta.appendText("Panel " + str + " saw mouse down...\n"); }
return super.handleEvent(evt); }
Listing 1: A typical handleEvent()
method
Event helper methods
The handleEvent()
method is one place a programmer can put application code for handling events. Occasionally, however, a component will only be interested in events of a certain type (for example, mouse events). In these cases, the programmer can place the code in a helper method, rather than placing it in the handleEvent()
method.
Here is a list of the helper methods available to programmers. There are no helper methods for certain types of events.
action(Event evt, Object what)
gotFocus(Event evt, Object what)
lostFocus(Event evt, Object what)
mouseEnter(Event evt, int x, int y)
mouseExit(Event evt, int x, int y)
mouseMove(Event evt, int x, int y)
mouseUp(Event evt, int x, int y)
mouseDown(Event evt, int x, int y)
mouseDrag(Event evt, int x, int y)
keyDown(Event evt, int key)
keyUp(Event evt, int key)
false to indicate that the helper method did not handle the event.
The implementation of the handleEvent()
method provided by class Component invokes each helper method. For this reason, it is important that the redefined implementations of the handleEvent()
method in derived classes always end with the statement
return super.handleEvent(e);
The code in Listing 2 illustrates this rule.
public boolean handleEvent(Event e) { if (e.target instanceof MyButton) { // do something... return true; }
return super.handleEvent(e); }
Listing 2: Rule for ending statement in handleEvent()
method
Failure to follow this simple rule will prevent the proper invocation of helper methods.
Figure 5 contains an applet that handles mouse events solely through code placed in helper methods. The source code is available here.
Event | evt | The next event in a linked list of events. |
Window events | ||
Window events are generated in response to changes in the state of a window, frame, or dialog. | ||
Event | ID | |
WINDOW_DESTROY | 201 | |
WINDOW_EXPOSE | 202 | |
WINDOW_ICONIFY | 203 | |
WINDOW_DEICONIFY | 204 | |
WINDOW_MOVED | 205 | |
Keyboard events | ||
Keyboard events are generated in response to keys pressed and released while a component has input focus. | ||
Event | ID | |
KEY_PRESS | 401 | |
KEY_RELEASE | 402 | |
KEY_ACTION | 403 | |
KEY_ACTION_RELEASE | 404 | |
Mouse events | ||
Mouse events are generated in response to mouse actions occurring within the boundary of a component. | ||
Event | ID | |
MOUSE_DOWN | 501 | |
MOUSE_UP | 502 | |
MOUSE_MOVE | 503 | |
MOUSE_ENTER | 504 | |
MOUSE_EXIT | 505 | |
MOUSE_DRAG | 506 | |
Scroll events | ||
Scroll events are generated in response to manipulation of scrollbars. | ||
Event | ID | |
SCROLL_LINE_UP | 601 | |
SCROLL_LINE_DOWN | 602 | |
SCROLL_PAGE_UP | 603 | |
SCROLL_PAGE_DOWN | 604 | |
SCROLL_ABSOLUTE | 605 | |
List events | ||
List events are generated in response to selections made to a list. | ||
Event | ID | |
LIST_SELECT | 701 | |
LIST_DESELECT | 702 | |
Miscellaneous events | ||
Miscellaneous events are generated in response to a variety of actions. | ||
Event | ID | |
ACTION_EVENT | 1001 | |
LOAD_FILE | 1002 | |
SAVE_FILE | 1003 | |
GOT_FOCUS | 1004 | |
LOST_FOCUS | 1005 |
Ketahui lebih lanjut mengenai topik ini
- Tutorial Java oleh Mary Campione dan Kathy Walrath. Versi draf dalam talian boleh didapati di //java.sun.com/tutorial/index.html.
Kisah ini, "Java dan event handling" awalnya diterbitkan oleh JavaWorld.