Newer
Older
CasicTimeGuard / src / com / casic / swing / ui / TimeGuardNtp.java
package com.casic.swing.ui;

import com.casic.swing.utils.CommandUtil;
import com.casic.swing.utils.StringHelper;
import com.casic.swing.utils.TimeOrDateUtil;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author a203
 */
public class TimeGuardNtp {
    private JPanel ntpPanel;
    private JComboBox<String> hostComboBox;
    private JLabel timeValueLabel;
    private JButton updateTimeButton;
    private JLabel dotView;
    private JLabel currentTimeLabel;
    private JCheckBox autoCheckBox;
    private JComboBox<Integer> periodComboBox;

    private static final String[] HOST_NAME = {"NTP服务器(上海)", "中国国家授时中心", "清华大学", "北京大学", "自定义"};
    private static final String[] HOST_IP = {"ntp.api.bz", "210.72.145.44", "s1b.time.edu.cn", "s1c.time.edu.cn"};
    /**
     * 同步周期,单位:小时
     */
    private static final Integer[] PERIOD = {1, 6, 12, 24};
    private boolean hasNtp = false;
    private String host = HOST_IP[0];
    private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(
            1, new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build());

    public static void main(String[] args) {
        TimeGuardNtp timeGuard = new TimeGuardNtp();
        JFrame frame = new JFrame("TimeGuardNtp");
        frame.setContentPane(timeGuard.ntpPanel);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setSize(410, 280);
        //居中
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        //内边距
        timeGuard.ntpPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        timeGuard.dotView.setText("未同步");
        timeGuard.dotView.setIcon(new ImageIcon("image/dot_gray.png"));

        /**
         * 时间间隔,单位为毫秒
         * */
        timeGuard.currentTimeLabel.setForeground(Color.BLUE);
        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String systemTime = TimeOrDateUtil.timestampToTime(System.currentTimeMillis());
                timeGuard.currentTimeLabel.setText(systemTime);
            }
        }).start();

        String assertsData = StringHelper.getAssertsData();
        if (!"".equals(assertsData)) {
            timeGuard.timeValueLabel.setText(assertsData);
        } else {
            timeGuard.timeValueLabel.setText("无法确定最近同步时间");
        }

        //初始化JComboBox
        initComBox(timeGuard);
        timeGuard.hostComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                String item = (String) e.getItem();
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    if ("自定义".equals(item)) {
                        String inputContent = JOptionPane.showInputDialog(timeGuard.ntpPanel, "请输入授时中心域名或者IP地址", "", JOptionPane.INFORMATION_MESSAGE);
                        if (inputContent.isEmpty()) {
                            JOptionPane.showMessageDialog(timeGuard.ntpPanel, "输入错误,请检查", "Runtime Error", JOptionPane.ERROR_MESSAGE);
                        } else {
                            timeGuard.host = inputContent;
                        }
                    } else {
                        for (int i = 0; i < HOST_NAME.length; i++) {
                            if (item.equals(HOST_NAME[i])) {
                                timeGuard.host = HOST_IP[i];
                            }
                        }

                    }
                }
            }
        });

        //检查环境
        new SwingWorker<Boolean, Void>() {

            @Override
            protected Boolean doInBackground() {
                timeGuard.hasNtp = CommandUtil.checkEnv();
                return timeGuard.hasNtp;
            }

            @Override
            protected void done() {
                if (!timeGuard.hasNtp) {
                    JOptionPane.showMessageDialog(timeGuard.ntpPanel, "未当前设备发现可用的NTP配置", "Runtime Error", JOptionPane.ERROR_MESSAGE);
                    //环境不对,关闭窗体
                    frame.dispose();
                }
                super.done();
            }
        }.execute();

        timeGuard.autoCheckBox.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                JCheckBox checkBox = (JCheckBox) e.getSource();
                timeGuard.updateTimeButton.setEnabled(!checkBox.isSelected());
                timeGuard.periodComboBox.setEnabled(checkBox.isSelected());
            }
        });

        timeGuard.periodComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                int period = (Integer) e.getItem();
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    /**
                     * 开启同步,只能开启一个同步线程
                     *
                     * scheduleAtFixedRate
                     * 是以上一个任务开始的时间计时,period时间过去后,检测上一个任务是否执行完毕
                     * 如果上一个任务执行完毕,则当前任务立即执行
                     * 如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行
                     * */
                    timeGuard.executorService.scheduleAtFixedRate(new Runnable() {
                        @Override
                        public void run() {
                            updateView(timeGuard);
                        }
                    }, 0, period, TimeUnit.HOURS);
                }
            }
        });

        //按钮点击事件
        timeGuard.updateTimeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateView(timeGuard);
            }
        });
    }

    private static void updateView(TimeGuardNtp timeGuard) {
        String result = CommandUtil.ntpDate(timeGuard.host);
        System.out.println("命令执行结果 ===> " + result);
        boolean isSuccess = result.contains("step time server") || result.contains("adjust time server");
        if (isSuccess) {
            String systemTime = TimeOrDateUtil.timestampToTime(System.currentTimeMillis());
            timeGuard.dotView.setIcon(new ImageIcon("image/dot_green.png"));
            timeGuard.dotView.setText("同步成功");
            timeGuard.timeValueLabel.setText(systemTime);
            //同步成功之后将时间存入本地
            StringHelper.saveAssertsData(systemTime);
        } else {
            timeGuard.dotView.setIcon(new ImageIcon("image/dot_red.png"));
            timeGuard.dotView.setText("同步失败");
            timeGuard.timeValueLabel.setText("");
        }
    }

    private static void initComBox(TimeGuardNtp timeGuard) {
        for (String s : HOST_NAME) {
            timeGuard.hostComboBox.addItem(s);
        }
        for (Integer integer : PERIOD) {
            timeGuard.periodComboBox.addItem(integer);
        }
    }
}