Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記
阿新 • • 發佈:2018-09-25
windows date contain 失去 apt 掩碼 標題欄 imp ted
Java核心技術卷一基礎技術-第8章-事件處理-讀書筆記
本章內容:
* 事件處理基礎
* 動作
* 鼠標事件
* AWT事件繼承層次
8.1 事件處理基礎
- 在AWT所知的事件範圍內,完全可以控制事件從事件源(event source)例如,按鈕或滾動條,到事件監聽器(event listener)的傳遞過程,並將任何對象指派給事件監聽器。不過事實上,應該選擇一個能夠便於響應事件的對象。這種事件委托模型(event delegation event)與Visual Basic那種預定義監聽器模型比較起來更加靈活。
- 事件源有一些向其註冊事件監聽器的方法。當某個事件源產生事件時,事件源會向為事件註冊的所有事件監聽器對象發送一個通告。
- 像Java這樣的面向對象語言,都將事件的相關信息封裝在一個事件對象(event object)中。在Java中,所有的事件對象都最終派生於java.util.EventObject類。
- 不同的事件源可以產生不同類別的事件。
- AWT事件處理機制的概要:
- 監聽器對象是一個實現了特定監聽器接口(listener interface)的類的實例。
- 事件源是一個能夠註冊監聽器對象並發送事件對象的對象。
- 當事件發生時,事件源將事件對象傳遞給所有註冊的監聽器。
- 監聽器對象將利用事件對象中的信息決定如何對事件做出響應。
8.1.1 實例:處理按鈕點擊事件
- 可以通過在按鈕構造器中指定一個標簽字符串、一個圖標或兩項都指定來創建一個按鈕。
- ActionListener接口並不僅限於按鈕點擊事件。它可以應用於很多情況:
- 當采用鼠標雙擊的方式選擇了列表框中的一個選項時;
- 當選擇一個菜單項時;
- 當在文本域中按回車鍵時;
- 對於一個Timer組件來說,當達到指定的時間間隔時。
在所有這些情況下,使用ActionListener接口的方式都是一樣的:actionPerformed方法(ActionListener中的唯一方法)將接收一個ActionEvent類型的對象作為參數。這個事件對象包含了事件發生時的相關信息。
- 事件監聽器對象通常需要執行一些對其他對象可能產生影響的操作。可以策略性地將監聽器類放置在需要修改狀態的那個類中。
- jaxax.swing.JButton 1.2
- JButton(String label)
- JButton(Icon icon)
- JButton(String label,Icon icon)
構造一個按鈕,標簽可以是常規的文本,從Java1.3開始,也可以是HTML。
- java.awt.Container 1.0
- Component add(Component c)
將組件c添加到這個容器中。
- Component add(Component c)
8.1.2 建議使用內部類
- 內部類機制將自動地生成一個構造器,其中存儲著所有用在內部類方法中的final局部變量。
- java.util.EventObject 1.1
- Object getSource()
返回發生事件的對象引用。
- Object getSource()
- java.awt.event.ActionEvent 1.1
- String getActionCommand()
返回與這個動作事件相關的命令字符串。如果動作事件來源於按鈕,命令字符串就等於按鈕標簽,除非已經使用setActionCommand方法對字符串進行了修改。
- String getActionCommand()
8.1.3 創建包含一個方法調用的監聽器
- EventHandler類可以使用下列調用,自動地創建這樣一個監聽器:
EventHandler.create(ActionListener.class,frame,"loadData")
。 - 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 實例:改變觀感
- 在默認情況下,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方法沒有找到所希望的觀感或在加載過程中出現錯誤時,將會拋出異常。 - javax.swing.UIManager 1.2
- static UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
獲取一個用於描述已安裝的觀感實現的對象數組。 - static setLookAndFeel(String className)
利用給定的類名設置當前的觀感。例如,javax.swing.plaf.MetalLookAndFeel。
- static UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
- javax.swing.UIManager.LookAndFeelInfo 1.2
- String getName()
返回觀感的顯示名稱。 - String getClassName()
返回觀感實現類的名稱。
- String getName()
8.1.5 適配器類
- 為了能夠查看窗口是否被最大化,需要安裝WindowStateListener。
- 每個含有多個方法的AWT監聽器接口都配有一個適配器(adapter)類,這個類實現了接口中的所有方法,但每個方法沒有做任何事情。這意味著適配器類自動滿足了Java實現相關監聽器接口的技術需求。可以通過擴展適配器類來指定對某些時間的響應動作,而不必實現接口中的每個方法。
- 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。
- void windowOpened(WindowEvent e)
8.2 動作
- 通常,激活一個命令可以有多種方式。用戶可以通過菜單、擊鍵或工具欄上的按鈕選擇特定的功能。在AWT事件模型中實現這些非常容易:將所有事件連接到同一個監聽器上。
- Swing包提供了一種非常實用的機制來封裝命令,並將它們連接到多個事件源,這就是Action接口。一個動作是一個封裝下列內容的對象:
- 命令的說明(一個文本字符串和一個可選圖標);
- 執行命令所需要的參數。
- Action接口擴展於ActionListener接口,因此,可以在任何需要ActionListener對象的地方使用Action對象。
- 預定義動作表名稱
名稱 值 NAME 動作名稱,顯示在按鈕和菜單上 SMALL_ICON 存儲小圖標的地方;顯示在按鈕、菜單項或工具欄中 SHORT_DESCRIPTION 圖標的簡要說明;顯示在工具提示中 LONG_DESCRIPTION 圖標的詳細說明;使用在在線幫助中。沒有Swing組件使用這個值 MNEMONIC_KEY 快捷鍵縮寫;顯示在菜單項中 ACCELERATOR_KEY 存儲加速擊鍵的地方;Swing組件不使用這個值 ACTION_COMMAND_KEY 歷史遺留;僅在舊版本的registerKeyboardAction方法中使用 DEFAULT 常用的綜合屬性;Swing組件不使用這個值 - 如果動作對象添加到菜單或工具欄上,它的名稱和圖標就會被自動地提取出來,並顯示在菜單欄或工具欄項中。SHORT_DESCRIPTION值變成了工具提示。
- Action是一個接口,而不是一個類。有一個類實現了這個接口除actionPerformed方法之外的所有方法,它就是AbstractAction。這個類存儲了所有名、值對。並管理著屬性變更監聽器。可以直接擴展AbstractAction類,並在擴展類中實現了actionPerformed方法。
- 每個JComponent有三個輸入映射(input maps),每一個映射的KeyStore對象都與動作關聯。三個輸入映射對應著三個不同的條件。
輸入映射表標誌 激活動作 WHEN_FOCUSED 當這個組件擁有鍵盤焦點時 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 當這個組件包含了擁有鍵盤焦點的組件時 WHEN_IN_FOCUSED_WINDOW 當這個組件被包含在一個擁有鍵盤焦點組件的窗口中時 - 按鍵處理將按照下列順序檢查這些映射:
1)檢查具有輸入焦點組件的WHEN_FOCUSED映射。如果這個按鍵存在,將執行對應的動作。如果動作已啟動,則停止處理。
2)從具有輸入焦點的組件開始,檢查其父組件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT映射。一旦找到按鍵對應的映射,就執行對應的動作。如果動作已啟用,將停止處理。
3)查看具有輸入焦點的窗口中的所有可視的和啟用的組件,這個按鍵被註冊到WHEN_IN_FOCUSED_WINDOW映射中。給這些組件(按照按鍵註冊的順序)一個執行對應動作的機會。一旦第一個啟用的動作被執行,就停止處理。如果一個按鍵咋多個WHEN_IN+FOCUSED_WINDOW映射中出現,這部分處理就可能會出現問題。 - 可以使用getInputMap方法從組件中得到輸入映射。
- InputMap不能直接將KeyStore對象映射到Actoin對象中。而是先映射到任意對象上,然後由ActionMap類實現將對象映射到動作上的第2個映射。這樣很容易實現來自不同輸入映射的按鍵共享一個動作的目的。
- 每個組件都可以有三個輸入映射和一個動作映射。為了將他們組合起來,需要為動作命名。
- 用同一個動作響應按鈕、菜單項或按鍵的方式:
1)實現一個擴展於AbstractAction類的類。多個相關的動作可以使用同一個類。
2)構造一個動作類的對象。
3)使用動作對象創建按鈕或菜單項。構造器將從動作對象中讀取標簽文本和圖標。
4)為了能夠通過按鍵觸發動作,必須額外地執行幾步操作。首先定位頂層窗口組件,例如,包含所有其他組件的面板。
5)然後,得到頂層組件的WHEN_ANCESTOR_OF_FOCUS_COMPONENT輸入映射。為需要的按鍵創建一個KeyStore對象。創建一個描述動作字符串這樣的動作鍵對象。將(按鍵,動作鍵)對添加到輸入映射中。
6)最後,得到頂層組件的動作映射。將(動作鍵,動作對象)添加到映射中。 - javax.swing.Action 1.2
- boolean isEnabled()
- void setEnabled(boolean b)
獲得或設置這個動作額enabled屬性。 - void putValue(String key,Object value)
將名/值對防止在動作對象內。
參數:key 用動作對象存儲性能的名字。它可以是一個字符串,但預定義了幾個名字。 value 與名字關聯的對象。 - Object getValue(String key)
返回被存儲的名/值對的值。
- 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。
- static KeyStore getKeyStroke(String description)
- javax.swing.JComponent 1.2
- ActionMap getActionMap() 1.3
返回關聯動作映射鍵(可以是任意的對象)和動作對象的映射。 - InputMap getInputMap(int flag) 1.3
獲得將案件映射到動作鍵的輸入映射。
參數:flag 觸發動作的鍵盤焦點條件。
- ActionMap getActionMap() 1.3
8.3 鼠標動作
- 當用戶點擊鼠標按鈕時,將會調用三個監聽器方法:鼠標第一次按下時調用mousePressed;鼠標被釋放時調用mouseReleased;最後調用mouseClicked。如果只對最終的點擊事件感興趣,就可以忽略前兩個方法。用MouseEvent類對象作為參數,調用getX和getY方法可以獲得鼠標被按下時鼠標指針所在x和y坐標。要想區分單擊、雙擊和三擊(!),需要使用getClickCount方法。
- getModifiersEx方法能夠準確地報告鼠標事件的鼠標按鈕和鍵盤修飾符。
- 在Windows環境下,使用BUTTON3_DOWN_MASK檢測鼠標右鍵(非主要的)的狀態。
- java.awt.event.MouseEvent 1.1
- int getX()
- int getY()
- Point getPoint()
返回事件發生時,事件源組件左上角的坐標x(水平)和y(垂直),或點信息。 - int getClickCount()
返回與事件關聯的鼠標連擊次數(“連擊”所指定的時間間隔與具體系統有關)。
- 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”。
- int getModifiersEx() 1.4
- java.awt.Toolkit 1.0
- public Cursor createCustomCursor(Image image,Point hotSpot,String name) 1.2
創建一個新的定制光標對象。
參數:image 光標活動時顯示的圖像。hotSpot 光標熱點(箭頭的頂點或十字中心)。name 光標的描述,用來支持特殊的訪問環境。
- public Cursor createCustomCursor(Image image,Point hotSpot,String name) 1.2
- java.awt.Component 1.0
- public void setCursor(Cursor cursor) 1.1
用光標圖像設置給定光標。
- public void setCursor(Cursor cursor) 1.1
8.4 AWT事件繼承層次
- Java事件處理采用的是面向對象方法,所有的事件都是由java.util包中的EventObject類擴展而來的。EventObject類有一個子類AWTEvent,它是所有AWT事件類的父類。有些Swing組件將生成其他事件類型的事件對象;它們都直接擴展於EventObject,而不是AWTEvent。事件對象封裝了事件源與監聽器彼此通信的事件信息。在必要的時候,可以對傳遞給監聽器對象的事件對象進行分析。
- AWT將事件分為低級(low-level)事件和語義(semantic)事件。語義事件是表示用戶動作的事件,因此,ActionEvent是一種語義事件。低級事件是形成那些事件的事件。
- java.awt.event包中最常用的語義事件類:
- ActionEvent(對應按鈕點擊、菜單選擇、選擇列表項或文本框中ENTER);
- AdjustmentEvent(用戶調節滾動條);
- ItemEvent(用戶從復選框或列表框中選擇一項)。
- 常用的5個低級事件類是:
- KeyEvent(一個鍵被按下或釋放);
- MouseEvent(鼠標鍵被按下、釋放、移動或拖動);
- MouseWheelEvent(鼠標滾輪被轉動);
- FocusEvent(某個組件獲得焦點或失去焦點)。
- WindowEvent(窗口狀態被改變)。
下列接口將監聽這些事件:ActionListener、AdjustmentListener、FocusListener、ItemListener、KeyListener、MouseListener、MouseMotionListener、MouseWheelListener、WindowListener、WindowFocusListener、WindowStateListener。
- 常用的適配器類:FocusAdapter、KeyAdapter、MouseAdapter、MouseMotionAdapter、WindowAdapter。
- 事件處理總結
接口 方法 參數/訪問方法 事件源 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章-事件處理-讀書筆記