Java Tutorial/Swing Event/Event

Материал из Java эксперт
Перейти к: навигация, поиск

ActionEvent Example with One Button That Demonstrates Sources, Events, and Their Listeners

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
class ButtonListener implements ActionListener {
  public void actionPerformed(ActionEvent ae) {
    Toolkit.getDefaultToolkit().beep();
  }
}
public class UseActionListener {
  public static void main(String[] a) {
    JFrame frame = new JFrame("Popup JComboBox");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JButton source = new JButton("Ring the bell!");
    source.addActionListener(new ButtonListener());
    frame.add(source, BorderLayout.SOUTH);
    source.addActionListener(new ButtonListener());
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}





Creating a Custom Event

import java.util.EventListener;
import java.util.EventObject;
import javax.swing.event.EventListenerList;
class MyEvent extends EventObject {
  public MyEvent(Object source) {
    super(source);
  }
}
interface MyEventListener extends EventListener {
  public void myEventOccurred(MyEvent evt);
}
class MyClass {
  protected EventListenerList listenerList = new EventListenerList();
  public void addMyEventListener(MyEventListener listener) {
    listenerList.add(MyEventListener.class, listener);
  }
  public void removeMyEventListener(MyEventListener listener) {
    listenerList.remove(MyEventListener.class, listener);
  }
  void fireMyEvent(MyEvent evt) {
    Object[] listeners = listenerList.getListenerList();
    for (int i = 0; i < listeners.length; i = i+2) {
      if (listeners[i] == MyEventListener.class) {
        ((MyEventListener) listeners[i+1]).myEventOccurred(evt);
      }
    }
  }
}
public class Main {
  public static void main(String[] argv) throws Exception {
    MyClass c = new MyClass();
    c.addMyEventListener(new MyEventListener() {
      public void myEventOccurred(MyEvent evt) {
        System.out.println("fired");
      }
    });
  }
}





Enabling Other Low-level Events

processWindowFocusEvent(WindowEvent e)called for any window focus events that arise as long as such events are enabled for the window.processWindowStateEvent(WindowEvent e)called for events arising as a result of the window changing state.processEvent(AWTEvent e)called first for any events that are enabled for the component. If you implement this method and fail to call the base class method, none of the methods for specific groups of events will be called.processFocusEvent(FocusEvent e)called for focus events, if they are enabled for the component.processKeyEvent(KeyEvent e)called for key events, if they are enabled for the component.processMouseEvent(MouseEvent e)called for mouse button events, if they are enabled for the component.processMouseMotionEvent(MouseEvent e)called for mouse move and drag events, if they are enabled for the component.processMouseWheelEvent(MouseWheelEvent e)called for mouse wheel rotation events, if they are enabled for the component.


Event mask

public void mousePressed(MouseEvent mouseEvent) {
      int modifiers = mouseEvent.getModifiers();
      if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {
        System.out.println("Middle button pressed.");
      }
    }





Event object has information about an event, that has happened.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class EventObject {
  public static void main(String[] args) {
    JFrame f = new JFrame();
    JButton ok = new JButton("Ok");
    ok.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(event.getWhen());
        Locale locale = Locale.getDefault();
        String s = DateFormat.getTimeInstance(DateFormat.SHORT, locale).format(new Date());
        if (event.getID() == ActionEvent.ACTION_PERFORMED)
          System.out.println(" Event Id: ACTION_PERFORMED");
        System.out.println(" Time: " + s);
        String source = event.getSource().getClass().getName();
        System.out.println(" Source: " + source);
        int mod = event.getModifiers();
        if ((mod & ActionEvent.ALT_MASK) > 0)
          System.out.println("Alt ");
        if ((mod & ActionEvent.SHIFT_MASK) > 0)
          System.out.println("Shift ");
        if ((mod & ActionEvent.META_MASK) > 0)
          System.out.println("Meta ");
        if ((mod & ActionEvent.CTRL_MASK) > 0)
          System.out.println("Ctrl ");
      }
    });
    f.add(ok);
    f.setSize(420, 250);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}





Event source and listener

import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
abstract class TestEventSource {
  public abstract void addListener(TestEventListener l);
  public abstract void removeListener(TestEventListener l);
  public abstract void fireEvent(java.util.EventObject o);
  public void test() {
    addListener(new TestEventListener("A"));
    fireEvent(new java.util.EventObject(this));
  }
}
class TestEventListener implements EventListener {
  String id;
  public TestEventListener(String id) {
    this.id = id;
  }
  public void handleEvent(EventObject o) {
    System.out.println(id + " called");
    if (id.equals("C")) {
      ((TestEventSource) o.getSource()).removeListener(this);
    }
  }
}
public class Main extends TestEventSource {
  ArrayList listeners = new ArrayList();
  public void addListener(TestEventListener l) {
    listeners.add(l);
  }
  public void removeListener(TestEventListener l) {
    listeners.remove(l);
  }
  public void fireEvent(EventObject o) {
    for (int i = 0; i < listeners.size(); i++) {
      TestEventListener l = (TestEventListener) listeners.get(i);
      l.handleEvent(o);
    }
  }
  public static void main(String[] args) {
    Main pfles = new Main();
    pfles.test();
  }
}





