Java Swing - KeyListener - java

How can I know when the key typed change my text? Or if the key is a char?

The interface KeyListener contain three methods:
void keyTyped(KeyEvent)
void keyPressed(KeyEvent)
void keyReleased(KeyEvent)
So, if you get the char in the KeyEvent object like:
if ("a".equals(KeyEvent.getKeyChar()))
System.out.println("It's a letter")

i guess you want to know wether typing a specific key actually prints a char or is some "invisible" control character or something:
in this case you can check the typed key in the KeyEvent which gets passed into the implemented methods of the KeyListener:
this quick example should work, although i didnt test it. It constructs a new String on the char returned by the KeyEvent, than invokes the length() method to chekc if the char created a readable character in the String. kinda hacky but i hope you get the gist of it
public void keyReleased(KeyEvent ke){
if (new String(ke.getKeyChar()).length() == 0){
// do something important...
}
}
alternativley you can use ke.getKeyCode() and check vs the static fields in KeyEvent (VK_F12,VK_ENTER...)
check here:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html

You need a document listener. See the oracle docs for more information: How to Write a Document Listener

Related

How to validate Regular Expression in real time on jtextbox?

I'm trying to validate/filter my jtextbox wwith this Regex:
^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$
I want to filter two names with one space.
Tried using keytyped and keyreleased, but it just does not work (won't let me write anything on the textbox) and e.consume() does not work.
boolean StrCheck(String Exp,String str) {
return Pattern.matches(Exp,str);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getSource() == jTextField) {
String regexp = "^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$";
if (jTextField.getText().length() == 25) {
e.consume();
} if (StrCheck(regexp,jTextField.getText())){
}else {
e.consume();
}
I've been searching, but the only possible answer I got, was to create a Documentlistene BUT can't find any example or how actually do it and make it work.
Neither KeylListener, neither DocumentListener will work. In most of this kind of cases you would need to use a DocumentFilter. Before you do though, take a look on how to use formatted textfields. It might be enough for you. If it does not, this answer is what you are looking for.

Distinguishing left and right shift keys in Processing 3

Alright, I'll say in advance I'm aware this isn't a new concept... But no matter what I research nothing seems to work. Basically, I want to be able to sense every key on my keyboard including the different shift/ctrl/alt/enter keys. Every key besides these returns a unique keyCode which is good, but I can't seem to distinguish these duplicates.
Without any modifications, the void keyPressed () will work just fine. I'm told that to distinguish the duplicate keys I can import java.awt.event.KeyEvent; and then use
void keyPressed (KeyEvent e) {
if (keyCode == SHIFT) {
int location = e.getKeyLocation ();
if (location == KEY_LOCATION_RIGHT) {
RShift = true;
}
if (location == KEY_LOCATION_LEFT) {
LShift = true;
}
}
}
However, some problems arise with this:
If I import the library, keyPressed () never gets called at all.
If I import the library but take out the KeyEvent parameter in keyPressed () it works as long as I comment out any reference to the nonexistent KeyEvent e.
If I DON'T import it and leave the parameter it just complains that getKeyLocation () doesn't exist, but that's it.
Do I need like a reverse override or something?? Help is much appreciated!
P.S. Another related question, how can I distinguish more than left, center, and right mouse buttons? I can get these and the scrollwheel but any other button just returns a mouseButton code of 0. Suggestions? Thanks!
https://processing.org/reference/keyPressed_.html
The keyPressed() function is called once every time a key is pressed. The key that was pressed is stored in the key variable.
if you want to override keyPressed you must use the same signature so no parameters, in the method you can reference the key variable of the PApplet
like this i believe
void keyPressed ()
**int location = key
edit: int location = keyEvent

Get the parameters of a method in a anonymous class

I have a question concerning the key bindings. I have the following Java code:
private void registerPressedReleasedKey(String keyChar, boolean key, boolean pressedKey) {
// 1. decide if the key is pressed or released
// 2. save key and its action name
// 3. decide, what to do, when the action name is being mentioned
// 4. change the boolean value in actionPerformed(ActionEvent ae)
String keyStatus;
if(pressedKey == true)
keyStatus = "pressed ";
else
keyStatus = "released ";
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(keyStatus + keyChar), keyStatus + keyChar);
getActionMap().put(keyStatus + keyChar, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
key = pressedKey;
}
});
}
Eclipse says to me that key = keyPressed; is wrong, because I only can use final variables. My question is if there is a possibility to access and change key inside the actionPerformed(ActionEvent ae) method.
Answering your question
It is impossible to modify external variables in an anonymous class the way you are trying to since these must be final.
If this was a field of your class, you could use access it directly (in Java > 7) or use an accessor (setter). Since it is not, the way to go would be to use a wrapper: final means you cannot assign a new value, but you can still call its methods and any accessor is basically a method.
Warning notice
I assume your code is incomplete, as in this example, you try to set the variable key, which is not used anywhere.
However, assigning a new value to a parameter is generally a bad practice.
Moreover, getActionMap() & AbstractAction suggest that a Swing component is being used, which means that actionPerformed() will get called by Swing thread, probably even after registerPressedReleaseKey() has finished. As a consequence, updating a parameter for this method makes no sense.

