2016-05-08 7 views
1

私はJavaのテキストに600ページあり、混乱しています。Java Lambda式とイベント情報

Swingプログラミングのセクションでは、ボタンクリックを処理するための "EventListener"を作成する3つの異なる方法を示します。まず、ActionListenerを実装するクラスで関数を使用する方法、次にActionListenerを実装するネストされたクラスを使用する方法、最後にラムダ式を使用する方法を示します。

最初の2つの方法は、本質的に同一の機能(コメントは私です)を使用します。

… 
    button1=new JButton("foobar");    //create a button object 
    button1.addActionListener(this);   //add an event handler to it 
… 
public void actionPerformed(ActionEvent e) { //event handler (standalone or in a class) 
    if (e.getSource() == button1) {   //check if event source is the button 
    //do something 
    } 
} 

非常に簡単です。ボタンが作成され、ボタンオブジェクト自体、または関数を含む別のクラスがaddActionListenerに渡され、イベントハンドラがボタンに追加されます。

ラムダ式は一見似ているわずかストリップダウン機能使用しています。私を混乱させる何

… 
    button1 = new JButton("foobar");    //create a button 
    button1.addActionListener(e -> button1Click()); //set button1Click as event handler 
… 
public void button1Click() {      //event handler 
    //do something 
} 

をイベント情報の欠如です。最初の2つのメソッドでは、関数がボタンであるかどうかを確認するためにイベントソースをチェックする必要がありますが、ラムダ式はイベントソースがボタンであることを前提としています。どうやって?

これはどこですか? addActionListenerの呼び出しはbutton1で始まりますが、ラムダ式のどこにも記載されていません。また、ラムダ式を使用すると利用可能な情報が制限されているわけではありませんか?それはキーのようなものを見つけるための機能にアクセスする方法はありませんので、関数内eへの参照は、タイムスタンプが



等、、、存在しない(ああ、なぜJavaがイベントを呼び出しますリスナーの代わりに、ほぼすべての他の言語のようハンドラは私を超えている。そして、彼らは非ラムダ例に渡されたリスナーがthisであることを

+0

匿名の内部クラスを渡すのと同じように、1つのJButtonにのみlambaを追加します。これを行うときに、ボタンのソースを確認する必要はありません。一方、ラムダを作成し、この単一のラムダを複数のボタンに渡した場合、ActionEvent(ここではe)をbutton1Clickメソッドに渡したいとします。 –

+0

e-> button1Click(e) '。次に、button1ClickメソッドはもちろんActionEventパラメータを必要とし、その上で 'getSource()'を呼び出すことができます。 –

答えて

1

注)... JavaとJavaScriptは名前だけが似ていると言いますつまり、ボタンを設定するオブジェクトです。おそらく、そのオブジェクト(一部のコントローラまたはコンテナ)は、複数のボタンのイベントリスナーとして機能するため、どのイベントを送信したのかを区別する必要があります。一方、ラムダは、その単一のボタンにのみ取り付けられたワンオフハンドラインスタンスを作成しているので、あいまいさはありません。

+0

これは私が想定したものですが、ボタンオブジェクトへのポインタ(より良い用語がないため)がどこから来ているのかわかりません。最初のメソッドでは、これが 'this'のために使われているのがわかりますが、ラムダ(そして私が見ている内部クラスさえ)では、ボタンオブジェクトへの参照はありません。私はこれがすべて自動的に舞台裏で起こっていると仮定することができます(これはGCにとってはいいですが、このようなことの混乱につながります)。 – Synetech

+0

@Synetechこれはちょうど基本的なJavaです。 *ボタン*への参照は 'new JButton'から来ます。次に、そのボタンのメソッドを呼び出し、イベントリスナーのオブジェクトを渡します。ラムダでは、リスナーオブジェクトは1回だけ使用されます。それ以外の場合は、複数のボタンに再利用される可能性があります。 – chrylis

1

ラムダ式に「イベント情報がありません」と記載されています。イベント情報はラムダ式のです。他の例のように使用されていません。

この文脈で表現、

e -> button1Click() 

はそうあなたがeはイベント情報であることがわかります

(ActionEvent e) -> buttonClick() 

の省略形です。

一方、「イベント情報が不足している」とは、「イベント情報の使用が不足している」という意味で、答えが間違っているようです。2つのアプローチは同等であるため、リンゴをリンゴと比較するには、どちらの例もソースをチェックしてください。

+0

イベント情報がないため、 'e'は' addEventListener'の呼び出しでしか見られず、 'button1Click'(引数を取らない)関数に渡されないので、イベントソースを見るだけでなく、キープレスやタイムスタンプのような他のイベント情報にアクセスすることもできないようです。 – Synetech

+0

@Synetechの2つのアプローチは、可能な限り非常に似ています。ラムダは最初の例と同じように書くことができます。たとえば '(ActionEvent e) - > {if(e.getSource()== button1){/ *何か* /}}'です。最初の例と同じ情報で、まったく同じことをします。どちらの方法もイベントリスナを登録し、両方のハンドラが渡された同じイベントへのアクセス権を持ち、両方とも同じクラスフィールドとメンバ関数の可視性を持ちます。なぜ特定の事例がイベントデータを無視して別の言葉で書かれたのかが別の問題です。 –

関連する問題