Java/Swing JFC/Timer

Материал из Java эксперт
Перейти к: навигация, поиск

An applet that counts down from a specified time

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.NumberFormat;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
/**
 * An applet that counts down from a specified time. When it reaches 00:00, it
 * optionally plays a sound and optionally moves the browser to a new page.
 * Place the mouse over the applet to pause the count; move it off to resume.
 * This class demonstrates most applet methods and features.
 */
public class Countdown extends JApplet implements ActionListener, MouseListener {
  long remaining; // How many milliseconds remain in the countdown.
  long lastUpdate; // When count was last updated
  JLabel label; // Displays the count
  Timer timer; // Updates the count every second
  NumberFormat format; // Format minutes:seconds with leading zeros
  Image image; // Image to display along with the time
  AudioClip sound; // Sound to play when we reach 00:00
  // Called when the applet is first loaded
  public void init() {
    // Figure out how long to count for by reading the "minutes" parameter
    // defined in a <param> tag inside the <applet> tag. Convert to ms.
    String minutes = getParameter("minutes");
    if (minutes != null)
      remaining = Integer.parseInt(minutes) * 60000;
    else
      remaining = 600000; // 10 minutes by default
    // Create a JLabel to display remaining time, and set some properties.
    label = new JLabel();
    label.setHorizontalAlignment(SwingConstants.CENTER);
    label.setOpaque(true); // So label draws the background color
    // Read some parameters for this JLabel object
    String font = getParameter("font");
    String foreground = getParameter("foreground");
    String background = getParameter("background");
    String imageURL = getParameter("image");
    // Set label properties based on those parameters
    if (font != null)
      label.setFont(Font.decode(font));
    if (foreground != null)
      label.setForeground(Color.decode(foreground));
    if (background != null)
      label.setBackground(Color.decode(background));
    if (imageURL != null) {
      // Load the image, and save it so we can release it later
      image = getImage(getDocumentBase(), imageURL);
      // Now display the image in the JLabel.
      label.setIcon(new ImageIcon(image));
    }
    // Now add the label to the applet. Like JFrame and JDialog, JApplet
    // has a content pane that you add children to
    getContentPane().add(label, BorderLayout.CENTER);
    // Get an optional AudioClip to play when the count expires
    String soundURL = getParameter("sound");
    if (soundURL != null)
      sound = getAudioClip(getDocumentBase(), soundURL);
    // Obtain a NumberFormat object to convert number of minutes and
    // seconds to strings. Set it up to produce a leading 0 if necessary
    format = NumberFormat.getNumberInstance();
    format.setMinimumIntegerDigits(2); // pad with 0 if necessary
    // Specify a MouseListener to handle mouse events in the applet.
    // Note that the applet implements this interface itself
    addMouseListener(this);
    // Create a timer to call the actionPerformed() method immediately,
    // and then every 1000 milliseconds. Note we don"t start the timer yet.
    timer = new Timer(1000, this);
    timer.setInitialDelay(0); // First timer is immediate.
  }
  // Free up any resources we hold; called when the applet is done
  public void destroy() {
    if (image != null)
      image.flush();
  }
  // The browser calls this to start the applet running
  // The resume() method is defined below.
  public void start() {
    resume();
  } // Start displaying updates
  // The browser calls this to stop the applet. It may be restarted later.
  // The pause() method is defined below
  public void stop() {
    pause();
  } // Stop displaying updates
  // Return information about the applet
  public String getAppletInfo() {
    return "Countdown applet Copyright (c) 2003 by David Flanagan";
  }
  // Return information about the applet parameters
  public String[][] getParameterInfo() {
    return parameterInfo;
  }
  // This is the parameter information. One array of strings for each
  // parameter. The elements are parameter name, type, and description.
  static String[][] parameterInfo = {
      { "minutes", "number", "time, in minutes, to countdown from" },
      { "font", "font", "optional font for the time display" },
      { "foreground", "color", "optional foreground color for the time" },
      { "background", "color", "optional background color" },
      { "image", "image URL", "optional image to display next to countdown" },
      { "sound", "sound URL", "optional sound to play when we reach 00:00" },
      { "newpage", "document URL", "URL to load when timer expires" }, };
  // Start or resume the countdown
  void resume() {
    // Restore the time we"re counting down from and restart the timer.
    lastUpdate = System.currentTimeMillis();
    timer.start(); // Start the timer
  }
  // Pause the countdown
  void pause() {
    // Subtract elapsed time from the remaining time and stop timing
    long now = System.currentTimeMillis();
    remaining -= (now - lastUpdate);
    timer.stop(); // Stop the timer
  }
  // Update the displayed time. This method is called from actionPerformed()
  // which is itself invoked by the timer.
  void updateDisplay() {
    long now = System.currentTimeMillis(); // current time in ms
    long elapsed = now - lastUpdate; // ms elapsed since last update
    remaining -= elapsed; // adjust remaining time
    lastUpdate = now; // remember this update time
    // Convert remaining milliseconds to mm:ss format and display
    if (remaining < 0)
      remaining = 0;
    int minutes = (int) (remaining / 60000);
    int seconds = (int) ((remaining % 60000) / 1000);
    label.setText(format.format(minutes) + ":" + format.format(seconds));
    // If we"ve completed the countdown beep and display new page
    if (remaining == 0) {
      // Stop updating now.
      timer.stop();
      // If we have an alarm sound clip, play it now.
      if (sound != null)
        sound.play();
      // If there is a newpage URL specified, make the browser
      // load that page now.
      String newpage = getParameter("newpage");
      if (newpage != null) {
        try {
          URL url = new URL(getDocumentBase(), newpage);
          getAppletContext().showDocument(url);
        } catch (MalformedURLException ex) {
          showStatus(ex.toString());
        }
      }
    }
  }
  // This method implements the ActionListener interface.
  // It is invoked once a second by the Timer object
  // and updates the JLabel to display minutes and seconds remaining.
  public void actionPerformed(ActionEvent e) {
    updateDisplay();
  }
  // The methods below implement the MouseListener interface. We use
  // two of them to pause the countdown when the mouse hovers over the timer.
  // Note that we also display a message in the statusline
  public void mouseEntered(MouseEvent e) {
    pause(); // pause countdown
    showStatus("Paused"); // display statusline message
  }
  public void mouseExited(MouseEvent e) {
    resume(); // resume countdown
    showStatus(""); // clear statusline
  }
  // These MouseListener methods are unused.
  public void mouseClicked(MouseEvent e) {
  }
  public void mousePressed(MouseEvent e) {
  }
  public void mouseReleased(MouseEvent e) {
  }
}





