0

この投稿は私の最後の投稿に関連しています。コードのブロックは、目的の時間の後にテキストを目的の色に変更します。ただし、今では、各文字が同じ時間になるように特定の単語の色を変更したいと考えています。例えば、「hello」に 1000 ミリ秒の時間が与えられている場合 (5 文字)、「h''e''l' 'l''o' の各文字は 1000/5 ミリ秒、つまりそれぞれ 200 ミリ秒になります。

私はこれのためにスイングタイマーを実装しました:

public Reminder() {

    a[0]=2000;
    a[1]=1000;
    a[2]=3000;
   a[3]=5000;
    a[4]=3000;
ActionListener actionListener = new ActionListener() {
  public void actionPerformed(ActionEvent actionEvent) {
  point =point +arr[i].length();
i++;

     doc.setCharacterAttributes(0,point+1, textpane.getStyle("Red"), true);
     timer.setDelay(a[i]);

    }
};

timer = new Timer(a[i], actionListener);
timer.setInitialDelay(0);
timer.start();

これを行うには、特定の文字にさらにタイミングを与えるためにTimer内部で別のものを使用する必要がありますか?または、最初に時間を破って からタイマーを使用する必要がありますか?私はより良い方法を決めることができません.何かアイデアはありますか?actionListener.length()

4

1 に答える 1

1

複数のタイマーが必要になることはありません。すべてがいつ起こるべきかを事前に正確に知っているので、それらの時間を計算し、それらをリスト (時間でソート) に入れて、それぞれを実行します。

public colorize(int offset, int length) {
    long triggerTime[] = new long[length];
    long startTime = System.currentTimeMillis();
    for (int i=0; i<length; i++) {
         triggerTime[i] = startTime + (1000*i)/length;
    }

    for (int i=0; i<length; i++) {
        //just wait for the next time to occur
        Thread.sleep(triggerTime[i]-System.currentTimeMillis());
        doc.setCharacterAttributes(offset, i+1, textpane.getStyle("Red"), true);
    }
}

これは TimerTask オブジェクトを使用しないため、非常に平凡に思えるかもしれませんが、効果的で効率的で、デバッグが容易です。必要なスレッドでこのメソッドを呼び出すだけで、スレッド全体を占有し、単語は 1 秒で完了するような速度で色付けされます。

手元にスレッドがない場合は、これを呼び出すタイマーを作成できますが、その唯一の理由はスレッドにアクセスすることです。本当のポイントは、複数のタイマーを設定しないでください。時間値の配列を作成するだけです。1 つのイベントが成立した後、次回まで遅延するように設定します。複数のタイマーは必要ありません。

キャラクターのカラーリング (または任意のアクション) を表すオブジェクトを作成し、これらのアクションのコレクションをまとめると、少しきれいになります。次に、コレクション全体をオフにする時間で並べ替えます。上記のループはコレクションをウォークスルーし、アクションの時間になるまで待ってから実行します。このアプローチのもう 1 つの利点は、コレクションをクリアしてループを終了できることです。

なぜこれが悪いのかを理解するには、私のウェブサイトでタイマーの使いすぎに関する議論を参照してください。

于 2013-01-15T05:34:01.387 に答える