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
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 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");
}
});
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());
}
}
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
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();
}
}
});
}
}