Java – GUI clock using large amounts of RAM?

  1. Reduce the number of updates to the required minimum
  2. Reduce the number of temporary objects as best as you can
  3. Ensure that all updates to the UI are made from within the context of the main UI thread (Event Dispatching Thread for Swing)

Take a look at:

For example…

Clock

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClockMeBaby {

    public static void main(String[] args) {
        new ClockMeBaby();
    }

    public ClockMeBaby() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        protected static final DateFormat CLOCK_FORMAT = new SimpleDateFormat("hh:mm:ss a");
        private JLabel clock;

        public TestPane() {
            setLayout(new GridBagLayout());
            clock = new JLabel("...");
            clock.setFont(clock.getFont().deriveFont(Font.BOLD, 64f));
            add(clock);
            updateClock();

            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    updateClock();
                }
            });
            timer.start();
        }

        protected void updateClock() {

            clock.setText(CLOCK_FORMAT.format(System.currentTimeMillis()));

        }

    }

}

The reason the SwingTimer uses a 500 millisecond delay is to ensure we remain in sync, otherwise your clock might update “out of sync” with the rest of the UI because you’ve missed a second boundry. If this is not important to you, you could us 1000 millisecond delay instead

Leave a Comment