Calculating change from JTextField - java

I have 3 TextFields. One is a totalTF the other is a tenderedTF and the last is a changeTF. I am wondering how to go about taking the total price in the totalTF and allowing the user to enter in the amount they give to the cashier into the tenderedTF, then it should work out the change once the pay button is chosen and display in the changeTF. Here is my code so far. Im trying to do the math then set the changeTF. Any help would be greatly appreciated thanks.
JButton payButton = new JButton("Pay");
payButton.setBounds(970, 569, 209, 51);
contentPane.add(payButton);
// Calculate Change
changeTF.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == payButton)
{
double change = Double.valueOf(totalTF.getText()) - Double.valueOf(tenderedTF.getText());
changeTF.setText(String.valueOf(change));
}
}
});
tenderedTF.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == payButton)
{
double change = Double.valueOf(totalTF.getText()) - Double.valueOf(tenderedTF.getText());
changeTF.setText(String.valueOf(change));
}
}
});

You want to execute code when user clicks on payButton, so I think you should add the listener on the payButton:
payButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double change = Double.valueOf(totalTF.getText()) - Double.valueOf(tenderedTF.getText());
changeTF.setText(String.valueOf(change));
}
});
I think the listeners you added to textfields can't work because e.getSource() returns the textfield that originated the event, it can't be the payButton.
Edit: New revision to include the question posted in comment:
payButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double change = Double.valueOf(tenderedTF.getText()) - Double.valueOf(totalTF.getText());
if(change<0){
changeTF.setText(String.valueOf(-change) + " missing");
} else {
changeTF.setText(String.valueOf(change));
}
}
});
Honestly I did not compile and test this code but I hope it gives you the idea: check 'change' and provide different messages according to the positive or negative value.
This is a very basic approach, you might want to think of something more sophisticated.
Please note I chenged the computation for the value of change because this new one sounds more in line with the description you gave according to field names. Please double check.
Hope it helps.
Good luck.

Related

JButton Prints Multiple Times Instead of Once. Why?

I have a JButton and the code is below. When pressed it prints 3 times to the console instead of once. Why is it doing that and how to fix that? Thanks in advance! I also posted on code ranch.
change61 = new JButton("N");
change61.setLocation(0,0);
change61.setSize(25,14);
change61.setFocusPainted(false);
change61.setBorder(new LineBorder(Color.BLACK));
change61.setMargin(new Insets(0,0,0,0));
change61.setFont(new Font("Arial", Font.BOLD, 7));
change61.setRolloverEnabled(false); // TEST
change61.addActionListener(this);
change61.setActionCommand("Normal");
buttons16.add(change61);
change61.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = change61.getModel();
if (model.isArmed()) {
cl1.setIcon(CL2);
lvrvr1.setIcon(LVRL);
dsw1.setIcon(LSIG);
dsy1.setIcon(CL1);
b1b.setIcon(LHC);
System.out.println("Button Pressed"); // THIS GETS PRINTED 3 TIMES TO CONSOLE INSTEAD OF ONCE
} else {
cl1.setIcon(CL1);
}
}
});
Within stateChagned method, use isPressed instead of isArmed. It should work.
Or as #camickr suggested
change61.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl1.setIcon(CL2);
lvrvr1.setIcon(LVRL);
dsw1.setIcon(LSIG);
dsy1.setIcon(CL1);
b1b.setIcon(LHC);
System.out.println("Button Pressed"); // THIS GETS PRINTED 3 TIMES TO CONSOLE INSTEAD OF ONCE
}
});
Since the question got me hooked, I wanted to know why it is fired three times.
As the stacktrace reveals, the changes are fired by the mouse event.
First, the mouse is pressed. It calls DefaultButtonModel.isArmed(true) and DefaultButtonModel.isPressed(true). Each method triggers a change event. Here we have the first and second iteration.
Second, the mouse is released. It calls DefaultButtonModel.isPressed(false), again triggering a change event. The third iteration.
FYI, the DefaultButtonModel is the implementation of the ButtonModel- Interface.

