第十章

事件處理

10.1 事件類別

MouseListener 介面

public interface MouseListener
{
   void mousePressed(MouseEvent event);
      //Called when a mouse button has been pressed on a component
   void mouseReleased(MouseEvent event);
      //Called when a mouse button has been released on a component
   void mouseClicked(MouseEvent event);
      //Called when the mouse has been clicked on a component
   void mouseEntered(MouseEvent event);
      //Called when the mouse enters a component 
   void mouseExited(MouseEvent event);
      //Called when the mouse exits a component 
}


File MouseSpy.java

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
   This listener simply prints out the listener method name
   and the x- and y-coordinate of the mouse position.
*/
public class MouseSpy implements MouseListener
{
   public void mousePressed(MouseEvent event)
   {
      System.out.println("Mouse pressed. x = "
         + event.getX() + " y = " + event.getY());
   }

   public void mouseReleased(MouseEvent event)
   {
      System.out.println("Mouse released. x = "
         + event.getX() + " y = " + event.getY());
   }

   public void mouseClicked(MouseEvent event)
   {
      System.out.println("Mouse clicked. x = "
         + event.getX() + " y = " + event.getY());
   }

   public void mouseEntered(MouseEvent event)
   {
      System.out.println("Mouse entered. x = "
         + event.getX() + " y = " + event.getY());
   }

   public void mouseExited(MouseEvent event)
   {
      System.out.println("Mouse exited. x = "
         + event.getX() + " y = " + event.getY());
   }
}


File MouseSpyApplet.java

import java.applet.Applet;

/**
   This applet installs a mouse spy. Try generating the
   five mouse event types by moving and clicking the mouse.
*/
public class MouseSpyApplet extends Applet
{
   public MouseSpyApplet()
   {
      MouseSpy listener = new MouseSpy();
      addMouseListener(listener);
   }
}



偵測滑鼠事件


10.2 處理滑鼠輸入

移動長方形的滑鼠聽候者

public MouseApplet()
{
   ...
   //add mouse press listener 
   class MousePressListener implements MouseListener
   {
      public void mousePressed(MouseEvent event)
      {
         int x = event.getX();
         int y = event.getY();
         box.setLocation(x,y);
         repaint(); 
      }
      //do-nothing methods 
      public void mouseReleased(MouseEvent event){}
      public void mouseClicked(MouseEvent event){}
      public void mouseEntered(MouseEvent event){}
      public void mouseExited(MouseEvent event){}
   }
   MouseListener listener = new MousePressListener();
   addMouseListener(listener);
}

The Mouse Applet

MouseApplet.java

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

/**
   This applet lets the user move a rectangle by clicking
   the mouse.
*/
public class MouseApplet extends Applet
{
   public MouseApplet()
   {
      // the rectangle that the paint method draws
      box = new Rectangle(BOX_X, BOX_Y,
         BOX_WIDTH, BOX_HEIGHT);

      // add mouse press listener

      class MousePressListener implements MouseListener
      {
         public void mousePressed(MouseEvent event)
         {
            int x = event.getX();
            int y = event.getY();
            box.setLocation(x, y);
            repaint();
         }

         // do-nothing methods
         public void mouseReleased(MouseEvent event) {}
         public void mouseClicked(MouseEvent event) {}
         public void mouseEntered(MouseEvent event) {}
         public void mouseExited(MouseEvent event) {}
      }

      MouseListener listener = new MousePressListener();
      addMouseListener(listener);
   }

   public void paint(Graphics g)
   {
      Graphics2D g2 = (Graphics2D)g;
      g2.draw(box);
   }

   private Rectangle box;
   private static final int BOX_X = 100;
   private static final int BOX_Y = 100;
   private static final int BOX_WIDTH = 20;
   private static final int BOX_HEIGHT = 30;
}


10.3 處理文字輸入

有控制面板的小程式


控制面板(panel)元件

按鈕聽候者

public ButtonApplet()
{
   ...
   class MoveButtonListener implements ActionListener
   {
      public void actionPerformed(ActionEvent event)
      {
         int x =Integer.parseInt(xField.getText());
         int y =Integer.parseInt(yField.getText());
         box.setLocation(x,y);
         repaint();
      }
   };
   ActionListener listener = new MoveButtonListener();
   moveButton.addActionListener(listener);
   ...
}

在面板中放置元件

File ButtonApplet.java

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
   This applet lets the user move a rectangle by specifying
   the x- and y-position of the top left corner.
*/
public class ButtonApplet extends Applet
{
   public ButtonApplet()
   {
      // the rectangle that the paint method draws
      box = new Rectangle(BOX_X, BOX_Y,
         BOX_WIDTH, BOX_HEIGHT);

      // the text fields for entering the x- and y-coordinates
      final JTextField xField = new JTextField(5);
      final JTextField yField = new JTextField(5);

      // the button to move the rectangle
      JButton moveButton = new JButton("Move",
          new ImageIcon("hand.gif"));

      class MoveButtonListener implements ActionListener
      {
         public void actionPerformed(ActionEvent event)
         {
            int x = Integer.parseInt(xField.getText());
            int y = Integer.parseInt(yField.getText());
            box.setLocation(x, y);
            repaint();
         }
      }

      ActionListener listener = new MoveButtonListener();
      moveButton.addActionListener(listener);

      // the labels for labeling the text fields
      JLabel xLabel = new JLabel("x = ");
      JLabel yLabel = new JLabel("y = ");

      // the panel for holding the user interface components
      JPanel panel = new JPanel();

      panel.add(xLabel);
      panel.add(xField);
      panel.add(yLabel);
      panel.add(yField);
      panel.add(moveButton);

      // the frame for holding the component panel
      JFrame frame = new JFrame();
      frame.setContentPane(panel);
      frame.pack();
      frame.show();
   }

