李曉菁201771010114《面向對象程序設計(java)》第十三週學習總結

理論知識:事件處理java

1.事件源:可以產生事件的對象均可以成爲事件源,如文本框,按鈕等。一個事件源是一個可以註冊監聽器並向監聽器發送事件對象的對象。程序員

2.事件監聽器:事件監聽器對象接收事件源發送的通告(事件對象),並對發生的事件做出響應。一個監聽器對象就是一個實現了專門監聽器接口的類實例,該類必須實現接口中的方法,這些方法當事件發生時,被自動執行。編程

3.事件對象:Java將事件的相關信息封裝在一個事件對象中,全部的事件對象都最終被派生於Java.util.EventObject類。不一樣的事件源能夠產生不一樣類別的事件。數組

2.AWT事件處理機制的概要;安全

監聽器對象 :是一個實現了特定監聽器接口 ( listener interface )的類實例 。網絡

當事件發生時,事件源將事件對象自動傳遞給全部註冊的監聽器 。多線程

監聽器對象利用事件對象中的信息決定如何對事件作出響應。框架

 3.事件源與監聽器之間的關係:dom

 

4.GUI設計中,程序員須要對組件的某種事件進行響應和處理時,必須完成兩個步驟;ide

(1)定義實現某事件監聽器接口的事件監聽器類,並具體化接口中聲明的事件的處理抽象方法。

(2)爲組件註冊實現了規定接口的事件監聽器對象;

5.註冊監聽器方法:eventSourceObject.addEventListener(eventListenerObject)

 6.動態事件:當特定組件動做(點擊按鈕)發生時,該組件生成此動做事件。

該事件被傳遞給組件註冊的每個ActionListener對象,並調用監聽器對象的actionPerformed方法以接受這類事件對象。

可以觸發事件動做的動做,主要包括:

(1)點擊按鈕

(2)雙擊一個列表中的選項

(3)選擇菜單項

(4)在文本框中輸入回車

7.監聽器接口的實現

監聽器類必須實現與事件源相對應的接口,即必須提供接口中方法的實現。

監聽器接口的方法實現

class MyListener implenments ActionListener

{

    public void actionPerformed(ActionEvent event)

{......}

}

8.命令按鈕Jbutton主要API

(1)建立按鈕對象

Jbutton類經常使用的一組構造方法;

(1) JButton(String text):建立一個帶文本的按鈕。
(2) JButton(Icon icon) :建立一個帶圖標的按鈕。
(3)JButton(String text, Icon icon) :建立一個帶文本和圖標
的按鈕

(2)按鈕對象的經常使用方法:

① getLabel( ):返回按鈕的標籤字符串;
② setLabel(String s):設置按鈕的標籤爲字符串s。

9. 用匿名類、lambda表達式簡化程序

例ButtonTest.java中,各按鈕須要一樣的處理:
1) 使用字符串構造按鈕對象;
2) 把按鈕添加到面板上;
3) 用對應的顏色構造一個動做監聽器;
4) 註冊動做監聽器

10.適配器類

當程序用戶試圖關閉一個框架窗口時,Jframe
對象就是WindowEvent的事件源。
⚫ 捕獲窗口事件的監聽器:

WindowListener listener=…..;
frame.addWindowListener(listener);
⚫ 窗口監聽器必須是實現WindowListener接口的
類的一個對象,WindowListener接口中有七個
方法,它們的名字是自解釋的。

11.鑑於代碼簡化的要求,對於有不止一個方法的AWT監聽器接口都有一個實現了它的全部方法,但卻

不作任何工做的適配器類。
例:WindowAdapter類。

適配器類動態地知足了Java中實現監視器類的技術要求。

⚫ 經過擴展適配器類來實現窗口事件須要的動做

12.註冊事件監聽器

可將一個Terminator對象註冊爲事件監聽器:
WindowListener listener=new Terminator();
frame.addWindowListener(listener);
⚫ 只要框架產生一個窗口事件,該事件就會傳遞給
監聽器對象。

