2

I'm using Netbeans' bean form to create my GUI.
I've added a keyTyped event to a JTextArea and I want to detect if the typed key is a Backspace.

I'm using keyTyped event for other reasons so I cannot just use the keyPressed event.

This is the generated code (and my if check):

private void langArea1KeyTyped(java.awt.event.KeyEvent evt) {   

    if(evt.getChar()== backspace) //how can I make this check?   
}     

evt.getKeyCode() always returns 0 independent of the typed key.
evt.getKeyChar() simply deletes the last character printed when printed so I can't use System.out.print(evt.getKeyChar()) to detect its value and check for it.

How can I detect if the typed key is Backspace (or Delete)?

Watermel0n
  • 241
  • 2
  • 10
WVrock
  • 1,725
  • 3
  • 22
  • 30
  • You need to use *keyDown* or *keyUp* to determine if backspace has been pressed rather than a *keyPressed* event. `public void keyReleased(KeyEvent evt) { if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) { // Do stuff... } }` – Mr. Polywhirl Jun 06 '15 at 06:56
  • @Mr.Polywhirl I'm not using keyPressed. I'm using keyTyped. I need it to fire whenever a key is typed instead of pressed. – WVrock Jun 06 '15 at 06:57
  • 1
    `keyTyped` will not work, see this question: http://stackoverflow.com/a/14714992/1762224 – Mr. Polywhirl Jun 06 '15 at 07:01
  • Use key bindings instead of key listener. The real question is, what are you trying to achieve? – MadProgrammer Jun 06 '15 at 07:28
  • @MadProgrammer I'm always being told to use key bindings but I don't like them. Besides, keyTypedEvent is a feature of NetBeans. I can generate the code with a single click. – WVrock Jun 06 '15 at 07:41
  • KeyListener can be overridden by Key Bindings, they also represent the ability to generate self contained, reusable units of work which can be used in many other parts of the Swing API, but of course, if the only tool you have is a hammer, then all your problems are nails. If you limit yourself to only working with Netbeans form editor (don't get me started on that), then you'll limit yourself to only what it's capable of doing. – MadProgrammer Jun 06 '15 at 09:14
  • *"I'm always begin told to use key bindings"* - There's probably a very (and even a number of) good reasons for that, given that the top posters here have upwards of 100s of person years of experience with the api, but what do we know – MadProgrammer Jun 06 '15 at 09:15
  • Mind you, anytime someone wants to use a key listener with any text component, warning bells go off – MadProgrammer Jun 06 '15 at 09:16
  • @MadProgrammer well, you don't need a bullet train to travel from living room to kitchen. If it works why should I bother to change it? I've learned using swing without NetBeans but it was taking 10 times more to do the same thing. If I ever try to do something that keyListeners can't and keyBindings can, I will learn it. – WVrock Jun 06 '15 at 09:20
  • @wvrock "If I ever try to dos emoting that KeyListener can't" - setText, appendText, paste text or any modification made directly to the underlying Document which didn't come from the keyboard will not notify either the key listener or key binding, which is why I was curious as to "why" you're trying to monitor the delete key. But since you're of interested in learning how the problem might be solved better, you're left with what you have, which is entirely your choice of course. I'm just trying to see if there is a better solution to your problem, but if you're not interesred – MadProgrammer Jun 06 '15 at 10:29
  • @MadProgrammer if these will also not notify the keyBindings then there is no point in using it. What is the mainstream solution to this if it is neither keyListener nor keyBindings? I'm trying to make a dictionary that reads the written word and instantly searches it. Currently I have a recently introduced bug so I can't test what you are saying. – WVrock Jun 06 '15 at 10:47
  • @MadProgrammer I'm always open to more info. Just not when it would take me hours to learn something that I may or may not need – WVrock Jun 06 '15 at 10:48
  • 2
    @WVrock *"I'm trying to make a dictionary that reads the written word and instantly searches it"* A `DocumentListener` would be a better choice (IMHO). This notifies you when the document is changed in some way, which would allow you to make decisions about what to do based on the type of change. [How to write a document listener](https://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html). *"if these will also not notify the keyBindings then there is no point in using it"* - Which is the point to my question ;) – MadProgrammer Jun 06 '15 at 10:54
  • @WVrock [For example](http://stackoverflow.com/questions/29644309/how-to-fixed-keylistener-on-jtextfield/29644408#29644408) – MadProgrammer Jun 06 '15 at 10:57
  • I want to confirm that this worked. documentListener did the trick even though I should have probably used documentFilter – WVrock Jun 06 '15 at 15:00

3 Answers3

2

backspace and delete have the following constants:

VK_BACK_SPACE

VK_DELETE

Constants are listed here: Class KeyEvent

From docs.oracle.com

WARNING: Aside from those keys that are defined by the Java language (VK_ENTER, VK_BACK_SPACE, and VK_TAB), do not rely on the values of the VK_ constants. Sun reserves the right to change these values as needed to accomodate a wider range of keyboards in the future.

Aside from that, I suggest you use keyPressed() or keyReleased() since keyTyped() is only used for keys that produce characters. Keys backspace and delete do not produce characters.

Additional:

getKeyChar() works well with KEY_TYPED, as mentioned here:

The getKeyChar method always returns a valid Unicode character or CHAR_UNDEFINED. Character input is reported by KEY_TYPED events: KEY_PRESSED and KEY_RELEASED events are not necessarily associated with character input.

Therefore, the result of the getKeyChar method is guaranteed to be meaningful only for KEY_TYPED events.

You can take a look at these links:

The keyTyped() event is only used for keys that produce character input.

"Key typed" events are higher-level and generally do not depend on the platform or keyboard layout.

Community
  • 1
  • 1
raymelfrancisco
  • 828
  • 2
  • 11
  • 21
  • `if(e.getKeyChar() == KeyEvent.VK_BACKSPACE || e.getKeyChar() == KeyEvent.VK_DELETE)` did the trick. I used keyTyped. I still have no idea why I'm not supposed to use keyTyped for this. That warning is worrying me though. – WVrock Jun 06 '15 at 07:28
  • `getKeyChar()` is really for `KEY_TYPED` events. As mentioned here: "The `getKeyChar` method always returns a valid Unicode character or `CHAR_UNDEFINED`. Character input is reported by `KEY_TYPED` events: `KEY_PRESSED` and `KEY_RELEASED` events are not necessarily associated with character input. Therefore, the result of the `getKeyChar` method is guaranteed to be meaningful only for `KEY_TYPED` events." http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html – raymelfrancisco Jun 06 '15 at 07:32
  • And 4 years later, can somebody explain why keyTyped events are fired by the BACKSPACE and DELETE keys. Also why getKeyChar() actually returns something for those keys? Maybe because they are actually printable? Maybe valid control characters? Like when you use BACKSPACE to go back in a console application and "draw" over already used spaces? I was sure that getKeyChar would return CHAR_UNDEFINED for anything non printable and then ended with weirds [BS] signs in my text editor. I had to filter those two inside a keyTyped event to avoid inserting them into a text file. – Hatoru Hansou Oct 11 '19 at 04:24
2

You cannot use keyTyped, you need to use either keyPressed or keyReleased to determine if backspace character has been typed. The keyTyped event only picks up non-escape characters (only characters that can be displayed).

The backspace character can be checked with KeyEvent.VK_BACK_SPACE.

Try adding this listener to the keyPressed event:

import java.awt.event.KeyEvent;

private void langArea1KeyPressed(KeyEvent evt) {   
    if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
        // Do something...
    }
}

Additional Reading

You can check out the official Java tutorial on How to Write a Key Listener.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • I don't understand this. The event is firing up when backspace is typed. I can even add the typed key to a string. `System.out.println("hello" + e.getKeyChar());` writes `hell` to the console when backspace is typed. – WVrock Jun 06 '15 at 07:12
  • I was talking about the keyTyped event. Not keyPressed. I've managed to it with the keyTyped. – WVrock Jun 06 '15 at 07:24
0

I think is possible to check BACKSPACE in "KeyTyped" event. You can compare the hexadecimal value of the char against the hexadecimal value of the constant KeyEvent.VK_BACK_SPACE.

Example (only return true if the key typed is Backspace, otherwise return false and consumes the event):

public static boolean CheckBackspace(KeyEvent e) {
    if (!((Integer.toHexString(e.getKeyChar()).equals(Integer.toHexString(KeyEvent.VK_BACK_SPACE))))) {
        e.consume();
        return false;
    }
    return true;
}