程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java action的替用品

java action的替用品

編輯:關於JAVA

正如早先指出的那樣,action()並不是我們對所有事進行分類後自動為handleEvent()調用的唯一方法。有三個其它的被調用的方法集,如果我們想捕捉某些類型的事件(鍵盤、鼠標和焦點事件),因此我們不得不過載規定的方法。這些方法是定義在基礎類組件裡,所以他們幾乎在所有我們可能安放在窗體中的組件中都是有用的。然而,我們也注意到這種方法在Java 1.1版中是不被支持的,同樣盡管我們可能注意到繼承代碼利用了這種方法,我們將會使用Java 1.1版的方法來代替(本章後面有詳細介紹)。

組件方法 何時調用

action(Event evt, Object what) 當典型的事件針對組件發生(例如,當按下一個按鈕或下拉列表項目被選中)時調用
keyDown(Event evt, int key) 當按鍵被按下,組件擁有焦點時調用。第二個自變量是按下的鍵並且是冗余的是從evt.key處復制來的
keyup(Event evt, int key) 當按鍵被釋放,組件擁有焦點時調用
lostFocus(Event evt, Object what) 焦點從目標處移開時調用。通常,what是從evt.arg裡冗余復制的
gotFocus(Event evt, Object what) 焦點移動到目標時調用
mouseDown(Event evt, int x,int y) 一個鼠標按下存在於組件之上,在X,Y座標處時調用
mouseUp(Event evt, int x, int y) 一個鼠標升起存在於組件之上時調用
mouseMove(Event evt, int x, int y) 當鼠標在組件上移動時調用
mouseDrag(Event evt, int x, int y) 鼠標在一次mouseDown事件發生後拖動。所有拖動事件都會報告給內部發生了mouseDown事件的那個組件,直到遇到一次mouseUp為止
mouseEnter(Event evt, int x, int y) 鼠標從前不在組件上方,但目前在
mouseExit(Event evt, int x, int y) 鼠標曾經位於組件上方,但目前不在

當我們處理特殊情況時——一個鼠標事件,例如,它恰好是我們想得到的鼠標事件存在的座標,我們將看到每個程序接收一個事件連同一些我們所需要的信息。有趣的是,當組件的handleEvent()調用這些方法時(典型的事例),附加的自變量總是多余的因為它們包含在事件對象裡。事實上,如果我們觀察component.handleEvent()的源代碼,我們能發現它顯然將增加的自變量抽出事件對象(這可能是考慮到在一些語言中無效率的編碼,但請記住Java的焦點是安全的,不必擔心。)試驗對我們表明這些事件事實上在被調用並且作為一個有趣的嘗試是值得創建一個過載每個方法的程序片,(action()的過載在本章的其它地方)當事件發生時顯示它們的相關數據。
這個例子同樣向我們展示了怎樣制造自己的按鈕對象,因為它是作為目標的所有事件權益來使用。我可能會首先(也是必須的)假設制造一個新的按鈕,我們從按鈕處繼承。但它並不能運行。取而代之的是,我們從畫布組件處(一個非常普通組件)繼承,並在其上不使用paint()方法畫出一個按鈕。正如我們所看到的,自從一些代碼混入到畫按鈕中去,按鈕根本就不運行,這實在是太糟糕了。(如果您不相信我,試圖在例子中為畫布組件交換按鈕,請記住調用稱為super的基礎類構建器。我們會看到按鈕不會被畫出,事件也不會被處理。)
myButton類是明確說明的:它只和一個自動事件(AutoEvent)“父窗口”一起運行(父窗口不是一個基礎類,它是按鈕創建和存在的窗口。)。通過這個知識,myButton可能進入到父窗口並且處理它的文字字段,必然就能將狀態信息寫入到父窗口的字段裡。當然這是一種非常有限的解決方法,myButton僅能在連結AutoEvent時被使用。這種代碼有時稱為“高度結合”。但是,制造myButton更需要很多的不是為例子(和可能為我們將寫的一些程序片)擔保的努力。再者,請注意下面的代碼使用了Java 1.1版不支持的API。
 

//: AutoEvent.java
// Alternatives to action()
import java.awt.*;
import java.applet.*;
import java.util.*;

