4

誰かが答えてくれることを願っています。基本的に、イベントリスナーが接続されているコンボボックスの値に基づいて変更する必要がある文字列変数があります。ただし、文字列を最終にすると変更できませんが、最終にしないと、最終ではないことを日食がうめきます。最善の (そして最も簡単な) 回避策は何ですか?

コードは次のとおりです

final String dialogOutCome = "";

//create a listener for the combo box
Listener selection = new Listener() {

    public void handleEvent(Event event) {
    //get the value from the combo box
    String comboVal = combo.getText();

    switch (comboVal) {
         case "A": dialogOutCome = "a";
         case "B": dialogOutCome = "b";
         case "C": dialogOutCome = "c";
         case "D": dialogOutCome = "d";
    }
   }
};
4

6 に答える 6

5

できません。

このことを考慮:

  • ローカル変数は、それが宣言されているメソッドが実行される限り存在します。
  • そのメソッドの呼び出しが終了するとすぐに (通常はメソッドが存在するため)、変数は消えます
  • リスナーはより長く生きることができます(そして通常はそうします)

では、メソッドがすでに返されているときに、リスナーがローカル変数を変更しようとするとどうなるでしょうか?

この質問には本当に良い答えがないため、非finalローカル変数へのアクセスを許可しないことで、そのシナリオを不可能にすることにしました。

この問題を回避するには、次の 2 つの方法があります。

  • ローカル変数の代わりにフィールドを変更してみてください (これはおそらくリスナーの寿命にもより適しています)または
  • コンテンツfinalを変更できるローカル変数を使用します(たとえば、単一の要素を持つaまたは a )。ListString[]
于 2013-01-17T15:15:06.607 に答える
3

これらの答えはすべて、欠陥のあるアプローチを表面的なレベルで「機能させる」方法を教えてくれます。

本当の問題は、従来の同期的な「call/return」コーディング パターンを、それをサポートしていないライブラリに適用しようとしていることにあります。本当の答えは、待っているイベントが非同期で発生した場合、イベントの後にやりたいことも非同期で発生する必要があるということです。Swing のイベント駆動型の性質を理解することは、Swing で効果を発揮するために不可欠です。

つまり、コードのどの部分が を読み取るかを考えてくださいdialogOutCome。なんらかのアクションが実行されますか? その場合は、代わりにハンドラーから(またはハンドラーの結果として) そのアクションを実行します。

于 2013-01-17T15:20:58.207 に答える
2

別の方法は、このアプローチを使用することです。

public class ReturnValueListener implements Listener {

    private String dialogOutCome;

    public void handleEvent(Event event) {
        //get the value from the combo box
        String comboVal = combo.getText();

        switch (comboVal) {
            case "A": dialogOutCome = " gay";
            ase "B": dialogOutCome = " ugly";
            case "C": dialogOutCome = " smelly";
            case "D": dialogOutCome = " great";
        }
    }

    public String getDialogOutCome() {
        return dialogOutCome;
    }
}

Listener selection = new ReturnValueListener();
//Set my listener somewhere,
....registerListener(selection);
//After my handleEvent is called
String dialogOutCome = selection.getDialogOutCome();
于 2013-01-17T15:15:24.107 に答える
1

シンプルなStringWrapperオブジェクトを作成するだけです:

static class StringWrapper {
       String value;

       StringWrapper(String value) {
           this.value = value;
       } 
}

フィールドのタイプでそれを使用しますdialogOutCome

final StringWrapper dialogOutCome = new StringWrapper("");

Listener selection = new Listener() {

    public void handleEvent(Event event) {
        String comboVal = combo.getText();

        switch (comboVal) {
          case "A": dialogOutCome.value = " gay";
          case "B": dialogOutCome.value = " ugly";
          case "C": dialogOutCome.value = " smelly";
          case "D": dialogOutCome.value = " great";
        }
   }
};
于 2013-01-17T15:14:39.313 に答える
0

間接化にはセッターを使用できます。これにより、最終的な制限が取り除かれます (アクセスしているフィールドが「dialogOutcome」ではなく「this」であるためです。

String dialogOutCome = "";

void setOutcome(String value){
  dialogOutCome = value;
}

//create a listener for the combo box
Listener selection = new Listener() {

    public void handleEvent(Event event) {
    //get the value from the combo box
    String comboVal = combo.getText();

    switch (comboVal) {
         case "A": setOutcome(" gay");
         case "B": setOutcome(" ugly");
         case "C": setOutcome(" smelly");
         case "D": setOutcome(" great");
    }
   }
};
于 2013-01-17T15:18:12.470 に答える
-2

回避策:の代わりにStringBuilderStringを使用します。もちろん、 でStringBuilder参照を変更することはできませんがhandleEvent、そのメソッドを呼び出すことはできます。

    final StringBuilder sb = new StringBuilder();

    Listener selection = new Listener() {

        public void handleEvent(Event event) {
        ...
        switch (comboVal) {
             case "A": sb.delete(0, sb.length()).append("a");
             case "B": sb.delete(0, sb.length()).append("b");
            ...
        }
       }
    };

...
System.out.println(sb.toString());

次に、文字列値を取得できますStringBuilder.toString();

編集:この回答に投票する理由を記入してください。

于 2013-01-17T15:20:19.523 に答える