JavaFX checking if Event's KeyCode is a digit key - java

I'm creating a custom textfield class in which i have a custom behaviour depending on if the user types digit keys on it.
!event.getCode().isDigitKey() always returns true, even when i type digits. I tried to check if KeyCode is a letter also and still it returns false. What seems to be the issue here?
I always get false when checking the event's KeyCode against any other KeyCode, even when they should be equal.
public class ScoreField extends TextField implements Customizable {
public ScoreField() {
super();
customize();
}
#Override
public void customize() {
this.setOnKeyTyped(new EventHandler<KeyEvent>() {
int curChar = 0;
#Override
public void handle(KeyEvent event) {
event.consume();
KeyCode keyTyped = event.getCode();
char charTyped = event.getCharacter().charAt(0);
System.out.println(charTyped);
// Do nothing if not a digit
if (!event.getCode().isDigitKey()) {
System.out.println("NOT A DIGIT KEY");
if (keyTyped == KeyCode.BACK_SPACE) {
System.out.println("RESETTING");
resetText();
return;
}
return;
}
if (getText().length() >= 5) {
if (curChar == 2) {
curChar = 3;
}
if (curChar == 5) {
curChar = 0;
}
StringBuilder builder = new StringBuilder(getText());
builder.setCharAt(curChar, charTyped);
setText(builder.toString());
curChar++;
return;
}
if (getText().length() == 2) {
setText(getText() + ":");
}
setText(getText() + charTyped);
}
});
}
private void resetText() {
setText("");
}
}

As James_D stated:
For key typed events, the code is always KeyCode.UNDEFINED
So i did as he suggested and instead of checking the KeyCode if it's a digit, i checked event.getCharacter()[0] using Character.isDigit(char) in the 1ST if statement, and it worked perfectly for my case.
P.S: I tried to use a TextFormatter with a StringConverter, but i couldn't get it to work.

Related

JButtons don't follow the intended handlers?

I'm making a minesweeper game, in the first part, I'm deciding whether or not there is a bomb at a certain button by using boolean1 (the field is a 16x16 array) I have tested this part, and the output is correct. 50 random true values and the rest are false my problem starts at the second part, where I want to get a certain action by the button based on the value of the boolean1. When implementing the code, all of the jbuttonsfollow the second ActionListener where the icon is set to bomb I want to get the jbuttons to also follow the first handler.
1st procedure
static void placeMines()
{
for (int x=0;x<16;x++)
{
for (int y=0;y<16;y++)
{
if(boolean1[x][y]=(true))
{
boolean1[x][y]=false;
}
}
}
int minesPlaced = 0;
Random random = new Random();
while(minesPlaced < 50)
{
int a = random.nextInt(Width);
int b = random.nextInt(Height);
boolean1[a][b]=(true);
minesPlaced ++;
}
}
2nd procedure:
static void buttonfunctions()
{
for(int c=0;c<16;c++)
{
for(int d=0;d<16;d++)
{
if (boolean1[c][d]=false)
{
final int temp3=c;
final int temp4=d;
jbuttons[c][d].addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent e)
{
jbuttons[temp3][temp4].setIcon(clickedCell);
}
});
}
if(boolean1[c][d]=true)
{
final int temp1=c;
final int temp2=d;
jbuttons[temp1][temp2].addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent e)
{
jbuttons[temp1][temp2].setIcon(bomb);
}
});
}
}
}
}
In order to check if a boolean is true, you want to do :
if (myBoolean)
doing
if (myBoolean == true)
is equivalent, but more verbose than needed.
doing
if (myBoolean = true) is syntactically correct, but has the effect of assigning true to myBoolean, and then evaluating the result of the assignment, which is true. So, going back to your code:
If the intent of the following code is to reset the matrix:
if(boolean1[x][y]=(true))
{
boolean1[x][y]=false;
}
then you should just do
boolean1[x][y] = false;
Also
if (boolean1[c][d]=false)
should probably be:
if (! boolean1[c][d])
There may be more stuff wrong with your code, but you may want to start fixing this.

