So the program is supposed to display the box like this (for LIST ALL TRANSACTIONS)
List all transactions: ID Type Amount
0 check 50.00
1 svr.chg 5.15
2 deposit 40.00
3 svr.chg 0.10

the box displays other transactions; it saves the old and new ones and display them one by one.
however, service charge doesn't show. instead, it keeps displaying the new ones and does not display the old ones.
do i have to make another method to do this? so this is how my program displays the box:

List all transactions:

ID Type Amount
0 check 50.00
0 svr.chg 5.25
1 deposit 40.00
1 svr.chg 5.20
(check amount 50 -> deposit amount -> 40)

also, i can't figure out how to display the number in order, instead of displaying in 0-0 1-1 2-2 and so on.
i know i have to add something more and edit here and there, but i just can't figure out.

here's my code:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import javax.swing.*;

public class CheckingAccountActions extends JPanel
{
    public static double initialBalance, transactionAmount;
    public static int firstTime = 0;
    public static int transactionCode;

    static CheckingAccount ca;
    static DecimalFormat dollar;
    static Transaction t;

    public static int check = 1, deposit = 2, serviceCharge = 3;

    private JLabel message;
    private JRadioButton transaction, listTrans, checks, deposits;

    ArrayList transList;

    public CheckingAccountActions()
    {
        initialBalance = initialBalance();
        ca = new CheckingAccount(initialBalance);
        dollar = new DecimalFormat("#,###.00");

        message = new JLabel ("Choose an action: ");
        message.setFont (new Font ("Helvetica", Font.BOLD, 24));

        transaction = new JRadioButton("Entering a Transaction");
        transaction.setBackground (Color.yellow);
        listTrans = new JRadioButton("Listing All Transactions");
        listTrans.setBackground(Color.yellow);
        checks = new JRadioButton("Listing All Checks");
        checks.setBackground(Color.yellow);
        deposits = new JRadioButton("Listing All Deposits");
        deposits.setBackground(Color.yellow);

        ButtonGroup group = new ButtonGroup();
        group.add(transaction);
        group.add(listTrans);
        group.add(checks);
        group.add(deposits);

        CheckingAccountActionsListener listener = new CheckingAccountActionsListener();
        transaction.addActionListener(listener);
        listTrans.addActionListener(listener);
        checks.addActionListener(listener);
        deposits.addActionListener(listener);

        add(message);
        add(transaction);
        add(listTrans);
        add(checks);
        add(deposits);

        setBackground(Color.YELLOW);
        setPreferredSize (new Dimension(250, 180));

    }

    private class CheckingAccountActionsListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            Object source = e.getSource();
            int i = 0;

