Search code examples
javaswinguser-interfacejframejlabel

Can't change a JLabel across classes


I have a multi-class project involving some basic Java GUI. I am to create a loan calculator using 10 classes (6 of which are JPanel subclasses, a calculation class, a CombinedPanels class, a LoanCalculatorGUI class which creates instances of the CombinedPanels class and calculation class, and a driver). I have to make a reset button in one of the JPanel subclasses (ActionButtons) change a private JLabel in a different JPanel subclass (PaymentInformation). Here is the ActionButtons class:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class ActionButtons extends JPanel{
private JButton calc, reset, exit;
private JPanel actionButtons;
public ActionButtons(){
    PaymentInformation pi = new PaymentInformation();
    actionButtons = new JPanel(new GridLayout(1, 3, 20, 20));
    calc = new JButton("Calculate");
    reset = new JButton("Reset");
    exit = new JButton("Exit");
    actionButtons.add(calc);
    actionButtons.add(reset);
    actionButtons.add(exit);
    actionButtons.setBorder(BorderFactory.createTitledBorder("Action Buttons"));

    //Add ActionListeners
    calc.addActionListener(new ButtonListener());
    reset.addActionListener(new ButtonListener());
    exit.addActionListener(new ButtonListener());

}

public JPanel getGUI(){
    return actionButtons;
}



private class ButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent e) {
        PaymentInformation pi = new PaymentInformation();
        if(e.getActionCommand().equals("Exit")){
            System.exit(0);
        }
        if(e.getActionCommand().equals("Reset")){
            pi.changeValues("0.0");
        }
        if(e.getActionCommand().equals("Calculate")){
            //TODO DO CALCULATIONS 
        }

    }

  }
}

And the PaymentInformation class:

import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;


 @SuppressWarnings("serial")
 public class PaymentInformation extends JPanel{
//Declare variables
private JPanel payInfo;
private JLabel loanAmt, monthPay, totalPay, loanVal, monthVal, totalVal;

public PaymentInformation(){
    //Give panel layout
    payInfo = new JPanel(new GridLayout(3, 2));
    //Give titles, set alignment
    loanAmt = new JLabel("Total Loan Amount:  $", JLabel.LEFT);
    monthPay = new JLabel("Monthly Payment:  $", JLabel.LEFT);
    totalPay = new JLabel("Total Payment:  $", JLabel.LEFT);
    loanVal = new JLabel("5.0", JLabel.RIGHT);
    monthVal = new JLabel("0.0", JLabel.RIGHT);
    totalVal = new JLabel("0.0", JLabel.RIGHT);
    //Add stuff to JPanel
    payInfo.add(loanAmt);
    payInfo.add(loanVal);
    payInfo.add(monthPay);
    payInfo.add(monthVal);
    payInfo.add(totalPay);
    payInfo.add(totalVal);
    //Set border
    payInfo.setBorder(BorderFactory.createTitledBorder("Payment Information"));
}
//Method to get the JPanel
public JPanel getGUI(){
    return payInfo;
}

public void changeValues(String val){
    loanVal.setText(val);
 }
}

I'm trying to use the setValue method in PaymentInformation to change the text of the JLabel, but it stays the same (at "5.0") when the reset button is clicked. I'm not sure if this is needed, but the CombinedPanels class (takes all the JLabel subclasses and puts them into a JFrame) is here:

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class CombinedPanels extends JFrame{
public CombinedPanels(){
    setTitle("Auto Loan Calculator");
    setSize(700,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new BorderLayout());
    JPanel center = new JPanel(new GridLayout(2, 2, 20, 20));

    //Add other classes to this layout
    TitleBar tb = new TitleBar();
    add(tb.getGUI(), BorderLayout.NORTH);
    ActionButtons ab = new ActionButtons();
    add(ab.getGUI(), BorderLayout.SOUTH);
    //Add center JPanel to the center of BorderLayout
    add(center, BorderLayout.CENTER);
    //Continue with adding rest of classes to center JPanel
    PaymentInformation pi = new PaymentInformation();
    center.add(pi.getGUI());
    LoanTerm lt = new LoanTerm();
    center.add(lt.getGUI());
    FinancingInformation fi = new FinancingInformation();
    center.add(fi.getGUI());
    PriceWithOptions pwo = new PriceWithOptions();
    center.add(pwo.getGUI());
 }
}

Lastly, here is an image of the GUI: image.

It stays the same when reset is hit, even though the "5.0" JLabel should be changed to "0.0". The exit button, however, is functional.

Sorry for the wall of text, but this problem is driving me crazy. Any help or explanation is much appreciated. Thanks in advance.


Solution

  • You have 3 seperate instances of PaymentInformation. First one in the CombinedPanels class (the one that is displayed), one in the ActionButtons class and one in the ButtonListener class. You only change the values of the last one (which is invisible).

    So one solution would be to pass the (visible) pi of the CombinedPanels class to the ActionButtons class and call changeValues() on that instance and on no other.

    Relevant code (changed):

    public CombinedPanels() {
        setTitle("Auto Loan Calculator");
        setSize(700, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        JPanel center = new JPanel(new GridLayout(2, 2, 20, 20));
    
        // Add other classes to this layout
        PaymentInformation pi = new PaymentInformation();
        ActionButtons ab = new ActionButtons(pi);
        add(ab.getGUI(), BorderLayout.SOUTH);
        // Add center JPanel to the center of BorderLayout
        add(center, BorderLayout.CENTER);
        // Continue with adding rest of classes to center JPanel
        center.add(pi.getGUI());
        setVisible(true);
    }
    


    public class ActionButtons extends JPanel {
        private JButton calc, reset, exit;
        private JPanel actionButtons;
        PaymentInformation pi;
    
        public ActionButtons(PaymentInformation pi) {
            this.pi = pi;
            actionButtons = new JPanel(new GridLayout(1, 3, 20, 20));
            calc = new JButton("Calculate");
            reset = new JButton("Reset");
            exit = new JButton("Exit");
            actionButtons.add(calc);
            actionButtons.add(reset);
            actionButtons.add(exit);
            actionButtons.setBorder(BorderFactory.createTitledBorder("Action Buttons"));
    
            // Add ActionListeners
            calc.addActionListener(new ButtonListener());
            reset.addActionListener(new ButtonListener());
            exit.addActionListener(new ButtonListener());
    
        }
    
        public JPanel getGUI() {
            return actionButtons;
        }
    
        private class ButtonListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("Exit")) {
                    System.exit(0);
                }
                if (e.getActionCommand().equals("Reset")) {
                    pi.changeValues("0.0");
                }
                if (e.getActionCommand().equals("Calculate")) {
                    // TODO DO CALCULATIONS
                }
    
            }
    
        }
    }