1. 程式人生 > >Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記

Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記

windows date contain 失去 apt 掩碼 標題欄 imp ted

Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記

本章內容:
* 事件處理基礎
* 動作
* 鼠標事件
* AWT事件繼承層次

8.1 事件處理基礎

  1. 在AWT所知的事件範圍內,完全可以控制事件從事件源(event source)例如,按鈕或滾動條,到事件監聽器(event listener)的傳遞過程,並將任何對象指派給事件監聽器。不過事實上,應該選擇一個能夠便於響應事件的對象。這種事件委托模型(event delegation event)與Visual Basic那種預定義監聽器模型比較起來更加靈活。
  2. 事件源有一些向其註冊事件監聽器的方法。當某個事件源產生事件時,事件源會向為事件註冊的所有事件監聽器對象發送一個通告。
  3. 像Java這樣的面向對象語言,都將事件的相關信息封裝在一個事件對象(event object)中。在Java中,所有的事件對象都最終派生於java.util.EventObject類。
  4. 不同的事件源可以產生不同類別的事件。
  5. AWT事件處理機制的概要:
    • 監聽器對象是一個實現了特定監聽器接口(listener interface)的類的實例。
    • 事件源是一個能夠註冊監聽器對象並發送事件對象的對象。
    • 當事件發生時,事件源將事件對象傳遞給所有註冊的監聽器。
    • 監聽器對象將利用事件對象中的信息決定如何對事件做出響應。

8.1.1 實例:處理按鈕點擊事件

  1. 可以通過在按鈕構造器中指定一個標簽字符串、一個圖標或兩項都指定來創建一個按鈕。
  2. ActionListener接口並不僅限於按鈕點擊事件。它可以應用於很多情況:
    • 當采用鼠標雙擊的方式選擇了列表框中的一個選項時;
    • 當選擇一個菜單項時;
    • 當在文本域中按回車鍵時;
    • 對於一個Timer組件來說,當達到指定的時間間隔時。
      在所有這些情況下,使用ActionListener接口的方式都是一樣的:actionPerformed方法(ActionListener中的唯一方法)將接收一個ActionEvent類型的對象作為參數。這個事件對象包含了事件發生時的相關信息。
  3. 事件監聽器對象通常需要執行一些對其他對象可能產生影響的操作。可以策略性地將監聽器類放置在需要修改狀態的那個類中。
  4. jaxax.swing.JButton 1.2
    • JButton(String label)
    • JButton(Icon icon)
    • JButton(String label,Icon icon)
      構造一個按鈕,標簽可以是常規的文本,從Java1.3開始,也可以是HTML。
  5. java.awt.Container 1.0
    • Component add(Component c)
      將組件c添加到這個容器中。

8.1.2 建議使用內部類

  1. 內部類機制將自動地生成一個構造器,其中存儲著所有用在內部類方法中的final局部變量。
  2. java.util.EventObject 1.1
    • Object getSource()
      返回發生事件的對象引用。
  3. java.awt.event.ActionEvent 1.1
    • String getActionCommand()
      返回與這個動作事件相關的命令字符串。如果動作事件來源於按鈕,命令字符串就等於按鈕標簽,除非已經使用setActionCommand方法對字符串進行了修改。

8.1.3 創建包含一個方法調用的監聽器

  1. EventHandler類可以使用下列調用,自動地創建這樣一個監聽器:EventHandler.create(ActionListener.class,frame,"loadData")
  2. java.beans.EventHandler 1.4
    • static Object create(Class listenerInterface,Object target,String action)
    • static Object create(Class listenerInterface,Object target, String action,String eventProperty)
    • static Object create(Class listenerInterface,Object target,String action,String eventProperty,String listenerMethod)
      構造實現給定接口的一個代理類對象。命名方法或接口的所有方法都將在目標對象上執行給定動作。
      這個動作可以是一個方法名或目標的一個屬性。如果是一個屬性,將執行其設置方法。
      事件屬性包括一個或多個用點號分割的屬性名。第一個屬性從監聽器方法的參數讀取,第二個屬性由結果對象讀取,依次類推。最後的結果將作為動作的參數。