            if(source==transaction)
            {
                transactionCode = getTransCode();

                switch(transactionCode)
                {
                case 1:
                    transactionAmount = getTransAmt();
                    processCheck(transactionAmount);               
                    break;

                case 2:
                    transactionAmount = getTransAmt();
                    processDeposit(transactionAmount);  
                    break;

                case 0:
                    JOptionPane.showMessageDialog(null, "Transaction: End\n"
                            + "Current Balance: $" + ca.getBalance() + "\n"
                            + "Total Service Charge: $" + dollar.format(ca.getServiceCharge()) + "\n"
                            + "Final Balance: $"
                            + dollar.format(ca.getBalance() - ca.getServiceCharge()));
                    break;

                default:
                    JOptionPane.showMessageDialog(null, "Invalid Choice. Enter Again.");

                }

                t = new Transaction(ca.getTransCount(),transactionCode,transactionAmount);
                ca.addTrans(t);
                JOptionPane.showMessageDialog(null, transList.get(i));  

            }
            else if(source==listTrans)
            {      

                int nums;
                double amount, service;
                String line, message = "";

                line = "List All Transactions" + "\n" 
                                        + "ID           Type       Amount" + "\n";

                for(int index = 0; index < ca.getSize(); index++)
                {               
                    nums = ca.getTrans(index).getTransNumber();  
                    switch(ca.getTrans(index).getTransId())
                    {
                        case 1:
                            message = "Check ";
                            break;
                        case 2:
                            message = "Deposits ";
                            break;
                        case 3:
                            message = "Svr.Chrg";
                            break;                          
                    }

                    amount = ca.getTrans(index).getTransAmount();
                    service = getServiceCharge();                  
                    line += String.format("%-10d  %7s %10.2f", nums,message,amount) + "\n" ;
                    line += String.format("%-10d  %7s %10.2f", nums,"Svr.Chrg",service) + "\n";
                }

                JTextArea text = new JTextArea(line);
                text.setBorder(null);
                text.setOpaque(false);
                text.setFont(new Font("Monospaced", Font.PLAIN, 14));
                JOptionPane.showMessageDialog(null, text);

            }
            else if(source==checks)
            {
                int nums = 0;
                double amount = 0.0;

                String line = "Checks made: \n" + "ID      \t Amount \n";

                for(int index = 0; index<ca.getSize(); index++)
                {
                    if(ca.getTrans(index).getTransId()==1)
                    {
                        nums = ca.getTrans(index).getTransNumber();
                        amount = ca.getTrans(index).getTransAmount();
                    }  

                    line+=String.format("%-10d  %10.2f", nums,amount)+"\n";
                }

                JTextArea text = new JTextArea(line);
                text.setBorder(null);
                text.setOpaque(false);
                text.setFont(new Font("Monospaced", Font.PLAIN, 14) );
                JOptionPane.showMessageDialog(null, text);
            }
            else if(source==deposits)
            {
                int nums = 0;
                double amount = 0.0;

                String line = "Deposits made: \n"+"ID     \t Amount \n";

                for(int index = 0; index<ca.getSize(); index++)
                {
                    if(ca.getTrans(index).getTransId()==2)
                    {
                        nums = ca.getTrans(index).getTransNumber();
                        amount = ca.getTrans(index).getTransAmount();
                    }

                    line+=String.format("%-10d  %10.2f", nums,amount)+"\n";
                }

                JTextArea text = new JTextArea(line);
                text.setBorder(null);
                text.setOpaque(false);
                text.setFont(new Font("Monospaced", Font.PLAIN, 14) );
                JOptionPane.showMessageDialog(null, text);
            }
        }
    }

    public static int getTransCode()
    {
        int code;
        String userInput;
        userInput=JOptionPane.showInputDialog("Enter the transaction code:\n"+
                "1) Check \n2) Deposit \n0) Exit the program");
        code=Integer.parseInt(userInput);
        return code;
    }

    public static double initialBalance()
    {    
        String userInput;
        userInput = JOptionPane.showInputDialog("Enter initial account balance :");
        initialBalance = Double.parseDouble(userInput);
        return initialBalance;
    }

    public static double getTransAmt()
    {
       double amount;
       String userInput;
       userInput=JOptionPane.showInputDialog("Enter the transaction amount: ");
       amount=Double.parseDouble(userInput);
       return amount;
    }

    public static double getServiceCharge()
    {
        double charge = 0.0;

        if(transactionCode==1)
        {
            charge = 0.15;  
        }
        else if(transactionCode==2)
        {
          charge = 0.10;
        }

        return charge;
    }

    public static double processCheck(double transAmt)
   {
       ca.setBalance(transAmt, 1);
       ca.setServiceCharge(0.15);

       if(ca.getBalance()<500)
       {
           if(firstTime==0)
           {
                ca.setServiceCharge(5.00);
                JOptionPane.showMessageDialog(null,"Transaction Amount: Check in Amount of $"
                     + transactionAmount + "\n" +"Current Balance: $" + dollar.format(ca.getBalance())
                     + "\n"+"Service Charge: Check --- charge $0.15 \n"
                     + "Service Charge: Below $500 --- charge $5.00\n" 
                     + "Total Service Charge: $" + dollar.format(ca.getServiceCharge()) );
                firstTime++;
           }

           JOptionPane.showMessageDialog(null,"Transaction Amount: Check in Amount of $"
                     + transactionAmount + "\n" +"Current Balance: $" + dollar.format(ca.getBalance())
                     + "\n"+"Service Charge: Check --- charge $0.15 \n"
                     + "Total Service Charge: $" + dollar.format(ca.getServiceCharge()) );           
       }

       else
       {
               JOptionPane.showMessageDialog(null,"Transaction Amount: Check in Amount of $"
                    + transactionAmount + "\n" + "Current Balance: $" 
                    + dollar.format(ca.getBalance())
                    + "\n"+"Service Charge: Check --- charge $0.15 \n"
                    + "Service Charge: None\n" + "Total Service Charge: $" 
                    + dollar.format(ca.getServiceCharge())  );

       }

        if(ca.getBalance()<0)
       {
           ca.setServiceCharge(10.00);
           JOptionPane.showMessageDialog(null, "Your balance is under $0.");
       }

       if(ca.getBalance()<50)
       {
           JOptionPane.showMessageDialog(null, "Your balance is under $50.");
       }

       return transAmt;
   }
   public static double processDeposit(double transAmt)
   {       
       ca.setBalance(transAmt, 2);
       ca.setServiceCharge(0.10);

       if(ca.getBalance()<500)
       {
           if(firstTime==0)
           {    
                ca.setServiceCharge(5.00);
                JOptionPane.showMessageDialog(null,"Transaction Amount: Deposit in Amount of "
                    + transactionAmount + "\n" +"Current Balance: " 
                    + dollar.format(ca.getBalance())
                    + "\n"+"Service Charge: Deposit --- charge $0.10 \n"
                    + "Service Charge: Below $500 --- charge $5.00\n" 
                    + "Total Service Charge: " + dollar.format(ca.getServiceCharge()));
           }

           JOptionPane.showMessageDialog(null,"Transaction Amount: Deposit in Amount of "
                    + transactionAmount + "\n" +"Current Balance: " 
                    + dollar.format(ca.getBalance())
                    + "\n"+"Service Charge: Deposit --- charge $0.10 \n"
                    + "Total Service Charge: $" + dollar.format(ca.getServiceCharge()));
       }
       else
       {
           JOptionPane.showMessageDialog(null,"Transaction Amount: Deposit in Amount of "
               + transactionAmount + "\n" +"Current Balance: " 
               + dollar.format(ca.getBalance())
               + "\n"+"Service Charge: Deposit --- charge $0.10 \n"
               + "Service Charge: None\n" + "Total Service Charge: $"
               + dollar.format(ca.getServiceCharge()));
       }

       if(ca.getBalance()<0)
       {
           ca.setServiceCharge(10.00);
           JOptionPane.showMessageDialog(null, "Your balance is under $0.");
       }

       if(ca.getBalance()<50)
       {
           JOptionPane.showMessageDialog(null, "Your balance is under $50.");
       }

       return transAmt;
   }

}

