0

TimerTaskを使用して、ペイントコンポーネントクラスによって呼び出されるクラスの1つのループにタイマーを追加しました。基本的に、すでにペイントされているページには白い円があり、配列から値を読み取るforループがあり、値の範囲に応じて円の色が変わります。各円は、配列内の次の値を表す必要があります。しかし、それは機能していません。私は基本的なプログラマーであり、何がうまくいかないのか本当に理解していません。誰かが私に手を貸してくれたら本当にありがたいです。これまでの私のコードは次のとおりです。

public DoThePaint() {



    String fileName;
    fileName = "/Users/Desktop/test2.txt";
    read = new Reader(fileName);
    read.displayArrayList();

    panel = new JPanel();
    newImage = new ImageIcon(this.getClass().getResource("resource/background2T.png")).getImage();

    circlesT = new ArrayList<Shape>();
    circlesT.add(new Ellipse2D.Float(197.0f, 352.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(247.0f, 307.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(152.0f, 303.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(172.0f, 372.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(223.0f, 378.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(273.0f, 285.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(130.0f, 281.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(148.0f, 393.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(246.0f, 403.0f, 10.0f, 10.0f));
    circlesT.add(new Ellipse2D.Float(297.0f, 264.0f, 10.0f, 10.0f));
}
public void paintComponent(Graphics g) {

    drawShapes(g, circlesT);

}

public void drawShapes(Graphics g, final ArrayList<Shape> circlesT) {
    final Graphics2D ga = (Graphics2D) g;
    ga.drawImage(newImage, 0, 0, null);



    for (int i = 0; i < circlesT.size(); i++) {
        ga.draw(circlesT.get(i));
        ga.setPaint(Color.white);
        ga.fill(circlesT.get(i));
    }



    Timer timer = new Timer();
    TimerTask t;
    t = new TimerTask() {
        @Override
        public void run() {

            for (int i = 0; i < 10; i++) {


                if (read.temp.get(i) < 31 && read.temp.get(i) > 30) {
                    ga.draw(circlesT.get(i));
                    ga.setPaint(Color.green);
                    ga.fill(circlesT.get(i));
                } else if (read.temp.get(i) < 32 && read.temp.get(i) > 31) {
                    ga.draw(circlesT.get(i));
                    ga.setPaint(Color.red);
                    ga.fill(circlesT.get(i));
                } else if (read.temp.get(i) < 33 && read.temp.get(i) > 32) {
                    ga.draw(circlesT.get(i));
                    ga.setPaint(Color.yellow);
                    ga.fill(circlesT.get(i));
                }

            }
        }
    };
    repaint();
    timer.schedule(t, 0, 5000);

}
4

2 に答える 2

4

申し訳ありませんが、これはあなたが作った恐怖の殿堂です。paintComponent()あなたの中で 、 を作成しnew Timernew TimerTask最終的に を呼び出してrepaint()います。

  1. paintComponent(): ペイント操作 (画像の描画、円の塗りつぶし、線の描画、テキストの描画などGraphics) を行うだけです。あなたがすべきことはそれだけです。
  2. 呼び出しrepaint()は、最終的にpaintComponent()再度呼び出されるようにトリガーされます--> タイマー、タイマー タスクを再作成し、repaint() を呼び出します-->paintComponent()->repaint()-->...リソースを食い尽くす無限ループ
  3. あなたのReaderクラスが何をし、どのようなデータを保持しているのかわかりません。変更する 2 つの点がわかりました。ゲッターまたはその他のアクセス メソッドを使用して適切にアクセスするtemp必要があります。privateループ内の条件は非常に厳密です。すべての値が 3 つの条件のいずれかに一致することを確認してください (ところで、条件はすべて、またはを返すfalse場合です)。read.temp.get(i)intInteger
  4. これらの問題をすべて解決するには、Timer をドロップし、TimerTask をドロップして、最初のfor-loopルックアップで直接円の色を指定し、すぐに適切に描画します。ある時点で表示を更新したい場合は、呼び出すことができますrepaint()
  5. ところで、TimerTaskEDT (イベント ディスパッチ スレッド) では実行されませんが、その中から UI 関連のものにアクセスします。これは、すべての UI 関連のタスクを EDT で実行する必要があるという事実に違反しています (SwingTimerまたはを使用SwingUtilities.invokeLater()) 。
  6. あなたが提供するものと同じTimerTaskあなたのアクセスでは、メソッドの範囲外でそのオブジェクトにアクセスすることはできません。は作成および破棄されるため、その範囲外で使用しないでください。一般に、オブジェクトへの参照を保持するべきではありません (また、魅力的ではあるがあらゆる種類の頭痛の種の原因となるメソッドを使用することもできません)。Graphics2D gaGraphics gpaintComponent()GraphicspaintComponentGraphicsGraphicsgetGraphics()
于 2013-02-26T13:42:46.283 に答える
1

Swingでペイントがどのように機能するかについて根本的な誤解があります。大したことではありませんが、誰もがどこかから始めなければなりません。

アニメーションをやりたいようです。そのため、paintComponentメソッドは、特定の時点でのオブジェクトの状態を描画する必要があります。ペイントのタイミングを制御しているタイマーは、別のクラスにある必要があります。

単純なアニメーションの場合、TimerTaskで十分です。ゲームや優れたパフォーマンスが必要なものをアニメーション化する場合は、AndrewDavison著の『Killer Game Programming in Java』の第2章にあるアニメーションクラスをお勧めします。実際には、AmazonのLookInside機能で第2章を読むことができます。

于 2013-02-26T14:14:13.063 に答える