Java 使用ActionListener通过几何计算器输出计算结果

Java 使用ActionListener通过几何计算器输出计算结果,java,swing,awt,Java,Swing,Awt,我正在构建一个几何计算器,但是很难实现ActionListener。我在Oracle网站上找到了一些示例代码,并对其进行了修改,以适应我正在尝试的视觉概念 我仔细检查了我的代码,寻找拼写错误和不正确的标点符号,要么改正了,要么没有发现任何突出我的地方。我研究了有关堆栈溢出和教科书中的类似问题,我的代码在结构上与示例中所做的类似。我已经在下面粘贴了代码的相关部分 Eclipse向我提供以下错误消息:线程“AWT-EventQueue-0”java.lang中出现异常。错误:未解决的编译问题: Ca

我正在构建一个几何计算器,但是很难实现ActionListener。我在Oracle网站上找到了一些示例代码,并对其进行了修改,以适应我正在尝试的视觉概念

我仔细检查了我的代码,寻找拼写错误和不正确的标点符号,要么改正了,要么没有发现任何突出我的地方。我研究了有关堆栈溢出和教科书中的类似问题,我的代码在结构上与示例中所做的类似。我已经在下面粘贴了代码的相关部分

Eclipse向我提供以下错误消息:线程“AWT-EventQueue-0”java.lang中出现异常。错误:未解决的编译问题: CalcButtonListenerA无法解析为类型,我不明白为什么会发生这种情况。我认为这些行将负责解析类型:

            `calcButton1 = new JButton("Calculate");
    calcButton1.addActionListener(new CalcButtonListenerA());`
其他相关代码如下