Pressed button as a hotkey

I'm trying to make something like hotkey textbox. User presses F11 / Caps lock / any key and it appears in the box.
I did it this way:
#Override
public void keyPressed(KeyEvent e) {
textField_1.setText(String.valueOf(e.getKeyChar()));
}
but it doesn't work for the Fs, caps lock etc. (what is obvious, because those aren't chars).
How can I deal with this problem?
You can use:
event.getKeyCode();
But in general you should probably use Key Bindings.
As Agusti-N states in his answer:
The interface KeyListener contain three methods:
void keyTyped(KeyEvent)
void keyPressed(KeyEvent)
void keyReleased(KeyEvent)
If you use keyPressed and you are using event.getKeyChar() to check for the character entered, this will not work. You should use getKeyChar() for keyTyped and getKeyCode() for keyPressed and keyReleased. Otherwise you'll get null.
As stated in the javadoc.
You probably want to use e.getKeyText() instead of e.getKeyChar() that will return F1 if the F1 key is presed. Here is the API description:
getKeyText
public static String getKeyText(int keyCode)
Returns a String describing the keyCode, such as "HOME", "F1" or "A".
These strings can be localized by changing the awt.properties file.
Returns: a string containing a text description for a physical key, identified by its keyCode
-- http://docs.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html#getKeyText(int)
Alternatively:
You could also use e.getKeyCode that will give you the key codes for the various key events identified their corresponding constant values. For instance, e.getKeyCode will return 112 as the value for a key press for F1, which can be accessed by the constant VK_F1. Following is the API Description:
getKeyCode
public int getKeyCode()
Returns the integer keyCode associated with
the key in this event.
Returns: the integer code for an actual key on
the keyboard. (For KEY_TYPED events, the keyCode is VK_UNDEFINED.)
-- http://docs.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html#getKeyCode()
And here are the listings for the Key Constants: http://docs.oracle.com/javase/6/docs/api/constant-values.html#java.awt.event.KeyEvent.CHAR_UNDEFINED

using an array for a switch case statement in java

I'm making a game, and i want the controls to be editable. well, i've got that part down, but they are being read and changed in a .txt file. that is the way i wanted it to work for now. the values are stored as the key value (ie. KeyEvent.VK_W is equal to 83, so the value for the line is 83). I also have it reading the values and saving them to a String array variable in my core class. In my key event class, the one that handles the pushing of the keys, i have it refering to the array to check if a command key was pushed. i'm continuously getting this error: case expressions must be constant expressions when i try it. here is the WRONG code:
switch(key){
case Integer.parseInt(commands[1]):
...
break;
}
and i get that error. the value of commands[1] is 83. it is the value for "W". here is my declaration of the variable:
for (int i = 0; i < commands.length; i++) {
commands[i] = io.readSpecificLine(FILES.controlsFileFinalDir,
i + 1);
}
and if i have it print out every value, it does work. i've tried making the array final but that didnt work. i've run across the solution before, about 2 years ago, but i cant find it again. does anyone have any ideas on how to fix this? thanks in advance!
As the compiler says, the case expressions must be constant expressions. You can't use an array element as a case expression. You can simply use an if/else if/else clause instead.
You can't use non-constant expressions in case statements. An alternative approach is to build a map from values to the actions. So instead of this (which doesn't actually make any sense to me):
switch (key) {
case Integer.parseInt(commands[1]):
// action 1
break;
// other cases...
default:
// default action
}
You can do something like this:
static Map<Integer, Runnable> keyMap = new HashMap<Integer, Runnable>();
static {
keyMap.put(83, new Runnable() {
#Override
public void run() {
// actions for code 83
}
});
. . .
}
(If it makes more sense, this could also be done on a per-instance basis instead of as a static map.) Then later:
Runnable action = keyMap.get(Integer.parseInt(commands[1]));
if (action != null) {
action.run();
} else {
// default action
}
If you need to pass variables to your actions, you can define your own interface instead of using Runnable for the actions.

Categories