0

私がC#でプログラミングしていたとき、私は非常に頻繁にイベントを利用していました。ここで、Javaで同様のことを実現したいと思います。私は両方の言語が異なっていることを知っています、そしてそのようなメカニズムを実装することにはいくつかの違いがあります。より良い画像を提供するために、用語の一部を混乱させる可能性があるため、取得したいものについて少し説明します。

MyClassには、 MyEventの起動を処理するコードと、特定の状況でそのイベントを起動するコードが含まれています。

MyEventArgsは、 MyClassからデータを転送し、イベントの起動とともに送信されるクラスであるため、MyEventを処理する関数には、 MyClassインスタンスの状態に関する追加情報があります。

また、メインメソッドにMyClassのインスタンスとMyEventを処理するコードを含むMyAppクラスがあり、MyClass内でイベントが発生すると、 MyEventをリッスンするコードで特定のアクションが実行されます。

それでも不明な場合は、ボタンクリックの背後にあるc#メカニズムとまったく同じです。ボタンの代わりにクラスがあり、マウスイベント引数の代わりにイベント引数があり、クリックの代わりに私が設計した動作があります。

私は自分の問題に対するいくつかの答えをグーグルで検索しようとしました、そして例えば私は次のようなサイトを見つけました:

http://javarevisited.blogspot.com/2011/12/observer-design-pattern-java-example.html http://www.javaworld.com/javaworld/javaqa/2002-03/01-qa-0315-happyevent .html

そして、私はちょうど迷子になり、悪い場所を探している/悪いキーワードを使用している、またはこれらの例から何も理解できない/必要な方法で機能するように変換できない可能性があります。

MyClass、 MyEvent、 MyEventArgs、名前、イベントを発生させるためにクラスで使用する必要のあるポインティングコード、およびクラスの使用例とイベントの処理を使用して、このようなメカニズムを処理するコードの例または少なくともドラフトを求めています。 Mainメソッドでは、この問題に頭を悩ませるのに役立ちます。

==========編集========

たぶん、Android開発者が利用できるようなものがいくつかありますか?私の目標は、Javaを削除した後、モバイルアプリの開発に取り掛かることです。

==========編集========

まだ興味のある人がいれば、ここにいくつかのサンプルコードがあります。これは私が言及した名前を使用せず、一般的に私が探しているものを示しています。

そして、正確な解決策はありません、多分誰かが私が探しているものに似た何かを提案するでしょうか?

frmTest.cs

namespace SampleApp
{
    public partial class frmTest : Form
    {
        CountdownTimer ctmrTest;

        public frmTest()
        {
            InitializeComponent();
            ctmrTest = new CountdownTimer(100);
            ctmrTest.CountdownTimerTick += new CountdownTimer.CountdownTimerTickEventHandler(ctmrTest_CountdownTimerTick); 
        }

        void ctmrTest_CountdownTimerTick(object sender, CountdownTimerEventArgs ea)
        {
            lblTimer.Text = ea.timeString;
            if (ea.countdownFinished) countdownEnd();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            ctmrTest.Reset();
            ctmrTest.Start();
        }

        void countdownEnd()
        {
            MessageBox.Show("Finish");
        }
    }
}

CountdownTimer.cs

namespace SampleApp
{
    public class CountdownTimer
    {
        Timer tmrTicks = new Timer();
        int secondsLeft = 0;
        int numberOfSecondsToCountdown = 0;

        public bool IsWorking
        {
            get { return tmrTicks.Enabled; }
        }

        public CountdownTimer(int seconds)
        {
            ...
        }

        void tmrTicks_Tick(object sender, EventArgs e)
        {
            ...
            WhenCountdownTimerTick(new CountdownTimerEventArgs(secondsLeft, numberOfSecondsToCountdown, true));
        }

        public void Reset()
        {
            ...
            WhenCountdownTimerTick(new CountdownTimerEventArgs(secondsLeft, numberOfSecondsToCountdown, false));
        }

        public void Stop()
        {
            tmrTicks.Enabled = false;
        }

        public void Start()
        {
            ,,,
        }

        public delegate void CountdownTimerTickEventHandler(object sender, CountdownTimerEventArgs ea);

        public event CountdownTimerTickEventHandler CountdownTimerTick;

        protected virtual void WhenCountdownTimerTick(CountdownTimerEventArgs ea)
        {
            if (CountdownTimerTick != null)
            {
                CountdownTimerTick(this, ea);
            }
        }
    }
}

CountdownTimerEventArgs.cs

namespace SampleApp
{
    public class CountdownTimerEventArgs : EventArgs
    {
        public string timeString = "";
        public bool countdownFinished = false;

        public CountdownTimerEventArgs(int secondsLeft, int SecondsToCountdown, bool isfinished)
        {
            countdownFinished = isfinished;
            timeString = string.Format("{0:00}:{1:00}", secondsLeft / 60, secondsLeft % 60);
        }
    }
}
4

2 に答える 2

3

