-5

I'm working on some project, and a part of it - digital clock. I want that time like: 17:3:5 will appear like 17:03:05. My code is below (working). But some problems with it: I don't sure if I use correct the timer, and also my program looks to complex, maybe you can help to simplify the code or give some ideas how to write it in a simple way, thanks.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class SimpleDigitalClock {

    public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        DigitalClock myClock = new DigitalClock();
        f.add(myClock);
        f.pack();
        f.setVisible(true);
    }

    static class DigitalClock extends JPanel {

        String stringTime;
        int hour, minute, second;

        String correctionHour = "";
        String correctionMinute = "";
        String correctionSecond = "";

        public void setStringTime(String xyz) {
            this.stringTime = xyz;
        }

        public int findMinimumBetweenTwoNumbers(int a, int b) {
            return (a <= b) ? a : b;
        }

        DigitalClock() {

            Timer t1 = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent e) {

                    repaint();
                }
            });
            t1.start();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            Calendar now = Calendar.getInstance();
            hour = now.get(Calendar.HOUR_OF_DAY);
            minute = now.get(Calendar.MINUTE);
            second = now.get(Calendar.SECOND);

            if (hour < 10) {
                this.correctionHour = "0";
            }
            if (hour >= 10) {
                this.correctionHour = "";
            }

            if (minute < 10) {
                this.correctionMinute = "0";
            }
            if (minute >= 10) {
                this.correctionMinute = "";
            }

            if (second < 10) {
                this.correctionSecond = "0";
            }
            if (second >= 10) {
                this.correctionSecond = "";
            }
            setStringTime(correctionHour + hour + ":" + correctionMinute+ minute + ":" + correctionSecond + second);
            g.setColor(Color.BLACK);
            int length = findMinimumBetweenTwoNumbers(this.getWidth(),this.getHeight());
            Font myFont = new Font("SansSerif", Font.PLAIN, length / 5);
            g.setFont(myFont);
            g.drawString(stringTime, (int) length/6, length/2);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}
user1924939
  • 43
  • 2
  • 2
  • 4

3 Answers3

3

Formatting dates is what SimpleDateFormat was designed to do:

DateFormat format = new SimpleDateFormat("hh:mm:ss");
String stringTime = format.format(new Date());
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Just wondering - Wouldn't it be an overkill to call new Date() each second? – TJ- Dec 27 '12 at 17:30
  • More elegant approach than my answer. – MrSmith42 Dec 27 '12 at 17:33
  • @TJ- You are quite correct. Creating objects costs time and CPU effort for an application. Garbage collection and memory recycling cost more time and CPU effort. One optimization here might be to update the time every minute instead of every second. – Reimeus Dec 27 '12 at 17:44
  • In this case, I guess an approach could be to use local counters and using math to show the time.(Assuming that the time is updated only by a single thread, the System time is not modified after the app launch and the processing time of other tasks is not significant). If the processing time is significant, the counters will go wrong. Yes, as you suggested, updating the actual time every minute should be a acceptable compromise. – TJ- Dec 27 '12 at 18:17
1

The other answers have commented on other parts of your code.

To center your display, you can use the following drawing code.

        g.setColor(Color.BLACK);
        int length = Math.min(this.getWidth(), this.getHeight());
        Font myFont = new Font("SansSerif", Font.PLAIN, length / 5);
        g.setFont(myFont);
        Graphics2D g2d = (Graphics2D) g;
        FontMetrics fm = g2d.getFontMetrics();
        Rectangle2D r = fm.getStringBounds(stringTime, g2d);
        int x = (this.getWidth() - (int) r.getWidth()) / 2;
        int y = this.getHeight() / 2;
        g.drawString(stringTime, x, y);
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

Complete modified class:

static class DigitalClock extends JPanel {

    String stringTime;

    public void setStringTime(String xyz) {
        this.stringTime = xyz;
    }

    public int findMinimumBetweenTwoNumbers(int a, int b) {
        return (a <= b) ? a : b;
    }

    DigitalClock() {

        Timer t1 = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                repaint();
            }
        });
        t1.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Calendar now = Calendar.getInstance();
        int hour = now.get(Calendar.HOUR_OF_DAY);
        int minute = now.get(Calendar.MINUTE);
        int second = now.get(Calendar.SECOND);

        String correctionHour = (hour < 10) ? "0" : "":
        String correctionMinute = (minute < 10) ? "0" : "";
        String correctionSecond = (second < 10) ? "0" : "";
        setStringTime(correctionHour + hour + ":" + correctionMinute+ minute + ":" + correctionSecond + second);
        g.setColor(Color.BLACK);
        int length = findMinimumBetweenTwoNumbers(this.getWidth(),this.getHeight());
        Font myFont = new Font("SansSerif", Font.PLAIN, length / 5);
        g.setFont(myFont);
        g.drawString(stringTime, (int) length/6, length/2);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }
}

}

MrSmith42
  • 9,961
  • 6
  • 38
  • 49