Swing Timer Demo

 
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
/*
 * SwingTimerDemo.java
 *
 * Created on May 2, 2007, 3:25 PM
 *
 * Copyright (c) 2007, Sun Microsystems, Inc
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the TimingFramework project nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 *
 * @author Chet
 */
public class SwingTimerDemo implements ActionListener {
    
    private static long prevTime = 0;
    private static long startTime = 0;
    private static final int DELAY = 100;
    private static final int DURATION = 5 * DELAY;
    private static final int PROCESSING_TIME = 30;
    private static final long INITIAL_PROCESSING_TIME = 2 * DELAY;
    private static Timer timer = null;
    private boolean firstTime = true;
    
    /** 
     * This method will be called during every tick of the Timers.
     * We insert an artificial delay each time, to simulate some processing.
     * The first time through, this delay is greater than the delay between
     * timing events, so that we can see how this hiccup is handled by
     * fixed-rate and fixed-delay timers.
     */
    public void actionPerformed(ActionEvent ae) {
        long nowTime = System.currentTimeMillis();
        long elapsedTime = nowTime - prevTime;
        long totalTime = nowTime - startTime;
        System.out.println("Elapsed time = " + elapsedTime);
        if (totalTime > DURATION) {
            timer.stop();
        }
        prevTime = nowTime;
        try {
            if (firstTime) {
                Thread.sleep(INITIAL_PROCESSING_TIME);
                firstTime = false;
            } else {
                Thread.sleep(PROCESSING_TIME);
            }
        } catch (Exception e) {}
    }
    public SwingTimerDemo() {
        firstTime = true;
    }
    
    public static void main(String[] args) {        
        // Run a default fixed-delay timer
        timer = new Timer(DELAY, new SwingTimerDemo());
        startTime = prevTime = System.currentTimeMillis();
        System.out.println("Fixed Delay Times");
        timer.start();
        // Sleep for long enough that the first timer ends
        try {
            Thread.sleep(DURATION*2);
        } catch (Exception e) {}
        
        // Run a timer with no coalescing to get fixed-rate behavior
        timer = new Timer(DELAY, new SwingTimerDemo());
        startTime = prevTime = System.currentTimeMillis();
        timer.setCoalesce(false);
        System.out.println("\nFixed Rate Times");
        timer.start();
    }
    
}





Tick Tock with an Inner Class

 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class TickTockInner {
  public static void main(String[] args) {
    TickTockInner t = new TickTockInner();
    t.go();
  }
  private void go() {
    Timer t = new Timer(1000, new Ticker());
    t.start();
    JOptionPane.showMessageDialog(null, "Click OK to exit program");
    System.exit(0);
  }
  class Ticker implements ActionListener {
    private boolean tick = true;
    public void actionPerformed(ActionEvent event) {
      if (tick) {
        System.out.println("Tick...");
      } else {
        System.out.println("Tock...");
      }
      tick = !tick;
    }
  }
}





