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).
Related
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 have made this application:
For example when I click on the clear button when the counter JLabel (pointsAvailable) is 19 then the counter JLabel goes blank as expected, however when I start adding points again it starts from 19 not 40 as set on the start. I would like to make it to reset back to 40 instead of just making it blank
Code for the clear button
private void JButtonActionPerformed(java.awt.event.ActionEvent evt) {
speedPoints.setText("");
attackPoints.setText("");
defencePoints.setText("");
powerPoints.setText("");
agilityPoints.setText("");
focusPoints.setText("");
availablePoints.setText("");
}
Code for Jlabel counter
public class addingPointsUI extends javax.swing.JFrame {
int pointsAvailable=40;
int speed=0;
int power=0;
int focus=0;
int agility=0;
int defence=0;
int attack=0;
Code for buttons +/-: to allow me to add or decrease value "example power - button"
private void powerMinusActionPerformed(java.awt.event.ActionEvent evt) {
if (power > 0 ){
if (pointsAvailable <= 0) {
JOptionPane.showMessageDialog(null, "You are out of available points");
return;
}
power = power - 1;
pointsAvailable = pointsAvailable +1;
availablePoints.setText(String.valueOf(pointsAvailable));
powerPoints.setText(String.valueOf(power));
}else {
JOptionPane.showMessageDialog(null,"You cannot take anymore points from Power");
}
}
Thank your for your kind replies.
Use a JSpinner with SpinnerNumberModel. Change the value of the model. The component will update and further changes will act on the current value of the model.
I can quickly think of two solutions:
1. In the event handler of your clear button include the following:
private void JButtonActionPerformed(ActionEvent evt){
...
pointsAvailable=40;
speed=0;
power=0;
focus=0;
agility=0;
defence=0;
attack=0;
}
This will reset all of your stats.
2. Or you can add an if statement to the listeners of every button that adds or subtracts a stat that will check if the specific statistic is empty. For example, for the speed buttons the code would look like so:
if (speedPoints.getText() == ""){
pointsAvailable += speed;
speed = 0;
}
Found my own solution on google:
private void ClearActionPerformed(java.awt.event.ActionEvent evt) {
speedPoints.setText(String.valueOf(0));
powerPoints.setText(String.valueOf(0));
agilityPoints.setText(String.valueOf(0));
defencePoints.setText(String.valueOf(0));
focusPoints.setText(String.valueOf(0));
attackPoints.setText(String.valueOf(0));
availablePoints.setText(String.valueOf(40));
}
Works perfectly
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.
I am notdoing a school project, so please do not be alarmed. I am doing some private programming to brush up. My program, a program of type .java, creates a form that asks for the boundaries and quantities of a lottery-drawing activity and acts on the generating based on the input.
Here's my problem. On the WIndows 2000 computer where I coded the program, shows itself, perfectly. That's only half the story. When I tried to put it on another computer, the program shows a blank window; it compiles and runs, but it shows a blank window. Now, I do consider version numbers to be factors, so I will provide the versions and ask for confirmation if those are the root of the evil.
On my original computer, which is Windows 2000, the version is 1.6.0_31-b05. The other computer, which is Windows 7 dual-booted with Linux Mint 17.2, is running 1.8.0_60-b27 and 1.8.0_00 respectively.
My program is not finished yet, but I'll worry about that later. What I'm hoping to do now is to get the program, such as it is, to run on the platforms of all my computers. Since Java is known for its portability, I expect it to run on all my computers. Is that a misconception?
Anyways, here's the code:
//Import class libraries
import javax.swing.*;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.event.*;
public class Lotterygui //Begin class
{
//VARIABLES FOR DATA COLLECTION
private JTextField lowerRange; //Lowest number
private JTextField higherRange; //Highest number
private JTextField quantity; //How many numbers to generate
private JTextArea displayArea; //What to display when the program is in use
//ADD WARNING CONSTANT FOR INVALID INPUT
private final String WARNING = "Please fill out valid data "
+ "and not leave anything out. "
+ "Also,do not enter any "
+ "zeroes.";
public Lotterygui()
{
//GUI CONFIGURATION
//Frame settings
JFrame jfrFrame = new JFrame("Lottery Program");
jfrFrame.setSize(300,400);
jfrFrame.setLocationRelativeTo (null);
jfrFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrFrame.setVisible(true);
jfrFrame.setResizable(false);
//Panel to hold the user input controls in place
JPanel jplInputs = new JPanel();
jplInputs.setLayout(new GridLayout(4, 2));
//CREATE INPUT CONTROLS
//Lowest range
JLabel jlblLowerRange = new JLabel("Lowest");
lowerRange = new JTextField();
//Highest range
JLabel jlblHigherRange = new JLabel("Highest");
higherRange = new JTextField();
//Quantity
JLabel jlblQuantity = new JLabel("Quantity");
quantity = new JTextField();
//Buttons and their respective action associations
//Generate numbers button
JButton jbtnGenerate = new JButton("Generate");
ActionListener alGenerate = new listenGenerate();
jbtnGenerate.addActionListener(alGenerate);
//Reset all values button
JButton jbtnReset = new JButton("Reset");
ActionListener alReset = new listenReset();
jbtnReset.addActionListener(alReset);
//ADD CONTROLS TO FORM
jplInputs.add(jlblLowerRange);
jplInputs.add(lowerRange);
jplInputs.add(jlblHigherRange);
jplInputs.add(higherRange);
jplInputs.add(jlblQuantity);
jplInputs.add(quantity);
jplInputs.add(jbtnGenerate);
jplInputs.add(jbtnReset);
//CREATE DISPLAY AREA AND ADD
//The display area used for showing generated numbers
displayArea = new JTextArea();
displayArea.setLineWrap(true);
displayArea.setText(WARNING);
//The control that sets autoscrolling for the display area
JScrollPane jspDisplayArea = new JScrollPane(displayArea);
jfrFrame.add(jspDisplayArea);
//Add the JPanels to the window
jfrFrame.add(jplInputs, BorderLayout.NORTH);
jfrFrame.add(jspDisplayArea);
}//END lotteryGUI constructor
//MAIN Method
public static void main (String[] args)
{
//CALL UP lotteryGUI CLASS
new Lotterygui();
}//END Main method
//GENERATE BUTTONS ACTION
private class listenGenerate implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//DECLARE VARIABLES
int low; //Lowest number
int high; //Highest number
int qty; //How many numbers
try //Monitor the input of above variables in the form
{
low = Integer.parseInt(lowerRange.getText());
high = Integer.parseInt(higherRange.getText());
qty = Integer.parseInt(quantity.getText());
}
catch (NumberFormatException nfe)
{
//RESET ALL FORM VALUES
reset();
//RESET VARIABLE VALUES
low = 0;
high = 0;
qty = 0;
}//END format errors try-catch
//CHECK IF PROGRAM CAN CONTINUE
if (low != 0 || high != 0 || qty != 0) //If valid
{
//Action pending
displayArea.setText("Generate here - incomplete");
}
else //If there are more one or more errors in the input
{
//ISSUE WARNING
JOptionPane.showMessageDialog(null, WARNING);
}//END IF continue CHECK
}//END actionPerformed method
}//END listenGenerate class
I've been looking up and down at the code. Can this that I did not reference any of the layouts outlined in import? I know it's not JPanel as I did try that can still the problem existed. Anything that will help me will be appreciated. Thank you.
You're calling
jfrFrame.setVisible(true);
first and then adding a bunch of components to the JFrame, and that's backwards and can result in a GUI that does not render components until it is resized or minimized and restored. In fact try this -- run your program, then minimize the blank GUI and restore it, and I'll bet you'll see your components.
I suggest that you swap this order around -- call jfrFrame.setVisible(true); last after adding everything to the GUI.
I have a JFrame with small squares set as background. Squares are pictures.
Amount of squares depends on JFrame size, so I use ArrayList and I add JLabels to JFrame using:
for(int i = 0; i < squares.size(); i++){
add(squares.get(i));
}
I want to write a method so when mouse enters square it would change its color.
I have implemented MouseListener. However this does not work(it works with normal JLabels):
ArrayList<JLabel> squares = new ArrayList<JLabel>();
.
.
.
#Override
public void mouseEntered(MouseEvent e) {
Object source = e.getSource();
if(source == squares){
System.out.println("AAA");
}
if(source == squares.get(0)){
System.out.println("BBB");
}
}
My question: How do I get element out of ArrayList, so I could set it equal to source and if its equal to source do something?
However this does not work(it works with normal JLabels):
This statement does not make sense. A JLabel is a JLabel. As long as you add the label to the frame it should work. The fact that you created an ArrayList as well doesn't affect how the label works on the frame.
Object source = e.getSource();
You already have the source, so all you need to do is cast it to a JLabel:
JLabel enteredLabel = (JLabel).getSource();
enteredLabel.doSomething(...)