PDA

View Full Version : سوال: Swing & AWT Event Handling Patterns



bamdadd
چهارشنبه 27 آذر 1387, 11:42 صبح
سلام دوستان عزیز
من در حال مطالعه swing هستم ، سوالی که برام پیش اومده اینه که گویا در swing ما دو نوع الگو برای مدیریت رخداد ها داریم.
یکی The Modified Observer Pattern و دیگری Property Change Listener Observer Pattern که من الگو های UML هر دو را می گذارم.
از شما درخواست دارم که راجع به این دو الگو به من توضیح بدید و نحوه فعالیتش.
دوم اینکه هر کدام در چه مبحثی به کار می رود؟ و آیا یکیشون امتیازی به دیگری داره؟

خلاصه اینکه این قضیه رو نمی فهمم که گویا خیلی مهمه :قلب:

Modified Observer Pattern
http://tinypic.info/files/uyfrp9e8oy75eogqjudg_thumb.jpg (http://tinypic.info/viewer.php?file=uyfrp9e8oy75eogqjudg.jpg)

Event Delegation Sequence Diagram.

http://tinypic.info/files/nvc592zrtpr7k6a9q1dv_thumb.jpg (http://tinypic.info/viewer.php?file=nvc592zrtpr7k6a9q1dv.jpg)

Property change Listener Observer Pattern
http://tinypic.info/files/b0vbcm5ukurho6rhr7mk_thumb.jpg (http://tinypic.info/viewer.php?file=b0vbcm5ukurho6rhr7mk.jpg)

javaphantom
چهارشنبه 27 آذر 1387, 13:05 عصر
سلام دوستان عزیز
من در حال مطالعه swing هستم ، سوالی که برام پیش اومده اینه که گویا در swing ما دو نوع الگو برای مدیریت رخداد ها داریم.
یکی The Modified Observer Pattern و دیگری Property Change Listener Observer Pattern که من الگو های UML هر دو را می گذارم.
از شما درخواست دارم که راجع به این دو الگو به من توضیح بدید و نحوه فعالیتش.
دوم اینکه هر کدام در چه مبحثی به کار می رود؟ و آیا یکیشون امتیازی به دیگری داره؟

خلاصه اینکه این قضیه رو نمی فهمم که گویا خیلی مهمه :قلب:

Modified Observer Pattern
http://tinypic.info/files/uyfrp9e8oy75eogqjudg_thumb.jpg (http://tinypic.info/viewer.php?file=uyfrp9e8oy75eogqjudg.jpg)

Event Delegation Sequence Diagram.

http://tinypic.info/files/nvc592zrtpr7k6a9q1dv_thumb.jpg (http://tinypic.info/viewer.php?file=nvc592zrtpr7k6a9q1dv.jpg)

Property change Listener Observer Pattern
http://tinypic.info/files/b0vbcm5ukurho6rhr7mk_thumb.jpg (http://tinypic.info/viewer.php?file=b0vbcm5ukurho6rhr7mk.jpg)


به این می گن سوال خوب. خوندی و گیر کردی. توی swing اکثر event ها توسط متدود های add همگی قابل handle هستند که بنا بر اینکه component شما یک container باشه مثل JFrame یا اینکه یک componet معمولی مثل یک Jbutton باشه تمامی event ها قابل handle شدن هستند. از طریق متدود های fire هم می تونی چندین component رو از لحاظ مدیریت eventی کنترل کنی. مطلب و مثال در مورد event in swing زیاده پس من دیگه وارد این معقوله نمی شم و بقیه کار رو به عهده خودت می زارم.
بحثی که اینجا اشاره کردی در مورد pattern ها ست که بسیار بحث مهم و کلیدی هست. بقدری مهمه که دونستن این pattern ها برای یک برنامه نویس ساده از نون شب واجب تره. توی ایران که همه خدا هستند و اصلا نیازی به این ها ندارند.
همه برنامه نویسن و اصلا من کسی رون ندیدم که بیاد این سوالات رو مطرح کنه وشما اولین نفر هستید و جای تقدیر داره.

مهم بودن pattern ها و کلا مطلب pattern ها رو ، مطالعه و تحقیقش رو به عهده خودت می زارم. اگر توی پیاده ساز و مفهوم کار گیر کردی اون موقع پست بزار من کمکت می کنم. اما Observer pattern در جاوا. یکی از سخترین pattern ها از نظر مفهومی هست که بهت حق می دم که سردرگم بشی. بعد از اون داستان delegate ها ست که در C# عقب مونده که از جاوا کپ زده هم اومده. اما به چه درد می خوره. و چه جوری باهاش کار کنیم.

فرض کن توی یک کارخونه چندتا sensor هست که مدیریت تنظیم فشار سوپاپهایی رو داره. وقتی فشار از حد مجاز بالاتر بره باید این sensor ها سریعا به سوپاپ ها فرمان بدن تا دریچه بیشتر باز بشه تا فشار کمتری بوجود بیاد و برعکس.
حوب همطور که می بینی تنگ و گشاد شدن دریچه ها وابستگه به فشار ایجاد شده است و تشخیص اندازه فشار به sensor.
پس event صورت گرفته اندازه فشاره و مراقب کننده این مقدار اندازه sensor و چیزی که باید روی اون تغییر اعمال بشه می شه دریچه ها هستند. اینجاست که این pattern خودشو نشون می ده.

