مترجم:حبیب الله علیخانی
منبع:راسخون
منبع:راسخون
رویداد (Event)
ایجاد یک رابط گرافیکی کاربر (GUI) با استفاده از فرم های ویندوزی تا حد زیادی به پاسخ دادن به رویداد ها بستگی دارد. به همین علت برنامه نویسی برای ویندوز عموما به عنوان برنامه نویسی رویداد گرا شناخته می شود. همانطور که در قسمت های Swing مشاهده کردید، برای ایجاد یک فرم با استفاده از ماوس، کنترل های مورد نظرتان را بر روی یک فرم خالی که در بخش Design است قرار می دهید. هر کدام از این کنترل ها می توانند به شما بگویند که چه زمانی یک رویداد رخ می دهد. برای مثال اگر یک برنامه را اجرا کنید و بر روی دکمه ای که روی فرم قرار دارد کلیک کنید آن دکمه، رویداد کلیک را به برنامه اطلاع می دهد. بنابراین این فرصت به شما داده می شود که کدهایی را در برنامه مشخص کنید تا با کلیک کردن بر روی دکمه اجرا شوند.با هر یک از کنشهای کاربر در زمان کار با رابطهای گرافیکی کاربر، رویدادهای متعددی از طرف اجزای گرافیکی رابط کاربر تولید و یا صادر می شود. به عنوان مثال قرار گرفتن اشاره گر ماوس روی یک کلید (بدون فشرده شدن کلیدهای ماوس)، خارج شدن اشارهگر ماوس از محدوده همان کلید، پایین رفتن کلید سمت چپ در زمانی که اشاره گر در محدود هندسی کلید قرار دارد(press) و یا بالا آمدن کلید پس از کلیک شدن آن کلید(release)، نمونههایی از رویدادهای بسیار متعددی هستند که برنامه نویس تنها در برابر برخی از آنها تصمیم میگیرد تا واکنشهای مناسبی طراحی کند.
نکته دیگر آن است که کنشهای کاربر در برخورد با رابطهای گرافیکی تنها عامل تولید یا صدور بخشی از رویدادها هستند و بسیاری از رویدادهای دیگر در برابر کنش و واکنشهای درونی سختافزار تولید می شوند، مثلاً اتصال یک دستگاه چاپگر به درگاه موازی یا USB یک دستگاه کامپیوتر موجب تولید رویداد خواهد شد.
ما در این مقاله به رویدادهایی که بر اثر کنشهای کاربر در برابر رابطهای گرافیکی نرم افزارها تولید می شوند می پردازیم. بهطور کلی برنامه نویسان در محیطهای برنامه نویسی گوناگون میتوانند با انتخاب یکی از اشیای رابط کاربر در زمان طراحی نرمافزار خود برای هر یک از رویدادهای تولید شده توسط آن شی گرافیکی قطعات کد هدفداری بنویسند.
بهطور کلی در زبان جاوا هر شی رابط گرافیکی که بتواند رویداد تولید نماید، یک منبع نام دارد.
منابع رویداد متد هایی دارند که به شما اجاره می دهند تا با آنها گوش دهنده ی(listeners) رویداد را ثبت کنید. وقتی رویدادی برای منبع اتفاق می افتد، منبع یک اخطار یا پیام به همه ی اشیا گوش دهنده ی (listeners) که برای آن رویداد ثبت شده بود، می فرستد.
Event ها یا رویداد ها همان متد ها هستند اما پیاده سازی نشده اند (Method not Implemented). در واقع رویدادهای اشیا یک Interface می باشند چون نباید پیاده سازی شوند.
همانگونه که انتظار می رود در یک زبان شی گرا مانند جاوا، اطلاعات درباره ی رویداد در یک شی رویداد کپسوله سازی می شود. در جاوا همه ی اشیا رویداد، سرانجام از کلاس java.util.EventObject. مشتق می شوند. البته برای هر نوع رویداد زیرکلاسهایی وجود دارد مانند ActionEvent و WindowEvent .
منابع رویداد مختلف انواع مختلف رویداد را تولید می کنند. برای مثال یک Button می تواند شی ActionEvent را بفرستد در حالیکه یک پنجره می تواند شی WindowEvent را بفرستد.
ActionListener listener = . . .;
JButton button = new JButton("Ok");
button.addActionListener(listener);
اکنون شی listener زمانی که یک کنش رویداد("action event") در button اتفاق می افتد، را اعلام می کند. یکی از کنش های رویداد، کلیک کردن آن است. کد های بالا به کلاسی نیاز دارند که یک Interface خاص را با کلمه ی کلیدی implement به ارث می برد و شی listener را شامل می شوند(interface این مورد ActionListener می باشد).JButton button = new JButton("Ok");
button.addActionListener(listener);
برای implement کردن اینترفیس ActionListener (ارث بری از اینترفیس ActionListener )، کلاس listener باید متدی به نام actionPerformed (که یک شی ActionEvent را به عنوان پارامتر ورودی دریافت می کند) داشته باشد.
class MyListener implements ActionListener
{ . . .
public void actionPerformed(ActionEvent event)
{
// reaction to button click goes here
. . .
}}
وقتی که کاربر روی دکمه (button) کلیک می کند، شی JButton یک شی ActionEvent می سازد و listener.actionPerformed(event) (که آن شی رویداد را پاس می دهد) را فراخوانی می کند.{ . . .
public void actionPerformed(ActionEvent event)
{
// reaction to button click goes here
. . .
}}
تصویر زیر تعامل بین منبع رویداد، listener رویداد و شی رویداد(event source, event listener, event object ) را نشان می دهد:
پروژه جدید ایجاد می کنیم و کد های زیر را که ادامه ی پروژه ی chapter-15-estandard JFrame است را دریک کلاس، در این پروژه، وارد می کنیم:
اینترفیسی که تمامی رویداد های پنجره را دریافت می کند windowlistener است. لیست متد های آن در زیر آمده است:
windowClosed: وقتی پنجره بسته می شود.
windowClosing: وقتی پنجره در حال بسته شدن است.
windowDeactivated: وقتی پنجره غیر فعال می شود.
windowDeiconified: وقتی پنجره از حالت minimize به حالت نرمال تغییر می کند.
windowIconified: وقتی پنجره از حالت نرمال به حالت minimize تغییر می کند.
windowOpened: وقتی پنجره باز می شود.
در ادامه ی پروژه ی بالا، می خواهیم کاری کنیم که به محض اینکه کاربر وارد پروژه می شود وهمچنین خارج می شود پیغام خاصی دهد.
به طور خلاصه کلاسها و متد های پروژه در زیر آمده ( با کلیک علامت + کد های آن بخش را نشان می دهد):
اکنون برای رویداد های پنجره باید کلاسی بسازیم تا از اینترفیس windowlistener، empelement شود. این کلاس را در انتهای کد های بالا می نویسیم:
49 public class Windowlistener implements WindowListener
به محض اینکه کد بالا نوشته می شود، یک hint ظاهر می شود که می گوید این کلاس abstract نیست و متد abstract ندارد.قبل از هر کاری ابتدا مطلبی را اضافه می کنیم:
برای نمایش پیام در جاوا از متد) JOptionPane.showMessageDialog(rootPane, e استفاده می کنیم که پارامتر اول را null و پارامتر دوم پیام مورد نظر را وارد می کنیم.
کد های مربوط به این قسمت را در خطوط 54 تا 60 می بینید.
اما برای اینکه این رویداد را انتصاب دهیم، ابتدا از کلاس MyWindowlistener یک نمونه به نام winevent می سازیم و سپس آن را به فرم اضافه می کنیم. این کار ها را در متد سازنده ی کلاس event انجام می دهیم. کد های مربوط به این قسمت را هم در خطوط 21 و 22 می بینید.
به محض اینکه پروژه را run می کنیم، به غیر از فرم قرمز رنگ، پیام "به سایت راسخون خوش آمدید" هم ظاهر می شود:
Public void actionPerformed(ActionEvent event)
نکته : ActionListener ای که ما در مثال استفاده کردیم، به کلیک کردن دکمه محدود نمی شود و در جا های زیادی استفاده می شود.
Public void actionPerformed(ActionEvent event)
{
// set panel background color . . .
}
private Color backgroundColor;
}
سپس یک (شی)action مثلا به نام yellowAction، برای هر رنگ می سازیم و هر (شی)action را به هر دکمه نسبت می دهیم (با استفاده از addActionListener) :{
// set panel background color . . .
}
private Color backgroundColor;
}
58 ColorAction yellowAction = new ColorAction(Color.YELLOW);
59 ColorAction blueAction = new ColorAction(Color.BLUE);
60 ColorAction redAction = new ColorAction(Color.RED);
64 yellowButton.addActionListener(yellowAction);
65 blueButton.addActionListener(blueAction);
66 redButton.addActionListener(redAction);
67 }
اگر یک کاربر برای مثال روی دکمه ی "Yellow" کلیک کند، متد actionPerformed با پارامتر ورودی yellowAction (که یک event است)، فراخوانی می شود:59 ColorAction blueAction = new ColorAction(Color.BLUE);
60 ColorAction redAction = new ColorAction(Color.RED);
64 yellowButton.addActionListener(yellowAction);
65 blueButton.addActionListener(blueAction);
66 redButton.addActionListener(redAction);
67 }
public void actionPerformed(ActionEvent event)
و backgroundColor با Color.YELLOW جایگزین می شود و با متد setBackground رنگ پس زمینه ی پنل را تغییرمی دهد.
setBackground(backgroundColor);
فقط این موضوع می ماند که شی ColorAction نمی تواند به متغییر panel دسترسی داشته باشد. شما این مشکل را با دو روش می توانید حل کنید. می توانید پنل را در ColorAction ذخیره کنید و در سازنده ی ColorAction قرار دهید ویا به طور ساده تر، می توانید ColorAction را به عنوان یک کلاس داخلی کلاس ButtonPanel بسازید. این روش می تواند به طور اتوماتیک به پنل خارجی دسترسی داشته باشد.ما از آخرین روش پیروی می کنیم. در زیر نشان می دهیم که چگونه کلاس ColorAction را داخل کلاس ButtonPanel قرار می دهیم:
class ButtonPanel extends JPanel
{
. . .
private class ColorAction implements ActionListener
{
. . .
public void actionPerformed(ActionEvent event)
{
setBackground(backgroundColor);
// i.e., outer.setBackground(...)
}
private Color backgroundColor;
}
}
در زیر یک برنامه ی کامل را آورده ایم. وقتی شما روی یکی از دکمه ها کلیک می کنید، action listener مخصوص به آن رنگ پس زمینه ی پنل را تغییر می دهد:{
. . .
private class ColorAction implements ActionListener
{
. . .
public void actionPerformed(ActionEvent event)
{
setBackground(backgroundColor);
// i.e., outer.setBackground(...)
}
private Color backgroundColor;
}
}
/ج