JButton repeating action depending on how many times pressed

I'm building a simple program in Java which gets a balance (mine is set to $8000). I want to deposit money into that so I have a UI with 0-9 buttons, a textarea and a deposit button, so if the user wanted to deposit $100 he would press 1 once then 0 twice. All that works and it deposits for the first time, but the second time it deposits the double amount of money. If I press my deposit button 10 times and select $1 then press enter it deposits $10. I think the structure of my btn action listener might be wrong.
Any ideas?
Code:
btnDeposit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label1.setText("Deposit: How much would you like to deposit?");
btnWithdraw.setEnabled(false);
btnBalance.setEnabled(false);
btnEnter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
//convert text area into double
double depositNumber = Double.parseDouble(ta.getText());
sav.deposit(depositNumber);
btnWithdraw.setEnabled(true);
btnBalance.setEnabled(true);
}
});
}
});
My deposit function is:
public void deposit(double depositAmount) {
balance += depositAmount;
System.out.println("Your updated balance is: " + balance);
}
I also noticed that it doesn't go back to where it started, if I keep clicking on Enter it keeps adding and adding...
Button that clear my text area:
btnClear.addActionListener(new new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
ta.setText("");
}
});
The problem is called out in the comment section. You are declaring multiple listeners which are calling the respective deposit() or withdraw() method every time you perform an action.
To avoid this. You can set one listener class to all of your buttons like this.
Create an inner class
private class MySpecialListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent ae) {
if(e.getSource == btnDesposit) // do stuff and so on
}
}
and add the listener like this
MySpecialListener myListener = new MySpecialListener();
btnDeposit.addActionListener(myListener);
The above requires you to re-write your code, but it has a better structure then your current one.
To fix your current problem you can remove the last listener like this:
for(ActionListener al : btnEnter.getActionListeners())
btnEnter.removeActionListener(al)
btnEnter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
//convert text area into double
double depositNumber = Double.parseDouble(ta.getText());
sav.deposit(depositNumber);
btnWithdraw.setEnabled(true);
btnBalance.setEnabled(true);
}
});

Is there a way I can stop the program and wait for the user to click a button

The problem is that when the button is clicked and enters the start game method, the program does not wait for the action listener that is included in the question methods. Instead it skips to the last method. Thanks.
//Setting Main Layout
Game.setLayout(new BorderLayout());
Game.add(NorthName, NORTH);
Game.add(SouthScore, SOUTH);
Game.add(Center, CENTER);
//Setting NorthName Layout
NorthName.setLayout(new GridLayout(0,2,2,0));
NorthName.add(name);
NorthName.add(getName);
//Setting SouthScore Layout
SouthScore.setLayout(new FlowLayout());
SouthScore.add(scoreL);
scoreL.setText("Score: " + String.valueOf(scoreN) + "/10");
//Setting Center
Center.setLayout(new GridLayout(4,3,0,0));
Center.add(intro);
Center.add(question);
Center.add(True);
Center.add(False);
Center.add(status);
Center.add(answer);
True.setText("Start");
False.setText("Exit");
intro.setText("");
question.setText("");
status.setText("");
answer.setText("");
True.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
intro.setText("Hello " + getName.getText());
True.setText("True");
False.setText("False");
status.setText("");
answer.setText("");
startGame();
}
});
False.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
intro.setText("Hello guest");
True.setText("True");
False.setText("False");
status.setText("Well... ");
answer.setText("That's too bad. ;)");
startGame();
}
});
}
start game methods
void startGame(){
scoreN = 0;
setQuestionOne();
setQuestionTwo();
setQuestionThree();
setQuestionFour();
setQuestionFive();
setFinalScore();
}
This is what is in the set question methods is the same through out each one.
void setQuestionOne(){
question.setText("i'Robot is about Robots.");
True.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
status.setText("Correct! +3");
answer.setText("This Movie is about robots!");
scoreN = scoreN + 3;
scoreL.setText("Score: " + String.valueOf(scoreN) + "/10");
}
});
False.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
status.setText("Incorrect! +0");
answer.setText("This Movie is about robots!");
scoreN = scoreN + 0;
}
});
}
Use a JOptionPane. You can display each question separately in a JOptionPane. The dialog will only close when the user responds to the dialog.
Read the section from the Swing tutorial on How to Make Dialogs for working examples.
Otherwise you need to redesign your form. That is you would display a single question. Then in the ActionListener for the first question, you would display the second question and so on. In the ActionListener for the second question you display the third question.
Or in your ActionListener you would need to invoke a "Next Question" method. So in this case you would use an ArrayList to hold each question. Then every time a question is answered, you move to the next question in the ArrayList. This is the better approach because you can easily change the number of questions you want to ask. You should never really hard code methods to ask a different question.
Also, variable names should NOT start with an upper case character. Some of you variable names are correct, others are not. Be consistent!