Tick Tock with a Static Inner Class

 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class MainClass {
  public static void main(String[] args) {
    Timer t = new Timer(1000, new Ticker());
    t.start();
    JOptionPane.showMessageDialog(null, "Click OK to exit program");
    System.exit(0);
  }
  static class Ticker implements ActionListener {
    private boolean tick = true;
    public void actionPerformed(ActionEvent event) {
      if (tick) {
        System.out.println("Tick...");
      } else {
        System.out.println("Tock...");
      }
      tick = !tick;
    }
  }
}





Timer: clock label

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class ClockTest extends JFrame {
  public ClockTest() {
    super("Timer Demo");
    setSize(300, 100);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    ClockLabel clock = new ClockLabel();
    getContentPane().add(clock, BorderLayout.NORTH);
  }
  public static void main(String args[]) {
    ClockTest ct = new ClockTest();
    ct.setVisible(true);
  }
}
class ClockLabel extends JLabel implements ActionListener {
  public ClockLabel() {
    super("" + new Date());
    Timer t = new Timer(1000, this);
    t.start();
  }
  public void actionPerformed(ActionEvent ae) {
    setText((new Date()).toString());
  }
}





Time Resolution

 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
/*
 * TimeResolution.java
 *
 * Created on May 2, 2007, 3:38 PM
 *
 * Copyright (c) 2007, Sun Microsystems, Inc
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the TimingFramework project nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 *
 * @author Chet
 */
public class TimeResolution implements ActionListener {
    
    private static int INCREMENT = 5;
    private static int MAX = 50;
    
    /**
     * Measures how much time has elapsed according to both currentTimeMillis()
     * and nanoTime() at each interval. Note that the time reported for 
     * sleep() may not be accurate since the internal sleep timer may not
     * have the appropriate resolution to sleep for the requested time.
     * The main utility of this function is to compare the two timing
     * functions, although it is also interesting to see how the measured
     * time varies from the sleep() time.
     */
    private void measureTimeFunctions(int increment, int max) {
        long startTime = System.currentTimeMillis();
        long startNanos = System.nanoTime();
        long elapsedTimeActual = 0;
        long elapsedTimeMeasured = 0;
        long elapsedNanosMeasured = 0;
        System.out.printf("sleep   currentTimeMillis   nanoTime\n");
        while (elapsedTimeActual < max) {
            try {
                Thread.sleep(increment);
            } catch (Exception e) {}
            long currentTime = System.currentTimeMillis();
            long currentNanos = System.nanoTime();
            elapsedTimeActual += increment;
            elapsedTimeMeasured = currentTime - startTime;
            elapsedNanosMeasured = (currentNanos - startNanos) / 1000000;
            System.out.printf(" %3d           %4d          %4d\n",
                    elapsedTimeActual, elapsedTimeMeasured, elapsedNanosMeasured);
        }
    }
    /**
     * This method measures the actual time slept, compared to the requested
     * sleep() time. We run many iterations for each value of sleep() to
     * get more accurate timing values; this accounts for possible 
     * inaccuracies of our nanoTime() method for small time differences.
     */
    private void measureSleep() {
        System.out.printf("                                 measured\n");
        System.out.printf("sleep time   iterations   total time   per-sleep\n");
        for (int sleepTime = 0; sleepTime <= 20; ++sleepTime) {
            int iterations = (sleepTime == 0) ? 10000 : (1000 / sleepTime);
            long startTime = System.nanoTime();
            for (int i = 0; i < iterations; ++i) {
                try {
                    Thread.sleep(sleepTime);
                } catch (Exception e) {
                }
            }
            long endTime = System.nanoTime();
            long totalTime = (endTime - startTime) / 1000000;
            float calculatedSleepTime = totalTime / (float)iterations;
            System.out.printf("   %2d          %5d         %4d       %5.2f\n", 
                    sleepTime, iterations, totalTime, calculatedSleepTime);
        }
    }
    /**
     * This method is like the measureSleep() method above, only for the
     * wait() method instead of sleep().
     */
    private synchronized void measureWait() {
        System.out.printf("                                measured\n");
        System.out.printf("wait time   iterations   total time   per-wait\n");
        for (int sleepTime = 1; sleepTime <= 20; ++sleepTime) {
            int iterations = (sleepTime == 0) ? 10000 : (1000 / sleepTime);
            long startTime = System.nanoTime();
            for (int i = 0; i < iterations; ++i) {
                try {
                    wait(sleepTime);
                } catch (Exception e) {
                    System.out.println("Exception: " + e);
                    Thread.dumpStack();
                }
            }
            long endTime = System.nanoTime();
            long totalTime = (endTime - startTime) / 1000000;
            float calculatedSleepTime = totalTime / (float)iterations;
            System.out.printf("  %2d          %5d         %4d       %5.2f\n", 
                    sleepTime, iterations, totalTime, calculatedSleepTime);
        }
    }
    
