/* * Copyright © 2023 Dean Lee */ package alarm; import java.lang.Error; import javax.swing.Timer; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.Calendar; import java.net.URL; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.DataLine; import javax.sound.sampled.Clip; /** * * @author dean */ public class Alarm extends javax.swing.JFrame implements ActionListener { private Audio audio = new Audio(); private boolean audioPlaying = false; private boolean alarmEnabled = true; private Calendar previousTime = captureTime(); private Calendar currentTime; private Calendar alarmTime = Calendar.getInstance(); /** * Creates new form Alarm */ public Alarm() { initComponents(); initAlarm(); initTimer(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { timeDisplay = new javax.swing.JLabel(); message = new javax.swing.JLabel(); alarmDisplay = new javax.swing.JLabel(); dateDisplay = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Alarm"); addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { formKeyPressed(evt); } }); timeDisplay.setFont(new java.awt.Font("Dialog", 1, 48)); // NOI18N timeDisplay.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); timeDisplay.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); message.setFont(new java.awt.Font("Dialog", 1, 18)); // NOI18N message.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); message.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); alarmDisplay.setFont(new java.awt.Font("Dialog", 1, 36)); // NOI18N alarmDisplay.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); alarmDisplay.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); dateDisplay.setFont(new java.awt.Font("Dialog", 1, 36)); // NOI18N dateDisplay.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); dateDisplay.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(183, 183, 183) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(alarmDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(dateDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(timeDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGroup(layout.createSequentialGroup() .addGap(61, 61, 61) .addComponent(message, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(76, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(message, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(70, 70, 70) .addComponent(timeDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(dateDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, Short.MAX_VALUE) .addComponent(alarmDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void formKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyPressed if (audioPlaying) alarmOff(); else handleSpecificKey(evt); }//GEN-LAST:event_formKeyPressed private void handleSpecificKey(java.awt.event.KeyEvent evt) { switch(evt.getKeyCode()) { case KeyEvent.VK_PERIOD: alarmTime.roll(Calendar.HOUR_OF_DAY, 1); break; case KeyEvent.VK_COMMA: alarmTime.roll(Calendar.HOUR_OF_DAY, -1); break; case KeyEvent.VK_K: alarmTime.roll(Calendar.MINUTE, -1); break; case KeyEvent.VK_L: alarmTime.roll(Calendar.MINUTE, 1); break; case KeyEvent.VK_SEMICOLON: alarmTime.roll(Calendar.MINUTE, 10); break; case KeyEvent.VK_J: alarmTime.roll(Calendar.MINUTE, -10); break; case KeyEvent.VK_SLASH: alarmTime.set(Calendar.HOUR_OF_DAY, 12); break; case KeyEvent.VK_M: alarmTime.set(Calendar.HOUR_OF_DAY, 0); break; case KeyEvent.VK_SPACE: toggleAlarmEnabled(); break; }; updateAlarmDisplay(); } // basically the "ticking" method. public void actionPerformed(ActionEvent e) { setTime(); handleTimeChange(); previousTime = currentTime; } private void alarmOff() { if (audioPlaying) audio.stop(); audioPlaying = false; setAlarmMessage(); } private void alarmOn() { if (!audioPlaying) audio.play(); audioPlaying = true; message.setText("Press any key to stop audio."); } private void toggleAlarmEnabled() { if (alarmEnabled) alarmEnabled = false; else alarmEnabled = true; setAlarmMessage(); } private void setAlarmMessage() { if (alarmEnabled) message.setText("Alarm enabled. Press space bar to disable."); else message.setText("Alarm disabled. Press space bar to enable."); } private void updateAlarmDisplay() { alarmDisplay.setText(String.format("%tR", alarmTime)); } private Calendar captureTime() { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(System.currentTimeMillis()); return cal; } private void setTime() { currentTime = captureTime(); timeDisplay.setText(String.format("%tR", currentTime)); dateDisplay.setText(String.format("%tD", currentTime)); } private boolean timesMatch(Calendar timeA, Calendar timeB) { return (timeA.get(Calendar.HOUR_OF_DAY) == timeB.get(Calendar.HOUR_OF_DAY)) && (timeA.get(Calendar.MINUTE) == timeB.get(Calendar.MINUTE)); } private boolean timeChanging() { return !timesMatch(previousTime, currentTime); } private boolean alarmMatching() { return timesMatch(currentTime, alarmTime); } private void handleAlarmMatch() { if (alarmEnabled && alarmMatching()) alarmOn(); } private void handleTimeChange() { if (timeChanging()) handleAlarmMatch(); } private void initAlarm() { alarmTime.set(Calendar.HOUR_OF_DAY, 0); alarmTime.set(Calendar.MINUTE, 0); updateAlarmDisplay(); setAlarmMessage(); } private void initTimer() { timer = new Timer(1000, this); timer.setInitialDelay(0); timer.start(); } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ // /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(Alarm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(Alarm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(Alarm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(Alarm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Alarm().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel alarmDisplay; private javax.swing.JLabel dateDisplay; private javax.swing.JLabel message; private javax.swing.JLabel timeDisplay; // End of variables declaration//GEN-END:variables // Manually declared variables - can modify! private Timer timer; } class Audio { private Clip clip; public Audio() { init(); } private void init() { try { URL url = getClass().getResource("/resources/wakeupkorn.wav"); AudioInputStream stream = AudioSystem.getAudioInputStream(url); AudioFormat format = stream.getFormat(); DataLine.Info info = new DataLine.Info(Clip.class, format); Clip line = (Clip) AudioSystem.getLine(info); line.open(stream); line.setLoopPoints(0, -1); clip = line; } catch (Throwable e) { throw new Error(e.getMessage()); } } public void play() { clip.loop(Clip.LOOP_CONTINUOUSLY); } public void stop() { clip.stop(); clip.setFramePosition(0); } }