建立擴展於WindowAdapter的監聽器類是很好的
改進,但還能夠進一步將上面語句也可簡化爲:
frame.addWindowListener(new Terminator());

13.動做事件

(1)激活一個命令能夠有多種方式,如用戶能夠經過
菜單、擊鍵或工具欄上的按鈕選擇特定的功能。
(2)在AWT事件模型中,不管是經過哪一種方式下達命
令(如:點擊按鈕、菜單選項、按下鍵盤),其
操做動做都是同樣的。

14.動做接口及其類

Swing包提供了很是實用的機制來封裝命令,並將它
們鏈接到多個事件源,這就是Action接口。
⚫ 動做對象是一個封裝下列內容的對象:
–命令的說明:一個文本字符串和一個可選圖標;
–執行命令所須要的參數。

⚫ Action是一個接口,而不是一個類,實現這個接
口的類必需要實現它的7個方法。
⚫ AbstractAction 類 實 現 了 Action 接 口 中 除
actionPerformed方法以外的全部方法,這個類存
儲了全部名/值對,並管理着屬性變動監聽器。

在 動 做 事 件 處 理 應 用 中 , 可 以 直 接 擴 展
AbstractAction 類 , 並 在 擴 展 類 中 實 現
actionPerformed方法。

15.鼠標事件

⚫ 鼠標事件
– MouseEvent
⚫ 鼠標監聽器接口
– MouseListener
– MouseMotionListener
⚫ 鼠標監聽器適配器
– MouseAdapter
– MouseMotionAdapter

用戶點擊鼠標按鈕時,會調用三個監聽器方法:
– 鼠標第一次被按下時調用mousePressed方法;
– 鼠標被釋放時調用mouseReleased方法;
– 兩個動做完成以後,調用mouseClicked方法。
⚫ 鼠標在組件上移動時,會調用mouseMoved方法。

若是鼠標在移動的時候還按下了鼠標,則會調用
mouseDragged方法

⚫ 鼠標事件返回值
– 鼠標事件的類型是MouseEvent,當發生鼠標事件時:
MouseEvent類自動建立一個事件對象,以及事件發生
位置的x和y座標,做爲事件返回值。

MouseEvent類中的重要方法
– public int getX( );
– public int getY( );
– public Point getPoint( );
– public int getClickCount( );

實驗十三  圖形界面事件處理技術

實驗時間 2018-11-22

1、實驗目的與要求

(1) 掌握事件處理的基本原理,理解其用途;

(2) 掌握AWT事件模型的工做機制;

(3) 掌握事件處理的基本編程模型;

(4) 瞭解GUI界面組件觀感設置方法;

(5) 掌握WindowAdapter類、AbstractAction類的用法;

(6) 掌握GUI程序中鼠標事件處理技術。

2、實驗內容和步驟

實驗1: 導入第11章示例程序,測試程序並進行代碼註釋。

測試程序1:

l 在elipse IDE中調試運行教材443頁-444頁程序11-1,結合程序運行結果理解程序;

l 在事件處理相關代碼處添加註釋;

lambda表達式簡化程序;

掌握JButton組件的基本API;

l 掌握Java中事件處理的基本編程模型。

package button;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class ButtonTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new ButtonFrame();
         frame.setTitle("ButtonTest");//設置窗口的標題
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);//將窗口設爲可見的
      });
   }
}
button
package button;

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

/**
 * A frame with a button panel
 */
public class ButtonFrame extends JFrame
{
   private JPanel buttonPanel;//該類對象屬性
   private static final int DEFAULT_WIDTH = 300;
   private static final int DEFAULT_HEIGHT = 200;

   public ButtonFrame()
   {      
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);//經過setsize來更改框架的寬度和高度

      // create buttons
      JButton yellowButton = new JButton("Yellow");
      JButton blueButton = new JButton("Blue");
      JButton redButton = new JButton("Red");//生成三個按鈕對象,string影響的是顯示在button上的文本