    // Variables used in measurement of Swing timer
    int timerIteration = 0;
    int iterations = 0;
    Timer timer;
    long startTime, endTime;
    int sleepTime;
    
    /**
     * This method is called during the execution of the Swing timer.
     */
    public void actionPerformed(ActionEvent ae) {
        if (++timerIteration > iterations) {
            timer.stop();
            timerIteration = 0;
            endTime = System.nanoTime();
            long totalTime = (endTime - startTime) / 1000000;
            float calculatedDelayTime = totalTime / (float)iterations;
            System.out.printf("  %2d          %5d         %5d        %5.2f\n", 
                    sleepTime, iterations, totalTime, calculatedDelayTime);
        }
    }
       
    /**
     * This method measures the accuracy of the Swing timer, which is 
     * internally dependent upon both the internal timing mechanisms
     * (either currentTimeMillis() or nanoTime()) and the wait() method.
     * So the results we see here should be predictable from the results
     * we see in the other measurement methods.
     */
    public void measureTimer() {
        System.out.printf("                                  measured\n");
        System.out.printf("timer delay   iterations   total time   per-delay\n");
        for (sleepTime = 0; sleepTime <= 20; ++sleepTime) {
            iterations = (sleepTime == 0) ? 1000 : (1000 / sleepTime);
            timerIteration = 1;
            timer = new Timer(sleepTime, this);
            startTime = System.nanoTime();
            timer.start();
            while (timerIteration > 0) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {}
            }
        }
    }
    /**
     * Execute the various timer resolution tests.
     */
    public static void main(String args[]) {
        TimeResolution timeResolution = new TimeResolution();
        timeResolution.measureTimer();
        timeResolution.measureTimeFunctions(INCREMENT, MAX);
        timeResolution.measureSleep();
        timeResolution.measureWait();
    }
    
}





Timer Sample

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class TimerSample {
  public static void main(String args[]) {
    new JFrame().setVisible(true);
    ActionListener actionListener = new ActionListener() {
      public void actionPerformed(ActionEvent actionEvent) {
        System.out.println("Hello World Timer");
      }
    };
    Timer timer = new Timer(500, actionListener);
    timer.start();
  }
}





Timer with ProgressBar

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TimerExample extends JPanel implements ActionListener {
    private Timer timer = new Timer(100, this);
    private JLabel clockLabel;
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("h:mm ss a");
    private JProgressBar secondsProgressBar = new JProgressBar(0, 1000);
    public TimerExample() {
        this.clockLabel = new JLabel("Clock Stopped");
        this.clockLabel.setFont(this.clockLabel.getFont().deriveFont(Font.BOLD, 16));
        this.clockLabel.setHorizontalTextPosition(JLabel.CENTER);
        this.secondsProgressBar.setVisible(false);
        this.secondsProgressBar.setForeground(Color.blue);
        add(this.clockLabel);
        add(secondsProgressBar);
        add(new JButton(new ToggleClockAction()));
    }
    private class ToggleClockAction extends AbstractAction {
        private String startClock = "Start Clock";
        private String stopClock = "Stop Clock";
        private String clockStopped = "Clock Stopped";
        public ToggleClockAction() {
            super();
            putValue(Action.NAME, startClock);
        }
        public void actionPerformed(ActionEvent e) {
            if (TimerExample.this.timer.isRunning()) {
                putValue(Action.NAME, startClock);
                TimerExample.this.timer.stop();
                TimerExample.this.secondsProgressBar.setVisible(false);
                TimerExample.this.clockLabel.setText(clockStopped);
            } else {
                putValue(Action.NAME, stopClock);
                // Call Action Performed To Initialize Time Before Timer is Started.
                // Null is ok since we ignore the event.
                TimerExample.this.actionPerformed(null);
                TimerExample.this.secondsProgressBar.setVisible(true);
                TimerExample.this.timer.start();
            }
        }
    }
    public void actionPerformed(ActionEvent e) {
        this.calendar.setTimeInMillis(System.currentTimeMillis());
        this.clockLabel.setText(this.dateFormat.format(this.calendar.getTime()));
        int milliseconds = this.calendar.get(Calendar.MILLISECOND);
        this.secondsProgressBar.setValue(milliseconds);
    }
    public void endExample() {
        this.timer.stop();
    }
    public static void main(String[] a){
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(1);
      f.add(new TimerExample());
      f.pack();
      f.setVisible(true);
    } 
}