java闹钟小程序
第一次分享,也不知道怎么介绍一番,那么就按照程序思路贴代码吧,如有不足烦请多多指教!
开发环境:MyEclipse8.5,JDK1.6,jxl.jar,Dom4j.jar
java知识点:Interface接口、Thread线程、TreeSet集合等。
一、java project 结构如下:

二、config文件夹中的文件截图
config.xml
1 <?xml version="1.0" encoding="GBK"?> 2 <ConfigParam version="1.0"> 3 <!--系统配置变量 --> 4 <rundate> 5 <name>画画</name> 6 <!-- 开始分析时间 如0700为早上7点整开始--> 7 <startTime>0600</startTime> 8 <!-- 音乐文件名,默认后缀是 .wav 格式--> 9 <music>music</music> 10 </rundate> 11 <rundate> 12 <name>画画</name> 13 <startTime>1000</startTime> 14 <music>music</music> 15 </rundate> 16 <rundate> 17 <name>跆拳道</name> 18 <startTime>0900</startTime> 19 <music>music</music> 20 </rundate> 21 </ConfigParam>
excel

三、代码
1 /*** 2 * main主函数 3 * @author caojsvm 4 * 2022.01.13 5 */ 6 public class ClockMain { 7 8 /** 9 * @param args 10 */ 11 public static void main(String[] args) { 12 System.out.println("启动程序"); 13 try { 14 15 /** 16 * 替换方法(xml 、excel可修改此处替换使用) 17 */ 18 //ClockXmlConfig appCfg = ClockXmlConfig.getInstance(); 19 ClockExcelConfig appCfg = new ClockExcelConfig(); 20 21 22 //初始化闹钟 23 appCfg.initConfig(); 24 25 ClockTaskPool ctp= new ClockTaskPool(); 26 Thread taskPoolThread = new Thread(ctp); 27 28 //启动闹钟任务池线程 29 taskPoolThread.start(); 30 31 //启动闹钟响铃检测线程 32 ClockExcute ec = new ClockExcute(ctp); 33 Thread t1 = new Thread(ec); 34 Thread t2 = new Thread(ec); 35 36 t1.start(); 37 38 CommonUtil.sleep("main",1); 39 40 t2.start(); 41 42 } catch (Exception e) { 43 System.out.println("Error:初始化配置Config.xml失败"); 44 e.printStackTrace(); 45 System.exit(0); 46 } 47 } 48 }
1 public class Clock { 2 private String time; 3 private String clockName; 4 private String musicName ; 5 private boolean clockFlag = false; 6 7 Clock(){ 8 9 } 10 11 Clock(String time,String clockName,String musicName){ 12 this.clockName = clockName; 13 this.musicName = musicName; 14 this.time = time; 15 16 } 17 18 19 public boolean isClockFlag() { 20 return clockFlag; 21 } 22 23 public void setClockFlag(boolean clockFlag) { 24 this.clockFlag = clockFlag; 25 } 26 27 public String getTime() { 28 return time; 29 } 30 public void setTime(String time) { 31 if("".equals(time)) 32 throw new RuntimeException("设置的闹钟时间错误,请检查。"); 33 this.time = time; 34 } 35 public String getClockName() { 36 return clockName; 37 } 38 public void setClockName(String clockName) { 39 if("".equals(clockName)) 40 throw new RuntimeException("设置的闹钟名称错误,请检查。"); 41 this.clockName = clockName; 42 } 43 public String getMusicName() { 44 return musicName; 45 } 46 public void setMusicName(String musicName) { 47 if("".equals(musicName)) 48 this.musicName = "music"; 49 else{ 50 this.musicName = musicName; 51 } 52 } 53 54 @Override 55 public String toString() { 56 return this.clockName+":"+this.time+" ,musicName:"+this.musicName+" , IsExcute:"+this.clockFlag; 57 } 58 59 60 public String toClockString() { 61 return this.clockName+":"+this.time.substring(0, 2)+":"+this.time.substring(2, 4)+"\n闹铃音乐:"+this.musicName; 62 } 63 }
1 import java.util.Comparator; 2 3 public class ClockCompareTo implements Comparator<Clock>{ 4 5 public int compare(Clock o1, Clock o2) { 6 int compare = o1.getTime().compareTo(o2.getTime()) ; 7 if(compare == 0 ){ 8 return o1.getClockName().compareTo(o2.getClockName()); 9 } 10 return compare; 11 } 12 13 }
1 import java.io.File; 2 import java.io.FileNotFoundException; 3 import java.io.IOException; 4 import java.util.TreeSet; 5 6 import jxl.Cell; 7 import jxl.Sheet; 8 import jxl.Workbook; 9 import jxl.read.biff.BiffException; 10 11 import org.dom4j.DocumentException; 12 13 public class ClockExcelConfig implements ClockSet { 14 private TreeSet<Clock> clockSet ; 15 16 public ClockExcelConfig(){ 17 this.clockSet = new TreeSet<Clock>(new ClockCompareTo()); 18 } 19 20 @Override 21 public TreeSet<Clock> getClockSet() { 22 // TODO Auto-generated method stub 23 return clockSet; 24 } 25 26 @Override 27 public void initConfig() throws DocumentException { 28 String filePath = CommonUtil.WORK_PATH + "config" + File.separator + "clock.xls"; 29 30 System.out.println(filePath); 31 try { 32 File excel = new File(filePath); 33 Workbook book = Workbook.getWorkbook(excel);// 创建workbook 34 35 if(book.getNumberOfSheets() < 1){ 36 return; 37 } 38 39 Sheet sheet=book.getSheet(0); //获得第一个工作表对象 40 41 if(sheet.getRows() < 3){ //如果sheet小于3行视为无效的闹铃设置(默认第一、二行为标题,第三行开始是闹铃设置内容。) 42 return; 43 } 44 45 for(int i = 2; i<sheet.getRows(); i++){ 46 //System.out.println(i); 47 48 //可用for循环读取各行每列单元格数据,此处读取配置文件,一共固定的三列,所以没有用循环。 49 Cell cell_1=sheet.getCell(0, i); //获得第i行第1列的单元格 50 Cell cell_2=sheet.getCell(1, i); //获得第i行第2列的单元格 51 Cell cell_3=sheet.getCell(2, i); //获得第i行第3列的单元格 52 53 if(cell_1.getContents().trim().length()!=0 && cell_1.getContents().trim().length()!=0 ){ //如果等于0 ,说明港航数据无效,直接跳过。 54 Clock clock = new Clock(); 55 clock.setClockName(cell_1.getContents()); 56 clock.setTime(CommonUtil.changeTime(cell_2.getContents())); 57 clock.setMusicName(cell_3.getContents()); 58 this.clockSet.add(clock); 59 } 60 } 61 } catch (BiffException e) { 62 System.out.println("error:读取excel失败2"); 63 e.printStackTrace(); 64 } catch (FileNotFoundException e) { 65 System.out.println("设置闹钟的excel文件(.xls)不存在,请您检查!"); 66 e.printStackTrace(); 67 } catch (IOException e) { 68 System.out.println("error:读取excel失败2"); 69 e.printStackTrace(); 70 } 71 72 } 73 }
1 public class ClockExcute implements Runnable{ 2 private boolean flag = true; 3 private ClockTaskPool ctp = null; 4 5 public ClockExcute(ClockTaskPool ctp){ 6 this.ctp = ctp; 7 } 8 9 @Override 10 public void run() { 11 while(flag){ 12 System.out.println("ExcuteClock............."); 13 this.ctp.clock(); 14 CommonUtil.sleep("ExcuteClock",10); 15 } 16 } 17 }
import java.applet.Applet; import java.applet.AudioClip; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JTextArea;
@SuppressWarnings("serial") public class ClockMusic extends JDialog implements ActionListener,ItemListener,Runnable,WindowListener{ JButton btn_play,btn_stop,btn_loop; JTextArea testAreaClockIno; AudioClip clip; Thread thead; private String musicFileStr ; public ClockMusic(Clock clock,String musicFileStr) { clock(clock,musicFileStr); } public void clock(Clock clock,String musicFileStr){ setSize(350, 200); setLayout(new FlowLayout()); testAreaClockIno = new JTextArea("闹铃信息:\n"+clock.toClockString(),5,2); btn_stop = new JButton("停止"); this.musicFileStr = musicFileStr; addWindowListener(this); //添加监听函数,引发WindowEvent事件 thead = new Thread(this); thead.isDaemon();//守护线程 add(testAreaClockIno); add(btn_stop); btn_stop.addActionListener(this); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setVisible(true); //启动响铃线程 itemStateChanged(); } public void run() { try { File file = new File(this.musicFileStr);//创建一个file对象 URI uri = file.toURI();//创建一个URI对象 URL url = uri.toURL();//创建一个URL对象 clip = Applet.newAudioClip(url);//创建一个音频对象 //响铃 clip.play(); } catch (MalformedURLException e) { e.printStackTrace(); } } public void itemStateChanged(ItemEvent e) { System.out.println("itemStateChanged(ItemEvent e).....run"); if(!(thead.isAlive())){ thead = new Thread(this); } try{ //守护线程 //thead.isDaemon(); thead.start(); }catch(Exception ee){ System.out.println("线程异常"); } } public void itemStateChanged() { if(!(thead.isAlive())){ thead = new Thread(this); } try{ thead.start(); }catch(Exception ee){ System.out.println("线程异常"); } } @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == btn_play){ clip.play(); }else if(e.getSource() == btn_stop){ clip.stop(); }else if(e.getSource() == btn_loop){ clip.loop(); } } @Override public void windowActivated(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowClosed(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowClosing(WindowEvent e) { (e.getWindow()).dispose(); if (clip != null){ clip.stop(); clip = null; } } @Override public void windowDeactivated(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeiconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowIconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowOpened(WindowEvent e) { // TODO Auto-generated method stub } }
1 import java.util.TreeSet; 2 import org.dom4j.DocumentException; 3 4 /*** 5 * 6 * @author caojsvm 7 * 闹铃设置信息获取来源接口,目前实现两种方式:excel、xml 8 */ 9 public interface ClockSet { 10 TreeSet<Clock> getClockSet(); 11 void initConfig()throws DocumentException; 12 }
1 import java.util.Iterator; 2 import java.util.TreeSet; 3 import org.dom4j.DocumentException; 4 5 /*** 6 * 响铃的任务池 7 * @author caojsvm 8 * 9 */ 10 public class ClockTaskPool implements Runnable{ 11 private static TreeSet<Clock> clockTreeSet = new TreeSet<Clock>(new ClockCompareTo()); 12 private boolean flag = true; 13 14 public void run() { 15 while(flag){ 16 System.out.println("ClockTaskPool............."); 17 getTaskPool(); 18 } 19 } 20 21 public void addClock(TreeSet<Clock> ts){ 22 for(Iterator<Clock> cIt = ts.iterator();cIt.hasNext();){ 23 Clock clock = cIt.next(); 24 if(!clock.isClockFlag()){ 25 clockTreeSet.add(clock); 26 } 27 } 28 } 29 30 /*** 31 * 获取、更新响铃任务池 32 */ 33 public void getTaskPool(){ 34 35 /** 36 * 替换方法(xml 、excel替换,需要和ClockMain类中的同时替换方可) 37 */ 38 //ClockXmlConfig appCfg = ClockXmlConfig.getInstance(); 39 ClockExcelConfig appCfg = new ClockExcelConfig(); 40 41 42 //读取闹铃设置信息 43 System.out.println("更新闹铃设置信息"); 44 try { 45 appCfg.initConfig(); 46 TreeSet<Clock> ts = appCfg.getClockSet(); 47 addClock(ts); 48 49 System.out.println("更新:" + clockTreeSet); 50 } catch (DocumentException e) { 51 System.out.println("读取闹铃设置信息失败"); 52 e.printStackTrace(); 53 }finally{ 54 CommonUtil.sleep("ClockTaskPool",1);; //线程睡眠?秒 55 } 56 57 } 58 59 /*** 60 * 响铃 61 */ 62 public void clock(){ 63 Iterator<Clock> it = clockTreeSet.iterator(); 64 String today = CommonUtil.getDate("yyyyMMdd"); 65 String todayTime = CommonUtil.getDate("yyyyMMddHHmm"); 66 67 while(it.hasNext()){ 68 Clock clock = it.next(); 69 String clockDateTime = today+clock.getTime(); 70 if(clockDateTime.compareTo(todayTime) <= 0 && !clock.isClockFlag()){ 71 new ClockMusic(clock, CommonUtil.musicFileStr + clock.getMusicName() + ".wav"); 72 clock.setClockFlag(true); 73 } 74 } 75 76 } 77 78 }
1 import java.io.File; 2 import java.util.Iterator; 3 import java.util.List; 4 import java.util.TreeSet; 5 6 import org.dom4j.Document; 7 import org.dom4j.DocumentException; 8 import org.dom4j.Element; 9 import org.dom4j.Node; 10 import org.dom4j.io.SAXReader; 11 12 13 /*** 14 * 获取xml中的闹铃设置信息 15 * @author caojsvm 16 * 17 */ 18 public class ClockXmlConfig implements ClockSet{ 19 private static ClockXmlConfig appCfg; 20 private TreeSet<Clock> clockSet ; 21 private ClockXmlConfig(){ 22 23 } 24 public static ClockXmlConfig getInstance(){ 25 if(appCfg == null){ 26 synchronized (Clock.class) { 27 if(appCfg == null){ 28 appCfg = new ClockXmlConfig(); 29 } 30 } 31 } 32 return appCfg; 33 } 34 35 /*** 36 * 读取下xml文档,获得document对象。 37 * @throws DocumentException 38 */ 39 @SuppressWarnings("unchecked") 40 public void initConfig() throws DocumentException { 41 SAXReader reader = new SAXReader(); 42 String str = CommonUtil.WORK_PATH + "config" + File.separator + "Config.xml"; 43 44 System.out.println("获取配置文件:"+str); 45 Document document = reader.read(new File(str)); 46 47 /** 48 * 节点对象的操作方法 49 */ 50 51 //获取文档根节点 52 Element root = document.getRootElement(); 53 System.out.println("获取闹钟项目及设定信息...."); 54 55 //获取根节点下面的所有子节点(不包过子节点的子节点) 56 List<Element> list = root.elements() ; 57 //遍历List的方法 58 clockSet = new TreeSet<Clock>(new ClockCompareTo()); 59 for (Iterator<Element> it = list.iterator();it.hasNext();){ 60 Element rundateEmt = (Element)it.next(); 61 List<Element> rundateList = rundateEmt.elements() ; 62 Iterator<?> rundateIte= rundateList.iterator(); 63 Clock clock = new Clock(); 64 while (rundateIte.hasNext()){ 65 Object obj = (Object)rundateIte.next(); 66 if (obj instanceof Node){ 67 Node node = (Node)obj; 68 if("name".equals(node.getName())){ 69 clock.setClockName(node.getText()); 70 }else if("startTime".equals(node.getName())){ 71 clock.setTime(node.getText()); 72 }else if("music".equals(node.getName())){ 73 clock.setMusicName(node.getText()); 74 }else{ 75 System.out.println("error,read config error."); 76 } 77 } 78 } 79 if(!clockSet.add(clock)){ 80 System.out.println("warning:Alarm clock definition repetition!"); 81 } 82 } 83 System.out.println("闹铃信息获取完成。"); 84 } 85 86 public TreeSet<Clock> getClockSet() { 87 return clockSet; 88 } 89 }
1 import java.io.File; 2 import java.text.SimpleDateFormat; 3 import java.util.Date; 4 5 /*** 6 * 公共方法类 7 * @author caojsvm 8 * 9 */ 10 public class CommonUtil { 11 public static String WORK_PATH = System.getProperty("user.dir")+ File.separator; 12 public static String musicFileStr = CommonUtil.WORK_PATH + "music" + File.separator ; 13 14 /*** 15 * 获取当天时间 16 * @param strFormat 17 * @return 18 */ 19 public static String getDate(String strFormat) { 20 SimpleDateFormat sFormat = new SimpleDateFormat(strFormat); 21 Date date = new Date(); 22 String str = sFormat.format(date); 23 return str; 24 } 25 26 /*** 27 * 线程睡眠方法 28 * @param tName 29 * @param miao 30 */ 31 public static void sleep(String tName,int miao){ 32 try { 33 System.out.println("线程睡眠"+miao+"秒。"); 34 Thread.sleep(miao*1000); 35 } catch (InterruptedException e) { 36 System.out.println("线程睡眠失败"); 37 e.printStackTrace(); 38 } 39 } 40 41 42 /*** 43 * 转换时间格式,把08:59转化为0859 44 * @param str 45 * @return 46 */ 47 public static String changeTime(String str){ 48 int hour = Integer.parseInt(str.substring(0, str.indexOf(':'))); 49 if(hour > 24){ 50 throw new RuntimeException("设置的时间("+str+")格式有误,请检查。"); 51 } 52 int size = str.length(); 53 if(size == 4 && str.indexOf(':')==1) 54 return "0"+str.replace(":", ""); 55 if(size == 5 && str.indexOf(':')==2) 56 return str.replace(":", ""); 57 58 throw new RuntimeException("设置的时间("+str+")格式有误,请检查。"); 59 } 60 }
以上 ,就是这个闹钟的全部代码了,虽然是个小程序,但是通过动手还是深入理解了一些知识点。
如有问题可留言哈。谢谢!
浙公网安备 33010602011771号