Plays the DTMF sounds immediately upon pressing the respective buttons; otherwise, playing them sequentially results in sounds which are played/heard many seconds or even a minute after the respective button is pressed.

fix-message-formatting
Lyubomir Marinov 12 years ago
parent 59f44e2026
commit fcec891d0f

@ -135,6 +135,7 @@ public void init()
/**
* Reloads dial buttons.
*/
@Override
public void loadSkin()
{
dialPadPanel.removeAll();
@ -162,10 +163,13 @@ public void loadSkin()
}
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
/**
@ -173,6 +177,7 @@ public void mouseExited(MouseEvent e) {}
* dial buttons.
* @param e the event
*/
@Override
public void mousePressed(MouseEvent e)
{
JButton button = (JButton) e.getSource();
@ -186,6 +191,7 @@ public void mousePressed(MouseEvent e)
* dial buttons.
* @param e the event
*/
@Override
public void mouseReleased(MouseEvent e)
{
dtmfHandler.stopSendingDtmfTone();

@ -28,78 +28,11 @@
* @author Lyubomir Marinov
*/
public class DTMFHandler
implements KeyEventDispatcher,
Runnable
implements KeyEventDispatcher
{
/**
* DTMF extended information.
*/
public static class DTMFToneInfo
{
/**
* The image to display in buttons sending DTMFs.
*/
public final ImageID imageID;
/**
* The char associated with this DTMF tone.
*/
public final char keyChar;
/**
* The key code when entered from keyboard.
*/
public final int keyCode;
/**
* The image to display on Mac buttons.
*/
public final ImageID macImageID;
/**
* The id of the image to display on Mac buttons on rollover.
*/
public final ImageID macImageRolloverID;
/**
* The sound to play during send of this tone.
*/
public final String sound;
/**
* The tone itself
*/
public final DTMFTone tone;
/**
* Creates DTMF extended info.
* @param tone the tone.
* @param keyCode its key code.
* @param keyChar the char associated with the DTMF
* @param imageID the image if any.
* @param macImageID the Mac OS X-specific image if any.
* @param macImageRolloverID the Mac OS X-specific rollover image if any
* @param sound the sound if any.
*/
public DTMFToneInfo(
DTMFTone tone,
int keyCode, char keyChar,
ImageID imageID, ImageID macImageID, ImageID macImageRolloverID,
String sound)
{
this.tone = tone;
this.keyCode = keyCode;
this.keyChar = keyChar;
this.imageID = imageID;
this.macImageID = macImageID;
this.macImageRolloverID = macImageRolloverID;
this.sound = sound;
}
}
/**
* All available tones and its properties like images for buttons, and
* sounds to be played during send.
* All available DTMF tones and their properties such as images for buttons
* and sounds to be played during send.
*/
public static final DTMFToneInfo[] AVAILABLE_TONES
= new DTMFToneInfo[]
@ -235,9 +168,16 @@ public DTMFToneInfo(
};
/**
* Whether we have already loaded the defaults for dtmf tones.
* Whether we have already loaded the defaults for DTMF tones.
*/
private static boolean defaultsLoaded = false;
/**
* The maximum number of milliseconds of idleness after which
* {@link #dtmfToneNotificationThread} should die.
*/
private static Boolean defaultsLoaded = false;
private static final long DTMF_TONE_NOTIFICATION_THREAD_IDLE_TIMEOUT
= 15 * 1000;
/**
* Default event type for DTMF tone.
@ -251,29 +191,27 @@ public DTMFToneInfo(
private static final Logger logger = Logger.getLogger(DTMFHandler.class);
/**
* Load the defaults for dtmf tones.
* Load the defaults for DTMF tones.
*/
public static void loadDefaults()
public static synchronized void loadDefaults()
{
synchronized(defaultsLoaded)
{
if(defaultsLoaded)
return;
if(defaultsLoaded)
return;
// init the
NotificationService notificationService =
GuiActivator.getNotificationService();
NotificationService notificationService
= GuiActivator.getNotificationService();
for(DTMFToneInfo info : AVAILABLE_TONES)
{
notificationService.registerDefaultNotificationForEvent(
for(DTMFToneInfo info : AVAILABLE_TONES)
{
notificationService.registerDefaultNotificationForEvent(
DTMF_TONE_PREFIX + info.tone.getValue(),
new SoundNotificationAction(
info.sound, 0, false, true, false));
}
defaultsLoaded = true;
info.sound,
0,
false, true, false));
}
defaultsLoaded = true;
}
/**
@ -284,8 +222,14 @@ public static void loadDefaults()
/**
* The list of audio DTMF tones to play.
*/
private Vector<DTMFToneInfo> dtmfToneNotifications
= new Vector<DTMFToneInfo>(1, 1);
private final List<DTMFToneInfo> dtmfToneNotifications
= new LinkedList<DTMFToneInfo>();
/**
* The background/daemon <tt>Thread</tt> which plays the audio of
* {@link #dtmfToneNotifications} as sound notifications.
*/
private Thread dtmfToneNotificationThread;
/**
* The <tt>KeyboadFocusManager</tt> to which this instance is added as a
@ -376,6 +320,7 @@ public void addParent(Window parent)
* continue dispatching it. <tt>DTMFHandler</tt> always returns
* <tt>false</tt>
*/
@Override
public boolean dispatchKeyEvent(KeyEvent e)
{
if (e.getID() == KeyEvent.KEY_TYPED)
@ -455,57 +400,122 @@ public void removeParent(Window parent)
* {@link #dtmfToneNotifications} through the current
* {@link NotificationService}.
*/
public void run()
private void runInDTMFToneNotificationThread()
{
long idleStartTime = -1;
do
{
DTMFToneInfo toneToPlay;
synchronized (dtmfToneNotifications)
{
if (dtmfToneNotifications.size() != 0)
{
/*
* XXX We will purposefully remove the toneToPlay once it
* has been played in order to reduce the risk of
* simultaneously playing one and the same tone multiple
* times.
*/
toneToPlay = dtmfToneNotifications.get(0);
}
else
if (dtmfToneNotificationThread != Thread.currentThread())
break;
}
try
{
if (toneToPlay.sound != null)
if (dtmfToneNotifications.isEmpty())
{
NotificationService notificationService
= GuiActivator.getNotificationService();
// Plays the next DTMF sound notification.
NotificationData currentlyPlayingTone
= notificationService.fireNotification(
DTMF_TONE_PREFIX + toneToPlay.tone.getValue());
// Waits for the current notification to end.
while (notificationService.isPlayingNotification(
currentlyPlayingTone))
toneToPlay = null;
long now = System.currentTimeMillis();
if (idleStartTime == -1)
idleStartTime = now;
long timeout
= DTMF_TONE_NOTIFICATION_THREAD_IDLE_TIMEOUT
- (now - idleStartTime);
if (timeout <= 0)
{
break;
}
else
{
Thread.yield();
try
{
dtmfToneNotifications.wait(timeout);
}
catch (InterruptedException ie)
{
}
continue;
}
// Removes the ended notification from the DTMF list.
notificationService.stopNotification(currentlyPlayingTone);
}
else
{
toneToPlay = dtmfToneNotifications.remove(0);
idleStartTime = -1;
}
}
finally
// Play the DTMF tone as a sound notification.
if ((toneToPlay != null) && (toneToPlay.sound != null))
{
GuiActivator.getNotificationService().fireNotification(
DTMF_TONE_PREFIX + toneToPlay.tone.getValue());
}
}
while (true);
}
/**
* Initializes and starts {@link #dtmfToneNotificationThread} if it is
* <tt>null</tt> and {@link #dtmfToneNotifications} is not empty.
*/
private void startDTMFToneNotificationThreadIfNecessary()
{
synchronized (dtmfToneNotifications)
{
if((dtmfToneNotificationThread == null)
&& !dtmfToneNotifications.isEmpty())
{
synchronized (dtmfToneNotifications)
Thread t
= new Thread()
{
@Override
public void run()
{
try
{
runInDTMFToneNotificationThread();
}
finally
{
synchronized (dtmfToneNotifications)
{
if (dtmfToneNotificationThread
== Thread.currentThread())
{
dtmfToneNotificationThread = null;
startDTMFToneNotificationThreadIfNecessary();
}
}
}
}
};
t.setDaemon(true);
t.setName("DTMFHandler: DTMF tone notification player");
boolean started = false;
dtmfToneNotificationThread = t;
try
{
dtmfToneNotifications.remove(0);
t.start();
started = true;
}
finally
{
if (!started && (dtmfToneNotificationThread == t))
dtmfToneNotificationThread = null;
}
}
else
{
dtmfToneNotifications.notify();
}
}
while (true);
}
/**
@ -543,7 +553,12 @@ private void startSendingDtmfTone(Call call, DTMFToneInfo info)
}
catch (Throwable t)
{
logger.error("Failed to send a DTMF tone.", t);
if (t instanceof InterruptedException)
Thread.currentThread().interrupt();
else if (t instanceof ThreadDeath)
throw (ThreadDeath) t;
else
logger.error("Failed to send a DTMF tone.", t);
}
}
@ -558,37 +573,20 @@ private synchronized void startSendingDtmfTone(DTMFToneInfo info)
{
synchronized(dtmfToneNotifications)
{
boolean startThread = (dtmfToneNotifications.size() == 0);
dtmfToneNotifications.add(info);
if(startThread)
{
Thread dtmfToneNotificationThread = new Thread(this);
dtmfToneNotificationThread.setDaemon(true);
dtmfToneNotificationThread.setName(
"DTMFHandler: DTMF tone notification player");
dtmfToneNotificationThread.start();
}
startDTMFToneNotificationThreadIfNecessary();
}
}
if (callContainer != null)
{
for (Call c : callContainer.getCallConference().getCalls())
{
startSendingDtmfTone(c, info);
}
}
else
{
Collection<Call> activeCalls = CallManager.getInProgressCalls();
Collection<Call> calls
= (callContainer == null)
? CallManager.getInProgressCalls()
: callContainer.getCallConference().getCalls();
if (activeCalls != null)
{
for (Call activeCall : activeCalls)
startSendingDtmfTone(activeCall, info);
}
if ((calls != null) && !calls.isEmpty())
{
for (Call call : calls)
startSendingDtmfTone(call, info);
}
}
@ -616,22 +614,15 @@ public void startSendingDtmfTone(String toneValue)
*/
public synchronized void stopSendingDtmfTone()
{
if (callContainer != null)
{
for (Call c : callContainer.getCallConference().getCalls())
{
stopSendingDtmfTone(c);
}
}
else
{
Collection<Call> activeCalls = CallManager.getInProgressCalls();
Collection<Call> calls
= (callContainer == null)
? CallManager.getInProgressCalls()
: callContainer.getCallConference().getCalls();
if (activeCalls != null)
{
for (Call activeCall : activeCalls)
stopSendingDtmfTone(activeCall);
}
if ((calls != null) && !calls.isEmpty())
{
for (Call call : calls)
stopSendingDtmfTone(call);
}
}
@ -659,7 +650,78 @@ private void stopSendingDtmfTone(Call call)
}
catch (Throwable t)
{
logger.error("Failed to send a DTMF tone.", t);
if (t instanceof InterruptedException)
Thread.currentThread().interrupt();
else if (t instanceof ThreadDeath)
throw (ThreadDeath) t;
else
logger.error("Failed to send a DTMF tone.", t);
}
}
/**
* DTMF extended information.
*/
public static class DTMFToneInfo
{
/**
* The image to display in buttons sending DTMFs.
*/
public final ImageID imageID;
/**
* The char associated with this DTMF tone.
*/
public final char keyChar;
/**
* The key code when entered from keyboard.
*/
public final int keyCode;
/**
* The image to display on Mac buttons.
*/
public final ImageID macImageID;
/**
* The id of the image to display on Mac buttons on rollover.
*/
public final ImageID macImageRolloverID;
/**
* The sound to play during send of this tone.
*/
public final String sound;
/**
* The tone itself
*/
public final DTMFTone tone;
/**
* Creates DTMF extended info.
* @param tone the tone.
* @param keyCode its key code.
* @param keyChar the char associated with the DTMF
* @param imageID the image if any.
* @param macImageID the Mac OS X-specific image if any.
* @param macImageRolloverID the Mac OS X-specific rollover image if any
* @param sound the sound if any.
*/
public DTMFToneInfo(
DTMFTone tone,
int keyCode, char keyChar,
ImageID imageID, ImageID macImageID, ImageID macImageRolloverID,
String sound)
{
this.tone = tone;
this.keyCode = keyCode;
this.keyChar = keyChar;
this.imageID = imageID;
this.macImageID = macImageID;
this.macImageRolloverID = macImageRolloverID;
this.sound = sound;
}
}
}

Loading…
Cancel
Save