DanielLu
DanielLu

Reputation: 23

How do you call a method from a class depending on what button is chosen?

The code below calculates the tax of an income input that is given through a JTextField. Each respective class (ResidentTaxPayer, ForeignResidentTaxPayer and WorkingTaxPayer) has its own method called calcTax().

The code below works up until the ActionListener for Calculate. In this action a string - StringIncome - is declared and initialized to an income value which is a JTextField. This JTextField is then converted to a double and assigned to a double value: totalIncome. Finally JOptionPane.showMessageDialog() is used to call the calcTax() method in the ResidentTaxPayer class. This returns a correct calculation.

The code up to this point is fine if only dealing with a single Taxpayer instance. However I have designed my program to use JButtons to choose from a list (not actually an ArrayList just so no one gets confused) of 3 possible choices. I chose to ask my question like this to show everyone the sort of code I want/input for all buttons.

My code after the ActionListener for Calculate only changes the message title for whatever button is chosen.

My question for you all is how do I code my program so that, for instance if the residentTaxPayerButton is chosen then the income is passed to the calcTax() method in that class and the appropriate calculations are done. But if the NonResidentTaxPayer button is chosen then the income is passed so its calcTax() method and the appropriate calculations are done.

Would the isSelect() method be appropriate here? Or would you need to call the method from the button listeners?

Just in case anyone asks, the respective code for the classes are irrelevent to the question. This is an issue with my GUI and not the taxpayer classes. Those classes work fine without the use of the GUI.


import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

class personalFrame {

    private String title = "";
    JTextField Income = new JTextField(10);
    private JFrame personalTaxFrame = new JFrame("Personal Tax Calculator");
    JButton Calculate = new JButton("Calculate");

    ButtonGroup Tax = new ButtonGroup();
    JRadioButton residentTax = new JRadioButton("Resident Tax");
    JRadioButton nonresidentTax = new JRadioButton("Non-Resident Tax");
    JRadioButton workingTax = new JRadioButton("Working Tax");

    public personalFrame() {

        personalTaxFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        personalTaxFrame.setSize(300, 100);
        personalTaxFrame.setVisible(true);
        personalTaxFrame.setLayout(new FlowLayout());

        personalTaxFrame.add(new JLabel("Total Income "));

        personalTaxFrame.add(Income);
        personalTaxFrame.add(Calculate);

        Tax.add(residentTax);
        personalTaxFrame.add(residentTax);

        Tax.add(nonresidentTax);
        personalTaxFrame.add(nonresidentTax);

        Tax.add(workingTax);
        personalTaxFrame.add(workingTax);

        Calculate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                String stringIncome = Income.getText();
                Double totalIncome = Double.parseDouble(stringIncome);
                JOptionPane.showMessageDialog(null, "Tax payable is A$" + ResidentTaxPayer.calcTax(totalIncome), title, JOptionPane.INFORMATION_MESSAGE);

            }

        });

        residentTax.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ie) {

                title = "Resident Tax";


            }
        });

        nonresidentTax.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ie) {

                title = "Non-resident Tax";

            }
        });

        workingTax.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ie) {

                title = "Working Tax";

            }
        });

    }
}

common interface


public interface TaxProfile {

    double getPayableTax();
    public String getTaxID();
    public String getNameOfTaxPayer();
}
    TaxProfile taxProfile;//create TaxProfileField


    residentTax.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ie) {
                taxProfile.getPayableTax(); //use field to call interface method
                title = "Resident Tax";

            }
        });

Upvotes: 0

Views: 75

Answers (1)

Fildor
Fildor

Reputation: 16059

There are different options here, working on a common base, which is:

  • Make a new Field on the Form class that holds a representation of the desired calculation option.
  • Make the choice-Buttons' listeners set that field to the respective represention
  • Make the Calculate listener evaluate the field and call the corresponding method.

Your teacher discouraged using enum, which I can understand, but they gave you a really poor reason. Anyway, technically, you could use an enum.

You could use a numerical value ( for example int ). In that case, I'd introduce some well documented const int values to represent the choice. But that would be very similar to using an enum, so they are likely to disapprove of this, too.

There are even more, but the option I'd prefer would be:

Have all your calculation classes implement a common interface. Then make the field (let's call it calculationChoice) have that interface type.

The choice-buttons' listeners would then just set for example calculationChoice = new ResidentTaxPayer(); and the Calculation listener wouldn't even have to care anymore, it would just call taxAmount = calculationChoice.calcTax(amount);


Unrelated: try using BigDecimal instead of double and document results with different inputs for both types and compare them. You'd be surprised, I guess.


Example

public class HelloWorld{

     public static void main(String []args){
         // ResidentTaxPayer is-a TaxProfile, so we can assign it like so:
         TaxProfile taxProfile = new ResidentTaxPayer();
        System.out.println("Payable Amount in US $: " + taxProfile.getPayableTaxAmount(5432.10));
         // so is NonResidentTaxPayer, so this is also valid
         taxProfile = new NonResidentTaxPayer();
        System.out.println("Payable Amount in US $: " + taxProfile.getPayableTaxAmount(5432.10)); // different result!
     }
}

public interface TaxProfile{
    double getPayableTaxAmount( double income );
}

public class ResidentTaxPayer implements TaxProfile {
    public double getPayableTaxAmount( double income )
    {
        double tax = 0.0;
        // calculate tax
        tax = income * 0.18; // Just a dummy
        return tax;
    }
}

public class NonResidentTaxPayer implements TaxProfile {
    public double getPayableTaxAmount( double income )
    {
        double tax = 0.0;
        // calculate tax
        tax = income * 0.24; // Just a dummy
        return tax;
    }
}

Upvotes: 1

Related Questions