Need help in JavaFx Textfield Focus property about changing the text after focus out

Need help in Javafx text field focus property, I want to change the text in the text field if enter number greater than 12 using focus property when i focus out the text field then it must change the text inside to 12
code I am using is
NumberTextField numberTextField = new NumberTextField();
numberTextField.setLayoutX(280);
numberTextField.setLayoutY(280);
//Textfield1 working
numberTextField.focusedProperty().addListener((arg0, oldPropertyValue, newPropertyValue) -> {
if (newPropertyValue)
{
}
else
{
if(numberTextField.getText() == "" && Integer.parseInt(numberTextField.getText()) > 12)
{
}
numberTextField.setText("12");
System.out.println("Textfield 1 out focus");
}
});
and the numberTextfield class is
public class NumberTextField extends TextField
{
#Override
public void replaceText(int start, int end, String text)
{
if (validate(text))
{
super.replaceText(start, end, text);
}
}
#Override
public void replaceSelection(String text)
{
if (validate(text))
{
super.replaceSelection(text);
}
}
private boolean validate(String text)
{
return ("".equals(text) || text.matches("[0-9]"));
}
}
so its working properly, it change text of the text field whenever i focus out, not after entering any text, or when i enter text less than 12.
You have written condition wrongly. to write proper conditions, learn Trueth tables See this
NumberTextField numberTextField = new NumberTextField();
numberTextField.setLayoutX(280);
numberTextField.setLayoutY(280);
// Textfield1 working
numberTextField.focusedProperty().addListener((arg0, oldPropertyValue, newPropertyValue) -> {
if (newPropertyValue) {
} else {
if (numberTextField.getText().isEmpty() || numberTextField.getText() == null
|| Integer.parseInt(numberTextField.getText()) > 12) {
numberTextField.setText("12");
}
System.out.println("Textfield 1 out focus");
}
});

Java game walking + jumping stops the key pressing action?