私があなたを正しく理解している場合(私はC#を学び始めたばかりです)、Javaでそれを行う通常の方法は、オブザーバーパターン(リスナーパターン)を使用することです。

イベントが発生したときに呼び出されるメソッドを使用して、リスナーインターフェイスを作成します。このメソッドは、必要に応じて、いくつかのイベント引数と送信者をパラメーターとして受け取ることができます。例えば:

public interface MyListener { // This is probably your MyEvent
    void myEventFired(Object sender, MyEventArgs eventArgs);
}

public class MyEventArgs {
    ...something...
}

あなたの種類のイベントに応答するクラスは、上記のインターフェースを実装する必要があります。(少し下の例を参照してください(MyListeningClass))

では、イベントを発生させるクラス(または複数のクラス)が必要です:MyClass。通常、MyClassには、 MyClassのイベントに応答したい他のクラスが、自分自身をMyClassに登録するための何らかの方法があります。(より正確には、MyClassの特定のオブジェクトに自分自身を登録します)。これにより、MyClassオブジェクトは、イベントが発生したときに通知する必要がある他のオブジェクトを知ることができます。

これは通常、イベントを発生させるクラスに「add [ListenerName]」というメソッドを作成することによって行われます。この場合は、 MyClassに「 addMyListener」を作成します。この例を簡単にするために、リスナーは1つしか存在できないと仮定して、代わりに「 setMyListener 」と呼びます。

public class MyClass {

    private MyListener listener = null;

    // This is a method which sometimes fires an event, by calling the fireEvent() method below
    public void doSomething() {
        ...
        if (something) {
            // Let's say the event happens if "something" is true. 
            // So now we "fire the event". What "firing the event" means, 
            // is just to call the "myEventFired" method in the listener.
            fireEvent();
        }
        ...

    }

    // this is called from the method above to fire the event - i.e. to tell the listener that the event has happened
    protected void fireEvent() {
        if (listener != null) {
            Object sender = this; 
            MyEventArgs eventArgs = new MyEventArgs(...something...);
            listener.myEventFired(sender, eventArgs);
        }
    }

    // This method is called by the listener, to register itself as listener on this object.
    // MyClass remembers the listener in the "listener" instance variable, so that 
    // when the event happens at some later point in time, it knows which object it  
    // has to tell it to.
    public void setMyListener(MyListener listener) {
        this.listener = listener;
    }
}

(複数のリスナーをサポートするList<MyListener> listenersには、インスタンス変数の代わりにリスナーのリストをMyListener listener用意し、setListenerメソッドの代わりにaddListenerメソッドとremoveListenerメソッドを作成します。AndroidAPIでは通常1つのリスナーしか許可されないため、次のように表示します。そのバージョン)

だから今、私たちはイベントを聞きたいクラスが必要です。つまり、 MyListenerインターフェースを実装するクラスです。(したがって、このクラスはリスナーです)。簡単な例:

public class MyListeningClass implements MyListener {

    public MyListeningClass() {
        MyClass myClass = ...get the MyClass object from somewhere...;
        myClass.setMyListener(this);
    }

    // this is called by MyClass when the event occurs
    public void myEventFired(Object sender, MyEventArgs eventArgs) {
        System.out.println("EVENT HAPPENED!");
        System.out.println("Sender is: "+sender);
        System.out.println("MyEventArgs are: "+eventArgs);
    }    
}

(もちろん、必要がなければ実際にインターフェースを作成する必要はありません。もちろん、代わりにMyClassでMyListeningClassをハードコーディングすることもできますが、インターフェースを使用してMyClassとMyListeningClassを互いに分離する方が良いスタイルです。また、後でさらに拡張可能になり、MyListeningClass以外のクラスもイベントをリッスンできるようになります。)

JavaAPIにはこの例がたくさんあります。たとえば、SWINGはリスナーを多用します。たとえば、ボタンのクリックなどです。そしてもちろん、AndroidAPIも。

後でいくつかの例を見つけることができるかどうかを確認しますが、それは非常に遅く、私は非常に疲れているので、多分明日:D(そしてスペルミスを修正する:D)。それが少し役に立ったことを願っています。

要点をまとめると:

  • MyClass(イベントを生成するクラス)は、イベントが発生したときに、イベントが発生したことを他のクラスに通知する方法が必要です。これは、イベントが発生したときにこれらのクラスのメソッドを呼び出すことによって行われます。

  • MyClassがこれらの他のクラスのメソッドを呼び出せるようにするには、いくつかのインターフェースを実装する必要があります。

  • イベントが発生したときに伝えたいクラスは、 MyClassにそれについて伝えたいことを伝える方法が必要です。これが、MyClass.setMyListenerメソッドが必要な理由です。 (または、複数のリスナーを許可した場合:MyClass.addMyListenerメソッド)

(したがって、これには魔法のようなものは何もありません。単純なメソッド呼び出しです。)




(リスナーインターフェイスは通常「[イベントの名前]リスナー」という名前であることに注意してください。したがって、イベントの名前を「 MyEvent "。しかし、この投稿では、長すぎて単純ではないと思います。更新:考えてみると、実際には名前から「Event」を省略しているので、「MyListener」は正しいです。たとえば、 「OnClickEvent」と呼ぶイベント、インターフェース「OnClickListener」と呼びます。)

于 2012-11-07T04:04:52.007 に答える
0

あなたの最善の策はおそらくを使用することでしょうGoogle Web Toolkit (GWT)GWT WidgetsVisual Studio / C#を使用するのとほぼ同じ方法で、のイベントハンドラーを定義できます。

Eclipseにはウィンドウビルダープラグインも組み込まれています。

于 2012-11-07T03:33:11.687 に答える