Java swt change typed character
I have swt browser widget in which user can type with keyboard, I need for certain character user press change it to others. for example when user press x, I change it y.
I add key listener where I can block user input with doit = false; bu开发者_开发知识库t now I can't pass my character.
here is what I am doing:
browser_1.addListener(SWT.KeyDown, new Listener() {
public void handleEvent(Event arg0) {
if(arg0.character=='x')
{
arg0.doit=false;
//now here how to send y as a charachter to browser widget
}
}
});
In other words can I somehow change character to other without using arg0.doit=false;
So after some search, here is the solution
In SWT you can add to display 'filter' listener instance which can modify pretty anything in the event (see docs for details).
Caution from Javadoc: Setting the type of an event to SWT.None from within the handleEvent() method can be used to change the event type and stop subsequent Java listeners from running. Because event filters run before other listeners, event filters can both block other listeners and set arbitrary fields within an event. For this reason, event filters are both powerful and dangerous. They should generally be avoided for performance, debugging and code maintenance reasons.
Here's the code (changes any typed key to 'l'
character and wrote that in console, when the event actually arise)
browser.addListener(SWT.KeyDown, new Listener() {
public void handleEvent(Event event) {
System.out.println(event.character);
}
});
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event event) {
if(event.widget instanceof Browser) {
event.character = 'l';
}
}
});
IMHO it's really dirty solution, implementation on browser side (by JavaScript) is much more prettier
Also when I'm looking to your code (don't know if it's just some testing, proof-of-concept code, anyway), using variables with something_number
or arg0
makes me sad. It makes code so much unreadable and obscure, try to avoid them ;]..
You can do following:
Text textControl = new Text(...);
textControl.addKeyListener(this);
...
public void keyPressed(KeyEvent e) {
if (e.character == 'x' && (e.stateMask & SWT.CONTROL) == 0) {
e.doit = false;
textControl.insert("y");
}
}
Some comments to this code:
We check for e.stateMask because we still need keep CTRL+X as cut-function. Please note, if you use instead of current code this one (that just check that no special button is pressed):
if (e.character == 'x' && e.stateMask == 0)
You will get a bug when CapsLock is on. In this case user should press Shift+X to get lower x.
Method insert("y") inserts charater to the place of cursor. When some text is seleted, the whole selection will be replaced by "y".
Current example changes only lower case of "x". You should change it if needed to handle also change upper X to Y.
I had a similar requirement: converting a decimal separator press on the keypad (a dot) to the decimal separator of our locale (a comma). I tried the same idea as Sorceror, but it didn't work for me either. What does work is setting event.doit = false and posting a new event that is the clone of the original event with the character replaced:
@Override
public void handleEvent(Event event) {
if (event.widget instanceof Browser && event.character == 'x') {
Event eventClone = cloneEvent(event);
eventClone.character = 'y';
event.doit = false;
display.post(eventClone);
}
}
(If display is a local variable you need to make it final.) I created a small utility method to create a clone of the event:
/**
* @return a clone of the given {@link Event}
*/
public static Event cloneEvent(Event event) {
Event clone = new Event();
clone.display = event.display;
clone.widget = event.widget;
clone.type = event.type;
clone.detail = event.detail;
clone.item = event.item;
clone.index = event.index;
clone.gc = event.gc;
clone.x = event.x;
clone.y = event.y;
clone.width = event.width;
clone.height = event.height;
clone.count = event.count;
clone.time = event.time;
clone.button = event.button;
clone.character = event.character;
clone.keyCode = event.keyCode;
clone.keyLocation = event.keyLocation;
clone.stateMask = event.stateMask;
clone.start = event.start;
clone.end = event.end;
clone.text = event.text;
clone.doit = event.doit;
clone.data = event.data;
clone.touches = event.touches;
clone.xDirection = event.xDirection;
clone.yDirection = event.yDirection;
clone.magnification = event.magnification;
clone.rotation = event.rotation;
return clone;
}
精彩评论