JFormattedTextfield.selectAll() does not work when formatting the text

I have a lot of different JFormattedTextFields with action and keylisteners. Every Field has a keylistener, so when I press enter I will focus the next JFormattedTextField. The Problem is, for some JFormattedTextFields my code is formatting the input and then sets the text new and for those selectAll() does not work.
JFormattedTextField a = new JFormattedTextField(someDouble);
JFormattedTextField b = new JFormattedTextField(someDouble2);
a.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
leasingfaktor1Field.selectAll();
if(...) {
//do something
a.setText(tausenderPunkt(someValue));
}
}
});
a.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
b.requestFocusInWindow();
}
}
});
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
leasingfaktor1Field.selectAll();
if(...) {
//do something
b.setText(tausenderPunkt(someValue));
}
}
});
b.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
c.requestFocusInWindow();
}
}
});
The function tausenderPunkt():
public String tausenderPunkt(double value) {
String s = String.format("%1$,.2f", value);
return s;
}
So when my cursor is in field a and i press enter the cursor goes to field b but does not select the text or values. When i do not use setText() i do not have the problem. Somebody has a solution?
Edit: For some JFormattedTextFields the solution was to add selectAll() to the keyAdapter, but not for all.
For example:
b.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
c.requestFocusInWindow();
c.selectAll();
}
}
});
Edit2:
The problem seems to be when i create the JFormattedTextFields.
When i do not create them with a value in the constructor it works.
But i have to do.
Before moving to your next text field you should consider handling all the required conditions for the text field you are currently focused on and this would of course include the formatting of values or text supplied to that field. Once all the desired conditions are met then move on to the next text field.
In reality this can all be accomplished through the keyPressed event for your particular situation. There is no need for the actionPerformed event on any of your text fields, for example:
a.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
checkConditions(a, b);
}
}
});
b.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
checkConditions(b, c);
}
}
});
//---------- and so on -------------
Here is a simple method so as to eliminate the need for repetitious code:
private void checkConditions(JFormattedTextField fieldA, JFormattedTextField fieldB) {
// Make sure something is contained within fieldA and
// that it's actually numerical text.
if(!fieldA.getText().isEmpty() &&
fieldA.getText().matches("([-]?)\\d+([,]\\d+)?(([.]\\d+)?)")) {
// Convert the supplied text to Double and
// ensure the desired numerical formating.
String res = (String)tausenderPunkt(Double.parseDouble(fieldA.getText().replace(",","")));
fieldA.setText(res);
// Set Focus to our next text fieldB.
fieldB.requestFocusInWindow();
// Highlight the contents (if any) within the
// next text fieldB.
fieldB.selectAll();
}
// If fieldA is empty or fieldA does not contain
// numerical text then inform User and re-highlight
// the entry in fieldA.
else {
JOptionPane.showMessageDialog (null, "Please Enter Numerical Values Only!",
"Incorrect Entry", JOptionPane.WARNING_MESSAGE);
fieldA.selectAll();
}
}
If you want the contents of your first text field to be highlighted as soon as focus has been established upon it (tabbed to or clicked on) then consider using a FocusGained event for that component or any other component where you desire the same effect.
I Hope this has helped in some way.
EDITED!
So as to handle OP's particular situation.
String str=this.getText();
this.setText(str);
this.selectAll();
You can get the focus owner and remove the focusable feature:
Component focusOwner = FocusManager.getCurrentManager().getFocusOwner();
When you get the component, put this sentence after load it:
component.setFocusable(false);

