I know that it is possible in an event driven program in Java to find out what object caused an event (e.g. JRadioButton was selected, therefore a certain action will take place). My question is, if you have 2 JRadioButtons in a buttongroup, both with action listeners added to them, and you keep selecting from one to the other, is it possible to find out what JRadioButton was previously selected? In other words, if I selected another JRadioButton, is it possible to write code that determines which JRadioButton was previously selected before selecting the current JRadioButton?
public class Drinks extends JPanel implements ActionListener{
double drinksPrice = 2.10;
double noDrinks = 0;
static String selectedDrink;
JRadioButton btnPepsi = new JRadioButton("Pepsi"); //add a button to choose different drinks
JRadioButton btnMtDew = new JRadioButton("Mt Dew");
JRadioButton btnDietPepsi= new JRadioButton("Diet Pepsi");
JRadioButton btnCoffee = new JRadioButton("Coffee");
JRadioButton btnTea = new JRadioButton("Tea");
JRadioButton btnNone = new JRadioButton("None");
JLabel lblDrinksHeading = new JLabel("Choose a drink (each drink is $2.10):");
ButtonGroup drinksButtonGroup = new ButtonGroup();
private static final long serialVersionUID = 1L;
public Drinks(){
setLayout(new FlowLayout()); //Using GridLayout
btnPepsi.setActionCommand(btnPepsi.getText()); //set the ActionCommand to getText so I can retrieve the name for the receipt
btnMtDew.setActionCommand(btnMtDew.getText());
btnDietPepsi.setActionCommand(btnDietPepsi.getText());
btnCoffee.setActionCommand(btnCoffee.getText());
btnTea.setActionCommand(btnTea.getText());
btnNone.setActionCommand(btnNone.getText());
drinksButtonGroup.add(btnPepsi);
drinksButtonGroup.add(btnMtDew);
drinksButtonGroup.add(btnDietPepsi);
drinksButtonGroup.add(btnCoffee);
drinksButtonGroup.add(btnTea);
drinksButtonGroup.add(btnNone);
btnNone.setSelected(true); //set default to "none"
btnPepsi.addActionListener(this);
btnMtDew.addActionListener(this);
btnDietPepsi.addActionListener(this);
btnCoffee.addActionListener(this);
btnTea.addActionListener(this);
btnNone.addActionListener(this);
add(lblDrinksHeading);
add(btnPepsi);
add(btnDietPepsi);
add(btnMtDew);
add(btnCoffee);
add(btnTea);
add(btnNone);
repaint();
revalidate();
selectedDrink = drinksButtonGroup.getSelection().getActionCommand();
//add the drink price to totalPrice, it is adding it every time though, even if its none
/*if(drinksButtonGroup.getSelection() == btnNone){
MenuFrame.totalPrice += 0;
}
else{
MenuFrame.totalPrice += drinksPrice;
}
*/
// buttonGroup1.getSelection().getActionCommand()
//String selectedDrink = drinksButtonGroup.getSelection().toString();
//class
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source == btnNone) {
MenuFrame.totalPrice += 0;
TaxAndGratuityFrame.subtotalTextField.setText("$" + MenuFrame.totalPrice);
TaxAndGratuityFrame.subtotalVariable = MenuFrame.totalPrice;
TaxAndGratuityFrame.taxVariable = TaxAndGratuityFrame.subtotalVariable * TaxAndGratuityFrame.TAX_RATE;
TaxAndGratuityFrame.taxTextField.setText("$" + TaxAndGratuityFrame.taxVariable);
Receipt.receiptTotal.setText("Total: $" + (MenuFrame.totalPrice));
Receipt.receiptsubtotal.setText("Subtotal: " + (TaxAndGratuityFrame.subtotalVariable));
}
else {
MenuFrame.totalPrice += drinksPrice;
TaxAndGratuityFrame.subtotalTextField.setText("$" + MenuFrame.totalPrice);
TaxAndGratuityFrame.subtotalVariable = MenuFrame.totalPrice;
TaxAndGratuityFrame.taxVariable = TaxAndGratuityFrame.subtotalVariable * TaxAndGratuityFrame.TAX_RATE;
TaxAndGratuityFrame.taxTextField.setText("$" + TaxAndGratuityFrame.taxVariable);
Receipt.receiptTotal.setText("Total: $" + (MenuFrame.totalPrice));
Receipt.receiptsubtotal.setText("Subtotal: " + (TaxAndGratuityFrame.subtotalVariable));
}
}
Edit: I'll be more specific. I am creating an "imaginary" restaurant program. In it, I list several drinks that have the same price (e.g. Pepsi: $2.10, Mountain Due: $2.10, etc). These listed drinks are JRadioButtons. Once a customer clicks one of these buttons to "order a drink", $2.10 will be added to a "total" variable. However, a problem occurs when a user wants to change there drink, because if they click a different JRadioButton, $2.10 will still be added to the "total" variable. I want to make it so that they can change there drink without adding $2.10 to the order every time.
I think the problem is at this line:
MenuFrame.totalPrice += drinksPrice;
Because "+=" increments a value by another value instead of simply adding two values.
So every time the user clicks on one of the radio buttons, it will continuously add 2.10 to your total value, whereas if you were you just say:
MenuFrame.totalPrice = MenuFrame.totalPrice + drinksPrice;
It will set your total price equal to the current total price plus the price of drinks, instead of adding 2.10 to the total value every time a button is pressed.
Perhaps I am misunderstanding the question, but I am thinking along the lines of creating a public variable, and then inside the action listeners updating the variable with the radio button that was just selected. When the selected event fires, you can look at the variable to see which radio button had last been selected, do what you want to about it, and then update it with the new radio button.
Related
Working on a school project, I am trying to get the action of clicking a button pull the selected index of a Combo Box string array, and associated that index with an int array so that a final price can be computed. Doesn't seem to work the price just remains at zero when button is pressed.
private final String[] deckArray = {"The Master
Thrasher ", "The Dictator", "The Street King"};
private final String[] trucksArray = {"7.75-inch
axle", "8-inch axle", "8.5-inch axle"};
private final String[] wheelsArray = {"51mm", "55mm",
"58mm", "61mm"};
private final int[] deckPrice = {60,45,50};
private final int[] trucksPrice = {35,40,45};
private final int[] wheelsPrice = {20,22,24,28};
comboDecks = new ComboBox();
comboDecks.getItems().addAll(deckArray);
comboTrucks = new ComboBox();
comboTrucks.getItems().addAll(trucksArray);
comboWheels = new ComboBox();
comboWheels.getItems().addAll(wheelsArray);
btnCalc = new Button("Calculate Total");
lblFinalPrice = new Label("Final Price:");
txtSubtotal = new Text("Subtotal: " + finalSubPrice);
txtTax = new Text("Tax:" + finalTaxPrice);
txtFinalPrice = new Text("Final Price: " +
finalTotalPrice);
EventHandler<ActionEvent> calcHandler = new
EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
finalDeckPrice = deckPrice[comboDecks.getSelectionModel().getSelectedIndex()];
finalTruckPrice = trucksPrice[comboTrucks.getSelectionModel().getSelectedIndex()];
finalWheelsPrice = wheelsPrice[comboWheels.getSelectionModel().getSelectedIndex()];
finalSubPrice = finalDeckPrice + finalTruckPrice + finalWheelsPrice;
finalTaxPrice = finalSubPrice * salesTax;
finalTotalPrice = finalSubPrice + finalTaxPrice;
}
};
You made the button, you made the event handler, but you never connected the event handler to the button. Same goes for the calculation and the label, you calculated but did not update the label with the calculated value.
Add the following line to your code after you create the handler.
btnCalc.setOnAction(calcHandler);
And add txtFinalPrice.setText(""+finalTotalPrice); after you finish calculations inside handle() method.
public void handle(ActionEvent actionEvent) {
...
finalTotalPrice = finalSubPrice + finalTaxPrice;
txtFinalPrice.setText("Final Price: " + finalTotalPrice);
}
Explanation (Abstract)
(1) When you create an Event Handler object you just wrote the code you want it to run but it won't run in serial as the code executes top to bottom, since as you said you want it to work when you click the button. So you have to let the Button know that when it gets clicked to execute this code. setOnAction() method takes as parameter an Event Handler object and executes it when some action happens to the Button, the action for the Button is when it gets clicked.
(2) Just by calculating the value, doesn't mean the Label knows that the value got calculated or something. The point where you calculating the price is the point that you have to tell to the Label take this value and use this as your content.
Suggestion
Event handlers, action events etc need a bit of good understanding to use them correctly. The baseline is that all of that work asynchronously and you gotta get at least the idea of it so you can understand the rest (no offense but from the question i believe you need some work on it).
Writing a program to increment a counter when a +1 button is pressed, then when the counter reaches a certain number, remove the +1 button and replace it with a +2 button and so on. I create both buttons at first but just set btnCount1 to setVisible(false). When the certain number passes, I make btnCount invisible and btnCount1 visible and increment by two from there. When it reaches 10 clicks, the btnCount disappears, but btnCount1 does not appear.
I have tried making an if(arg0.equals(btnCount1)), and incrementing by two from there. I tried putting the add(btnCount1) inside the else if statement to create it after the elseif condition is true.
public class AWTCounter extends Frame implements ActionListener
private Label lblCount;
private TextField tfCount;
private Button btnCount;
private Button btnCount1;
private int count = 0;
public AWTCounter() {
setLayout(new FlowLayout());
lblCount = new Label("Counter");
add(lblCount);
tfCount = new TextField(count + "",10);
tfCount.setEditable(false);
add(tfCount);
btnCount = new Button("Add 1");
btnCount1 = new Button("Add 2");
add(btnCount);
add(btnCount1);
btnCount1.setVisible(false);
btnCount.addActionListener(this);
btnCount1.addActionListener(this);
setTitle("AWT Counter");
setSize(500,500);
}
public static void main(String[]args) {
AWTCounter app = new AWTCounter();
}
public void actionPerformed(ActionEvent arg0) {
if(count <= 10) {
++count; //Increase the counter value
tfCount.setText(count + "");
}else if(count > 10) {
btnCount.setVisible(false);
btnCount1.setVisible(true);
count += 2;
tfCount.setText(count + "");
}
}
The better solution here is to just have one button object and a separate variable for the current increment amount. When you hit the required count, increase the increment amount and change the button's label to the new value.
There are also a few other things you could do better here.
Use String.valueOf() instead of int + "" for String representations of integers if you're not adding words before or after the integer.
Don't add obvious comments for code. (e.g. 'increment variable x', 'set textString to the new value')
Use descriptive names for method parameters and variables.
Use Labels instead of TextFields for text that doesn't need to be editable or selectable like counter displays.
I'd personally change the name of lblCount to something like lblTitle as well, since changing your tfCount to a Label would logically take up that name and lblTitle makes more sense.
Here's a better way to implement actionPerformed:
private int increment = 1;
private Label lblCount;
...
public void actionPerformed(ActionEvent ignore) {
if(count == 10) {
btnCount.setLabel("Add " + (++increment));
}
lblCount.setText(String.valueOf(count += increment));
}
I'm using JCheckBox to find what a costumer wants to buy, if the JCheckBox(hat) is selected then total += hatprice, but it's not updating the total.
My code :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class NgaFillimi extends JFrame implements ActionListener{
private JCheckBox hat;
private JLabel thetotal;
private int total = 0;
public NgaFillimi() {
Container c = getContentPane();
c.setLayout(new FlowLayout());
hat = new JCheckBox("hat");
thetotal = new JLabel("The total is " + total);
hat.addActionListener(this);
c.add(thetotal);
c.add(hat);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (hat.isSelected()) {
total += 50;
}
}
public static void main(String[] args) {
NgaFillimi gui = new NgaFillimi();
gui.setSize(300,200);
gui.setVisible(true);
gui.setDefaultCloseOperation(EXIT_ON_CLOSE);
gui.setTitle("GUI");
}
}
You're suffering from "magical thinking". Yes, the total variable is being
changed, but the JLabel's text is not going to magically change on its own just because total changes. You the coder have to change it yourself by re-calling thetotal.setText(...) within your actionPerformed method once total has been changed.
Why does your code not work? Because all the JLabel knows is that its text is set once to a String and that's it. The String object that it displays never changes (nor can it since Strings are immutable). Again, the only way for the JLabel to change its display is to explicitly call its setText method.
In addition, if you fixed your code so that the JLabel appropriately updates every time the JCheckBox is selected, it won't behave in a good way, since every time the JCheckBox is un-selected and then re-selected, total increments again, which doesn't seem right. Better to remove 50 when the JCheckBox is unselected and then add 50 back when it's selected.
I'm trying to what you said now that I fixed it, but it's getting negative, since I have a bunch of other JCheckBoxes
Then don't add/subtract but rather consider giving your gui a method, say called sumAllCheckBoxes() and have all the JCheckBox listeners call this method whether they are checked or unchecked. The method will zero out total -- total = 0;, and then go through all the JCheckBoxes, adding cost if the JCheckBox is checked, e.g.:
public void sumAllCheckBoxes() {
total = 0;
if (someCheckBox.isSelected()) {
total += someValue;
}
if (someOtherCheckBox.isSelected()) {
total += someOtherValue;
}
// .... etc...
// then set the text for theTotal here
}
At the end it sets the JLabel. The key is to think through what you want your code doing at each step of your program.
You haven't updated the actual JLabel. Rather, you updated the total variable. To update the JLabel, you would need code that says thetotal.setText("The total is " + total).
I'm writing a GUI Java program for student registration which will retrieve available classes from database, give the user an option to choose classes and then store this in DB.
What I'm trying to do and have so far achieved partial success, is this - I created a combo box with the available majors (got that from DB), retrieved the available classes for that major and displayed check boxes for these classes.
There are two issues with this code.
After selecting the major from combo box, the check boxes aren't displayed. They appear one by one only when I hover my cursor.
Once I change my major in the combo box, the check boxes are not updated, even though the console in eclipse says check boxes for newly selected major has been created.
ArrayList<JCheckBox> checkBoxes=new ArrayList<JCheckBox>();
//combox action listener below
public void actionPerformed(ActionEvent e)
{
//get all available classes for the selected major
avail_class = new String[count_class];
//get all available class ids
avail_classid = new String[count_class];
JCheckBox checkbox;
int xdim = 75;
for (int i = 0; i < count_class; i++)
{
checkbox = new JCheckBox(avail_classid[i] + "-" + avail_class[i]);
checkbox.setBackground(new Color(0, 255, 255));
checkbox.setBounds(183, xdim, 289, 23);
contentPane.add(checkbox);
checkBoxes.add(checkbox);
checkbox.setEnabled(true);
xdim = xdim + 50;
}
}
EDIT
For my second problem, I called repaint() and it worked. For the first one, I did the following:
if(flag < 0)
//flag will be raised whenever there is a change in the selected major. For ex, from web dev to data analytics
for(int i = 0; i < checkBoxes.size(); i++)
{
checkBoxes.get(i).setVisible(false);
System.out.println("old Checkboxes invisible!" + i);
}
you need to call repaint and revalidate function to the container that holds your check boxes to redraw it with the new check boxes .
I'm trying to work to display a number of jtextfield according to one of the given values in a combobox.
So, I will have a drop down menu with let's say 1 to 4. If the user selects number 3, 3 textfields will be displayed. I've created the jcombobox with a selection of numbers. But I'm not sure how to implement this. If I'm not mistaken I need to use
ItemEvent.SELECTED
I think I need to create a reference to the JTextField object that will be available to the JComboBox's itemListener object.
Any help would be greatly appreciated.
I've added this to my class :
// aOption is the combobox I declared
aOptionComboBox.setModel(new DefaultComboBoxModel(new String[]{"1","2","3"}));
public void itemStateChanged(ItemEvent event) {
String num = (String)aOptionComboBox.getSelectedItem();
int num1 = Integer.parseInt(num);
JTextField[] textfields = new JTextField[num1];
for (int i = 0; i < num1; i++)
{
textfields[i] = new JTextField("Field");
getContentPane().add(textfields[i]);
textfields[i].setBounds(200, 90, 100, 25);
}
}
am I on a right track?
use the getSelectedItem() on the combobox. This will either yield a string or an integer (depending on how you implemented it). Next use a for-loop to determine the amount of JTextField's and store them in an array.
int amount = myJComboBox.getSelectedItem();
JTextField[] textfields = new JTextField[amount];
for (int i = 0; i < amount; i++) {
textfields[i] = new JTextField("awesome");
this.add(textfields[i]);
}
this way you can easily store the textfields and add them to your panel.
Some added information.
The textfield-array must be accesible outside the eventListener, so you must implement it in your class. that way the whole class can use it.