<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 13.13 `action`的替代品 正如早先指出的那樣,`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`中的字符串陳述。從我們可以真正注意到舉出的例子在我們的程序中運行事件時以來,可以發現這個例子運行起來頗為有趣的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看