How to enable / disable buttons in java, eclipse?

How can I disable buttons with the press of one button and when the task that the button which has been pressed was assigned to has been done then I want all the buttons to be enabled. for example;
UpButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
DownButton.setEnabled(false);
LeftButton.setEnabled(false);
RightButton.setEnabled(false);
System.out.printline("Up Button");
}
});
DownButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
UpButton.setEnabled(false);
LeftButton.setEnabled(false);
RightButton.setEnabled(false);
System.out.printline("Down Button");
}
});
LeftButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
DownButton.setEnabled(false);
UpButton.setEnabled(false);
RightButton.setEnabled(false);
System.out.printline("Left Button");
}
});
RightButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
DownButton.setEnabled(false);
LeftButton.setEnabled(false);
UpButton.setEnabled(false);
System.out.printline("Right Button");
}
});
I have tried to do it but it does not work. What I want is, for example, my Upbutton is printing out ("Up button"), so when a user presses this button I want all the other buttons to be disabled until it has finished doing the command that it was suppose to do, in this case print out a text but later on I will be adding things like adding up two user inputs e.g. I will have a button that will ask the user to type number 1 and then number 2 and then the computer will add them up and during this process I want all the buttons to be disabled expect the one that has been clicked on, until the user has given all numbers and the computer has given the output.
I hope I have explained myself properly, if not please let me know and I will try my best to give more information. Thanks in advance.
How about using Command objects? Each command object might have execute() and canExecute() methods at least. Then;
btnA.setEnabled( cmdA.canExecute() );
btnA.addActionListener( event-> {
cmdA.execute();
btnB.setEnabled( cmdA.canExecute() );
});
That seems right. Maybe you want them invisible instead of disabled...
In that case:
LeftButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DownButton.setVisible(false);
UpButton.setVisible(false);
RightButton.setVisible(false);
System.out.printline("Left Button");
HereĀ“s an example of something that works:
private void jButtonChangeChampActionPerformed(java.awt.event.ActionEvent evt) {
jComboBoxPlayer.setEnabled(true);
jComboBoxChampion.setEnabled(true);
jButtonSelecionar.setVisible(true);
jButtonMagias.setVisible(false);
}
What if you try this:
UpButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
UpButtonActionPerformed(evt);
}
});
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
DownButton.setEnabled(false);
LeftButton.setEnabled(false);
RightButton.setEnabled(false);
System.out.printline("Up Button");
}
It works here...
If you want to Set the Button Disabled , You can use the
btnExample.setDisable(true); // This will disable the Button
btnBreak.setVisible(false); // This will make the button Disappear visually only.
Hope this help guys.
You have to first disable the other buttons, finish your task and then enable the buttons again.
For example:
UpButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
// first disable all other buttons
DownButton.setEnabled(false);
LeftButton.setEnabled(false);
RightButton.setEnabled(false);
System.out.println("Up Button");
// do rest of your tasks here.
// now enable them again
DownButton.setEnabled(true);
LeftButton.setEnabled(true);
RightButton.setEnabled(true);
}
});
Similarly, setup the Listeners for the other buttons.
Hope this helps!

Categories