   public void paint(Graphics g)
   {
      Graphics2D g2 = (Graphics2D)g;
      g2.draw(box);
   }

   private Rectangle box;
   private static final int BOX_X = 100;
   private static final int BOX_Y = 100;
   private static final int BOX_WIDTH = 20;
   private static final int BOX_HEIGHT = 30;
}

10.4 行為類似的按鈕組

有按鈕組的小程式

File ButtonApplet.java

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
   This applet lets the user move a rectangle by clicking
   on buttons labeled "Left", "Right", "Up", and "Down".
*/
public class ButtonApplet extends Applet
{
   public ButtonApplet()
   {
      // the rectangle that the paint method draws
      box = new Rectangle(BOX_X, BOX_Y,
         BOX_WIDTH, BOX_HEIGHT);

      // the panel for holding the user interface components
      JPanel panel = new JPanel();

      panel.add(makeButton("Left", -BOX_WIDTH, 0));
      panel.add(makeButton("Right", BOX_WIDTH, 0));
      panel.add(makeButton("Up", 0, -BOX_HEIGHT));
      panel.add(makeButton("Down", 0, BOX_HEIGHT));

      // the frame for holding the component panel
      JFrame frame = new JFrame();
      frame.setContentPane(panel);
      frame.pack();
      frame.show();
   }

   public void paint(Graphics g)
   {
      Graphics2D g2 = (Graphics2D)g;
      g2.draw(box);
   }

   /**
      Makes a button that moves the box.
      @param label the label to show on the button
      @param dx the amount by which to move the box in x-direction
      when the button is clicked
      @param dy the amount by which to move the box in y-direction
      when the button is clicked
      @return the button
   */
   public JButton makeButton(String label, final int dx,
      final int dy)
   {
      JButton button = new JButton(label);

      class ButtonListener implements ActionListener
      {
         public void actionPerformed(ActionEvent event)
         {
            box.translate(dx, dy);
            repaint();
         }
      }

      ButtonListener listener = new ButtonListener();
      button.addActionListener(listener);
      return button;
   }

   private Rectangle box;
   private static final int BOX_X = 100;
   private static final int BOX_Y = 100;
   private static final int BOX_WIDTH = 20;
   private static final int BOX_HEIGHT = 30;
}

10.5 框架視窗

A Frame with Two Labels


File FrameTest.java

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
   This program displays a frame with an image and a text label.
*/
public class FrameTest
{
   public static void main(String[] args)
   {
      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      JLabel iconLabel = new JLabel(new ImageIcon("world.gif"));
      JLabel textLabel = new JLabel("Hello, World!");

      JPanel panel = new JPanel();
      panel.add(iconLabel);
      panel.add(textLabel);
      frame.setContentPane(panel);

      frame.pack();
      frame.show();
   }
}

10.6 文字元件

A Text Area with Scroll Bars


The Control Panel for Adding Interest


File TextAreaTest.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
   This program shows a frame with a text area that displays
   the growth of an investment. A second frame holds a text
   field to specify the interest rate.
*/
public class TextAreaTest
{
   public static void main(String[] args)
   {
      // the application adds interest to this bank account
      final BankAccount account = new BankAccount(INITIAL_BALANCE);
      // the text area for displaying the results
      final JTextArea textArea = new JTextArea(10, 30);
      textArea.setEditable(false);
      JScrollPane scrollPane = new JScrollPane(textArea);

      // construct the frame for displaying the text area
      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setContentPane(scrollPane);
      frame.pack();
      frame.show();

      // the label and text field for entering the interest rate
      JLabel rateLabel = new JLabel("Interest Rate: ");

      final JTextField rateField = new JTextField(10);
      rateField.setText("" + DEFAULT_RATE);

      // the button to trigger the calculation
      JButton calculateButton = new JButton("Add Interest");

      class CalculateListener implements ActionListener
      {
         public void actionPerformed(ActionEvent event)
         {
            double rate = Double.parseDouble(
               rateField.getText());
            double interest = account.getBalance()
               * rate / 100;
            account.deposit(interest);
            textArea.append(account.getBalance() + "\n");
         }
      }

      ActionListener listener = new CalculateListener();
      calculateButton.addActionListener(listener);

      // the control panel that holds the input components
      JPanel controlPanel = new JPanel();
      controlPanel.add(rateLabel);
      controlPanel.add(rateField);
      controlPanel.add(calculateButton);

      // the frame to hold the control panel
      JFrame controlFrame = new JFrame();
      controlFrame.setContentPane(controlPanel);
      controlFrame.pack();
      controlFrame.show();
   }

   private static final double DEFAULT_RATE = 10;
   private static final double INITIAL_BALANCE = 1000;
}