8.1.4 實例:改變觀感

  1. 在默認情況下,Swing程序使用Metal觀感,可以采用兩種方式改變觀感。第一種方式是在Java安裝的子目錄jre/lib下有一個文件swing.properties。在這個文件中,將屬性swing.defaultlaf設置為所希望的觀感類名。
    註意,Metal觀感位於javax.swing包中。其他的觀感位於com.sun.java包中,並且不是在每個Java實現中都提供。現在,鑒於版權的原因,Windows和Macintosh的觀感包只與Windows和Macintosh版本的Java運行時環境一起發布。
    第二種方式是動態地改變觀感。這需要調用靜態的UIManager.setLookAndFeel方法,並提供所想要的觀感類名,然後再調用靜態方法SwingUtilities.updateComponentTreeUI來刷新全部的組件集。這裏需要向這個方法提供一個組件,並由此找到其他的所有組件。當UIManager.setLookAndFeel方法沒有找到所希望的觀感或在加載過程中出現錯誤時,將會拋出異常。
  2. javax.swing.UIManager 1.2
    • static UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
      獲取一個用於描述已安裝的觀感實現的對象數組。
    • static setLookAndFeel(String className)
      利用給定的類名設置當前的觀感。例如,javax.swing.plaf.MetalLookAndFeel。
  3. javax.swing.UIManager.LookAndFeelInfo 1.2
    • String getName()
      返回觀感的顯示名稱。
    • String getClassName()
      返回觀感實現類的名稱。

8.1.5 適配器類

  1. 為了能夠查看窗口是否被最大化,需要安裝WindowStateListener。
  2. 每個含有多個方法的AWT監聽器接口都配有一個適配器(adapter)類,這個類實現了接口中的所有方法,但每個方法沒有做任何事情。這意味著適配器類自動滿足了Java實現相關監聽器接口的技術需求。可以通過擴展適配器類來指定對某些時間的響應動作,而不必實現接口中的每個方法。
  3. java.awt.event.WindowListener 1.1
    • void windowOpened(WindowEvent e)
      窗口打開後調用這個方法。
    • void windowClosing(WindowEvent e)
      在用戶發出窗口管理器命令關閉窗口時調用這個方法。需要註意的是,僅當調用hide或dispose方法後窗口才能夠關閉。
    • void windowClosed(WindowEvent e)
      窗口關閉後調用這個方法。
    • void windowIconified(WindowEvent e)
      窗口圖標化後調用這個方法。
    • void windowDeiconified(WindowEvent e)
      窗口非圖標化後調用這個方法。
    • void windowActivated(WindowEvent e)
      激活窗口後調用這個方法。只有框架或對話框可以被激活。通常,窗口管理器會對活動窗口進行修飾,比如,高亮度標題欄。
    • void windowDeactivated(WindowEvent e)
      窗口變為未激活狀態後調用這個方法。
    • void windowStateChanged(WindowEvent event)
      窗口最大化、圖標化或恢復為正常大小時調用這個方法。
    • int getNewState()1.4
    • int getOldState() 1.4
      返回窗口狀態改變事件中窗口的新、舊狀態。返回的整型數值是下列數值之一:Frame.NORMAL、Frame.ICONIFIED、Frame.MAXIMIZED_HORIZ、Frame.MAXIMIZED_VERT、Frame.MAXIMIZED_BOTH。

