====== Window Events & Window Listeners ====== Σε όλα τα προηγούμενα παραδείγματα χρησιμοποιήσαμε την μέθοδο //setDefaultCloseOperation// για τον προσδιορισμό της default συμπεριφοράς κατά το πάτημα του εικονιδίου που συνδέεται με το παράθυρο, όπως παρακάτω: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Στην πραγματικότητα αυτό που συμβαίνει κάθε φορά που πατάτε ένα από τα κουμπιά που συνδέονται με την λειτουργία του παραθύρου (στο δεξιό ή το αριστερό επάνω μέρος του παραθύρου - εξαρτάται από το λειτουργικό σύστημα) είναι ότι παράγεται ένα [[http://docs.oracle.com/javase/7/docs/api/java/awt/event/WindowEvent.html|WindowEvent]]. Ένα //event// αυτού του τύπου μπορείτε να το λάβετε φτιάχνοντας ένα αντικείμενο του τύπου [[http://docs.oracle.com/javase/7/docs/api/java/awt/event/WindowListener.html|WindowListener]] και συνδέοντας το JFrame του παραθύρου με το αντικείμενο αυτό μέσω της μεθόδου //setWindowListener()//. Οι μέθοδοι του interface //WindowListener// είναι οι παρακάτω: void windowActivated(WindowEvent e) //Invoked when the Window is set to be the active Window. void windowClosed(WindowEvent e) //Invoked when a window has been closed as the result of calling dispose on the window. void windowClosing(WindowEvent e) //Invoked when the user attempts to close the window from the window's system menu. void windowDeactivated(WindowEvent e) //Invoked when a Window is no longer the active Window. void windowDeiconified(WindowEvent e) //Invoked when a window is changed from a minimized to a normal state. void windowIconified(WindowEvent e) //Invoked when a window is changed from a normal to a minimized state. void windowOpened(WindowEvent e) //Invoked the first time a window is made visible. Όταν πατάτε το εικονίδιο σμίκρυνσης του παραθύρου ή πατάτε το συνδυασμό πλήκτρων //ALT+TAB// τότε παράθυρο φεύγει από το προσκήνιο. Αντίστοιχα, αν το επιλέξετε και πάλι ή αν πατήσετε ξανά //ALT+TAB// τότε το παράθυρο επανέρχεται. Στην πρώτη περίπτωση, το παράθυρο έχασε το focus, ενώ στην δεύτερη το ανάκτησε. Για την παρακολούθηση των γεγονότων αυτών υπάρχει ένας επιπλέον τύπος Listener, o [[http://docs.oracle.com/javase/7/docs/api/java/awt/event/WindowFocusListener.html|WindowFocusListener]] που λαμβάνει την μεταβολή των παραπάνω δύο καταστάσεων κάθε παραθύρου. Οι μέθοδοι που υποστηρίζει ο παραπάνω τύπος Listener είναι οι παρακάτω. void windowGainedFocus(WindowEvent e) //Invoked when the Window is set to be the focused Window, which means that the Window, or one of its subcomponents, will receive keyboard events. void windowLostFocus(WindowEvent e) //Invoked when the Window is no longer the focused Window, which means that keyboard events will no longer be delivered to the Window or any of its subcomponents. Δείτε το παρακάτω παράδειγμα (από το site της Oracle) το οποίο συνοψίζει την χρήση των παραπάνω δύο interfaces. package events; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class WindowEventDemo extends JFrame implements WindowListener, WindowFocusListener { static final String newline = System.getProperty("line.separator"); static final String space = " "; static WindowEventDemo frame = new WindowEventDemo("WindowEventDemo"); JTextArea display; public static void main(String[] args) { /* Use an appropriate Look and Feel */ try { //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); //UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } catch (UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } /* Turn off metal's use of bold fonts */ UIManager.put("swing.boldMetal", Boolean.FALSE); //Schedule a job for the event dispatch thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //Set up the content pane. frame.addComponentsToPane(); //Display the window. frame.pack(); frame.setVisible(true); } private void addComponentsToPane() { display = new JTextArea(); display.setEditable(false); JScrollPane scrollPane = new JScrollPane(display); scrollPane.setPreferredSize(new Dimension(500, 450)); getContentPane().add(scrollPane, BorderLayout.CENTER); addWindowListener(this); addWindowFocusListener(this); } public WindowEventDemo(String name) { super(name); } public void windowClosing(WindowEvent e) { displayMessage("WindowListener method called: windowClosing."); //A pause so user can see the message before //the window actually closes. ActionListener task = new ActionListener() { boolean alreadyDisposed = false; public void actionPerformed(ActionEvent e) { if (frame.isDisplayable()) { alreadyDisposed = true; frame.dispose(); } } }; Timer timer = new Timer(500, task); //fire every half second timer.setInitialDelay(2000); //first delay 2 seconds timer.setRepeats(false); timer.start(); } public void windowClosed(WindowEvent e) { //This will only be seen on standard output. displayMessage("WindowListener method called: windowClosed."); } public void windowOpened(WindowEvent e) { displayMessage("WindowListener method called: windowOpened."); } public void windowIconified(WindowEvent e) { displayMessage("WindowListener method called: windowIconified."); } public void windowDeiconified(WindowEvent e) { displayMessage("WindowListener method called: windowDeiconified."); } public void windowActivated(WindowEvent e) { displayMessage("WindowListener method called: windowActivated."); } public void windowDeactivated(WindowEvent e) { displayMessage("WindowListener method called: windowDeactivated."); } public void windowGainedFocus(WindowEvent e) { displayMessage("WindowFocusListener method called: windowGainedFocus."); } public void windowLostFocus(WindowEvent e) { displayMessage("WindowFocusListener method called: windowLostFocus."); } private void displayMessage(String msg) { display.append(msg + newline); System.out.println(msg); } }