implements AWTEventListener

import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ruponentEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
public class Main implements AWTEventListener {
  public void eventDispatched(AWTEvent evt) {
    if (evt.getID() == WindowEvent.WINDOW_OPENED) {
      ComponentEvent cev = (ComponentEvent) evt;
      if (cev.getComponent() instanceof JFrame) {
        System.out.println("event: " + evt);
        JFrame frame = (JFrame) cev.getComponent();
        loadSettings(frame);
      }
    }
  }
  public static void loadSettings(JFrame frame) {
    System.out.println("loading");
  }
  public static void saveSettings() {
    System.out.println("saving");
  }
  public static void main(String[] args) throws Exception {
    Toolkit tk = Toolkit.getDefaultToolkit();
    final Main main = new Main();
    tk.addAWTEventListener(main, AWTEvent.WINDOW_EVENT_MASK);
    final JFrame frame = new JFrame("");
    frame.setName("your frame");
    JMenuBar mb = new JMenuBar();
    JMenu menu = new JMenu("File");
    menu.add(new AbstractAction("Quit") {
      public void actionPerformed(ActionEvent evt) {
        try {
          main.saveSettings();
          System.exit(0);
        } catch (Exception ex) {
          System.out.println(ex);
        }
      }
    });
    mb.add(menu);
    frame.setJMenuBar(mb);
    frame.pack();
    frame.setVisible(true);
  }
}





In the event model, there are three participants

In the event model, there are three participants:

  1. The event source, the object whose state changes.
  2. The event object, encapsulates the state changes in the event source.
  3. The event listener, the object that wants to be notified.


int java.awt.AWTEvent.getID()

import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ruponentEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
public class Main implements AWTEventListener {
  public void eventDispatched(AWTEvent evt) {
    if (evt.getID() == WindowEvent.WINDOW_OPENED) {
      ComponentEvent cev = (ComponentEvent) evt;
      if (cev.getComponent() instanceof JFrame) {
        System.out.println("event: " + evt);
        JFrame frame = (JFrame) cev.getComponent();
        loadSettings(frame);
      }
    }
  }
  public static void loadSettings(JFrame frame) {
    System.out.println("loading");
  }
  public static void saveSettings() {
    System.out.println("saving");
  }
  public static void main(String[] args) throws Exception {
    Toolkit tk = Toolkit.getDefaultToolkit();
    final Main main = new Main();
    tk.addAWTEventListener(main, AWTEvent.WINDOW_EVENT_MASK);
    final JFrame frame = new JFrame("");
    frame.setName("your frame");
    JMenuBar mb = new JMenuBar();
    JMenu menu = new JMenu("File");
    menu.add(new AbstractAction("Quit") {
      public void actionPerformed(ActionEvent evt) {
        try {
          main.saveSettings();
          System.exit(0);
        } catch (Exception ex) {
          System.out.println(ex);
        }
      }
    });
    mb.add(menu);
    frame.setJMenuBar(mb);
    frame.pack();
    frame.setVisible(true);
  }
}





Managing Listener Lists with AWTEventMulticaster

import java.awt.AWTEventMulticaster;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
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;
  }
  public static void main(String[] a){
    JFrame frame = new JFrame("Key Text Sample");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    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);
    textField.setText("Press keyboard after clicking the above blank area");
    frame.add(textField, BorderLayout.SOUTH);
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}