and here's my CheckingAccount class:

import java.util.ArrayList;

public class CheckingAccount 
{
    private double balance;
    private double totalServiceCharge;
    private ArrayList<Transaction> transList;
    private int transCount = 0;
    private int transSize = 0;

    public CheckingAccount(double initialBalance)
    {
        balance = initialBalance;
        totalServiceCharge = 0;
        transList = new ArrayList<Transaction>();
    }

    public double getBalance()
    {
        return balance;
    }

    public void setBalance(double transAmt, int tCode)
    {      
         if(tCode==1)
            balance-=transAmt;
         else if(tCode==2)
            balance+=transAmt;
    }

     public void setServiceCharge(double currentServiceCharge)
     {
        totalServiceCharge += currentServiceCharge;
     }

     public double getServiceCharge()
     {
         return totalServiceCharge;            
     }

    public void addTrans(Transaction newTrans)
    {
        transList.add(newTrans); 
        transCount++;
    }

    public int getTransCount()
    {
        return transCount;      
    }

    public Transaction getTrans(int i)
    {
        return transList.get(i);   
    }

    public int getSize()
    {
        transSize = transList.size();
        return transSize;
    }
}

Dani AI

Generated

The immediate NullPointerException is caused by the unused field transList in CheckingAccountActions: it is declared but never initialized or populated, while the code actually stores transactions in the CheckingAccount instance (ca). That explains the crash at the transList.get(i) line (as pointed out). Several related logic bugs explain the strange output (duplicate IDs, missing/incorrect service‑charge values):

  • Listing code prints a service charge line for every transaction by calling a global method at display time; that method returns the running total or a value derived from a changing static transactionCode, so the shown fee is wrong and varies with later actions.
  • The checks/deposits listings append the last seen values even when the current item isn't of that type, because the formatted append is outside the if that selects items.
  • Mixing UI and mutable static fields (transactionCode, transactionAmount) makes later listing depend on current state instead of stored transaction data.