من با یک مثال ساده تر این pattern رو نشون می دم. فرض کن یک متغیر داریم که وقتی مقدار اون عوض می شه باید در جای دیگه برا ساس اون تغییر، باقی مانده اون متغیر بر ۲ حساب بشه. می خواهیم این برنامه رو از طریق این pattern انجام بدیم.


import java.util.Observable;
import java.util.Observer;

/**
*
* @author root
*/
public class MyObserver implements Observer {

public void update(Observable o, Object arg) {
if (arg instanceof Integer) {
Integer myInt = (Integer)arg;
System.out.println(myInt/2);
}
}

}
همینطور که می بینی من از interface ی که در جاوا هست به نام observer یک کلاسی ساختم که اون دائم مراقب که objectی که براش فرستاده می شه اگر از نوع integer هست بلافاصله نتیجه تقسیم بر 2 اون رو نشو بده. نقش sensor رو بازی می کنه.

import java.util.Observable;

/**
*
* @author root
*/
public class MyObesrvable extends Observable {

private int number;

public int getNumber() {
return number;
}

public void setNumber(int number) {
this.number = number;
this.setChanged();
this.notifyObservers(number);
}
}


توی این قسمت از کد کلاسی درست کردمم که از کلاس observable ارث گرفته. یک فیلد integer داره که همون مقداری ست که دائم عوض می شه و قرار بمحض تغییر کلاس قبلی وارد عمل بشه و نتیجه رو چاپ کنه. همانطور که می بینی دو تا متد دیگه توی setNumber صدا کردم که مخصوص کلاس observable هست که اولی می گه تغییر انجام شد و دومی مقدار رو می فرسه بکلاس قبلی که نوشتم که توی اون کلاس مقدار رو چک می کنم که مطمعن بشم از نوع integer هست.
پس می شه گفت number ما نقش مقدار فشار رو بازی می کنند و این کلاس نقشه سوپاپ هارو
حالا می ریم سراغ اجرا برنامه و نتیجه گیری آخر

public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
MyObserver myObserver = new MyObserver();
MyObesrvable myObesrvable = new MyObesrvable();
myObesrvable.addObserver(myObserver);
for (int i = 100; i<110; i++) {
myObesrvable.setNumber(i);
}
}

}

توی این کلاس من هم observer هم ovservable رو آماده کردم و به observable هم گفتم که کدوم کلاس مراقبش هست و در نهای هر موقع توی این حلقه که ساختم مقدار setNumber عوض می شه بلافاصله اونور بصورت automatic مشقول به کار می شه و نتیجه رو بر می گردونه.

در صورتی کلاسی که از کلاس observable ارث گرفته قبلا از کلاس دیگری ارث بگیره بحث delegate بوجود می یاد چون ما در جاوا وراثت چندگانه نداریم. می خوام خودت بگردی پیدا کنی و پیاده سازی کنی نتونستی بگو دباره کمکت می کنم. الان واقعا کلی کار دارم

bamdadd
چهارشنبه 27 آذر 1387, 14:20 عصر
خیلی ممنون واقعا! یه ذره درکش برام سخته! می فهمم کدی که نوشتی رو ولی خودم نمی تونم این طوری فکر کنم! یه 7-8 ساعت این کد هارو نگاه کنم دستم می آد!
واقعا دست درد نکنه خیلی زحمت کشیدی!
حالا منم خودم می خونم اگه مشکل بر خوردم می نویسم

bamdadd
چهارشنبه 27 آذر 1387, 14:51 عصر
مثال کتابی که من می خونم : The Defenetive Guide To Java Swing

البته بیشتر به نظر من پیاده سازی AWTEventMultiCaster جالبه !


package keytext;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class KeyTextComponent extends JComponent {
private ActionListener actionListenerList = null;
public KeyTextComponent() {
setBackground(Color.CYAN);
KeyListener internalKeyListener = new KeyAdapter() {
public void keyPressed(KeyEvent keyEvent) {
if (actionListenerList != null) {
int keyCode = keyEvent.getKeyCode();
String keyText = KeyEvent.getKeyText(keyCode);
ActionEvent actionEvent = new ActionEvent(
this,
ActionEvent.ACTION_PERFORMED,
keyText);
actionListenerList.actionPerformed(actionEvent);
}
}
};
MouseListener internalMouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent mouseEvent) {
requestFocusInWindow();
}
};
addKeyListener(internalKeyListener);
addMouseListener(internalMouseListener);
}
public void addActionListener(ActionListener actionListener) {
actionListenerList = AWTEventMulticaster.add(actionListenerList, actionListener);
}
public void removeActionListener(ActionListener actionListener) {
actionListenerList = AWTEventMulticaster.remove(actionListenerList, actionListener);
}
public boolean isFocusable() {
return true;
}
}و این کد به عنوان تستر کلاس قبلی



package keytext;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class KeyTextTester {

public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Key Text Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
KeyTextComponent keyTextComponent = new KeyTextComponent();
final JTextField textField = new JTextField();
ActionListener actionListener = new ActionListener() {

public void actionPerformed(ActionEvent actionEvent) {
String keyText = actionEvent.getActionCommand();
textField.setText(keyText);
}
};

keyTextComponent.addActionListener(actionListener) ;
frame.add(keyTextComponent, BorderLayout.CENTER);
frame.add(textField, BorderLayout.SOUTH);
frame.setSize(300, 200);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}

این کلاس هم اگه نگاه کنیم بد نیست ، جنریکه و کار کد بالا رو می شه باهاش انجام داد بدون استفاده از AWT
javax.swing.event.EventListenerList