如何使用时间作为rgb值来制作更新背景颜色的彩色数字时钟?

时间:2015-05-16 17:07:22

标签: java swing

我想制作一个背景颜色的数字时钟,每次时钟滴答时都会改变。颜色基于时间(使用时间作为rgb值)。我尝试了以下,时钟本身可以工作,但背景颜色不能按预期工作。

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.setBackground(new Color(myClock.getHour(), myClock.getMinute(), myClock.getSecond()));
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
}

static class DigitalClock extends JPanel {

    String stringTime;
    int hour, minute, second;

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

    public int getHour(){
      return hour;
    }

    public int getMinute(){
      return minute;
    }

    public int getSecond(){
      return second;
    }

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

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

    DigitalClock() {
        JPanel p1 = new JPanel(); 
        p1.setOpaque(true);
        p1.setBackground(new Color(hour, minute, second));
        add(p1);
        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("Digital", Font.PLAIN, length / 5);
        g.setFont(myFont);
        g.drawString(stringTime, (int) length/6, length/2);

    }

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

}

}

2 个答案:

答案 0 :(得分:1)

  

将时间转换为十六进制

将基于24小时的时间转换为十六进制不是唯一的。一个简单的方法是将24小时,60分钟和60秒的空间拉伸到256个空间:

hexHour = hour * 256 / 24 = hour * 10 2/3
hexMinute = minute * 256 / 60 = minute * 4 4/15
hexSecond = second * 256 / 60 = second * 4 4/15

如果您想要覆盖整个RGB空间,则需要进行小的修正,因为在此约定中您可以跳过如上所示的值。而不是每小时跳过红色空间10 2/3,你可以每5 5/8分钟跳1:

60 / (10 2/3) = 5 5/8

同样适用于其他空间。

  

并使用十六进制显示背景颜色。

至于设置背景颜色,只需在时钟上使用setBackground即可。在这里,我使用一个非常简单的GUI,其中包含3 JLabel秒的小时,分​​钟和秒:

public class ColorClock extends JFrame {

    ColorClock() {

        JLabel minutes = new JLabel();
        JLabel seconds = new JLabel();
        JLabel hours = new JLabel();

        new Timer().scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {

                LocalTime time = LocalTime.now();
                int hour = time.getHour();
                int min = time.getMinute();
                int sec = time.getSecond();
                hours.setText(String.valueOf(hour));
                minutes.setText(":" + String.valueOf(min + ":"));
                seconds.setText(String.valueOf(sec));
                Color color = new Color(hour * 256 / 24, min * 256 / 60, sec * 256 / 60);
                getContentPane().setBackground(color);
            }
        }, 0, 1000);

        setLayout(new FlowLayout());
        add(hours);
        add(minutes);
        add(seconds);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] arguments) {

        new ColorClock();
    }
}

请注意,代码没有以任何方式进行优化,也不是线程安全的,只是为了演示更改颜色(swing.Timer在这里比util.Timer更正确。)

答案 1 :(得分:1)

这是制作时钟的一种方法。

Clock

更改Border颜色的代码在Clock类的setBackground方法中。我只是使用分钟和秒来使边框颜色更快。

package com.ggl.testing;

import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Clock implements Runnable {

    private JFrame frame;

    private JPanel panel;

    private JTextField clockDisplay;

    private Timer timer;

    @Override
    public void run() {
        frame = new JFrame("Clock");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                exitProcedure();
            }
        });

        panel = new JPanel();
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 6));

        clockDisplay = new JTextField(12);
        clockDisplay.setEditable(false);
        clockDisplay.setHorizontalAlignment(JTextField.CENTER);

        panel.add(clockDisplay);

        frame.add(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        timer = new Timer(this);
        new Thread(timer).start();
    }

    public void exitProcedure() {
        timer.setRunning(false);
        frame.dispose();
        System.exit(0);
    }

    public void setText(String text) {
        clockDisplay.setText(text);
    }

    public void setBackground(Calendar calendar) {
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);

        hour = hour * 255 / 24;
        minute = minute * 255 / 60;
        second = second * 255 / 60;

        panel.setBorder(BorderFactory.createLineBorder(new Color(second,
                minute, second), 6));
        panel.validate();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Clock());
    }

    public class Timer implements Runnable {

        private volatile boolean running;

        private Clock clock;

        private SimpleDateFormat timeFormat;

        public Timer(Clock clock) {
            this.clock = clock;
            this.running = true;
            this.timeFormat = new SimpleDateFormat("h:mm:ss a");
        }

        @Override
        public void run() {
            while (running) {
                displayTime();
                sleep();
            }

        }

        public void displayTime() {
            final Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();
            final String s = timeFormat.format(date);
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    clock.setText(s);
                    clock.setBackground(calendar);
                }
            });
        }

        public void sleep() {
            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
            }
        }

        public synchronized void setRunning(boolean running) {
            this.running = running;
        }

    }

}