package net.java.sip.communicator.plugin.keybindingchooser.chooser;
import java.awt.event.*;
import javax.swing.KeyStroke;
/**
* Adaptor that uses keyboard input to set the selected shortcut field of a
* BindingChooser. This can be added to focused components to provide editing
* functionality for this chooser. This prevents duplicate entries and varies
* how it captures input according to the type of key event its set to capture.
*
* @author Damian Johnson (atagar1@gmail.com)
* @version August 19, 2007
*/
public class BindingAdaptor
extends KeyAdapter
{
private int inputEventType = KeyEvent.KEY_PRESSED; // Type of key event
// registered by input
private int disablingKeyCode = KeyEvent.VK_ESCAPE; // Input keycode that
// gives disabled status
private boolean isDisablingEnabled = false;
private final BindingChooser chooser;
private KeyEvent buffer = null;
BindingAdaptor(BindingChooser chooser)
{
this.chooser = chooser;
}
/**
* Provides if bindings are currently disableable via generated key adaptors
* or not.
*
* @return true if input can disable bindings, false otherwise.
*/
public boolean isBindingDisablingEnabled()
{
return this.isDisablingEnabled;
}
/**
* Sets if bindings can be disabled via generated key adaptors with the
* disabling key code. By default this is false.
*
* @param enable if true then input can disable bindings, otherwise bindings
* may not be disabled
*/
public void setBindingsDisableable(boolean enable)
{
this.isDisablingEnabled = enable;
}
/**
* Provides the keycode that can be input to generated key adaptors to
* disable key bindings.
*
* @return keycode of disabling input
*/
public int getDisablingKeyCode()
{
return this.disablingKeyCode;
}
/**
* Sets the keycode used to disable individual key bindings (removing it
* from returned mappings) via generated key adaptors. This only works if
* the set event type is KEY_PRESSED or KEY_RELEASED since KEY_TYPED events
* fail to provide keycodes. By default this is VK_ESCAPE.
*
* @param keycode keycode that sets selected entry to a disabled state
*/
public void setDisablingKeyCode(int keycode)
{
this.disablingKeyCode = keycode;
}
/**
* Provides the type of keystroke registered by input via generated key
* adaptors.
*
* @return type of input detected by generated key adaptors
*/
public int getInputEventType()
{
return this.inputEventType;
}
/**
* Sets the type of keystroke registered by input via generated key adaptors
* (by default KeyEvent.KEY_PRESSED). This must be a valid type of key event
* which includes: KEY_PRESSED, KEY_RELEASED, or KEY_TYPED.
*
* @param type type of keystroke registered by input
* @throws IllegalArgumentException if type doesn't match a valid key event
*/
public void setInputEventType(int type)
{
int[] validTypes = new int[]
{ KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, KeyEvent.KEY_TYPED };
boolean isValid = false;
for (int validType : validTypes)
{
isValid |= type == validType;
}
if (!isValid)
{
StringBuilder message = new StringBuilder();
message.append("Unrecognized event type: ");
message.append(type);
message
.append(" (must match KEY_PRESSED, KEY_RELEASED, or KEY_TYPED)");
throw new IllegalArgumentException(message.toString());
}
this.inputEventType = type;
}
@Override
public void keyPressed(KeyEvent event)
{
this.buffer = event; // Reports KEY_PRESSED events on release to support
// modifiers
}
@Override
public void keyReleased(KeyEvent event)
{
if (this.inputEventType == KeyEvent.KEY_PRESSED && this.buffer != null)
{
setShortcut(this.buffer);
}
else if (this.inputEventType == KeyEvent.KEY_RELEASED)
{
setShortcut(event);
}
}
@Override
public void keyTyped(KeyEvent event)
{
if (this.inputEventType == KeyEvent.KEY_TYPED)
setShortcut(event);
}
// Sets keystroke component of currently selected entry
private void setShortcut(KeyEvent event)
{
if (this.chooser.isBindingSelected())
{
KeyStroke input = KeyStroke.getKeyStrokeForEvent(event);
if (this.isDisablingEnabled
&& input.getKeyCode() == this.disablingKeyCode)
{
String action = this.chooser.getSelected().getAction();
if (this.chooser.getBindings().contains(
new BindingEntry(BindingEntry.DISABLED, action)))
{
this.chooser.setSelected(null); // This would cause a
// duplicate mapping
}
else
{
this.chooser.doInput(BindingEntry.DISABLED);
}
}
else if (!this.chooser.contains(input)
|| this.chooser.getSelected().getShortcut().equals(input))
{
this.chooser.doInput(input);
}
this.buffer = null;
}
}
}