无法在ActionListener

时间:2015-04-26 07:04:38

标签: java

我整个周末都被困在这里,我到处寻找,而不是单一的解决方案。感谢所有帮助。

    int iDayBirth = Integer.parseInt(jTextField_DoBDay.getText());
    int iMonthBirth = Integer.parseInt(jTextField_DoBMonth.getText());
    int iYearBirth = Integer.parseInt(jTextField_DoBYear.getText());

    int iDayCurrent = Integer.parseInt(jTextField_CdDay.getText());
    int iMonthCurrent = Integer.parseInt(jTextField_CdMonth.getText());
    int iYearCurrent = Integer.parseInt(jTextField_CdYear.getText());

    double iDaysAlive = 0;
    Calendar caBirthDate = new GregorianCalendar(iYearBirth, iMonthBirth - 1, iDayBirth);
    Calendar caCurrentDate = new GregorianCalendar(iYearCurrent, iMonthCurrent - 1, iDayCurrent);

    JButton btnCalculate = new JButton("Calculate");
    btnCalculate.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            iDaysAlive = (caCurrentDate.getTimeInMillis() - caBirthDate.getTimeInMillis());
            iDaysAlive = (iDaysAlive / (24 * 60 * 60 * 1000) + 1);
            // GET THE ERROR HERE: "Cannot refer to a non-final variable caBirthDate inside an inner class defined in a different method
            //get the same error for, caBirthDate and iDaysAlive
        }
    });
    btnCalculate.setFont(new Font("Calibri", Font.BOLD, 12));
    btnCalculate.setBounds(188, 187, 89, 23);
    frame.getContentPane().add(btnCalculate);

    jTextField_Result = new JTextField("Total Days Alive: " + iDaysAlive);
    jTextField_Result.setBounds(150, 233, 170, 20);
    frame.getContentPane().add(jTextField_Result);
    jTextField_Result.setColumns(10);

如果我将日历和整数变量移动到ActionListener中,那么我无法访问最终文本字段中的iDaysAlive变量。

3 个答案:

答案 0 :(得分:0)

如错误所示:

Cannot refer to a non-final variable caBirthDate inside an inner class defined in a different method

您需要声明变量final以便在ActionListener中访问它们:

final int CURR_X = redSquare.getX();

但要小心:

使变量最终意味着它可以/不会被程序修改。它允许编译器优化一些代码。 它还告诉任何读取程序的人变量是CONSTANTS。例如,在程序中,您可以将PI的值定义为常量,并在程序中使用该变量,而不是在3.14中键入...您需要具有该值的任何位置。

因此,一个好的解决方案是:

要创建一个类,实现 ActionListener类。然后,您可以让任何类访问所需的变量。

另一种可能的解决方案:

  1. 将所需的变量作为类变量包装在类中。
  2. 将此类中的变量声明为主类中的final。
  3. 然后使用其班级成员来满足您的需求
  4. 例如:

    class Wrapper {
      public int iDaysAlive;
    
      public Wrapper (int iDaysAlive){
        this.iDaysAlive = iDaysAlive;
      }
    }
    

    然后:

    int iDaysAlive = 0;
    final Wrapper w = new Wrapper(iDaysAlive);
    

    然后在ActionListener中:

    w.iDaysAlive = (caCurrentDate.getTimeInMillis() - caBirthDate.getTimeInMillis());
    

答案 1 :(得分:0)

解决方案是创建实现Action侦听器的类。然后你可以让tha类访问所需的变量:

class ActionHandler implements ActionListener {
 public ActionHandler (MainClass mainClass) {
    //now getters of the main class can be called 
 }
    public void actionPerformed(ActionEvent e) { }
}

答案 2 :(得分:0)

您声明了一个ActionListener的匿名类。有关oracle的文档,请参阅https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#accessing

  

匿名类无法访问其封闭范围内的局部变量,这些变量未被声明为最终或有效最终。

请参阅Why a non-final "local" variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?了解原因

适合您的情况: 1.声明iDaysAlive,caBirthDate,caCurrentDate以及您需要在类范围内的烦人类内访问的其他变量 2. refactor actionPerformed(ActionEvent e)调用处理程序方法

actionPerformed(ActionEvent e) {
     handleEvent(e);
}