Search code examples
javaswingscopejtextfield

Java Swing - How to get the value of text in a TextField from another class


Okay, beginner Java coder here. I'm trying to make a multi-purpose math utility application with Java Swing. One of the things I want it to do is be able to solve basic logarithms. I have the logic all down, but I'm having trouble with the outputting itself. I have a class (named "LogTab") and within it is a nested static class (named "LogPanel") for the actual input area. The button is outside the LogPanel class, and when I press it I want it to be able to take the values of the TextFields inside the LogTab (named "logBase" and "logNum"), calculate them, and send them to an output class. I have everything fine and working except for the part where I take the values from the TextFields.

Here's my code.

public class LogTab extends JPanel {

@SuppressWarnings("serial")
static class LogInput extends JComponent {

    public LogInput() {
        JComponent logInputPanel = new JPanel();
        setLayout(new GridBagLayout());

        JTextField logLbl = new JTextField();
        logLbl.setText("Log");
        logLbl.setEditable(false);
        JTextField logBase = new JTextField(1);
        JTextField logNum = new JTextField(5);

        GridBagConstraints lgc = new GridBagConstraints();

        lgc.weightx = 0.5;
        lgc.weighty = 0.5;

        lgc.gridx = 0;
        lgc.gridy = 0;
        add(logLbl,lgc);

        lgc.gridx = 1;
        lgc.gridy = 1;
        add(logBase,lgc);

        lgc.gridx = 2;
        lgc.gridy = 0;
        add(logNum,lgc);
    }
}

public LogTab() {
    // Set Layout
    setLayout(new GridBagLayout());

    // Create components
    JLabel promptLabel = new JLabel("Enter Logarithm: ");
    JButton solveButton = new JButton("Solve");
    final LogInput logInput = new LogInput();
    solveButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                double base = Double.valueOf(logInput.logBase.getText());
                double num = Double.valueOf(logInput.logNum.getText());
                OutputPanel.outputField.setText(String.valueOf(solve(base,num)));
            } finally {
            }

        }

    });



    // Code that adds the components, bla bla bla




}

public double solve(double base, double num) {
    return (Math.log(base)/Math.log(num));
}
}

When I try to compile this (through Eclipse, by the way), I get an error saying that "logBase/logNum can not be resolved or is not a field". How would I change this so that my ActionListener can get the text from the TextFields?

Thanks

P.S. This is my first question on Stack Overflow, so if I messed something up, tell me :)


Solution

  • Make logBase and logNum instance fields...

    static class LogInput extends JComponent {
    
        private JTextField logBase;
        private JTextField logNum;
    
        public LogInput() {
            JComponent logInputPanel = new JPanel();
            setLayout(new GridBagLayout());
    
            JLabel logLbl = new JLabel("Log");
            logBase = new JTextField(1);
            logNum = new JTextField(5);
    

    Now add some getters...

    public double getBase() {
        String text = logBase.getText();
        if (text.trim().isEmpty()) {
            text = "0";
        }
        return Double.parseDouble(text);
    }
    
    public double getNumber() {
        String text = logNum.getText();
        if (text.trim().isEmpty()) {
            text = "0";
        }
        return Double.parseDouble(text);
    }
    

    Now you can access the values of logBase and logNum from any instance of LogInput

    About this point, I'm thinking that either a JSpinner or JTextField would be a better idea, as they have the ability to validate the input themselves. See How to Use Spinners and How to Use Formatted Text Fields for more details