Managing Listener Lists with EventListenerList

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.event.EventListenerList;
class KeyTextComponent extends JComponent {
  private EventListenerList actionListenerList = new EventListenerList();
  public KeyTextComponent() {
    KeyListener internalKeyListener = new KeyAdapter() {
      public void keyPressed(KeyEvent keyEvent) {
        System.out.println("keyPressed");
        if (actionListenerList != null) {
          int keyCode = keyEvent.getKeyCode();
          String keyText = KeyEvent.getKeyText(keyCode);
          ActionEvent actionEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, keyText);
          fireActionPerformed(actionEvent);
        }
      }
    };
    MouseListener internalMouseListener = new MouseAdapter() {
      public void mousePressed(MouseEvent mouseEvent) {
        requestFocusInWindow();
      }
    };
    addKeyListener(internalKeyListener);
    addMouseListener(internalMouseListener);
  }
  public void addActionListener(ActionListener actionListener) {
    actionListenerList.add(ActionListener.class, actionListener);
  }
  public void removeActionListener(ActionListener actionListener) {
    actionListenerList.remove(ActionListener.class, actionListener);
  }
  protected void fireActionPerformed(ActionEvent actionEvent) {
    EventListener listenerList[] = actionListenerList.getListeners(ActionListener.class);
    for (int i = 0, n = listenerList.length; i < n; i++) {
      ((ActionListener) listenerList[i]).actionPerformed(actionEvent);
    }
  }
  public boolean isFocusable() {
    return true;
  }
}
public class KeyTextComponentDemo {
  public static void main(String[] args) {
    JFrame aWindow = new JFrame();
    aWindow.setBounds(30, 30, 300, 300); // Size
    aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    KeyTextComponent com = new KeyTextComponent();
    aWindow.add(com, "Center");
    com.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("action");
      }
    });
    aWindow.add(new JTextField(), "South");
    aWindow.setVisible(true); // Display the window
  }
}





Process On Swing Event Thread

/*
 * Copyright (C) 2001-2004 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
/**
 * Common GUI utilities accessed via static methods.
 * 
 * @author 
 */
public class GUIUtils {

  public static void processOnSwingEventThread(Runnable todo) {
    processOnSwingEventThread(todo, false);
  }
  public static void processOnSwingEventThread(Runnable todo, boolean wait) {
    if (todo == null) {
      throw new IllegalArgumentException("Runnable == null");
    }
    if (wait) {
      if (SwingUtilities.isEventDispatchThread()) {
        todo.run();
      } else {
        try {
          SwingUtilities.invokeAndWait(todo);
        } catch (Exception ex) {
          throw new RuntimeException(ex);
        }
      }
    } else {
      if (SwingUtilities.isEventDispatchThread()) {
        todo.run();
      } else {
        SwingUtilities.invokeLater(todo);
      }
    }
  }
}





Semantic Event Listeners

Listener InterfaceMethodActionListenervoid actionPerformed(ActionEvent e)ItemListenervoid itemStateChanged(ItemEvent e)AdjustmentListenervoid adjustmentValueChanged(AdjustmentEvent e)


Semantic Events

Event TypeProduced by Objects of TypeActionEventJButton, JToggleButton, JcheckBox, JMenuItem, JMenu, JCheckBoxMenuItem, JradioButtonMenuItem, JTextFieldItemEventJButton, JToggleButton, JcheckBox, JMenuItem, JMenu, JCheckBoxMenuItem, JRadioButtonMenuItemAdjustmentEventJScrollbar


Subclasses of AWTEvent

ClassPurposeActionEventThis is an event that indicates a component-defined action occurred, such as clicking a button.AdjustmentEventemitted by adjustable objectsAncestorEventIt tells a child component that an event occurred with one of the parent components.ruponentEventindicates a component moved, changed size, became visible or invisible, etc. This event is for notification purposes only.HierarchyEventThis event indicates some change to the component hierarchy to which a component belongs.InputMethodEventThis event fires when text is entered into an appropriate component. Anytime the text changes, for any reason, the input method sends an event.InternalFrameEventIt is an AWTEvent that adds support for JInternalFrame objects as the event source. It has the same event types as WindowEvent.InvocationEventThis event will execute the run() method on a Runnable when dispatched by the AWT event dispatcher thread.ItemEventThis event indicates that an item was selected or deselected. You will see this associated frequently with list boxes.TextEventThis event indicates that an object"s text changed.


Writing a Listener as an Anonymous Class

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class ActionListenerTest3 {
  public static void main(String[] args) {
    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JButton button = new JButton("Select File");
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JFileChooser fileChooser = new JFileChooser();
        int returnVal = fileChooser.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
          System.out.println(fileChooser.getSelectedFile().getName());
        }
      }
    });
    frame.add(button);
    frame.pack();
    frame.setVisible(true);
  }
}





Writing a listener as a nested class

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class ActionListenerTest2 {
  public static void main(String[] args) {
    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JButton button = new JButton("Select File");
    button.addActionListener(new MyActionListener());
    frame.add(button);
    frame.pack();
    frame.setVisible(true);
  }
}
class MyActionListener implements ActionListener {
  public void actionPerformed(ActionEvent e) {
    JFileChooser fileChooser = new JFileChooser();
    int returnVal = fileChooser.showOpenDialog(null);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      System.out.print(fileChooser.getSelectedFile().getName());
    }
  }
}