      buttonPanel = new JPanel();

      // add buttons to panel
      buttonPanel.add(yellowButton);
      buttonPanel.add(blueButton);
      buttonPanel.add(redButton);//向內容窗格添加三個容器組件

      // add panel to frame
      add(buttonPanel);

      // create button actions
      ColorAction yellowAction = new ColorAction(Color.YELLOW);
      ColorAction blueAction = new ColorAction(Color.BLUE);
      ColorAction redAction = new ColorAction(Color.RED);//生成三個ColorAction(監聽器類)對象

      // associate actions with buttons
      yellowButton.addActionListener(yellowAction);
      blueButton.addActionListener(blueAction);
      redButton.addActionListener(redAction);//將對應的監聽器類和組件之間進行註冊
   }

   /**
    * An action listener that sets the panel's background color.
    */
   private class ColorAction implements ActionListener//實現監聽器接口
   {
      private Color backgroundColor;

      public ColorAction(Color c)
      {
         backgroundColor = c;
      }

      public void actionPerformed(ActionEvent event)
      {
         buttonPanel.setBackground(backgroundColor);//更改背景色
      }
   }
}
buttonFrame

經過內部類方法實現:

package button;

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

/**
 * A frame with a button panel
 */
public class ButtonFrame extends JFrame {
    private JPanel buttonPanel;// 該類對象屬性
    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 200;

    public ButtonFrame() {
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);// 經過setsize來更改框架的寬度和高度

        buttonPanel = new JPanel();

        add(buttonPanel);

        makeButton("yellow", Color.yellow);
        makeButton("blue", Color.blue);
        makeButton("red", Color.red);
        makeButton("green", Color.green);//添加一個新的組件只須要該條語句
    }

    public void makeButton(String name, Color backgroundColor) {
        JButton button = new JButton(name);
        buttonPanel.add(button);
        ColorAction action = new ColorAction(backgroundColor);
        button.addActionListener(action);

    }

    /**
     * An action listener that sets the panel's background color.
     */
    private class ColorAction implements ActionListener// 實現監聽器接口
    {
        private Color backgroundColor;

        public ColorAction(Color c) {
            backgroundColor = c;
        }

        public void actionPerformed(ActionEvent event) {
            buttonPanel.setBackground(backgroundColor);// 更改背景色
        }
    }
}
buttonFrame

經過匿名內部類方法實現:

package button;

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

/**
 * A frame with a button panel
 */
public class ButtonFrame extends JFrame {
    private JPanel buttonPanel;// 該類對象屬性
    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 200;

    public ButtonFrame() {
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);// 經過setsize來更改框架的寬度和高度

        buttonPanel = new JPanel();

        add(buttonPanel);

        makeButton("yellow", Color.yellow);
        makeButton("blue", Color.blue);
        makeButton("red", Color.red);
        makeButton("green", Color.green);// 添加一個新的組件只須要該條語句
    }

    public void makeButton(String name, Color backgroundColor) {
        JButton button = new JButton(name);
        buttonPanel.add(button);
        // ColorAction action = new ColorAction(backgroundColor);
        // button.addActionListener(action);
        button.addActionListener(new ActionListener() {
            // 不能直接使用接口,new後面有一個匿名的類名,後面的ActionListener經過匿名類調用
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                buttonPanel.setBackground(backgroundColor);
            }
        });

    }

}
buttonFrame

經過lambda表達式實現:

package button;

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

/**
 * A frame with a button panel
 */
public class ButtonFrame extends JFrame {
    private JPanel buttonPanel;// 該類對象屬性
    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 200;

    public ButtonFrame() {
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);// 經過setsize來更改框架的寬度和高度

        buttonPanel = new JPanel();

        add(buttonPanel);

        makeButton("yellow", Color.yellow);
        makeButton("blue", Color.blue);
        makeButton("red", Color.red);
        makeButton("green", Color.green);// 添加一個新的組件只須要該條語句
    }

    public void makeButton(String name, Color backgroundColor) {
        JButton button = new JButton(name);
        buttonPanel.add(button);
        button.addActionListener((e) -> {
            buttonPanel.setBackground(backgroundColor);
        });

    }

}
buttonFrame