Hello in my game when I walk and jump, it stops everything after the jump finishes:
Can you see after a jump, it continues walking for a bit & then stops?
It should stop immediately but my walking queue continues executing because I didn't reset it, it should only reset upon keypress or release. But keypressing will stop working after i release my jump key. I think if I use 2 keys at a time and release on, the OS won't remember the old key I am still pressing. Even in your browser URL input, press and any key and hold, and then hold another key for bit & release it, it won't write the old key anymore.
Is there a fix for this? I am using keylistener, because i couldn't figure out how to find out when a key was released in KeyBinds.
This is how I do it:
public class Keyboard implements KeyListener {
private Player player;
public Keyboard(Player p) {
this.player = p;
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("yes");
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
this.player.getMovement().moveLeft();
break;
case KeyEvent.VK_RIGHT:
this.player.getMovement().moveRight();
break;
case KeyEvent.VK_SPACE:
this.player.getMovement().jump();
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
int left = KeyEvent.VK_LEFT;
int right = KeyEvent.VK_RIGHT;
if (e.getKeyCode() == left || e.getKeyCode() == right) {
this.player.getMovement().stopMovement();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
}
How can I fix this issue? If you need more parts of the code like the jump or walking queue, let me know.
Keylog:
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Space is a nice button
Remember process all the keypresses in a separate Thread.
http://wiki.processing.org/w/Multiple_key_presses
Method #1
/**
multiplekeys taken from http://wiki.processing.org/index.php?title=Keep_track_of_multiple_key_presses
#author Yonas Sandbæk http://seltar.wliia.org
*/
// usage:
// if(checkKey("ctrl") && checkKey("s")) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(String k)
{
for(int i = 0; i < keys.length; i++)
if(KeyEvent.getKeyText(i).toLowerCase().equals(k.toLowerCase())) return keys[i];
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
}
void keyReleased()
{
keys[keyCode] = false;
}
Methord #2 (And a simpler way of doing this just checking a few keys (without an array))
boolean keyup = false;
boolean keyright = false;
boolean keyleft = false;
boolean keydown = false;
float x,y;
void setup() {
size(640,360);
x = width/2;
y = height/2;
}
void draw() {
background(51);
fill(255);
ellipse(x,y,16,16);
if (keyup) y--;
if (keydown) y++;
if (keyleft) x--;
if (keyright) x++;
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) keyup = true;
if (keyCode == DOWN) keydown = true;
if (keyCode == LEFT) keyleft = true;
if (keyCode == RIGHT) keyright = true;
}
}
void keyReleased() {
if (key == CODED) {
if (keyCode == UP) keyup = false;
if (keyCode == DOWN) keydown = false;
if (keyCode == LEFT) keyleft = false;
if (keyCode == RIGHT) keyright = false;
}
}
Method #3
/**
Modified version of Option 1 multiplekeys (should provide improved performance and accuracy)
#author Yonas Sandbæk http://seltar.wliia.org (modified by jeffg)
*/
// usage:
// if(checkKey(KeyEvent.VK_CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(int k)
{
if (keys.length >= k) {
return keys[k];
}
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
if(checkKey(CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
}
void keyReleased()
{
keys[keyCode] = false;
}
Method #5
/**
* Snappier multiple key detection using Primitive Collections Classes for Java http://pcj.sourceforge.net/
* (standard Java Collection Objects can be used instead)
* #author analogAI http://recursivepath.com/analogAI/
*/
// usage:
// if(this.checkKeysHeld(KeyEvent.VK_CONTROL) && this.checkKeysHeld(KeyEvent.VK_S)) println("CTRL+S");
import bak.pcj.set.IntSet;
import bak.pcj.set.IntOpenHashSet;
public class HelloWorld extends PApplet {
public IntSet keysheld = new IntOpenHashSet();
/**
* #param keycode key integer code, the value are constants defined in KeyEvent Class
* http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/KeyEvent.html
* e.g. KeyEvent.VK_A for letter A
* KeyEvent.VK_0 for number 0
* KeyEvent.VK_SHIFT for shift button
* #return true if the key is currently held down, false otherwise
*/
public boolean checkKeysHeld(int keycode){
return this.keysheld.contains(keycode);
}
public void keyPressed(){
// add key to the list of keys held down
// with processing, the KeyEvent object is always available as "keyEvent",
// the getKeyChar() is already in the variable 'key', and getKeyCode() is in the variable 'keyCode'.
this.keysheld.add(this.keyEvent.getKeyCode());
println("key pressed: "+KeyEvent.getKeyText(this.keyEvent.getKeyCode()));
println("keys in current held list: "+this.keysheld.toString());
}
public void keyReleased(){
// remove key from the list of keys held down
this.keysheld.remove(this.keyEvent.getKeyCode());
}
}

How to prevent typing characters except numbers in JTable cells?

I am working in a project where I have to get input from user by using a JTable. Here I had created a JTable which will have only numerical values. I validated it on keyTyped and its working fine until I press F2 or click on the cell. When I am doing so, it put a cursor in cell and other characters are also being typed.
jtblValues.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER && (jtblValues.getRowCount() == (jtblValues.getSelectedRow()+1)))
model.addRow(new Object[]{"", "", ""});
else if (e.getKeyCode()==KeyEvent.VK_TAB && (jtblValues.getRowCount() == (jtblValues.getSelectedRow()+1)) && (jtblValues.getColumnCount() == (jtblValues.getSelectedColumn()+1)))
model.addRow(new Object[]{"", "", ""});
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (!((c >= '0') && (c <= '9') || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) || (c == KeyEvent.VK_ENTER) || (c == KeyEvent.VK_TAB))) {
getToolkit().beep();
e.consume();
}
}
} );
So, how to prevent user by typing other characters than numbers?
Thanks.
You can achieve this by providing an appropriate TableCellEditor as described in Using an Editor to Validate User-Entered Text section of How to Use Tables tutorial.
The key is using a JFormattedTextfield as editor with NumberFormatter and NumberFormat. For instance:
NumberFormat integerFormat = NumberFormat.getIntegerInstance();
NumberFormatter formatter = new NumberFormatter(integerFormat);
formatter.setAllowsInvalid(false);
JFormattedTextField textfield = new JFormattedTextField(formatter);
See How to Use Formatted Text Fields tutorial for further details.
Off-topic
It's preferable use Keybinding over KeyListeners when you're working with Swing for the reasons discussed in this topic: Key bindings vs. key listeners in Java. Refer to the tutorial to start with KeyBinding: How to Use Key Bindings
maybe I have same problem like you. This code worked for me using KeyListener.
//define KeyAdapter variable at header
KeyAdapter key1, key2;
make class TableEditor like this:
final class TableEditor extends DefaultCellEditor{
public TableEditor(){
super(new JTextField());
setClickCountToStart(1);
}
#Override
public Component getTableCellEditorComponent(final JTable table,Object value,boolean isSelected,final int row,final int column){
final JTextField cellEdit = (JTextField) super.getTableCellEditorComponent(table,value,isSelected,row,column);
cellEdit.setText((String)value);
table.setSurrendersFocusOnKeystroke(true);
//remove previous keyListener that store in memory
cellEdit.removeKeyListener(key1);
cellEdit.removeKeyListener(key2);
// KeyAdapter that accept numeric only (key1)
key1 = new KeyAdapter() {
#Override
public void keyPressed(KeyEvent evt){
// just for check how much times Enter keyEvent store in memory
if(evt.getKeyCode()==KeyEvent.VK_ENTER) System.out.println("enter 2");
}
#Override
public void keyReleased(KeyEvent evt){
}
#Override
public void keyTyped(KeyEvent evt){
char c = evt.getKeyChar();
if (!Character.isDigit(c)) evt.consume();
}
};
// KeyAdapter that accept all char (key2)
key2 = new KeyAdapter() {
#Override
public void keyPressed(KeyEvent evt){
// just for check how much times Enter keyEvent store in memory
if(evt.getKeyCode()==KeyEvent.VK_ENTER) System.out.println("enter 2");
}
#Override
public void keyReleased(KeyEvent evt){
}
#Override
public void keyTyped(KeyEvent evt){
}
};
// cell column 3rd accept numeric only > addKeyListener(key1)
if (column == 3) {
cellEdit.addKeyListener(key1);
cellEdit.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
cellEdit.setCaretPosition(1);
return cellEdit;
}
// other cell accept all char > addKeyListener(key2)
else {
cellEdit.addKeyListener(key2);
cellEdit.setHorizontalAlignment(javax.swing.JTextField.LEFT);
return cellEdit;
}
}
}
Then call the class using:
MyTable.setDefaultEditor(Object.class, new TableEditor());
That's all. I hope this code worked for you.
you can do this easy way in netbeans:
Step 1:see image 1 here
Step 2:see image 2 here
Step 3:see image 3 here

Vaadin TextArea keyboard listener consume event

I need a customized TextArea component, where I'd like disable some keys (f.e. backspace and del keys). For this I created a vaadin-archetype-widget artifact, and I created two subclasses (MyTextArea and VMyTextArea), and I overrode the onKeyDown method in class VMyTextArea:
#Override
public void onKeyDown(KeyDownEvent event) {
int kc = event.getNativeKeyCode();
if (kc == KeyCodes.KEY_BACKSPACE || kc == KeyCodes.KEY_DELETE) {
return;
}
super.onKeyDown(event);
}
Unfortunately this solution doesn't solve my problem, the backspace and delete keys work normally. My question how to do this?
The solution:
public class VMyTextArea extends VTextArea {
VMyTextArea() {
super();
addKeyDownHandler(new KeyDownHandler() {
public void onKeyDown(KeyDownEvent event) {
int kc = event.getNativeKeyCode();
if (kc == KeyCodes.KEY_BACKSPACE || kc == KeyCodes.KEY_DELETE) {
event.preventDefault();
}
}
});
}
}

Categories

Resources