package com.shrimpking.t1;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Formatter;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/11/2 11:11
*/
public class AlarmClock
{
private JLabel[] labels; //标签数组
private ButtonGroup buttonGroup; //单选按钮组
private JRadioButton intervalRadio; //间隔时间
private JRadioButton specifyRadio; //指定时间
private JTextField minuteText; //多少分后
private JTextField timeText; //时间
private JCheckBox chkBox; //弹出来
private JButton btnOk;
private JButton btnCancel;
private Container container; //容器
private GridBagLayout gridBagLayout; //布局
private JFrame frame; //窗体
private Date today; //日期
private Timer myTimer; //时钟线程
private int remainSeconds = 0; //还剩多少秒
private boolean startTime = false; //开始计时
public AlarmClock(){
final String[] msg = {"当前时间","","订于","分钟后","订于","提醒","现在还差"," 0 秒"};
GridBagConstraints c = new GridBagConstraints();
HandleBtn handleBtn = new HandleBtn();
labels = new JLabel[msg.length];
for (int i = 0; i < labels.length; i++)
{
labels[i] = new JLabel(msg[i],JLabel.CENTER); //标签居中显示
}
frame = new JFrame("小闹钟示例"); //窗体实例化
container = frame.getContentPane(); //获取面板容器
today = new Date(); //实例日期
gridBagLayout = new GridBagLayout();
container.setLayout(gridBagLayout); //窗体容器设置布局方式为网格增强布局
c.fill = GridBagConstraints.BOTH; //填充方式
c.insets = new Insets(0,0,5,0); //组件之间间隔距离
//设置第一行的标签
c.gridwidth = 1; //单元格占1列
this.addComponents(labels[0],c); //当前时间
c.gridwidth = GridBagConstraints.REMAINDER; //单元格占剩余空间
labels[1].setText(timeToString(today)); //显示时间
this.addComponents(labels[1],c); // ""
//设置第二行
c.gridwidth = 1; //占1列
intervalRadio = new JRadioButton("间隔时间",true); //单选按钮,选中
intervalRadio.addActionListener(handleBtn); //单选按钮事件
buttonGroup = new ButtonGroup(); //控件组
buttonGroup.add(intervalRadio); //加入组
this.addComponents(intervalRadio,c);
this.addComponents(labels[2],c); //订于
minuteText = new JTextField("5",6); //输入框,默认5分钟,6个字符宽度
this.addComponents(minuteText,c);
c.gridwidth = GridBagConstraints.REMAINDER; //占剩余空间
this.addComponents(labels[3],c); //分钟后
//设置第三行组件
c.gridwidth = 1; //占1列
specifyRadio = new JRadioButton("执行时间",false); //单选按钮,不选中
specifyRadio.addActionListener(handleBtn); //单选按钮事件
buttonGroup.add(specifyRadio); //加入组
this.addComponents(specifyRadio,c);
this.addComponents(labels[4],c); //订于
timeText = new JTextField(timeToString(today),6); //
timeText.setEditable(false);
this.addComponents(timeText,c);
c.gridwidth = GridBagConstraints.REMAINDER; //占剩余空间
this.addComponents(labels[5],c); //提醒
//设置第四行的组件
c.gridwidth = 1; //占1列
this.addComponents(labels[6],c); //现在还差
c.gridwidth = GridBagConstraints.REMAINDER; //占剩余空间
this.addComponents(labels[7],c); // 0 秒
//设置第五行
c.gridwidth = 1; //占1列
chkBox = new JCheckBox("弹出来",true); //复选框,选中
this.addComponents(chkBox,c);
JPanel panel = new JPanel(); //面板
panel.setLayout(new FlowLayout()); //流式布局
btnOk = new JButton("确定"); //
btnCancel = new JButton("取消");
btnOk.addActionListener(handleBtn); //按钮事件
btnCancel.addActionListener(handleBtn);
panel.add(btnOk);
panel.add(btnCancel);
c.gridwidth = GridBagConstraints.REMAINDER; //占剩余空间
this.addComponents(panel,c); //
frame.setSize(280,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //窗体关闭事件
myTimer = new Timer(); //定时器
Refresh task = new Refresh(); //定时任务,线程类
myTimer.schedule(task,1000,1000); //计划执行,延迟1秒,间隔1秒
}
private String timeToString(Date today)
{
// Formatter fmt = new Formatter();
// fmt.format("%tT",today);
// return fmt.toString();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(today);
}
//这个方法很优解,减少了代码堆叠
private void addComponents(Component obj,GridBagConstraints c){
gridBagLayout.setConstraints(obj,c); //添加约束
container.add(obj); //加入容器
}
//内部类
class Refresh extends TimerTask{
public Refresh(){
super();
}
@Override
public void run()
{
today = new Date(); //当前时间
labels[1].setText(timeToString(today)); //显示时间
//下面是新加入的报时功能
if (startTime){
//如果开始计时
labels[7].setText(remainSeconds + "秒"); //显示剩余多少秒
remainSeconds--; //秒数减少
if (remainSeconds == 0){
startTime = false; //时间到,停止计时
if (chkBox.isSelected()){
//如果弹出来,选中,窗体从最小化改变为正常现实模式
frame.setState(JFrame.NORMAL);
}
try
{
//播放声音
FileInputStream fis = new FileInputStream("d:\\test\\boom.wav"); //字节输入流
AudioStream as = new AudioStream(fis); //音频流
AudioPlayer.player.start(as); //音频播放器
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
class HandleBtn implements ActionListener{
@Override
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource(); //获取事件发生源
if (obj == intervalRadio){
//间隔时间
minuteText.setEditable(true); //可以编辑间隔时间
timeText.setEditable(false); //指定时间,不可编辑
}else if (obj == specifyRadio){
//指定时间
minuteText.setEditable(false); //间隔时间,不可编辑
timeText.setEditable(true); //指定时间,可用
}else if (obj == btnOk){
//确定按钮
try
{
if (intervalRadio.isSelected()){
//指定了间隔时间
//获取的分钟数,转换为十进制,乘以60秒
remainSeconds = Integer.parseInt(minuteText.getText(),10) * 60;
}else {
//指定了绝对时间
Date tempDate = new Date();
int curTime; //当前时间秒
int endTime; //结束时间秒
curTime = tempDate.getHours() * 3600
+ tempDate.getMinutes() * 60
+ tempDate.getSeconds();
endTime = parseTime(timeText.getText()); //解析时间
remainSeconds = endTime - curTime; //剩余秒数
}
if (remainSeconds > 0){
//还差多少秒,计时开始
startTime = true;
frame.setState(JFrame.ICONIFIED); //窗体状态,最小化
}else {
//剩余描述小于0时,取消闹钟
btnCancel.doClick(); //取消
}
}catch (NumberFormatException ex){
JOptionPane.showMessageDialog(frame,"对不起,输入的时间间隔有错误");
}catch (ParseException ex){
JOptionPane.showMessageDialog(frame,"对不起,指定的时间有错误");
}
}else if (obj == btnCancel){
//取消按钮
startTime = false; //停止计时
remainSeconds = 0; //剩余秒数
labels[7].setText(remainSeconds + "秒");
}
}
}
private int parseTime(String str) throws ParseException{
int i = 0; //字符位置
int hour = 0; //时
int minute = 0; //分
int second = 0; //秒
int ch;
//取出其中的小时
ch = str.charAt(i);
while (i < str.length() && ch !=':'){
if (ch < '0' || ch > '9'){
//不允许非数字
throw new ParseException(str,i);
}
hour = hour * 10 + ch - '0';
i++;
if (i < str.length()){
ch = str.charAt(i); //下一个字符
}else {
throw new ParseException(str,i);
}
}
//越过中间的冒号
i++;
//取出其中的分钟
ch = str.charAt(i);
while (i < str.length() && ch != ':'){
if (ch < '0' || ch > '9'){
throw new ParseException(str,i);
}
minute = minute * 10 + ch - '0';
i++;
if (i < str.length()){
ch = str.charAt(i);
}else {
throw new ParseException(str,i);
}
}
//越过中间的冒号
i++;
//取出其中的秒数
ch = str.charAt(i);
while (i < str.length()){
if (ch < '0' || ch > '9'){
throw new ParseException(str,i);
}
second = second * 10 + ch - '0';
i++;
if (i < str.length()){
ch = str.charAt(i);
}
}
if (hour > 23 || minute > 59 || second > 59){
throw new ParseException(str,i);
}
return hour * 3600 + minute * 60 + second;
}
public static void main(String[] args)
{
new AlarmClock();
}
}
