[Java] 简易闹钟 →→→→→进入此内容的聊天室

来自 , 2019-08-21, 写在 Java, 查看 120 次.
URL http://www.code666.cn/view/1ef91c21
  1. import java.awt.BorderLayout;  
  2. import java.awt.FlowLayout;  
  3. import java.awt.Font;  
  4. import java.awt.Frame;  
  5. import java.awt.GridLayout;  
  6. import java.awt.event.ActionEvent;  
  7. import java.awt.event.ActionListener;  
  8. import java.awt.event.KeyEvent;  
  9. import java.awt.event.KeyListener;  
  10. import java.io.IOException;  
  11. import java.text.DateFormat;  
  12. import java.text.SimpleDateFormat;  
  13. import java.util.Calendar;  
  14. import java.util.Timer;  
  15. import java.util.TimerTask;  
  16.    
  17. import javax.sound.sampled.AudioInputStream;  
  18. import javax.sound.sampled.AudioSystem;  
  19. import javax.sound.sampled.Clip;  
  20. import javax.sound.sampled.LineEvent;  
  21. import javax.sound.sampled.LineListener;  
  22. import javax.sound.sampled.LineUnavailableException;  
  23. import javax.sound.sampled.UnsupportedAudioFileException;  
  24. import javax.swing.JButton;  
  25. import javax.swing.JDialog;  
  26. import javax.swing.JFrame;  
  27. import javax.swing.JLabel;  
  28. import javax.swing.JPanel;  
  29. import javax.swing.JTextField;  
  30.  
  31. public class AlarmClock extends JFrame implements ActionListener {  
  32.     private static final int LOOP_COUNT = 5; // 重复播放的次数  
  33.     private JLabel labelClock, labelAlarm, labelNextAlarm;  
  34.     private JButton btnSet, btnClose;  
  35.     private SetDialog setDialog;  
  36.     private JPanel topPanel, alarmPanel;  
  37.     private Timer timer;  
  38.     private Clip clip;  
  39.     private Calendar alarmCal;  
  40.     private boolean timeReached = true;  
  41.     private DateFormat df = new SimpleDateFormat("HH : mm");  
  42.        
  43.     public AlarmClock() {  
  44.         super("闹钟");  
  45.     }  
  46.        
  47.     public void launch() {  
  48.         setSize(400, 300);  
  49.         setVisible(true);  
  50.         setDefaultCloseOperation(EXIT_ON_CLOSE);  
  51.            
  52.         getContentPane().setLayout(new BorderLayout()); // 利用边界布局将界面分割成上中下三部分  
  53.         labelAlarm = new JLabel("闹钟定时已到!");  
  54.         btnClose = new JButton("确定");  
  55.         labelNextAlarm = new JLabel(); // 指示下一次闹钟时间  
  56.         alarmPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); // 顶部提示栏提示闹钟时间已到,和确定按钮  
  57.         alarmPanel.add(labelAlarm);  
  58.         alarmPanel.add(btnClose);  
  59.            
  60.         topPanel = new JPanel(new GridLayout(2, 1));  
  61.         topPanel.add(alarmPanel);  
  62.         topPanel.add(labelNextAlarm);  
  63.         alarmPanel.setVisible(false); // 初始隐藏顶部提示栏  
  64.            
  65.         labelClock = new JLabel();  
  66.         Font font = new Font(Font.SERIF, Font.PLAIN, 48); // 中间的倒计时文本用大号字体展示  
  67.         labelClock.setFont(font);  
  68.         labelClock.setHorizontalAlignment(JLabel.CENTER); // 文本居中  
  69.         btnSet = new JButton("设置");  
  70.            
  71.         getContentPane().add(topPanel, BorderLayout.NORTH); // 界面顶部  
  72.         getContentPane().add(labelClock, BorderLayout.CENTER); // 界面中部  
  73.         getContentPane().add(btnSet, BorderLayout.SOUTH); // 界面底部  
  74.            
  75.         btnSet.addActionListener(this); // 设置按钮的点击事件  
  76.         btnClose.addActionListener(this); // 顶部确定按钮的点击事件  
  77.         setLocationRelativeTo(null); // 界面居中  
  78.         setDialog = new SetDialog(this); // 初始化设置对话框  
  79.    
  80.         try { // 初始化闹钟声音  
  81.             // 目前发现wav格式的文件是可以支持的,mp3不支持  
  82.             AudioInputStream ais = AudioSystem.getAudioInputStream(  
  83.                     AlarmClock.class.getResource("music.wav"));  
  84.             clip = AudioSystem.getClip();  
  85.             clip.open(ais);  
  86.             ais.close();  
  87.             int loop = LOOP_COUNT <= 0 ? 1 : LOOP_COUNT;  
  88.             final long totalFrames = ais.getFrameLength() * loop;  
  89.             clip.addLineListener(new LineListener() {  
  90.                 public void update(LineEvent e) {  
  91.                     // 当闹钟音乐播放结束时,自动隐藏顶部提示栏  
  92.                     if(e.getFramePosition() >= totalFrames) {  
  93.                         stopAlarm();  
  94.                     }  
  95.                 }  
  96.             });  
  97.         } catch (UnsupportedAudioFileException e) {  
  98.             e.printStackTrace();  
  99.         } catch (IOException e) {  
  100.             e.printStackTrace();  
  101.         } catch (LineUnavailableException e) {  
  102.             e.printStackTrace();  
  103.         }  
  104.         initTimer();  
  105.     }  
  106.    
  107.     public static void main(String[] args) {  
  108.         new AlarmClock().launch(); // 启动主界面  
  109.     }  
  110.    
  111.     public void actionPerformed(ActionEvent e) {  
  112.         Object source = e.getSource();  
  113.         if(source == btnSet) { // 点击设置按钮时弹出设置界面,以模对话框显示  
  114.             setDialog.setVisible(true);  
  115.         } else if(source == btnClose) { // 点击顶部确定按钮时隐藏顶部提示栏  
  116.             stopAlarm();  
  117.         }  
  118.     }  
  119.        
  120.     private void initTimer() {  
  121.         timer = new Timer(); // 初始化倒计时任务  
  122.         // 开始倒计时  
  123.         timer.scheduleAtFixedRate(new TimerTask() {  
  124.             @Override  
  125.             public void run() {  
  126.                 Calendar cal = Calendar.getInstance();  
  127.                 int hour = cal.get(Calendar.HOUR_OF_DAY);  
  128.                 int min = cal.get(Calendar.MINUTE);  
  129.                 int sec = cal.get(Calendar.SECOND);  
  130.                 // 设置倒计时文本  
  131.                 labelClock.setText(String.format("%02d : %02d : %02d", hour, min, sec));  
  132.                 if(null != alarmCal && !timeReached) {  
  133.                     int alarmHour = alarmCal.get(Calendar.HOUR_OF_DAY);  
  134.                     int alarmMin = alarmCal.get(Calendar.MINUTE);  
  135.                     if(alarmHour == hour && alarmMin == min) { // 到时间时播放声音  
  136.                         timeReached = true;  
  137.                         System.out.println("Time over");  
  138.                         startAlarm();  
  139.                     }  
  140.                 }  
  141.             }  
  142.         }, 0, 1000L); // 每隔1秒刷新倒计时文本  
  143.     }  
  144.        
  145.     /**
  146.      * 开始计时
  147.      * @param hour
  148.      * @param minute
  149.      */  
  150.     public void startTimer(int hour, int minute) {  
  151.         alarmCal = Calendar.getInstance();  
  152.         alarmCal.set(Calendar.HOUR_OF_DAY, hour);  
  153.         alarmCal.set(Calendar.MINUTE, minute);  
  154.         labelNextAlarm.setText("下次闹钟时间:" + df.format(alarmCal.getTime()));  
  155.         timeReached = false;  
  156.     }  
  157.        
  158.     /**
  159.      * 取消倒计时任务
  160.      */  
  161.     public void cancelTimer() {  
  162.         labelNextAlarm.setText("");  
  163.         alarmCal = null;  
  164.     }  
  165.        
  166.     private void startAlarm() { // 开始播放提示音  
  167.         if(null != clip) {  
  168.             alarmPanel.setVisible(true); // 显示顶部提示栏  
  169.             clip.setFramePosition(0); // 将音频帧重置为第0帧  
  170.             clip.loop(LOOP_COUNT); // 开始循环播放  
  171.         }  
  172.         labelNextAlarm.setText("");  
  173.     }  
  174.     private void stopAlarm() { // 停止播放提示音  
  175.         if(null != clip && clip.isRunning()) {  
  176.             clip.stop(); // 结束播放  
  177.         }  
  178.         labelNextAlarm.setText("");  
  179.         alarmPanel.setVisible(false); // 隐藏顶部提示栏  
  180.     }  
  181.        
  182.     /**
  183.      * 闹钟设置页面
  184.      */  
  185.     class SetDialog extends JDialog implements KeyListener, ActionListener {  
  186.         private JLabel labelHour, labelMin;  
  187.         private JTextField textHour, textMin;  
  188.         private JPanel mainPanel, labelPanel, buttonPanel;  
  189.         private JButton btnOk, btnCancel, btnBack;  
  190.         private Calendar cal = Calendar.getInstance();  
  191.            
  192.         public SetDialog(Frame frame) {  
  193.             super(frame);  
  194.             setTitle("设置");  
  195.             setModal(true); // 设置为模窗口,就是说在本弹窗未消失时不允许点击主界面。  
  196.             setSize(300, 150);  
  197.             // 显示时分  
  198.             labelHour = new JLabel("时");  
  199.             labelMin = new JLabel("分");  
  200.             labelHour.setHorizontalAlignment(JLabel.CENTER);  
  201.             labelMin.setHorizontalAlignment(JLabel.CENTER);  
  202.             textHour = new JTextField();  
  203.             textMin = new JTextField();  
  204.             // 上面的部分用网格布局将各组件以2x2的格子放进去  
  205.             labelPanel = new JPanel(new GridLayout(2, 2));  
  206.             labelPanel.add(labelHour);  
  207.             labelPanel.add(labelMin);  
  208.             labelPanel.add(textHour);  
  209.             labelPanel.add(textMin);  
  210.             // 时分输入框添加按键监听,只允许输入数字  
  211.             textHour.addKeyListener(this);  
  212.             textMin.addKeyListener(this);  
  213.                
  214.             // 初始化按钮  
  215.             btnOk = new JButton("确定");  
  216.             btnCancel = new JButton("取消");  
  217.             btnBack = new JButton("返回");  
  218.             // 下面的按钮依次居中放进去  
  219.             buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));  
  220.             buttonPanel.add(btnBack);  
  221.             buttonPanel.add(btnCancel);  
  222.             buttonPanel.add(btnOk);  
  223.             // 初始化主面板,将主面板分割为上下两部分  
  224.             mainPanel = new JPanel(new BorderLayout());  
  225.             mainPanel.add(labelPanel, BorderLayout.CENTER); // 上面显示时分的组件  
  226.             mainPanel.add(buttonPanel, BorderLayout.SOUTH); // 下面排列三个按钮  
  227.             setContentPane(mainPanel);  
  228.             // 设置按钮监听  
  229.             btnBack.addActionListener(this);  
  230.             btnOk.addActionListener(this);  
  231.             btnCancel.addActionListener(this);  
  232.    
  233.             cal.add(Calendar.HOUR, 1); // 默认设置为当前时间加1小时的整点时间  
  234.             cal.set(Calendar.MINUTE, 0);  
  235.             int hour = cal.get(Calendar.HOUR_OF_DAY);  
  236.             int min = cal.get(Calendar.MINUTE);  
  237.             textHour.setText(String.format("%02d", hour));  
  238.             textMin.setText(String.format("%02d", min));  
  239.             setLocationRelativeTo(frame);  
  240.         }  
  241.    
  242.         public void keyPressed(KeyEvent arg0) {  
  243.         }  
  244.         public void keyReleased(KeyEvent arg0) {  
  245.         }  
  246.         public void keyTyped(KeyEvent e) {  
  247.             int keyChar = e.getKeyChar();                  
  248.             if(keyChar >= KeyEvent.VK_0 && keyChar <= KeyEvent.VK_9){  
  249.             }else{ // 如果输入的不是数字则屏蔽输入  
  250.                 e.consume(); //关键,屏蔽掉非法输入    
  251.             }  
  252.         }  
  253.    
  254.         public void actionPerformed(ActionEvent e) {  
  255.             Object source = e.getSource();  
  256.             if(source == btnOk) { // 如果点击了确定按钮,则开始计时  
  257.                 int hour = 0, min = 0;  
  258.                 try {  
  259.                     hour = Integer.parseInt(textHour.getText());  
  260.                 } catch (NumberFormatException e1) {  
  261.                 }  
  262.                 try {  
  263.                     min = Integer.parseInt(textMin.getText());  
  264.                 } catch (NumberFormatException e1) {  
  265.                 }  
  266.                 startTimer(hour, min);  
  267.                 setVisible(false);  
  268.             } else if(source == btnCancel) { // 点击取消按钮时取消计时  
  269.                 cancelTimer();  
  270.                 setVisible(false);  
  271.             } else if(source == btnBack) { // 点击返回按钮时什么也不做,直接关闭设置界面  
  272.                 setVisible(false);  
  273.             }  
  274.         }  
  275.     }  
  276. }  

回复 "简易闹钟"

这儿你可以回复上面这条便签

captcha