How to intercept keyboard strokes going to Java Swing JTextField? - java

The JTextField is a calculator display initialized to zero and it is bad form to display a decimal number with a leading 0 like 0123 or 00123. The numeric buttons (0..9) in a NetBeans Swing JFrame use append() [below] to drop the leading zeros, but the user may prefer the keyboard to a mouse, and non-numeric characters also need to be handled.
private void append(String s) {
if (newEntry) {
newEntry = false;
calcDisplay.setText(s);
} else if (0 != Float.parseFloat(calcDisplay.getText().toString())) {
calcDisplay.setText(calcDisplay.getText().toString() + s);
}
}

You could restrict the characters input to the JTextField by adding a custom KeyListener. Here is a quick example to demonstrate the idea:
myTextField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (!Character.isDigit(c)) {
e.consume(); // Stop the event from propagating.
}
}
});
Of course, you need to consider special keys like Delete and combinations like CTRL-C, so your KeyListener should be more sophisticated. There are probably even freely available utilities to do most of the grunt work for you.

You can do this with DocumentFilter.
(Edit: This answer originally included a ling to a simple complete example program on my now defunct weblog.)

Related

JTextArea updating after KeyListener? [duplicate]

First off I making a simple typing program. If you type the a letter and hit the spacebar the TTextArea will be matched with the label text to see if it matches. But it keeps coming out wrong cause there is space added before the letter after the first output everytime and I do not understand why? Is this something that just happens or can ypu
The is my code
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_SPACE){
input = textArea.getText();
if(input.length() <= 0){
JOptionPane.showMessageDialog(null, "Type something first");
} else {
input.trim();
System.out.println(input);
gameLogic.score(input, letterLabel.getText());
gameLogic.error(input, letterLabel.getText());
scoreLabel.setText("Score: " + String.valueOf(gameLogic.score));
errorLabel.setText("Errors: " + String.valueOf(gameLogic.error));
gameLogic.changeDifficulty();
letterLabel.setText( gameLogic.changeText());
textArea.setText("");
textArea.setCaretPosition(0);
}
}
this is my output
l
l
x
k
ss
Several things...
KeyListener is not a recommend way to deal with monitoring or effecting the changes to any text component. If you are lucky enough that the key stroke isn't consumed by the component, the component has already being updated with the last key stroke.
A better approach would be to use a DocumentListener if you just wanted to monitor changes to the text component or a DocumentFilter if you want to change what is being passed to the field.
Check out Using Text Components for more details

Different Enter and mouse click event

i have a button that call a method, in this method it call another method to connect to the DB and return results, if results positive, change the labels and make a button ENABLED, and if the results is negative, the Button still disabled
the problem is, i have set in the TF a keytyped event, if someone type something new in it, disable the btnEditar:
public void keyTyped(KeyEvent e) {
btnEditar.setEnabled(false);
btnDeletar.setEnabled(false);
}
i dont want this event "capture" the enter to disable the button
there is a way to do that or i have to think i another logic way?
As others have pointed out, there are other ways to do this besides using a KeyListener. I will respond to your original attempt below. A KeyListener is a functional and easy tool to use for this job.
Use keyPressed instead of keyTyped, and then you'll have a valid key code that you can use to ignore enter presses:
public void keyPressed(KeyEvent e) { // not keyTyped!
if (e.getKeyCode() != KeyEvent.VK_ENTER) {
btnEditar.setEnabled(false);
btnDeletar.setEnabled(false);
}
}
If you insist on using keyTyped for some reason, you won't have a key code available, but you can cover most cases by checking the character for a newline or carriage return:
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() != 13 && e.getKeyChar() != 10) {
btnEditar.setEnabled(false);
btnDeletar.setEnabled(false);
}
}
Use a DocumentListener to listen for changes to the text in the Document. Read the section from the Swing tutorial on How to Write a Document Listener.

Using KeyStroke for input, is there an easier way of reading A - Z keys?