經過以上三種方式實現事件處理的基本代碼愈來愈簡化。

測試程序2:

l 在elipse IDE中調試運行教材449頁程序11-2,結合程序運行結果理解程序;

l 在組件觀感設置代碼處添加註釋;

l 瞭解GUI程序中觀感的設置方法。

package plaf;

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

/**
 * @version 1.32 2015-06-12
 * @author Cay Horstmann
 */
public class PlafTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new PlafFrame();
         frame.setTitle("PlafTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
plaf
package plaf;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 * A frame with a button panel for changing look-and-feel
 */
public class PlafFrame extends JFrame
{
   private JPanel buttonPanel;

   public PlafFrame()
   {
      buttonPanel = new JPanel();
//組件觀感設置
      UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();//UIManager 管理當前外觀、可用外觀集合及獲取各類默認值的便捷方法。
      //返回表示當前可用的 LookAndFeel 實現的 LookAndFeelInfo 數組。應用程序可使用 LookAndFeelInfo 對象爲用戶構造外觀選項的菜單,或肯定在啓動時要設置哪一個外觀 
      for (UIManager.LookAndFeelInfo info : infos)
         makeButton(info.getName(), info.getClassName());
//適合菜單或其餘展現的形式返回外觀的名稱 ,返回實現此外觀的類名稱
      add(buttonPanel);
      pack();//調整此窗口的大小,以適合其子組件的首選大小和佈局
   }

   /**
    * Makes a button to change the pluggable look-and-feel.
    * @param name the button name
    * @param className the name of the look-and-feel class
    */
   private void makeButton(String name, String className)
   {
      // add button to panel

      JButton button = new JButton(name);
      buttonPanel.add(button);

      // set button action

      button.addActionListener(event -> {
         // button action: switch to the new look-and-feel
         try
         {
            UIManager.setLookAndFeel(className);
            SwingUtilities.updateComponentTreeUI(this);//簡單的外觀更改
            pack();
         }
         catch (Exception e)
         {
            e.printStackTrace();
         }
      });
   }
}
plafFrame

不一樣的組件有不一樣的觀感

測試程序3:

l 在elipse IDE中調試運行教材457頁-458頁程序11-3,結合程序運行結果理解程序;

l 掌握AbstractAction類及其動做對象;

l 掌握GUI程序中按鈕、鍵盤動做映射到動做對象的方法。

package action;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class ActionTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new ActionFrame();
         frame.setTitle("ActionTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
action
package action;

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

/**
 * A frame with a panel that demonstrates color change actions.
 */
public class ActionFrame extends JFrame
{
   private JPanel buttonPanel;
   private static final int DEFAULT_WIDTH = 300;
   private static final int DEFAULT_HEIGHT = 200;

   public ActionFrame()
   {
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

      buttonPanel = new JPanel();

      // define actions
      Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),//Action 接口提供 ActionListener 接口的一個有用擴展,以便若干控件訪問相同的功能
            Color.YELLOW);//能夠將此接口添加到現有類中,或者用它建立一個適配器(一般經過子類化 AbstractAction 來實現)。
      Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
      Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
//根據指定的文件建立一個 ImageIcon。使用 MediaTracker 預載圖像以監視圖像的加載狀態。指定 String 能夠是一個文件名或是一條文件路徑。
      // add buttons for these actions
      buttonPanel.add(new JButton(yellowAction));
      buttonPanel.add(new JButton(blueAction));
      buttonPanel.add(new JButton(redAction));

      // add panel to frame
      add(buttonPanel);//添加組件

      // associate the Y, B, and R keys with names
      InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);//使用繼承自 JComponent 的組件
      //當接收組件是得到焦點的組件的祖先或者其自己就是得到焦點的組件時,應該調用命令。 
      imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
      imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
      imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
       //InputMap 提供輸入事件(目前只使用 KeyStroke)和 Object 之間的綁定。InputMap 一般與 ActionMap 一塊兒使用,
      //以肯定按下鍵時執行一個 Action。InputMap 能夠有一個父級,可搜索它來得到 InputMap 中未定義的綁定。
      // associate the names with actions
      ActionMap amap = buttonPanel.getActionMap();
      amap.put("panel.yellow", yellowAction);
      amap.put("panel.blue", blueAction);
      amap.put("panel.red", redAction);
      //ActionMap 提供從 Object(稱爲鍵 或 Action 名)到 Action 的映射。當按下某一個鍵時,ActionMap 一般與 InputMap 一塊兒使用來定位特定操做。
      //與 InputMap 一同使用時,ActionMap 能夠有一個父級,用來搜索沒有在該 ActionMap 中定義的鍵。
      
   }
   
   public class ColorAction extends AbstractAction
   {
      /**
       * Constructs a color action.
       * @param name the name to show on the button
       * @param icon the icon to display on the button
       * @param c the background color
       */
      public ColorAction(String name, Icon icon, Color c)
      {//putvalue設置與指定鍵關聯的值
         putValue(Action.NAME, name);//用於菜單或按鈕的名字
         putValue(Action.SMALL_ICON, icon);//該鍵一般用於菜單,同時指定了要使用SMALL-ICON
         putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase());//用來存儲動做的簡短 String 描述的鍵,用於工具提示文本。
       //toLowerCase使用默認語言環境的規則將此 String 中的全部字符都轉換爲小寫
         putValue("color", c);
      }

      public void actionPerformed(ActionEvent event)//actionListener中的一個方法
      {
         Color c = (Color) getValue("color");
         buttonPanel.setBackground(c);
      }
   }
}
actionFrame

 

