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 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 extends JFrame { 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 JPanel stateView; private final String[] HOST_NAME = {"NTP服务器(上海)", "中国国家授时中心", "清华大学", "北京大学", "自定义"}; private final String[] HOST_IP = {"ntp.api.bz", "ntp.ntsc.ac.cn", "s1b.time.edu.cn", "s2m.time.edu.cn"}; /** * 同步周期,单位:小时 */ private final Integer[] PERIOD = {10, 20, 30}; private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor( 1, new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build()); private boolean hasNtp = false; private String host = HOST_IP[0]; public static void main(String[] args) { new TimeGuardNtp(); } public TimeGuardNtp() { setContentPane(ntpPanel); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setSize(410, 280); //居中 setLocationRelativeTo(null); setVisible(true); dotView.setText("未同步"); setStateView(Color.GRAY); StringHelper.createLogFile(); /** * 时间间隔,单位为毫秒 * */ currentTimeLabel.setForeground(Color.BLUE); new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String systemTime = TimeOrDateUtil.timestampToTime(System.currentTimeMillis()); currentTimeLabel.setText(systemTime); } }).start(); String assertsData = StringHelper.getAssertsData(); if (!"".equals(assertsData)) { timeValueLabel.setText(assertsData); } else { timeValueLabel.setText("无法确定最近同步时间"); } //初始化JComboBox initComBox(); 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(ntpPanel, "请输入授时中心域名或者IP地址", "", JOptionPane.INFORMATION_MESSAGE); if (inputContent.isEmpty()) { JOptionPane.showMessageDialog(ntpPanel, "输入错误,请检查", "Runtime Error", JOptionPane.ERROR_MESSAGE); } else { host = inputContent; } } else { for (int i = 0; i < HOST_NAME.length; i++) { if (item.equals(HOST_NAME[i])) { host = HOST_IP[i]; } } } } } }); //检查环境 new SwingWorker<Boolean, Void>() { @Override protected Boolean doInBackground() { hasNtp = CommandUtil.checkEnv(); return hasNtp; } @Override protected void done() { if (!hasNtp) { JOptionPane.showMessageDialog(ntpPanel, "未当前设备发现可用的NTP配置", "Runtime Error", JOptionPane.ERROR_MESSAGE); //环境不对,关闭窗体 dispose(); } super.done(); } }.execute(); autoCheckBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { updateTimeButton.setEnabled(false); periodComboBox.setEnabled(true); startAutoSynchronize(PERIOD[0]); } else { updateTimeButton.setEnabled(true); periodComboBox.setEnabled(false); } } }); periodComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { int period = (Integer) e.getItem(); if (e.getStateChange() == ItemEvent.SELECTED) { startAutoSynchronize(period); } } }); //按钮点击事件 updateTimeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateView(); } }); } private void startAutoSynchronize(int period) { /** * 开启同步,只能开启一个同步线程 * * scheduleAtFixedRate * 是以上一个任务开始的时间计时,period时间过去后,检测上一个任务是否执行完毕 * 如果上一个任务执行完毕,则当前任务立即执行 * 如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行 * */ executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { updateView(); } }, 0, period, TimeUnit.MINUTES); } private void updateView() { String result = CommandUtil.ntpDate(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()); setStateView(Color.GREEN); dotView.setText("同步成功"); timeValueLabel.setText(systemTime); //同步成功之后将时间存入本地 StringHelper.saveAssertsData(systemTime); } else { setStateView(Color.RED); dotView.setText("同步失败"); timeValueLabel.setText(""); } } private void initComBox() { for (String s : HOST_NAME) { hostComboBox.addItem(s); } for (Integer integer : PERIOD) { periodComboBox.addItem(integer); } } private void setStateView(Color color) { stateView.setPreferredSize(new Dimension(15, 15)); stateView.setBackground(color); } }