隨筆 - 154  文章 - 60  trackbacks - 0
          <2007年11月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          聲明:

          該blog是為了收集資料,認識朋友,學習、提高技術,所以本blog的內容除非聲明,否則一律為轉載!!

          感謝那些公開自己技術成果的高人們!!!

          支持開源,尊重他人的勞動!!

          常用鏈接

          留言簿(3)

          隨筆分類(148)

          隨筆檔案(143)

          收藏夾(2)

          其他

          學習(技術)

          觀察思考(非技術)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          在Java Swing編程過程中,經常需要處理鍵盤事件,例如處理快捷鍵等。這里就介紹如何定義鍵盤事件,以及如何處理這些事件。

          在jdk1.2中,分別針對Jcomponent和Text類的對象定制了不同的處理鍵盤事件的方法:在Jcomponent中,定義了registerKeyboardAction方法,使用這個方法來將需要處理的鍵盤事件以及處理事件的行為綁定在一起。Text類中具有keymap對象,同Jcomponent中的處理方法類似,這個對象保存著需要處理的鍵盤事件和對應的行為。

          而在jdk1.3中,使用一種新的方法來處理鍵盤事件,它將jdk1.2的兩種方法整合在一起。不需要區分被處理的是Jcomponent還是Text類型的組件。它定義了兩個新的類:InputMap和ActionMap。他們均是簡單的表或映射。一個InputMap將一個Keystroke對應到一個對象,ActionMap將一個對象對應到一個行為(Action)。通常InputMap中KeyStroke所對應的對象是一個字符串,通過這個字符串可以在ActionMap中查找到相應的行為。

          InputMap和ActionMap中均有put方法。InputMap的put方法可以將Keystroke對應到一個對象,而ActionMap的put方法可以將一個對象對應到一個行為。

          在每一個Jcomponent組件中,會有三個缺省的InputMap和一個缺省的ActionMap。他們可以通過調用getInputMap(int condition)和getActionMap()得到。三個InputMap分別是當組件本身擁有焦點時的InputMap(WHEN_FOCUSED),當組件的祖先擁有焦點時的InputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)和組件所在的窗體具有焦點時的InputMap(WHEN_IN_FOCUSED_WINDOW)(括號內表示為了得到這些InputMap,應該在getInputMap中設置的參數)。以下分別說明這三種InputMap:

          1. 組件本身擁有焦點時的InputMap:當組件擁有焦點時,鍵盤按鍵按下,則java在這個InputMap中查找鍵盤事件所對應的KeyStroke對象。

          2. 組件的祖先擁有焦點時的InputMap:當組件的祖先擁有焦點時,鍵盤按鍵按下,則java查找這個InputMap。

          3. 組件所在的窗口擁有焦點時的InputMap:當組件所在的窗口具有焦點時,鍵盤按鍵按下,則java查找這個InputMap。

          當一個鍵被按下,這個事件被轉化成一個KeyStroke對象,java會查找這個Jcomponent的相應InputMap(例如,當組件的祖先具有焦點時,java就查找這個Jcomponent的祖先擁有焦點的InputMap)中是否有這個KeyStroke,如果有,取出它所對應的對象(通常是字符串),利用這個對象在這個Jcomponent的ActionMap中查找,如果找到對應的行為(Action),則java執行這個行為的actionPerformed方法(隨后介紹這個方法)。從而達到處理鍵盤事件的目的。

          每一個InputMap可以具有parent屬性,這個屬性的值是一個InputMap。當在一個InputMap中查找不到鍵盤事件的KeyStroke時,java會自動在它的parent屬性指定的InputMap中查找,依次向上查找,直至找到。使用parent的好處是:當有一些固定的,不希望用戶進行改動的鍵盤映射可以存放在parent屬性所指定的InputMap中,從而避免被意外修改;另外可以將多個Jcomponent的缺省InputMap設置具有相同的parent,使得可以共享一些鍵盤綁定的設置。可以通過InputMap類的setparent()方法設置它的parent屬性。ActionMap也具有相同的parent屬性,使用方法也相同。

          以上是如何將一個鍵盤事件對應到一個行為,以下就簡單介紹行為(Action)。

          行為是一個實現了Action接口的類。在Action接口中定義了7個方法。其中最關鍵的是actionPerformed()方法。這個方法描述了這個行為的具體操作過程。其他幾個方法包括setEnabled,isEnabled,putValue,getValue,addPropertyChangeListener,和removePropertyChangeListener方法。他們分別用來設置行為是否可用、判斷行為可用的狀態、設置和取得行為的一些屬性,最后兩個方法用來允許其他對象在行動對象的屬性發生變化后得到通知。

          通常我們使用一個實現了Action接口的大部分方法的抽象類AbstractAction類作為基類,重載actionPerformed方法以實現我們的行為。

          我們用一個例子來具體說明如何進行實際的操作。

          首先編寫一個具體的行為,對指定的鍵盤事件進行處理:

          public class TextAction extends AbstractAction
                      {
                       private String a;
                       public TextAction(String a)
                       { this.a = a; }
                        public void actionPerformed(ActionEvent parm1)
                        {
                         String b = parm1.getActionCommand(); //得到行為的命令字符串
                         System.out.println("command="+b);
                         System.out.println("prompt="+this.a);
                        }
                       }

          建立四個TextAction對象:

          TextAction whenFocusSon = new TextAction("focus son");

          TextAction whenFocusFather = new TextAction("focus father");

          TextAction window = new TextAction("window");

          TextAction ancestor = new TextAction("ancestor");

          隨后,在一個窗體中加入兩個面板,名為sonPanel和parentPanel,使得parentPanel是sonPanel的祖先。并在sonPanel中加入一個名為son的button,在parentPanel中加入名為parent的button。在fatherPanel外加入幾個button。

          得到son組件的三個InputMap,并創建一個名為focusFatherIm的InputMap,使得這個InputMap成為focusIm的parent:

          //get default inputMap (when focus inputmap) and set a parent InputMap
                      focusIm = son.getInputMap();
                      focusFatherIm = new InputMap();
                      focusIm.setParent(focusFatherIm);
                      //get WHEN_ANCESTOR_OF_FOCUSED_COMPONENT inputMap
                      ancestorIm = son.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                      //get WHEN_IN_FOCUSED_WINDOW inputMap
                      windowIm = son.getInputMap(WHEN_IN_FOCUSED_WINDOW);
                      //在這些InputMap中分別加入鍵盤綁定:
                      focusIm.put(KeyStroke.getKeyStroke('f'),"actionFocusSon");
                      focusFatherIm.put(KeyStroke.getKeyStroke('F'),"actionFocusFather");
                      ancestorIm.put(KeyStroke.getKeyStroke('a'),"actionAncestor");
                      windowIm.put(KeyStroke.getKeyStroke('w'),"actionWindow");
                      //得到son組件的缺省的ActionMap,并將已經建立的行為與特定的對象(字符串)進行綁定:
                      am = son.getActionMap();
                      am.put("actionFocusSon",whenFocusSon);
                      am.put("actionFocusFather",whenFocusFather);
                      am.put("actionAncestor",ancestor);
                      am.put("actionWindow",window);

          運行程序及其相應結果:

          1. 單擊son按鈕,這時如果按下'f','F','a','w',程序均會有相應的輸出。這是因為,此時的焦點在son按鈕上,而son按鈕組件的三個InputMap都是有效的。所以他們對應的事件都會發生。

          2. 單擊parent按鈕,這時按下'w',程序會有相應的輸出。而按下'f','F','a',程序沒有反應。這是因為parent按鈕具有焦點,這個按鈕不是son按鈕的祖先,而son所在的窗口具有焦點,所以只有組件所在窗口具有焦點的InputMap是有效的。

          3. 單擊其他的按鈕(parentPanel外的按鈕),這時按下'w',程序會有相應的輸出。而按下'f','F','a',程序沒有反應。這是因為這些按鈕具有焦點,他們不是son按鈕的祖先,而son所在的窗口具有焦點,所以只有組件所在窗口具有焦點的InputMap是有效的。

          附:主要程序代碼:

          import java.awt.*;
                      import javax.swing.*;
                      import com.borland.jbcl.layout.*;
                      import java.awt.event.ActionEvent;
                      import java.awt.event.ActionListener;
                      import com.sun.java.swing.plaf.motif.*;
                      public class EventPanel extends JPanel implements ActionListener
                      {
                       JButton btnYellow = new JButton();
                       JButton btnBlue = new JButton();
                       JButton btnRed = new JButton();
                       JPanel parentPanel = new JPanel();
                       JPanel sonPanel = new JPanel();
                       XYLayout xYLayout1 = new XYLayout();
                       JButton son = new JButton();
                       JButton parent = new JButton();
                       public EventPanel()
                       {
                        try{
                         jbInit();
                        }catch(Exception ex)
                        { ex.printStackTrace(); }
                        }
                       void jbInit() throws Exception
                       {
                        btnYellow.setText("Yellow");
                        btnYellow.setBounds(new Rectangle(35, 23, 97, 29));
                        this.setLayout(null);
                        btnBlue.setBounds(new Rectangle(154, 21, 97, 29));
                        btnBlue.setText("Blue");
                        btnRed.setBounds(new Rectangle(272, 24, 97, 29));
                        btnRed.setText("Red");
                        parentPanel.setBorder(BorderFactory.createRaisedBevelBorder());
                        parentPanel.setBounds(new Rectangle(27, 68, 358, 227));
                        parentPanel.setLayout(xYLayout1);
                        sonPanel.setBorder(BorderFactory.createLoweredBevelBorder());
                        son.setText("son");
                        parent.setText("parent");
                        this.add(btnYellow, null);
                        this.add(btnBlue, null);
                        this.add(btnRed, null);
                        this.add(parentPanel, null);
                        parentPanel.add(sonPanel, new XYConstraints(58, 22, 229, 125));
                        sonPanel.add(son, null);
                        parentPanel.add(parent, new XYConstraints(150, 167, -1, -1));
                        btnYellow.addActionListener(this);
                        btnRed.addActionListener(this);
                        btnBlue.addActionListener(this);
                        InputMap focusIm,focusFatherIm,ancestorIm,windowIm;
                        ActionMap am;
                        //create four TextAction for diff purpose
                        TextAction whenFocusSon = new TextAction("focus son");
                        TextAction whenFocusFather = new TextAction("focus father");
                        TextAction window = new TextAction("window");
                        TextAction ancestor = new TextAction("ancestor");
                        //get default inputMap (when focus inputmap) and set a parent InputMap
                        focusIm = son.getInputMap();
                        focusFatherIm = new InputMap();
                        focusIm.setParent(focusFatherIm);
                        //get WHEN_ANCESTOR_OF_FOCUSED_COMPONENT inputMap
                        ancestorIm = son.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                        //get WHEN_IN_FOCUSED_WINDOW inputMap
                        windowIm = son.getInputMap(WHEN_IN_FOCUSED_WINDOW);
                        //put the keyStroke to the InputMap
                        focusIm.put(KeyStroke.getKeyStroke('f'),"actionFocusSon");
                        focusFatherIm.put(KeyStroke.getKeyStroke('F'),"actionFocusFather");
                        ancestorIm.put(KeyStroke.getKeyStroke('a'),"actionAncestor");
                        windowIm.put(KeyStroke.getKeyStroke('w'),"actionWindow");
                        //get the actionMap
                        am = son.getActionMap();
                        am.put("actionFocusSon",whenFocusSon);
                        am.put("actionFocusFather",whenFocusFather);
                        am.put("actionAncestor",ancestor);
                        am.put("actionWindow",window);
                       }
                       public void actionPerformed(ActionEvent e)
                       {
                        //this code is used to change the backgracolor
                        Object source=e.getSource();
                        Color color=null;//=getBackground();
                        if (source==btnYellow) color=Color.yellow;
                        else if (source==btnRed) color = Color.red;
                        else if (source == btnBlue) color = Color.blue;
                        setBackground(color);
                        repaint();
                       }
                      }
          posted on 2007-11-15 13:52 lk 閱讀(678) 評論(0)  編輯  收藏 所屬分類: j2se
          主站蜘蛛池模板: 诸暨市| 鄯善县| 通州市| 昂仁县| 长海县| 随州市| 遵义市| 永清县| 新昌县| 海宁市| 浦江县| 浮山县| 唐山市| 凤山县| 呼伦贝尔市| 社会| 镇巴县| 桐城市| 车险| 临安市| 松潘县| 山西省| 临海市| 崇仁县| 遵义市| 三原县| 三河市| 商都县| 砀山县| 孙吴县| 会同县| 隆子县| 铜川市| 永德县| 康马县| 辰溪县| 南陵县| 青冈县| 策勒县| 巢湖市| 阳高县|