8.2 動作

  1. 通常,激活一個命令可以有多種方式。用戶可以通過菜單、擊鍵或工具欄上的按鈕選擇特定的功能。在AWT事件模型中實現這些非常容易:將所有事件連接到同一個監聽器上。
  2. Swing包提供了一種非常實用的機制來封裝命令,並將它們連接到多個事件源,這就是Action接口。一個動作是一個封裝下列內容的對象:
    • 命令的說明(一個文本字符串和一個可選圖標);
    • 執行命令所需要的參數。
  3. Action接口擴展於ActionListener接口,因此,可以在任何需要ActionListener對象的地方使用Action對象。
  4. 預定義動作表名稱
    名稱
    NAME 動作名稱,顯示在按鈕和菜單上
    SMALL_ICON 存儲小圖標的地方;顯示在按鈕、菜單項或工具欄中
    SHORT_DESCRIPTION 圖標的簡要說明;顯示在工具提示中
    LONG_DESCRIPTION 圖標的詳細說明;使用在在線幫助中。沒有Swing組件使用這個值
    MNEMONIC_KEY 快捷鍵縮寫;顯示在菜單項中
    ACCELERATOR_KEY 存儲加速擊鍵的地方;Swing組件不使用這個值
    ACTION_COMMAND_KEY 歷史遺留;僅在舊版本的registerKeyboardAction方法中使用
    DEFAULT 常用的綜合屬性;Swing組件不使用這個值
  5. 如果動作對象添加到菜單或工具欄上,它的名稱和圖標就會被自動地提取出來,並顯示在菜單欄或工具欄項中。SHORT_DESCRIPTION值變成了工具提示。
  6. Action是一個接口,而不是一個類。有一個類實現了這個接口除actionPerformed方法之外的所有方法,它就是AbstractAction。這個類存儲了所有名、值對。並管理著屬性變更監聽器。可以直接擴展AbstractAction類,並在擴展類中實現了actionPerformed方法。
  7. 每個JComponent有三個輸入映射(input maps),每一個映射的KeyStore對象都與動作關聯。三個輸入映射對應著三個不同的條件。
    輸入映射表
    標誌激活動作
    WHEN_FOCUSED 當這個組件擁有鍵盤焦點時
    WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 當這個組件包含了擁有鍵盤焦點的組件時
    WHEN_IN_FOCUSED_WINDOW 當這個組件被包含在一個擁有鍵盤焦點組件的窗口中時
  8. 按鍵處理將按照下列順序檢查這些映射:
    1)檢查具有輸入焦點組件的WHEN_FOCUSED映射。如果這個按鍵存在,將執行對應的動作。如果動作已啟動,則停止處理。
    2)從具有輸入焦點的組件開始,檢查其父組件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT映射。一旦找到按鍵對應的映射,就執行對應的動作。如果動作已啟用,將停止處理。
    3)查看具有輸入焦點的窗口中的所有可視的和啟用的組件,這個按鍵被註冊到WHEN_IN_FOCUSED_WINDOW映射中。給這些組件(按照按鍵註冊的順序)一個執行對應動作的機會。一旦第一個啟用的動作被執行,就停止處理。如果一個按鍵咋多個WHEN_IN+FOCUSED_WINDOW映射中出現,這部分處理就可能會出現問題。
  9. 可以使用getInputMap方法從組件中得到輸入映射。
  10. InputMap不能直接將KeyStore對象映射到Actoin對象中。而是先映射到任意對象上,然後由ActionMap類實現將對象映射到動作上的第2個映射。這樣很容易實現來自不同輸入映射的按鍵共享一個動作的目的。
  11. 每個組件都可以有三個輸入映射和一個動作映射。為了將他們組合起來,需要為動作命名。
  12. 用同一個動作響應按鈕、菜單項或按鍵的方式:
    1)實現一個擴展於AbstractAction類的類。多個相關的動作可以使用同一個類。
    2)構造一個動作類的對象。
    3)使用動作對象創建按鈕或菜單項。構造器將從動作對象中讀取標簽文本和圖標。
    4)為了能夠通過按鍵觸發動作,必須額外地執行幾步操作。首先定位頂層窗口組件,例如,包含所有其他組件的面板。
    5)然後,得到頂層組件的WHEN_ANCESTOR_OF_FOCUS_COMPONENT輸入映射。為需要的按鍵創建一個KeyStore對象。創建一個描述動作字符串這樣的動作鍵對象。將(按鍵,動作鍵)對添加到輸入映射中。
    6)最後,得到頂層組件的動作映射。將(動作鍵,動作對象)添加到映射中。
  13. javax.swing.Action 1.2
    • boolean isEnabled()
    • void setEnabled(boolean b)
      獲得或設置這個動作額enabled屬性。
    • void putValue(String key,Object value)
      將名/值對防止在動作對象內。
      參數:key 用動作對象存儲性能的名字。它可以是一個字符串,但預定義了幾個名字。 value 與名字關聯的對象。
    • Object getValue(String key)
      返回被存儲的名/值對的值。
  14. javax.swing.KeyStore 1.2
    • static KeyStore getKeyStroke(String description)
      根據一個便於人們閱讀的說明創建一個按鍵(由空格分割的字符串序列)。這個說明以0個或多個修飾符shift control strl meta alt altGraph開始,以由types和單個字符構成的字符串(例如:“typed a”)或者一個可選的事件說明符(pressed默認,或released)緊跟一個鍵碼結束。以VK_前綴開始的鍵碼應該對應一個KeyEvent常量,例如,“INSERT”對應KeyEvent.VK_INSERT。
  15. javax.swing.JComponent 1.2
    • ActionMap getActionMap() 1.3
      返回關聯動作映射鍵(可以是任意的對象)和動作對象的映射。
    • InputMap getInputMap(int flag) 1.3
      獲得將案件映射到動作鍵的輸入映射。
      參數:flag 觸發動作的鍵盤焦點條件。