class MyButton extends Canvas {
  AutoEvent parent;
  Color color;
  String label;
  MyButton(AutoEvent parent, 
           Color color, String label) {
    this.label = label;
    this.parent = parent;
    this.color = color;
  }
  public void paint(Graphics  g) {
    g.setColor(color);
    int rnd = 30;
    g.fillRoundRect(0, 0, size().width, 
                    size().height, rnd, rnd);
    g.setColor(Color.black);
    g.drawRoundRect(0, 0, size().width, 
                    size().height, rnd, rnd);
    FontMetrics fm = g.getFontMetrics();
    int width = fm.stringWidth(label);
    int height = fm.getHeight();
    int ascent = fm.getAscent();
    int leading = fm.getLeading();
    int horizMargin = (size().width - width)/2;
    int verMargin = (size().height - height)/2;
    g.setColor(Color.white);
    g.drawString(label, horizMargin, 
                 verMargin + ascent + leading);
  }
  public boolean keyDown(Event evt, int key) {
    TextField t = 
      (TextField)parent.h.get("keyDown");
    t.setText(evt.toString());
    return true;
  }
  public boolean keyUp(Event evt, int key) {
    TextField t = 
      (TextField)parent.h.get("keyUp");
    t.setText(evt.toString());
    return true;
  }
  public boolean lostFocus(Event evt, Object w) {
    TextField t = 
      (TextField)parent.h.get("lostFocus");
    t.setText(evt.toString());
    return true;
  }
  public boolean gotFocus(Event evt, Object w) {
    TextField t = 
      (TextField)parent.h.get("gotFocus");
    t.setText(evt.toString());
    return true;
  }
  public boolean 
  mouseDown(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseDown");
    t.setText(evt.toString());
    return true;
  }
  public boolean 
  mouseDrag(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseDrag");
    t.setText(evt.toString());
    return true;
  }
  public boolean 
  mouseEnter(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseEnter");
    t.setText(evt.toString());
    return true;
  }
  public boolean 
  mouseExit(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseExit");
    t.setText(evt.toString());
    return true;
  }
  public boolean 
  mouseMove(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseMove");
    t.setText(evt.toString());
    return true;
  }
  public boolean mouseUp(Event evt,int x,int y) {
    TextField t = 
      (TextField)parent.h.get("mouseUp");
    t.setText(evt.toString());
    return true;
  }
}

public class AutoEvent extends Applet {
  Hashtable h = new Hashtable();
  String[] event = {
    "keyDown", "keyUp", "lostFocus", 
    "gotFocus", "mouseDown", "mouseUp", 
    "mouseMove", "mouseDrag", "mouseEnter", 
    "mouseExit"
  };
  MyButton 
    b1 = new MyButton(this, Color.blue, "test1"),
    b2 = new MyButton(this, Color.red, "test2");
  public void init() {
    setLayout(new GridLayout(event.length+1,2));
    for(int i = 0; i < event.length; i++) {
      TextField t = new TextField();
      t.setEditable(false);
      add(new Label(event[i], Label.CENTER)); 
      add(t);
      h.put(event[i], t);
    }
    add(b1);
    add(b2);
  }
} ///:~

我們可以看到構建器使用利用自變量同名的方法,所以自變量被賦值,並且使用this來區分:
this.label = label;
paint()方法由簡單的開始:它用按鈕的顏色填充了一個“圓角矩形”,然後畫了一個黑線圍繞它。請注意size()的使用決定了組件的寬度和長度(當然,是像素)。這之後,paint()看起來非常的復雜,因為有大量的預測去計算出怎樣利用“font metrics”集中按鈕的標簽到按鈕裡。我們能得到一個相當好的關於繼續關注方法調用的主意,它將程序中那些相當平凡的代碼挑出,當我們想集中一個標簽到一些組件裡時,我們正好可以對它進行剪切和粘貼。
您直到注意到AutoEvent類才能正確地理解keyDown(),keyUp()及其它方法的運行。這包含一個Hashtable(譯者注:散列表)去控制字符串來描述關於事件處理的事件和TextField類型。當然,這些能被靜態的創建而不是放入Hashtable但我認為您會同意它是更容易使用和改變的。特別是,如果我們需要在AutoEvent中增加或刪除一個新的事件類型,我們只需要簡單地在事件列隊中增加或刪除一個字符串——所有的工作都自動地完成了。
我們查出在keyDown(),keyup()及其它方法中的字符串的位置回到myButton中。這些方法中的任何一個都用父句柄試圖回到父窗口。父類是一個AutoEvent,它包含Hashtable h和get()方法,當擁有特定的字符串時,將對一個我們知道的TextField對象產生一個句柄(因此它被選派到那)。然後事件對象修改顯示在TextField中的字符串陳述。從我們可以真正注意到舉出的例子在我們的程序中運行事件時以來,可以發現這個例子運行起來頗為有趣的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved