How to handle keypresses for a calculator made in Java? - java

I've made a simple calculator using an tutorial online using Netbeans and it works fine when clicking the respective buttons, however I'm looking to improve it by allowing keypresses to work.
What I'd like is for the numbers 0-9 to work, +, -, *, / and enter as =.
I think I know how to do it, but can't seem to figure it out.
For example, the code for my 1 button is:
private void btnOneActionPerformed(java.awt.event.ActionEvent evt) {
String btnOneText = txtDisplay.getText() + btnOne.getText();
txtDisplay.setText(btnOneText);
}
So for the keypress I created a keypress event but I'm not sure what the code is. I assume it's something like this:
private void jPanel1KeyPressed(java.awt.event.KeyEvent evt) {
//if statement to check if 1 key has been pressed, then execute rest of code
String btnOneText = txtDisplay.getText() + btnOne.getText();
txtDisplay.setText(btnOneText);
}
However I'm probably completely wrong. Any help?

You can use either of KeyListener or KeyBindings depending on your usage.
Since you are designing a simple calculator, there is no harm with KeyListener since there are not many controls.
Demo code for the same is.
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_0:
//handle 0 press
break;
case KeyEvent.VK_1:
// handle 1 press
break;
case KeyEvent.VK_2:
// handle 2 press
break;
case KeyEvent.VK_3 :
// handle 3 press
break;
//
}
}
You can find the keycodes here : http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html

Related

UPDATE of How to get string from JTextField and save it in variable?

I recently run in to same problem as this guy 4 years before. He get some answers there but non of it work either for him or me and then the question was not updated anymore.
How to get string from JTextField and save it in variable?
The point is to check what is typed in textfield and if, like in example is yet decimal dot in the TextField, then consume event and not allow to add second decimal dot.
Main problem I figured out is that I need to add this inside the key event as shown belox. But this. statement inside the event reffers to event itself and not on JTextField.So I need to find bypass or other solution how to write getText statement
String text = this.getText().toString();
if someone have ideas of how to improve code as well I'm opened to any suggestions except for rewriting it as formatted field because the user experience is a little different, from the point where I was trying formatted field.
public class TxtfNumber extends JTextField {
String text = this.getText().toString();
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
String text = this.getText().toString();
if(evt.getKeyChar()=='.'&& text.contains(".")){
evt.consume();
}
}
return false;
}
});
}
}
SOLUTION
I accidentally run in solution when I used lambda expression. The formula you need to use is the name of class then .this.
So in this case,
String text = TxtfNumber.this.getText().toString();
is the solution.
But eventually, when I know how to implement JTextField, I no longer need a solution by string. So I'm giving the whole code here for later use. Feel free to use it as Choose Bean component.
It restricts the user to use only one minus sign at the start of the text, one decimal dot anywhere and then type in two decimal numbers.
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import javax.swing.JTextField;
public class TxtfNumber extends JTextField {
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
//restricts input charactes
if(!Character.isDigit(evt.getKeyChar()) && (evt.getKeyChar()!='.') && (evt.getKeyChar()!='-') && (evt.getKeyChar()!=','))
evt.consume();
//change , and . for securing of different keyboard language
if (evt.getKeyChar()==',')
evt.setKeyChar('.');
//allow only one decimal dot in text
if (evt.getKeyChar()=='.' && TxtfNumber.this.getText().contains("."))
evt.consume();
//allow minus sign only at the start of text
if (evt.getKeyChar()=='-' && TxtfNumber.this.getText().length() != 0)
evt.consume();
//allow two decimal numbers after dot
for (int i = -1; (i = TxtfNumber.this.getText().indexOf(".", i + 1)) != -1; i++) {
if (i+3 == TxtfNumber.this.getText().length())
evt.consume();
}
break;
}
return false;
}
});
}
};

How do I switch between two views being visible?