測試程序4:

l 在elipse IDE中調試運行教材462頁程序11-四、11-5,結合程序運行結果理解程序;

l 掌握GUI程序中鼠標事件處理技術。

package mouse;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class MouseTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new MouseFrame();
         frame.setTitle("MouseTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
mouse
package mouse;

import javax.swing.*;

/**
 * A frame containing a panel for testing mouse operations
 */
public class MouseFrame extends JFrame
{
   public MouseFrame()
   {
      add(new MouseComponent());
      pack();
   }
}
mouseFrame
package mouse;

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

/**
 * A component with mouse operations for adding and removing squares.
 */
public class MouseComponent extends JComponent
{
   private static final int DEFAULT_WIDTH = 300;
   private static final int DEFAULT_HEIGHT = 200;

   private static final int SIDELENGTH = 10;
   private ArrayList<Rectangle2D> squares;//Rectangle2D 類描述經過位置 (x,y) 和尺寸 (w x h) 定義的矩形
   private Rectangle2D current; // the square containing the mouse cursor

   public MouseComponent()
   {
      squares = new ArrayList<>();//構造一個空列表
      current = null;

      addMouseListener(new MouseHandler());//添加鼠標監聽器
      addMouseMotionListener(new MouseMotionHandler());//添加指定的鼠標移動偵聽器,以接收發自此組件的鼠標移動事件。
   }

   public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }   
   //若是 preferredSize 已設置爲一個非 null 值,則返回該值。若是 UI 委託的 getPreferredSize 方法返回一個非 null 值,則返回該值;
   public void paintComponent(Graphics g)
   {
      Graphics2D g2 = (Graphics2D) g;

      // draw all squares
      for (Rectangle2D r : squares)
         g2.draw(r);//在畫布上畫出一個矩形
   }

   /**
    * Finds the first square containing a point.
    * @param p a point
    * @return the first square that contains p
    */
   public Rectangle2D find(Point2D p)//經過位置 (x,y) 和尺寸 (w x h) 定義的矩形。
   {
      for (Rectangle2D r : squares)
      {
         if (r.contains(p)) return r;//測試指定的 Point2D 是否在 Shape 的邊界內
      }
      return null;
   }

   /**
    * Adds a square to the collection.
    * @param p the center of the square
    */
   public void add(Point2D p)
   {
      double x = p.getX();//返回該圖形的X,Y座標
      double y = p.getY();

      current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,
            SIDELENGTH);
      squares.add(current);
      repaint();
   }

   /**
    * Removes a square from the collection.
    * @param s the square to remove
    */
   public void remove(Rectangle2D s)
   {
      if (s == null) return;
      if (s == current) current = null;
      squares.remove(s);
      repaint();
   }

   private class MouseHandler extends MouseAdapter//鼠標監聽器適配器
   {
      public void mousePressed(MouseEvent event)//鼠標按鍵在組件上按下時調用mousepressed方法,
      {
         // add a new square if the cursor isn't inside a square
         current = find(event.getPoint());
         if (current == null) add(event.getPoint());//若鼠標指針不在以前的矩形內,則點擊鼠標時,從新畫一個矩形
      }

      public void mouseClicked(MouseEvent event)//鼠標按鍵在組件上單擊(按下並釋放)時調用。 
      {
         // remove the current square if double clicked
         current = find(event.getPoint());
         if (current != null && event.getClickCount() >= 2) remove(current);//當鼠標在矩形框內雙擊時,取消該矩形框
      }
   }

   private class MouseMotionHandler implements MouseMotionListener//實現移動監聽器接口
   {
      public void mouseMoved(MouseEvent event)//鼠標光標移動到組件上但無按鍵按下時調用
      {
         // set the mouse cursor to cross hairs if it is inside
         // a rectangle

         if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());//爲指定的光標設置光標圖像
         else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));//十字光標類型。
      }

      public void mouseDragged(MouseEvent event)//鼠標按鍵在組件上按下並拖動時調用。在釋放鼠標按鍵前,MOUSE_DRAGGED 事件被連續地傳遞到發起該拖動的組件(而無論鼠標位置是否處於該組件的邊界內)。
      {
         if (current != null)
         {
            int x = event.getX();
            int y = event.getY();
//當發生鼠標事件時: MouseEvent類自動建立一個事件對象,以及事件發生位置的x和y座標,做爲事件返回值。
            // drag the current rectangle to center it at (x, y)
            current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
            repaint();//重組此繪件
         }
      }
   }   
}
mousecomponent

