This is an old revision of the document!
Όταν ο χρήστης πατήσει ένα πλήκτρο από το πληκτρολόγιο ή μετακινήσει το ποντίκι, ο window manager στέλνει μία ειδοποίηση (event) που σηματοδοτεί την ενέργεια που έκανε ο χρήστης. Για παράδειγμα, πατώντας με τη βοήεια του ποντικιού (αριστερό click) ένα κουμπί από το γραφικό περιβάλλον, μετακινώντας το ποντίκι πάνω στο ενεργό παράθυρο ή εισάγοντας ένα χαρακτήρα από το πληκτρολόγιο παράγεται ένα event που σηματοδοτεί την αλλαγή που έκανε ο χρήστης.
Ο window manager δημιουργεί events για κάθε απειροελάχιστη μεταβολή της θέσης του ποντικιού ή για το πάτημα ενός κουμπιού από το πληκτρολόγιο. Τα περισσότερα προγράμματα δεν τα ενδιαφέρει το σύνολο των events που παράγονται. Προκειμένου ένα πρόγραμμα να μην “βομβαρδίζεται” με πολλά διαφορετικά events τα οποία του είναι αδιάφορα θα πρέπει να θεσπίσει του δικούς του κανόνες για το ποια events το ενδιαφέρουν. Η θέσπιση των κανόνων αυτών γίνεται μέσα από αντικείμενα τύπου event listeners, τα οποία ακούν σε συγκεκριμένου τύπου events.
Θα πρέπει να τονίσουμε ότι υπάρχουν διαφορετικοί τύποι event για κάθε διαφορετικό τύπο αλληλεπίδρασης του χρήστης με το γραφικό περιβάλλον. Για παράδειγμα, η μετακίνηση του ποντικιού ή το πάτημα ενός κουμπιού από το ποντίκι παράγει ένα MouseEvent ενώ το πάτημα ενός κουμπιού ή η επιλογή ενός menu παράγει ένα ActionEvent. Επομένως, το κάθε πρόγραμμα θα πρέπει να θεσπίσει τους κατάλληλους event listeners που “πιάνουν” τα event που παράγονται από τις οντότητες του γραφικού περιβάλλοντος που μας ενδιαφέρουν. Η διαδικασία “πιασίματος” και αντίδρασης του προγράμματος σε ένα event, ονομάζεται event handling.
Όλα τα events που μας ενδιαφέρουν κληρονομούν την κλάση java.awt.AWTEvent που με τη σειρά της κληρονομεί την κλάση java.util.EventObject. Οι κλάσεις των events βρίσκονται μέσα στο πακέτο java.awt.event. Οι κυριότεροι τύποι event είναι οι εξής:
Για τον πιάσιμο των παραπάνω τύπων events, η Java ορίζει ένα σύνολο από interfaces, τα οποία τα οποία όταν υλοποιούνται από μία κλάση και συνδυαστούν με κάποιο από τα components του γραφικού περιβάλλοντος έχουν την δυνατότητα να πιάσουν συγκεκριμένους τύπους από events. Όλοι τα interfaces που μας ενδιαφέρουν είναι απόγονοι της κλάσης java.util.EventListener και βρίσκονται στο πακέτο java.awt.event
Οι κυριότεροι Event Listeners είναι οι εξής:
Παρακάτω δίνεται το παράδειγμα της κλάσης EventHandling, η οποία δημιουργεί ένα παράθυρο και “πιάνει” διάφορα events που παράγονται από το ποντίκι και το πληκτρολόγιο στα επιμέρους components της παραθυρικής εφαρμογής.
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class EventHandling extends JFrame { JFrame frame; JPanel framePanel; JPanel textFieldPanel; JButton button; JTextField actionEventTextField; JTextField keyEventTextField; JTextField mouseEventTextField; JTextField mouseMotionEventTextField; int buttonClickedCount; private static int TEXT_FIELD_SIZE = 20; public EventHandling() { frame = new JFrame("CE325 - Event Handling Demo"); //frame.setPreferredSize(new Dimension(500,180)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); button = new JButton(" Put Curson on Me! "); button.setBackground(new Color(0xe9,0xe9,0xe9)); //Border buttonBorder = BorderFactory.createEmptyBorder(15,15,15,15); Border buttonBorder = BorderFactory.createLineBorder(new Color(0xf9, 0xf9, 0xf9), 8); button.setBorder(buttonBorder); buttonClickedCount = 0; button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { buttonClickedCount++; actionEventTextField.setText("Button clicked "+buttonClickedCount+" times!"); } }); button.addMouseListener( new MouseListener() { public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { button.setText(" Now Click Me! "); } public void mouseExited(MouseEvent e) { button.setText(" Put Curson on Me! "); } public void mousePressed(MouseEvent e) { button.setText(" Release Me! "); } public void mouseReleased(MouseEvent e) { button.setText(" Press me again! "); } }); frame.addMouseListener( new MouseListener() { public void mouseClicked(MouseEvent e) { switch(e.getButton()) { case MouseEvent.BUTTON1: mouseEventTextField.setText("Clicked LEFT button at "+e.getX()+", "+e.getY()); break; case MouseEvent.BUTTON2: mouseEventTextField.setText("Clicked MIDDLE button at "+e.getX()+", "+e.getY()); break; case MouseEvent.BUTTON3: mouseEventTextField.setText("Clicked RIGHT button at "+e.getX()+", "+e.getY()); break; } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }); frame.add(button, BorderLayout.EAST); textFieldPanel = new JPanel(new GridLayout(4, 2, 3, 3)); textFieldPanel.add(new JLabel("ActionEvent:")); actionEventTextField = new JTextField("", TEXT_FIELD_SIZE); textFieldPanel.add(actionEventTextField); textFieldPanel.add(new JLabel("KeyEvent:")); keyEventTextField = new JTextField("", TEXT_FIELD_SIZE); keyEventTextField.addKeyListener( new KeyListener() { public void keyTyped(KeyEvent e) { keyEventTextField.setText("Character \""+e.getKeyChar()+"\" was pressed"); } public void keyPressed(KeyEvent e) { keyEventTextField.setText(""); } public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_SHIFT || e.getKeyCode() == KeyEvent.VK_CONTROL || e.getKeyCode() == KeyEvent.VK_ENTER ) return; String str = keyEventTextField.getText(); str = str.substring(0,str.length()-1); keyEventTextField.setText(str); } }); textFieldPanel.add(keyEventTextField); textFieldPanel.add(new JLabel("MouseEvent:")); mouseEventTextField = new JTextField("", TEXT_FIELD_SIZE); textFieldPanel.add(mouseEventTextField); textFieldPanel.add(new JLabel("MouseMotionEvent:")); mouseMotionEventTextField = new JTextField("", TEXT_FIELD_SIZE); frame.addMouseMotionListener( new MouseMotionListener() { public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { mouseMotionEventTextField.setText("Cursor position at "+e.getX()+", "+e.getY()); } }); textFieldPanel.add(mouseMotionEventTextField); frame.add(textFieldPanel, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } public static void main(String []args) { new EventHandling(); } }