I am making an application that helps score a table tennis game. I am at the final stages but I am having trouble with switching the server around every two points. I have given it a lot of thought but I can only get it to switch once. I know it is probably an easy solution but it's just not coming to me.
Here's how I am switching it once. I am using a count each time the button is pressed and when it reaches a number divisible by 2 it switches to the right.. However, using this logic is making it difficult to switch back! Thanks in advance.
public void serveSwitch() {
TextView leftServe = findViewById(R.id.leftServe);
TextView rightServe = findViewById(R.id.rightServe);
serverCount++;
if (server.serve=="left") {
if (serverCount % 2 == 0) {
rightServe.setVisibility(View.VISIBLE);
leftServe.setVisibility(View.GONE);
}
}
The part I'm struggling with is the logic on how to switch visibility every two points
If I get your point right, you want to toggle the visibility from off to on every two points and vice versa
You can do something like:
...
if (server.serve=="left") {
if (serverCount % 2 == 0) {
switch (rightServe.getVisibility()) {
case View.GONE:
rightServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
rightServe.setVisibility(View.GONE);
break;
}
switch (leftServe.getVisibility()) {
case View.GONE:
leftServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
leftServe.setVisibility(View.GONE);
break;
}
}
}
Note: I left the equality as-is as you say there is no problem with it. but in general you should use .equals() when it comes to compare strings in java.

KeyEvent.getKeyCode() always returns zero

I am working on a pause key in my little school project, but for some reason it refuses to work. Using this code :
public void keyTyped(KeyEvent me) { //ESCAPE PLS WORK ...
code = me.getKeyCode();
System.out.println(code);
}
For some reason "code" always stays zero. I tried to put it in different voids(pressed/released etc), but it still does not work. What could be the reason?
Here's what the javadoc says about getKeyCode()
Returns: the integer code for an actual key on the keyboard. (For KEY_TYPED events, the keyCode is VK_UNDEFINED.)
And the value of VK_UNDEFINED is zero.
The javadoc also says:
public static final int KEY_TYPED
The "key typed" event. This event is generated when a character is entered. In the simplest case, it is produced by a single key press. Often, however, characters are produced by series of key presses, and the mapping from key pressed events to key typed events may be many-to-one or many-to-many.
So maybe you are looking at the wrong kind of key events. Maybe should be looking at the KEY_PRESSED or KEY_RELEASED events rather than the KEY_TYPED events.
Why not try the keyPressed() method again as in the example below:
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
switch( code ) {
case KeyEvent.VK_UP:
// handle up
System.out.println(code);
break;
case KeyEvent.VK_DOWN:
// handle down
break;
case KeyEvent.VK_LEFT:
// handle left
break;
case KeyEvent.VK_RIGHT :
// handle right
break;
}
}
Note that you must expect an integer.

Multiple classes with Mouse.next()

As the title already shows I have an issue with the function "Mouse.next()".
I'm programming my own buttons at the moment and for that I have to check, if the left mouse-button was pressed. I thought, that I can do it so:
while(Mouse.next()) {
if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0) {
// some code..
}
}
This also works, if I only have one instance of my button. But if I add another instance the while loop never gets called for the second (last created) button...
Does somebody have any idea, why this could happen?...
And also what do these functions (found them on the internet) Mouse.getEventButtonState(), Mouse.getEventButton() == 0 and Mouse.isButtonDown(0)
Mouse is from org.lwjgl.input.Mouse
With another instance I mean something like: MyButton button = new MyButton();
EDIT:
My Question is: How can I get Mouse.next() to work with multiple instances of the surrounding class...
Because Mouse is a Singleton . As long as it is Singleton calling next will consume the Event. You can not consume the same event two times! When first object calls next() it consumes it and when the second calls next() the is no second click to consume.
The issue is that getEventButton() returns a different number depending on which button was pressed. What you should do instead is something like:
while (Mouse.next()) {
if (Mouse.getEventButtonState()) {
int buttonId = Mouse.getEventButton();
switch (buttonId) {
case -1: break; // no button was clicked
case 0:
// code for first button
break;
case 1:
// code for second button
break;
}
}
}

KeyPressed event

I'm trying to learn something about GUI, using NetBeans6.8, starting with the GUI section in The java tutorial.
There is a simple exercise for a Celsius-Fahrenheit converter. I want that to have two TextFields, one for Celsius and one for Fahrenheit temperature; if the user types in the celsius text field he got the result "printed" in the fahrenheit text filed. and vice versa.
So, i put on both the textfields one KeyTyped event, here's the code:
private void celsiusTextKeyTyped(java.awt.event.KeyEvent evt) {
int cels = Integer.parseInt(celsiusText.getText());
int fahr = (int)(cels * 1.8 + 32);
fahrText.setText(fahr + "");
}
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt) {
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
It doesn't work. If i type something in a textfield i got this exception: java.lang.NumberFormatException: For input string: ""
The code that attach the listeners:
celsiusText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
celsiusTextKeyTyped(evt);
}
});
fahrText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
fahrTextKeyTyped(evt);
}
});
[However, i can't modify it, it's autogenerated.]
Method .getText() returns a string not a number, if that string contains non-numeric characters (i.e. a letter, a space, nothing at all) then parseInt will throw a NumberFormatException. Since your using KeyEvent, as soon as you press say "7", the event is fired before 7 is entered into the text box. Thus the text box still only contains "", which is where the error comes from. You may wish to also listen to the keyUp event instead.
You need to enclose your code in a try catch block.
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt)
{
try
{
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
catch(NumberFormatException ex)
{
//Error handling code here, i.e. informative message to the user
}
}
An alternative is you could filter out non-numbers on keydown event, see example here - http://www.javacoffeebreak.com/java107/java107.html (Creating a custom component - NumberTextField)
I suspect that what's happened is that you added these handlers with something like celsiusText.addKeyListener, yes?
The thing is, that'll give you not just the KEY_TYPED events you wanted, but also KEY_DOWN and KEY_UP. The KEY_DOWN event will happen before the text is really entered into the field, so your code firing on that will see the field as blank still. Trying to convert the empty string to a number gives you a format exception.
The easiest way to fix this is the try/catch construct other people have been posting.
You probably set action to keyDown, this mean that even occur before the key value is "added" to textbox, while You retrieve the value from it is still empty "".
There is a simple exercise for a
Celsius-Fahrenheit converter
That is a really old example. The better approach is to use a DocumentListener, not a KeyListener.

Categories