First of all, this isn't for a keylogger, it's for an input in a roguelike game where the JLabel in my JFrame will say "Name: " and I want to be able to type A-Za-z. After having a look at lots of options for key input, I am back where I started using KeyStrokes and Actions.
What I am wondering is whether there is a way to add a range of keys, rather than repeating this 56 times:
Action a = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// add a to string
}
};
getInputMap().put(KeyStroke.getKeyStroke("a"), "a");
getActionMap().put("a", a);
I mean, I could do it this way, just write a bit of copy and pasting, but I really do hate that. There has to be a more elegant solution than using KeyListener which isn't very good as it means I have to somehow have focus but my window is simply one JFrame with a big JLabel in it.
Also, I've only been doing java a few days now, so that's why I am probably missing the a very commonly known solution, but if there is one, please do share! Appreciated.
This is a solution:
for (char c = 'a'; c <= 'z'; c++) {
String ks = String.valueOf(c);
getInputMap().put(KeyStroke.getKeyStroke(ks), ks);
getActionMap().put(ks, a);
ks = ks.toUpperCase();
getInputMap().put(KeyStroke.getKeyStroke(ks), ks);
getActionMap().put(ks, a);
}
but I think you should prefer a JTextField with DocumentListener.
I am using a content manager class which treats each "screen" as a JPanel which is set as the content pane, I put a reference to the parent JFrame into the base "screen" class and then added a KeyListener to the parent JFrame. This captures input just how I want it to. I didn't do this before as I mistakenly added the KeyListener to the content pane. It all appears to work fine now.
public void run() {
this.getParent().addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
appendLabel(e.getKeyChar());
}
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) { }
});
}
Thanks #millimoose!

Java: Register <ENTER> key press on JTextPane

I'm making an application with java that has a JTextPane. I want to be able to execute some code when the enter key is pressed (or when the user goes to the next line). I've looked on the web and not found a solution. Would it be better to tackle this with C#? If not, how can i register the Enter key in the JTextPane's keyTyped() event? If C# is a good option, how would i do this in C#?
Here is a solution i thought would work...but did not
//Event triggered when a key is typed
private void keyTyped(java.awt.event.KeyEvent evt) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
Toolkit.getDefaultToolkit().beep();
System.out.println("ENTER pressed");
}
}
Why the above example does not work is because no matter which key i press, i get a keyCode of 0. I would prefer a solution to this problem in Java but C# would work just as well, maybe better. Also, please try to answer the question with examples and not links(unless you really need to). Thanks!
One solution is to add a key binding on the textpane. e.g.,
JTextPane textPane = new JTextPane();
int condition = JComponent.WHEN_FOCUSED;
InputMap iMap = textPane.getInputMap(condition);
ActionMap aMap = textPane.getActionMap();
String enter = "enter";
iMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), enter);
aMap.put(enter, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("enter pressed");
}
});
This answer is in case anyone ever views this thread I got the same things as Mr. Mohammad Adib.
So instead of using ...
(evt.getKeyCode()==evt.VK_ENTER)
I used ...
(evt.getKeyChar()=='\n')
and the solution worked.
I am looking for ENTER key in the password text field, to launch the login method when ENTER was pressed. The code below will print in the console the keycode. After running the program and typing a few tihngs in the box I discovered for ENTER key it is code 13.
txtPass = new Text(shlLogin, SWT.BORDER | SWT.PASSWORD);
txtPass.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
System.out.println(e.keyCode);
if (e.keyCode == 13) { /* ... Do your stuff ... */ }
}
});
If you are looking for a single key press, you can still be a little lazy and avoid learning new stuff about key bindings, by using this method. The fun begins when adding CTRL+[Letter] shortcuts - but this is for another discussion.

In Java, when a key is pressed such as a letter, how do I prevent the key from outputting the letter that it is assigned to a jTextPane?

In Java, when a key is pressed such as a letter, how do I prevent the key from outputting the letter that it is assigned to a jTextPane? (Similar to how do game developers suppress the normal functions of the keyboard when a part of their application is in focus).
When KeyEvent.consume() doesn't do the job alone, is there another way?
I'm a fairly novice programmer compared to other people on this board, so please be patient with me. Any examples would be appreciated. I'm eager to learn. Thank you very much.
Assign custom DocumentFilter to the document from the JTextPane. You can intercept the insertString() and skip unnecessary input. It's better than key listener if you should also skip the same chars from pasted content.
This code is just a sample, I hope this will prevent A to Z getting entered , but does not cover all scenarios such as Shift,Ctrl and Alt presses.
JTextPane textPane = new JTextPane();
textPane.addKeyListener(new MyKeyListener());
public class MyKeyListener extends KeyAdapter
{
public void keyPressed(KeyEvent key) {
int i = key.getKeyCode();
if (i >= 65 && i <= 90)
{
((JTextPane)event.getSource()).cancelKey();
}
}
}

Categories

Resources