I made a custom JTextField
to input numeric values. The class looks as follows:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class JNumberField extends JTextField {
public JNumberField(int width, int height) {
this();
setPreferredSize(new Dimension(width, height));
}
public JNumberField() {
setFont(new Font("Monospace", Font.BOLD, 23));
setHorizontalAlignment(JTextField.HORIZONTAL);
}
@Override
public void processKeyEvent(KeyEvent ev) {
//Accepts digits, backspace, minus key and left/right arrow keys
if (Character.isDigit(ev.getKeyChar()) || ev.getKeyCode() == KeyEvent.VK_BACK_SPACE || ev.getKeyCode() == KeyEvent.VK_MINUS || ev.getKeyCode() == KeyEvent.VK_LEFT || ev.getKeyCode() == KeyEvent.VK_RIGHT) {
super.processKeyEvent(ev);
}
ev.consume();
}
public static void main(String[] args) {
JOptionPane.showInputDialog(new JNumberField(300,50));
}
}
All the keys are working except for the "-" key. I also printed the keycode that was pressed and it responded with 45 so the if statement is executed but it doesn't insert the - into the text field. Is this a bug or how can it be fixed? I also tried removing the if statement and just call the processKeyEvent
method and then it works to insert the - sign...
First of all I totally agree with Andrew, there are better solutions to solving the problem. For example you can use:
JSpinner
JFormattedTextField
DocumentFilter
- see: How to automatically update small letter characters to capital letter in Java JEditorPane?The reason the above solutions are better is because:
Your solution is a low level solution, which means you need to understands the events that are generated when you press a key and how those events are handled by Swing.
A more abstract solution is always better since you don't need to know the details. This is why the Swing API has evolved.
In your case you are not understanding the difference between a "displayable" key event and a "non displayable" event.
A text component is updated when the keyTyped
event is generated which is only generated for "displayable" character like " numeric digits" and "-".
A "keyTyped" event is not generated for using the arrow keys or backspace keys.
So your logic needs to be changed to handle the "-" as a character (not a key code):
//if (Character.isDigit(ev.getKeyChar()) || ev.getKeyCode() == KeyEvent.VK_MINUS ...
if (Character.isDigit(ev.getKeyChar()) || ev.getKeyChar() == '-' ...