منبع اصلی نوشتار زیر در این لینک قرار دارد

رخداد‌ها در جاوا

Clickیکی از بازدید کننده‌های «سار»، از من خواسته که در مورد ActionListener ها توی جاوا بگم. بهانه‌ی خوبیه برای یک پست. مطالبی رو که می‌گم، عمدتن از کتاب Core Java جلد ۱ و ۲ گرفته شده و تجربه‌ی شخصیم رو کمتر توی اون دخالت می‌دم.

تمام محیط‌های عامل که از رابط گرافیکی پشتیبانی می‌کنن، به صورت دائم به رخداد‌هایی مثل کلیک شدن موس یا فشردن کلید صفحه‌کیلد نظارت می‌کنن و رخداد این عوامل رو به برنامه‌های درحال اجرا گزارش می‌دن. هر برنامه تصمیم می‌گیره که چطور به اون رخداد (مثل کلیک شدن موس) پاسخ بده (و شاید هم پاسخی در کار نباشه).

توی زبون‌هایی مثل Visual Basic رابطه‌ی بین رخداد و کد مربوط به اون کاملن مشخصه. یک کد برای یک مشخصه‌ی خاص نوشته می‌شه و اون در جایی به نام «روال رخداد» قرار داده می‌شه. کد این رول بعد از رخ دادن رخداد مورد نظر، اجرا می‌شه.

در سمت مقابل، زبون‌هایی مثل C خام، برای این کار باید به صورت مستمر باید صف رخداد‌هایی که محیط عامل گزارش داده چک بشه. این شیوه به صورت کاملن آشکار زشت و در بعضی از موارد خیلی سخت و پیچیده می‌شه.

جاوا روشی بین روش Visual Basic و C خام رو در پیش می‌گیره که قدرت بیشتر و پیچیدگی کمتری رو داره.

ما یه عنصر داریم که می‌شه منبع رخداد که به اون می‌گیم Event Source و یک شنونده‌ی که به اون می‌گیم Event Listener. وقتی از سمت منبع یک رخداد رخ می‌ده، شنونده اون رو می‌شنوه و فعالیت اقدام لازم رو انجام می‌ده. هر منبع رخداد یک سری متد داره برای ثبت کردن یک شنونده. یعنی شما باید یک شنونده رو برای یک منبع رخداد ثبت کنید تا بتونید رخداد رو به اون شنونده گزارش بدین.

همونطور که از زبون‌های شیء گرا مثل جاوا انتظار می‌ره، اطلاعات مربوط به رخداد‌ها، توی یک شیء Event کپسوله می‌شه. توی جاوا تمام شیء های رخداد سرانجام از java.util.EventObject مشتق می‌شن. البته زیر کلاس‌هایی هم برای منظور‌های مختلف مثل WindowEvent و ActionEvent وجود داره. منابع مختلف رخداد می‌تونن انواع مختلفی از اون رو به وجود بیارن. به عنوان مثال یک دکمه شیء ActionEvent رو ارسال می‌کنه در صورتی که یک پنجره شیء WindowEvent رو.

در نهایت مثال زیر یک نمونه از کنترل رخداد برای یک دکمست:

ActionListener listener = . . .;
JButton button = new JButton("Ok");
button.addActionListener(listener);

با این حساب، وقتی یک رخداد از سمت button رخ بده، listener از اون آگاه می‌شه. همونطور که ممکنه متوجه شده باشید، این یک کنترل رخداد فشردن دکمست.

برای پیاده کردن یک واسط ActionListener کلاس شنونده باید یک متد با نام actionPerformed داشته باشکه که یک شیء ActionEvent رو به عنوان پارامتر قبول کنه، کد زیر رو ببینید:

class MyListener implements ActionListener
{
    . . .
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
}

خب، حالا وقتی کاربر روی button کلیک کنه، اون یک شیء ActionEvent می‌سازه و به listener.actionPerformed می‌فرسته. اشیائی مثل JButton می‌تونن تعدادی شنونده داشته باشن که وقتی رخداد رخ می‌ده، همه از اون آگاه می‌شن.

خب، Inner Classes چیزیه که اینجا به درد می‌خوره. ما می‌تونیم به جای این که یک کلاس بسازیم برای پیاده سازی واسط مثلن ActionEvent بیایم و واسط رو هرجا که خواستیم پیاده کنیم. یعنی کد بالا اینطور می‌شه:

JButton button = new JButton("Ok");
button.addActionListener(new ActionListener()
{
    . . .
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
});

و اما یه تجربه‌ی شخصی به من می‌گه که به جای این کارا از Action استفاده بشه، هم کار زیبا تر درمیاد، هم راحت تره و هم تعمیم پذیری کار بالا می‌ره. در این مورد هم یکم توضیح بدم. در نظر بگیرید که قراره توی یه طراحی، منو باشه، پاپ‌آپ منو هم باشه، نوار ابزار هم باشه. خب ممکنه، و به احتمال زیاد، گزینه‌هایی وجود خواهد داشت که توی هر سه تای این‌ها باشه. مثلن یک ویرایشگر متن، و گزینه‌ی کپی که هم توی منوی راست‌کلیک هست، هم توی منوی Edit و هم توی نوار ابزار. رفتار هر سه‌تای این گزینه‌ها یکیه، آیکنشون هم همینطور. و وقتی مثلن برای کپی نوشته‌ای وجود نداره، باید این ۳ تا غیر فعال بشن و …

خب اگر ما ۳ تای این‌ها رو جدا جدا داشته باشیم، مدیریتشون سخت می‌شه. اما با یک Action واحد می‌شه این کار رو به راحتی انجام داد. تمرکز رو روی یک Action می‌ذاریم و بعد از اون تمام عناصر گرافیکی مربوطه ساخته می‌شه. مثال گویا تر خواهد بود:

Action action = new AbstractAction()
{
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
};
action.putValue(Action.NAME, "OK");
action.putValue(Action.SMALL_ICON, smallIcon); //The menu will use this icon
action.putValue(Action.LARGE_ICON_KEY, largeIcon); //The button will use this icon
action.putValue(Action.SHORT_DESCRIPTION, "A short description for display in a tooltip");
JButton button = new JButton (action);
JMenuItem menuItem = new JMenuItem (action);

خب به همین راحتی! در کل بحث رخداد‌ها توی جاوا بحث شیرین، مهم و جالبیه. اگر درک نشه، خیلی سخت خواهد بود! در کل کتاب Core Java, Volume I یک فصل رو بهش اختصاص داده که در مورد خیلی از رخداد‌ها مثل رخداد‌های پنجره و موس بحث شده توش.

=-=-=-=-=
Powered by
Bilbo Blogger




برچسب ها : , , , , ,