當鼠標點擊畫布時,繪製一個矩形,當鼠標在窗體上移動時,若是鼠標通過一個小方塊的內部,光標會變成一個十字形;

當雙擊一個小方塊內部時,會擦除該小方塊;實現用鼠標拖動小方塊。

當鼠標點擊在全部小方塊的像素以外時,會繪製一個新的小方塊;

實驗2:結對編程練習

利用班級名單文件、文本框和按鈕組件,設計一個有以下界面(圖1)的點名器,要求用戶點擊開始按鈕後在文本輸入框隨機顯示2017級網絡與信息安全班同窗姓名,如圖2所示,點擊中止按鈕後,文本輸入框再也不變換同窗姓名,此同窗則是被點到的同窗姓名。

 

1 點名器啓動界面

 

2 點名器點名界面

 

 

package 點名器;

import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileNotFoundException;

import javax.swing.event.*;

public class NameFrame extends JFrame implements ActionListener {//採用多線程
    private JLabel jla;//JLabel 對象能夠顯示文本、圖像或同時顯示兩者。
    private JLabel jlb;
    private JButton jba;
    private static boolean flag = true;//定義一個靜態常量並將其值設置爲true

    public NameFrame() {
        this.setLayout(null);//類 Container 中的 setLayout,設置 LayoutManager。重寫此方法,從而有條件地將調用轉發到 contentPane

        jla = new JLabel("姓名");
        jlb = new JLabel("準備中");
        jba = new JButton("開始");//建立按鈕並將其命名爲開始
        this.add(jla);
        this.add(jlb);
        jla.setFont(new Font("Courier", Font.PLAIN, 25));//設置該組件的字體
        jla.setHorizontalAlignment(JLabel.CENTER);//設置標籤內容沿 X 軸的對齊方式並在該區域的中心位置
        jla.setVerticalAlignment(JLabel.CENTER);//設置標籤內容沿 Y 軸的對齊方式並在該區域的中心位置
        jla.setBounds(20, 100, 180, 30);
        jlb.setOpaque(true);//若是爲 true,則該組件繪製其邊界內的全部像素。不然該組件可能不繪製部分或全部像素,從而容許其底層像素透視出來。 
        jlb.setBackground(Color.cyan);//設置此組件的背景色。
        jlb.setFont(new Font("Courier", Font.PLAIN, 22));
        jlb.setHorizontalAlignment(JLabel.CENTER);
        jlb.setVerticalAlignment(JLabel.CENTER);
        jlb.setBounds(150, 100, 120, 30);

        this.add(jba);//設置開始按鈕的一些屬性
        jba.setBounds(150, 150, 80, 26);//移動組件並調整其大小。由 x 和 y 指定左上角的新位置,由 width 和 height 指定新的大小。

        jba.addActionListener(this);//將一個 ActionListener 添加到按鈕中

        this.setTitle("點名器");
        this.setBounds(400, 400, 400, 300);
        this.setVisible(true);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);//調用任意已註冊 WindowListener 的對象後自動隱藏並釋放該窗體。 
    }

    public void actionPerformed(ActionEvent e) {
        int i = 0;
        String names[] = new String[50];//建立一個數組,該數組的最大容量爲50
        try {
            Scanner in = new Scanner(new File("D:\\studentnamelist.txt"));
            while (in.hasNextLine()) {//若是在此掃描器的輸入中存在另外一行,則返回 true。在等待輸入信息時,此方法可能阻塞。掃描器不執行任何輸入。 
                names[i] = in.nextLine();
                i++;//遍歷名單
            }
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        if (jba.getText() == "開始") {//返回按鈕的文本
            jlb.setBackground(Color.BLUE);//設置組件的背景色
            flag = true;
            new Thread() {//分配新的 Thread 對象。這種構造方法與 Thread(null, null, gname) 具備相同的做用,其中 gname 是一個新生成的名稱。自動生成的名稱的形式爲 "Thread-"+n,其中的 n 爲整數。
                public void run() {
                    while (NameFrame.flag) {
                        Random r = new Random();
                        int i = r.nextInt(47);
                        jlb.setText(names[i]);//定義此組件將要顯示的單行文本。若是 text 值爲 null 或空字符串,則什麼也不顯示,此時爲name則顯示中止時的名字
                    }
                }
            }.start();//使該線程開始執行;Java 虛擬機調用該線程的 run 方法。
            jba.setText("中止");
            jba.setBackground(Color.ORANGE);
        } else if (jba.getText() == "中止") {
            flag = false;//當點擊按鈕的中止時,返回該按鈕的名字,而且變量flag的布爾值爲flase
            jba.setText("開始");//按鈕的名字爲開始
            jba.setBackground(Color.WHITE);//開始按鈕的顏色爲白色
            jlb.setBackground(Color.gray);//未開始點擊開始按鈕時,姓名輸入框爲灰色
        }
    }

    public static void main(String arguments[]) {
        new NameFrame();
    }
}
nameframe

在點名器的程序設計中,徹底沒有思路該如何寫,在學長的實例程序上作了註釋及稍許改動,但對於多線程仍是沒有理解該如何使用。

 

 實驗總結:經過本週學習,我基本掌握了事件處理的基本原理及AWT事件模型的工做機制;掌握事件處理的基本編程模型;並用多種方法簡化代碼,在老師和學長的教導進一步

理解了匿名內部類,但對於GUI界面組件觀感設置方法還不太理解; 掌握了AbstractAction類的用法及GUI程序中鼠標事件處理技術。

相關文章
相關標籤/搜索