I'm using Eclipse. I developed simple JavaFX calculator app, everything is working but keyevent for numpad MINUS and PLUS. Which is funny because every other numpad key is ok. Am I missing something?
public void onKeyPress(KeyEvent event) {
KeyCode keyCode = event.getCode();
Just a piece of my code:
case PLUS:
if (operation.getOperand() == 'x') {
operation.add(Double.parseDouble("" + display.getText()), display);
decimal.setDisable(false);
} else {
result.fire();
operation.add(Double.parseDouble("" + display.getText()), display);
decimal.setDisable(false);
}
break;
Just now i thought of debugging keycodes themselves while running the app. Added a simple console output of a keycode that is currently pressed, found out that constant for numpad plus and minus in not PLUS and MINUS but ADD and SUBTRACT.
Thanks to all who took the time to answer me.
Related
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:
a JSpinner
a JFormattedTextField
a DocumentFilter - see: How to automatically update small letter characters to capital letter in Java JEditorPane?
The reason the above solutions are better is because:
you don't need to extend a class
the solutions are more abstract
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() == '-' ...
mainNotes.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((keyCode != KeyEvent.KEYCODE_SLASH) && (titleMod = true) && (keyCode != 46) && (keyCode != KeyEvent.KEYCODE_SLASH) && (keyCode != KeyEvent.KEYCODE_ENTER)) {
Toast.makeText(MainActivity.this, "not a slash", Toast.LENGTH_SHORT).show();
titleEnd += 1;
slashCount = 1;
} else if ((keyCode == KeyEvent.KEYCODE_DEL) && (titleMod = true)) {
Toast.makeText(MainActivity.this, "deleted", Toast.LENGTH_SHORT).show();
titleEnd -= 1;}
The code does not recognize that delete is pressed. It works for all other keypresses like slash, other text and so on. It doesn't even register that delete is pressed?
KeyEvent.KEYCODE_DEL corresponds to your backspace key. Standard Android keyboards don't actually have a delete key at all, so you need to be pressing backspace when testing on emulator via keyboard.
To make sure that soft key events are detected, avoid using the KeyListener interface because it's unlikely to be recognized by a software keyboard or emulator. From the official documentation:
Key presses on soft input methods are not required to trigger the
methods in this listener, and are in fact discouraged to do so. The
default android keyboard will not trigger these for any key to any
application targetting Jelly Bean or later, and will only deliver it
for some key presses to applications targetting Ice Cream Sandwich or
earlier.
Instead, try using KeyboardView.OnKeyboardActionListener.
Sample code may be found here.
I'm developing an Eclipse RAP application where I have to use a combo box. The user can type a RQL filter in the combo or to select already existing one. The problem comes when the user types a left bracket "(" - SHIFT + 9 combination. This combination traverse the existing filters - started from first to the last for each combination and deleted all the stuff typed before that.
I tried with the code below and with TraverseListener, but the event continue to occurs.
combo.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent event) {
if (event.character == '\u0000') { // used to prevent SHIFT + 9 (left bracket) combination when typing a filter in the combo
event.doit = false;
}
}
});
Could some one helps me with this? Thanks in advance!
I'm currently working on a practice program that works with various keyboard inputs so I can understand how they work in Android apps with Java. But I am struggling to get the ESC key to be recognised. The code below doesn't work. Has anyone ever managed to get the ESC key to work in an app? Is it actually possible?
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
boolean handled = false;
if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_ESCAPE) {
textView.setText("Escapekey pressed");
handled = true;
}
return handled;
}
});
To summarize, I want the program to recognise the ESC key.
It seems that Android Emulator will not forward this key to the application, just like e.g. the function keys. Receiving these key events on a real device from a real keyboard works fine for me.
I'm sorry if this has been answered before, I tried to look for the solution, but I couldn't find anything relevant. I'm new to this, so there's a chance I completely overlooked or ignored something that would have led me to an easy solution.
I've implemented a key listener for the shift key so that when the user presses shift, he enters the cell exactly one row before into the edit more (please take a look at the code below). Although, there's one problem; If the user is currently entering data into the cell, the shift key doesn't work and when debugging, we can see that the the program never even enters the key listener. I've been told to use key binding instead of key listeners to fix this problem. I've tried to follow some tutorial online and it looks like I've failed. Any help will be much appreciated, thanks a lot!
Two key listeners (Tab works fine, while Shift does not):
table.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
//KeyCode 9 is a key code for the Tab key
if (e.getKeyCode() == 9) {
if(table.isCellEditable(table.getSelectedRow(),table.getSelectedColumn())) {
table.editCellAt(table.getSelectedRow(), table.getSelectedColumn());
} else {
table.editCellAt(table.getSelectedRow(), table.getSelectedColumn() + 1);
}
}
//The problem occurs here
//KeyCode 16 is a key code for the Shift key
if (e.getKeyCode() == 16) {
if(table.isCellEditable(table.getSelectedRow() + 1, table.getSelectedColumn())) {
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn());
table.setColumnSelectionInterval(table.getSelectedColumn(), table.getSelectedColumn());
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
} else {
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn() + 1);
table.setColumnSelectionInterval(table.getSelectedColumn() + 1, table.getSelectedColumn() + 1);
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
}
}
}
});
Here's my attempted (and failed) solution:
class ShiftAction extends AbstractAction{
public void actionPerformed(ActionEvent ae){
System.out.println("Shift");
table.editCellAt(table.getSelectedRow() + 1, table.getSelectedColumn());
table.setColumnSelectionInterval(table.getSelectedColumn(), table.getSelectedColumn());
table.setRowSelectionInterval(table.getSelectedRow() + 1, table.getSelectedRow() + 1);
}
}
shiftAction = new ShiftAction();
table.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT,KeyEvent.SHIFT_DOWN_MASK),"doShiftAction");
table.getActionMap().put("doShiftAction",shiftAction);
Hopefully the question's not too stupid, and once again, thanks in advance.
e.getKeyCode() == 9
First of all, don't use magic numbers. People reading the code don't know what "9" means. Use the provided fields from the KeyEvent API: KeyEvent.VK_???.
we can see that the the program never even enters the key listener.
Focus is on the JTextField being used as the editor for the cell so it receives the KeyEvent, not the table.
I've been told to use key binding instead of key listeners to fix this problem.
You need to use the appropriate InputMap. In this case it should be:
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
Read the section from the Swing tutorial on How to Use Key Bindings for more information.