Suggested fixes (minimal, focused changes):

  • Remove the unused transList field and use the account's list via ca.getTrans(index). Build the output from each Transaction object instead of re-calculating fees at display time.
StringBuilder sb = new StringBuilder();
sb.append("List all transactions:\nID  Type     Amount\n");
for (int i = 0; i < ca.getSize(); i++) {
    Transaction tr = ca.getTrans(i);
    String type = (tr.getTransId()==1) ? "check" : (tr.getTransId()==2) ? "deposit" : "svr.chrg";
    sb.append(String.format("%-3d  %-7s %8.2f%n", tr.getTransNumber(), type, tr.getTransAmount()));
}
JTextArea ta = new JTextArea(sb.toString());
  • Fix checks/deposits loops to append only when the if matches (no stale values):
for (int i = 0; i < ca.getSize(); i++) {
    Transaction tr = ca.getTrans(i);
    if (tr.getTransId() == 1) {
        sb.append(String.format("%-3d  %8.2f%n", tr.getTransNumber(), tr.getTransAmount()));
    }
}
  • Record service charges when processing a transaction (either extend Transaction to include a fee field, or create a separate Transaction with transId==3) instead of computing them later. Example (after processing the main transaction):
double fee = computedFee; // determined in processCheck/processDeposit
if (fee > 0.0) {
    ca.addTrans(new Transaction(ca.getTransCount(), 3, fee));
    ca.setServiceCharge(fee); // keep account total as before
}

Final notes: give Transaction a useful toString() for debugging, avoid mutable static UI state, and keep business logic (fee calculation and adding transactions) out of the display code. Small changes above will eliminate the NPE, stop the repeated/stale values, and make service charges show as stable entries in the transaction list.

Recommended Answers

All 7 Replies

The code is missing class definitions and will not compile.

here's the main:

import javax.swing.JFrame;

public class Main 
{   
    public static void main(String[] args) 
    {
        JFrame frame = new JFrame("Checking Account Actions");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        CheckingAccountActions panel = new CheckingAccountActions();
        frame.getContentPane().add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

transaction class:

public class Transaction 
{
    private int transNumber;
    private int transId;
    private double transAmt;

    public Transaction(int number, int id, double amount)
    {
       transNumber = number;
       transId = id;
       transAmt = amount;
    }

    public int getTransNumber()
    {
        return transNumber;
    }

    public int getTransId()
    {
        return transId;
    }

    public double getTransAmount()
    {
        return transAmt;
    }   

}

What errors do you get when you execute the program?
I got this:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at CheckingAccountActions$CheckingAccountActionsListener.actionPerformed(CheckingAccountActions.java:125)

same error except the line 108, not 125.

the line 108 is this in my program:

JOptionPane.showMessageDialog(null, transList.get(i));

What variable has a null value on that line? Probably transList. Print out its value to be sure.
Check the code to see why that variable does not have a valid non null value.

I tried by displaying in println but it doesn't show/display anything at all.
and what do you mean by 'non null' value?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.