4

私がやろうとしていることを説明させてください -タイトルはそれを大まかに説明していると思いますが、私が物事を正しい方法で行っているかどうかはあまり確信が持てないので、間違っている場合は修正してください!

を使用してカスタム ダイアログを作成しましたLayeredPane。基本的にjPanelは に表示されるためPOPUP_LAYER、メイン コンテンツの上に重ねて表示されます。このパネルには、単純な「label-textbox-okay-cancel」コントロール グループが含まれています。これを「ダイアログ パネル」と呼びます。

何をしようとしていますか: メイン ウィンドウ ( に含まれるLayeredPane) でボタンをクリックすると、ダイアログ パネルが表示され、ユーザーがテキストを入力できるようになり、[OK] または [キャンセル] をクリックします。これはすべて簡単ですが、このコードを再利用できるようにしたいと思います。つまり、メイン ウィンドウの他のボタンは同じDialog Panelを呼び出しますが、ラベルのテキストは異なります。

もちろん、これにはある種のコールバック関数を含める必要があります。これにより、ダイアログ パネルの OK ボタンが、それを呼び出したボタンに応じて正しいコードを実行します。

私の現在の試みは、ユーザーがDialog Panelの OK ボタンをクリックしたときに実行される関数の名前を含む文字列を格納することです。この文字列を取得して関数名に変換しようとしていますが、これまでに「リフレクション」への参照が多数見つかりましたが、その多くは良い考えではないことを示唆しています。

いずれにせよ、以下のコードの「obj」が何であるかを理解せず、メソッドを呼び出すことができないため、サンプルコードを動作させることができませんでした:

method = obj.getClass().getMethod(myCallbackString);

私の質問は次のとおりです。

まず、私はこれについて正しい方法で進んでいますか?私は提案を受け入れる以上のものですが、私は本当に始めたばかりなので、できるだけシンプルに保つようにしてください!

次に、上記のコードの「obj」は何ですか? これが私がやるべきことではない場合でも、私は本当に知りたいです!

私の他の考えには、次のようなものがあります。私のダイアログ パネルは独自のクラスにある必要があります。そうであれば、コールバック関数を渡す方法は?

ヘルプやアドバイスをいただければ幸いです。

ところで:「なぜ通常のダイアログを使わないのですか?」という質問への答えとして。私は現在実験しているとしか言えません。これができるかどうかを確認したいだけです。

MVK

4

5 に答える 5

5

Java プログラムがコールバック関数を渡す通常の方法は、特定のコールバック関数を実装するインターフェイスのインスタンスを渡すことです。必須ではありませんが、インターフェイスを匿名で実装するのが一般的です。

たとえば、次のインターフェイスがあります。

interface MyCallback {
    void performCallback();
}

コールバックを受け取るダイアログのメソッドを定義する方法は次のとおりです。

void openWithCallback(MyCallback cb) {
    // Do something useful...
    ...
    // Perform the callback
    cb.performCallback();
}

そのメソッドを呼び出す方法は次のとおりです。

public void OpenDialog() {
    myDialog.openWithCallback(new MyCallback() {
        public void performCallback() {
            System.out.println("Inside callback...");
        }
    });
}
于 2012-07-08T13:10:10.753 に答える
2
  1. 大きな欠点がありますが、あなたのアイデアは有効だと思います.メソッド名をコードに単純な文字列として保存するため、コンパイラはそれらの有効性をチェックできません。したがって、メソッドの名前を変更する場合は、それを参照するすべての文字列を手動で更新する必要があります。これは通常、「反省は悪い考えだ」という意味です。
  2. objコード内の は、メソッドを呼び出すオブジェクトです。someInteger.toString();簡単な例として、リフレクションと同等のものはsomeInteger.getClass().getMethod("toString").invoke();.

より一般的な注意として、Java に慣れたら、関数が通常のオブジェクトである Scala のような関数型言語もチェックしてみてください。意図したシナリオは、完全なコンパイラ チェックで実装できます。

于 2012-07-08T13:11:05.963 に答える
2

objメソッドを呼び出したいオブジェクトに名前を付けます。あなたの場合、おそらくそれを置き換えることができますthis(または完全に削除することthisが暗示されているため):

private void callByName(String name) { 
  try { getClass().getMethod(name).invoke(this); }
  catch (RuntimeException e) { throw e; }
  catch (Exception e) { throw new RuntimeException(e); }
}

これを機能させるには、適切な名前で引数なしの public メソッドを宣言する必要があります。

于 2012-07-08T13:09:59.327 に答える
2

この方法を必要以上に複雑にしていると思います。あなたはこれが欲しいと言った:

This is all easy enough, but I would like this code to be re-usable, which means 
that other buttons on the main window will invoke the same Dialog Panel, but with
different text in the label.

DialogBox は、定義上、再利用可能です。ボタン クリック リスナーが、クリックされたときに適切なテキストをダイアログ ボックスに渡して、正しい情報が表示されるようにしないのはなぜですか?

呼び出し側に応じて、ダイアログでボタンをクリックした後に特定のアクションを実行する必要がある場合は、次のことを検討してください。

  1. 誰がそれを呼び出したかに基づいて何をすべきかを知るロジックを含む、カスタム DialogBox 拡張機能を作成しました。次に、ボタンがカスタム ダイアログを呼び出すときに、パラメータを渡して、ダイアログ ボックスが閉じられた後に何をしたいのかを知らせます。

  2. 抽象的なファクトリ パターンのようなものを使用することを検討してください。

はい、リフレクションを介してこれを行うことができます。はい、他の人が他の回答で議論した多くの理由から、特にこれが製品コードである場合、それは非常に悪い考えです (ただし、実験であることを示しているようです)。

本当にリフレクションを使って作業する方法を見たいだけなら、おそらくそのトピックを読みたいと思うでしょう。これは、優れたチュートリアルの 1 つだと思います。

于 2012-07-08T13:17:39.170 に答える
1

JPanel を使用したことはありませんが、クエリから理解していることは、答えがかなり単純なようです。メソッド名を渡す代わりに、インターフェイスで作業して、そのインターフェイスの別の実装を渡さないのはなぜですか?

于 2012-07-08T13:09:23.453 に答える