8.3 鼠標動作

  1. 當用戶點擊鼠標按鈕時,將會調用三個監聽器方法:鼠標第一次按下時調用mousePressed;鼠標被釋放時調用mouseReleased;最後調用mouseClicked。如果只對最終的點擊事件感興趣,就可以忽略前兩個方法。用MouseEvent類對象作為參數,調用getX和getY方法可以獲得鼠標被按下時鼠標指針所在x和y坐標。要想區分單擊、雙擊和三擊(!),需要使用getClickCount方法。
  2. getModifiersEx方法能夠準確地報告鼠標事件的鼠標按鈕和鍵盤修飾符。
  3. 在Windows環境下,使用BUTTON3_DOWN_MASK檢測鼠標右鍵(非主要的)的狀態。
  4. java.awt.event.MouseEvent 1.1
    • int getX()
    • int getY()
    • Point getPoint()
      返回事件發生時,事件源組件左上角的坐標x(水平)和y(垂直),或點信息。
    • int getClickCount()
      返回與事件關聯的鼠標連擊次數(“連擊”所指定的時間間隔與具體系統有關)。
  5. java.awt.event.InputEvent 1.1
    • int getModifiersEx() 1.4
      返回事件擴展的或“按下”(down)的修飾符。使用下面的掩碼值檢測返回值:BTTON1_DOWN_MASK、BUTTON2_DOWN_MASK、BUTTON3_DOWN_MASK、SHIFT_DOWN_MASK、CTRL_DOWN_MASK、ALT_DOWN_MASK、ALT_GRAPH_DOWN_MASK、META_DOWN_MASK。
    • static String getModifiersExText(int modifiers) 1.4
      返回用給定標誌集描述的擴展或“按下”(down)的修飾符字符串,例如“Shift+Button1”。
  6. java.awt.Toolkit 1.0
    • public Cursor createCustomCursor(Image image,Point hotSpot,String name) 1.2
      創建一個新的定制光標對象。
      參數:image 光標活動時顯示的圖像。hotSpot 光標熱點(箭頭的頂點或十字中心)。name 光標的描述,用來支持特殊的訪問環境。
  7. java.awt.Component 1.0
    • public void setCursor(Cursor cursor) 1.1
      用光標圖像設置給定光標。

8.4 AWT事件繼承層次

  1. Java事件處理采用的是面向對象方法,所有的事件都是由java.util包中的EventObject類擴展而來的。EventObject類有一個子類AWTEvent,它是所有AWT事件類的父類。有些Swing組件將生成其他事件類型的事件對象;它們都直接擴展於EventObject,而不是AWTEvent。事件對象封裝了事件源與監聽器彼此通信的事件信息。在必要的時候,可以對傳遞給監聽器對象的事件對象進行分析。
  2. AWT將事件分為低級(low-level)事件和語義(semantic)事件。語義事件是表示用戶動作的事件,因此,ActionEvent是一種語義事件。低級事件是形成那些事件的事件。
  3. java.awt.event包中最常用的語義事件類:
    • ActionEvent(對應按鈕點擊、菜單選擇、選擇列表項或文本框中ENTER);
    • AdjustmentEvent(用戶調節滾動條);
    • ItemEvent(用戶從復選框或列表框中選擇一項)。
  4. 常用的5個低級事件類是:
    • KeyEvent(一個鍵被按下或釋放);
    • MouseEvent(鼠標鍵被按下、釋放、移動或拖動);
    • MouseWheelEvent(鼠標滾輪被轉動);
    • FocusEvent(某個組件獲得焦點或失去焦點)。
    • WindowEvent(窗口狀態被改變)。
      下列接口將監聽這些事件:ActionListener、AdjustmentListener、FocusListener、ItemListener、KeyListener、MouseListener、MouseMotionListener、MouseWheelListener、WindowListener、WindowFocusListener、WindowStateListener。
  5. 常用的適配器類:FocusAdapter、KeyAdapter、MouseAdapter、MouseMotionAdapter、WindowAdapter。
  6. 事件處理總結
    接口方法參數/訪問方法事件源
    ActionListener actionPerformed ActionEvent(getActionCommand、getModifiers) AbstractButton、JComboBox、JTextField、Timer
    AdjustmentListener adjustmentValueChanged AdjustmentEvent(getAdjustable、getAdjustmentType、getValue) JScrollbar
    ItemListener itemStateChanged ItemEvent(getItem、getItemSelectale、getStateChange) AbstractButton、JComboBox
    FocusListener FocusGained、FocusLayout FocusEvent(isTemporary) Component
    KeyListener keyPressed、keyReleased、KeyTyped KeyEvent(getKeyChar、getKeyCode、getKeyModifiersText、getKeyText、isActionKey) Component
    MouseListener mousePressed、mouseReleased、mouseEntered、mouseExited、mouseClicked MouseEvent(getClickCount、getX、getY、getPoint、translatePoint) Component
    MouseMotionListener mouseDragged、mouseMoved MouseEvent Component
    MouseWheelListener mouseWheelMoved MouseWheelEvent(getWheelRotation、getScrollAmount) Component
    WindowListener windowClosing、windowOpened、windowIconified、windowDeiconified、windowClosed、windowActivated、windowDeactivated WindowEvent(getWindow) Window
    WindowFocusListener windowGainedFocus、windowLostFocus WindowEvent(getOppsiteWindow) Window
    WindowStateListener windowStateChanged WindowEvent(getOldState、getNewState) Winow

Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記