Pregunta

importing libraries

public class Countdown1 extends Applet implements Runnable {
// getting user input

    String input = JOptionPane.showInputDialog("Enter seconds: ");
 // converting string to integer

    int counter = Integer.parseInt(input);

    Thread countdown;

    public void start() {
        countdown = new Thread(this);
        countdown.start();

    }

// executed by thread
    public void run() {

        Timer timer;

        timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
            public void actionPerformed(ActionEvent evt) {
                if (counter > 0) {

                    counter--;
// repainting each second

                    repaint();
                }
            }
        });
// timer started 

        timer.start();

    }

    public void paint(Graphics g) {
//painting text and time 

        g.setFont(new Font("Times New Roman", Font.BOLD, 35));
        g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
        setBackground(Color.orange);
        setForeground(Color.magenta);

// change background to cyan when timer reaches 0
        if (counter == 0) {
            setBackground(Color.cyan);
        }
    }
}
¿Fue útil?

Solución

The problem isn't your Timer (although I do question the need to start it within a separate thread), the problem is with overriding paint.

Top level containers like Applet are not double buffered, meaning that the each paint action tends to be sent to the underlying Graphics device desperately.

Now you can over come this by employee some double buffering process OR you could...

  • Extend from JApplet instead
  • Create a custom component extending from something like JPanel and override it's paintComponent method instead, moving your custom painting to this method
  • Add this component to the applet instead.

It should solve the immediate issue...

You should also avoid calling setForeground or setBackground from within any paint method. In fact, you should avoid calling any method that might call repaint from within any paint method...

Take a look at Performing Custom Painting

I'm pretty sure that String input = JOptionPane.showInputDialog("Enter seconds: "); this is a bad idea. Instead, you should provide some kind of control or option within the UI to change this value...

Crude example

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Countdown1 extends JApplet {

    @Override
    public void init() {
        add(new CounterPane());
    }

    public class CounterPane extends JPanel {

        String input = JOptionPane.showInputDialog("Enter seconds: ");

        int counter = Integer.parseInt(input);

        public CounterPane() {

            Timer timer;

            timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
                public void actionPerformed(ActionEvent evt) {
                    System.out.println(counter);
                    if (counter > 0) {

                        counter--;

                        setBackground(Color.orange);
                        setForeground(Color.magenta);

                        if (counter <= 0) {
                            setBackground(Color.cyan);
                        }

                        repaint();
                    }
                }
            });

            timer.start();

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setFont(new Font("Times New Roman", Font.BOLD, 35));
            g.setColor(getForeground());
            g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
        }

    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top