package layout;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GeometryCalculator implements ItemListener {
    JPanel calcTools; 
    final static String CIRCLEPANEL = "Circle Calculator";
    final static String RECTANGLEPANEL = "Rectangle Calculator";
    final static String TRIANGLEPANEL = "Triangle Calculator";


    private JLabel messageLabel1;
    private JLabel messageLabel2;
    private JLabel messageLabel3;
    private JLabel radiusLabel;
    private JLabel baseLabel;
    private JLabel heightLabel;
    private JLabel lengthLabel;
    private JLabel widthLabel;
    private JLabel circleAreaLabel;
    private JLabel circumferenceLabel;
    private JLabel rectanglePerimeterLabel;
    private JLabel rectangleAreaLabel;
    private JLabel triangleAreaLabel;
    private JTextField choiceTextField;
    private JTextField radiusTextField;
    private JTextField baseTextField;
    private JTextField heightTextField;
    private JTextField lengthTextField;
    private JTextField widthTextField;
    private JButton calcButton1;
    private JButton calcButton2;
    private JButton calcButton3;

    JTextField rectanglePerimeterField = new JTextField(15);
    JTextField rectangleAreaField = new JTextField(15);
    JTextField triangleAreaField = new JTextField(15);



    public void addComponentToPane(Container pane) {

        JPanel comboBoxPane = new JPanel(); 
        String comboBoxItems[] = { CIRCLEPANEL, RECTANGLEPANEL, TRIANGLEPANEL };
        JComboBox cb = new JComboBox(comboBoxItems);
        cb.setEditable(false);
        cb.addItemListener(this);
        comboBoxPane.add(cb);

        //Create the "calcTools".
        JPanel calcTool1 = new JPanel();
        radiusLabel = new JLabel("Radius");
        circumferenceLabel = new JLabel("Circumference");
        circleAreaLabel = new JLabel("Area");
        radiusTextField= new JTextField(10);
        messageLabel1 = new JLabel("Let's make some circle calculations.");
        final JTextField circumferenceField = new JTextField(15);
        circumferenceField.setEditable(false);
        final JTextField circleAreaField = new JTextField(15);
        circleAreaField.setEditable(false);
        calcButton1 = new JButton("Calculate");
        calcButton1.addActionListener(new CalcButtonListenerA());

        calcTool1.add(messageLabel1);
        calcTool1.add(radiusLabel);
        calcTool1.add(radiusTextField);
        calcTool1.add(circumferenceLabel);
        calcTool1.add(circumferenceField);
        calcTool1.add(circleAreaLabel);
        calcTool1.add(circleAreaField);
        calcTool1.add(calcButton1);

        class CalcButtonListenerA implements ActionListener
        {

            public void actionPerformed(ActionEvent e)
            {
                String radius;
                double circumference;
                double circleArea;

                radius = radiusTextField.getText();
                circumference = 2*Double.parseDouble(radius)*Math.PI;
                String circ = String.valueOf(circumference);
                circleArea = Double.parseDouble(radius)* Double.parseDouble(radius)*Math.PI; 
                String area = String.valueOf(circleArea);

                circumferenceField.setText(circ);
                circleAreaField.setText(area);          

            }
        }

        JPanel calcTool2 = new JPanel();
        messageLabel2 = new JLabel("Let's make some rectangle calculations.");
        lengthLabel = new JLabel("Length");
        widthLabel = new JLabel("Width");
        lengthTextField = new JTextField(10);
        widthTextField = new JTextField(10);
        rectanglePerimeterLabel = new JLabel("Perimeter");
        rectangleAreaLabel = new JLabel("Area");
        JTextField rectanglePerimeterField = new JTextField(15);
        rectanglePerimeterField.setEditable(false);
        JTextField rectangleAreaField = new JTextField(15);
        rectangleAreaField.setEditable(false);
        JButton calcButton2 = new JButton("Calculate");

        calcTool2.add(messageLabel2);
        calcTool2.add(lengthLabel);
        calcTool2.add(lengthTextField);
        calcTool2.add(widthLabel);
        calcTool2.add(widthTextField);
        calcTool2.add(rectanglePerimeterLabel);
        calcTool2.add(rectanglePerimeterField);
        calcTool2.add(rectangleAreaLabel);
        calcTool2.add(rectangleAreaField);
        calcTool2.add(calcButton2);


        JPanel calcTool3 = new JPanel();
        messageLabel3 = new JLabel("Let's make some triangle calculations");
        baseLabel = new JLabel("Base");
        heightLabel = new JLabel("Height");
        baseTextField = new JTextField(10);
        heightTextField = new JTextField(10);
        triangleAreaLabel = new JLabel("Area");
        triangleAreaField = new JTextField(15);
        triangleAreaField.setEditable(false);
        JButton calcButton3 = new JButton("calculate");

        calcTool3.add(messageLabel3);
        calcTool3.add(baseLabel);
        calcTool3.add(baseTextField);
        calcTool3.add(heightLabel);
        calcTool3.add(heightTextField);
        calcTool3.add(triangleAreaLabel);
        calcTool3.add(triangleAreaField);
        calcTool3.add(calcButton3);



        calcTools = new JPanel(new CardLayout());
        calcTools.add(calcTool1, CIRCLEPANEL);
        calcTools.add(calcTool2, RECTANGLEPANEL);
        calcTools.add(calcTool3, TRIANGLEPANEL);

        pane.add(comboBoxPane, BorderLayout.PAGE_START);
        pane.add(calcTools, BorderLayout.CENTER);
    }

    public void itemStateChanged(ItemEvent evt) {
        CardLayout cl = (CardLayout)(calcTools.getLayout());
        cl.show(calcTools, (String)evt.getItem());
    }


    private static void createAndShowGUI() {

        JFrame frame = new JFrame("Geometry Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        GeometryCalculator demo = new GeometryCalculator();
        demo.addComponentToPane(frame.getContentPane());


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

    public static void main(String[] args) {

        try {

            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }

        UIManager.put("swing.boldMetal", Boolean.FALSE);


        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

不要在方法中定义方法

使用这样的匿名类(更干净):


编译错误只是说,此时编译器不知道
CalcButtonListenerA
的意思。您在方法
addComponentToPane
中定义了类
CalcButtoListenera
,但是定义放在用法之后,因此此时类尚未定义,这在某种程度上等同于变量的情况,您无法执行以下操作:

int y = x + 5; //what is x?
int x = 10; //even if it's defined below, compiler error
您可以通过以下几种方式正确执行此操作:

  • 在方法中将其定义为“本地类”,但在使用之前:

    public void addComponentToPane(Container pane) {
        class CalcButtonListenerA implements ActionListener
        {
            //...
        }
        //...
        calcButton1.addActionListener(new CalcButtonListenerA());
    }
    
  • 在类GeometryCalculator中定义,而不是在方法中定义:

    public class GeometryCalculator implements ItemListener {
    
        public void addComponentToPane(Container pane) {
    
            //...
            calcButton1.addActionListener(new CalcButtonListenerA());
        }
    
        private class CalcButtonListenerA implements ActionListener
        {
            //...
        }
    }
    
  • 将其定义为一个匿名类,如果您不想在任何其他actionListener中使用该代码,这是一种紧凑的方法

    public void addComponentToPane(Container pane) {
        //...
        calcButton1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                //the actionPerformed code of CalcButtonListenerA
            }
        });
    }
    

如果这是一个非常重要的类,您也可以将其放在自己的文件中,并将其导入此处。

问题在哪里?@Sergiy我为不清楚而道歉。Eclipse向我提供以下错误消息:线程“AWT-EventQueue-0”java.lang中出现异常。错误:未解决的编译问题:CalcButtonListenerA无法解析为类型感谢您彻底分解了我的选项。问题已经解决了,但这对我在未来的项目中思考是非常好的。@kikiwelsh很高兴我能帮上忙!
public void addComponentToPane(Container pane) {
    //...
    calcButton1.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            //the actionPerformed code of CalcButtonListenerA
        }
    });
}