简体   繁体   English

无法在ActionListener外部访问这些变量

[英]Can't access these variables outside the ActionListener

I have been stuck on this all weekend, i have looked everywhere and not a single solution. 我整个周末都被困住了,我到处都是,没有一个单一的解决方案。 All help is appreciated. 感谢所有帮助。

    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);

If i move the calender and integer variable to inside the ActionListener then i can't access the iDaysAlive variable in the final textfield. 如果将calender和integer变量移至ActionListener内,则无法在最终文本字段中访问iDaysAlive变量。

As the error suggests: 如错误所示:

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

You need to declare the variables final inorder to access them inside the ActionListener : 您需要声明变量final以便在ActionListener访问它们:

final int CURR_X = redSquare.getX();

But be careful: 不过要小心:

Making a variable final means that it can/will not be modified by the program. 将变量定为final意味着程序可以/不会对其进行修改。 It allows the compiler to optimize some of the code. 它允许编译器优化某些代码。 Also it tells anyone reading the program the variables are CONSTANTS. 它也告诉任何阅读程序的变量都是常量。 For example in a program you would define the value of PI as a constant and use that variable in your program instead of typing in 3.14... everywhere you needed to have the value. 例如,在程序中,您将PI的值定义为常量,并在程序中使用该变量,而不是在需要该值的任何地方键入3.14...。

For this reason a good solution would be: 因此,一个好的解决方案是:

To create a class the implements ActionListener class. 要创建一个类,需要实现 ActionListener类。 Then you can have any class access to the variables needed. 然后,您可以对所需的变量进行任何类访问。

Another possible solution: 另一个可能的解决方案:

  1. To wrap the needed variables inside a class as class variables. 将所需的变量包装在类中作为类变量。
  2. Declare a variable from this class as final inside your main class. 在主类中声明一个此类的变量作为最终变量。
  3. Then use its class members to suit your needs 然后使用其班级成员来满足您的需求

for example: 例如:

class Wrapper {
  public int iDaysAlive;

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

Then: 然后:

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

Then in ActionListener: 然后在ActionListener中:

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

A solution is to create class the implements Action listener. 一种解决方案是创建实现Action侦听器的类。 Then you can give tha class access to the variable needed: 然后,您可以授予tha类访问所需变量的权限:

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

You declared an anonymous class of ActionListener. 您声明了ActionListener的匿名类。 Refer to https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#accessing for oracle's documentation: 请参阅https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#accessing了解oracle的文档:

An anonymous class cannot access local variables in its enclosing scope that are >not declared as final or effectively final. 匿名类无法在其封闭范围内访问未声明为final或实际上不是final的局部变量。

Refer to Why a non-final "local" variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can? 请参阅为什么不能在内部类内部使用非最终的“局部”变量,而可以在封闭类中使用非最终的字段? for why 为什么

A work-around for your situation: 1. declare iDaysAlive, caBirthDate, caCurrentDate and other variables you need to access inside the annoymous class in the class scope 2. refactor actionPerformed(ActionEvent e) to call a handler method 针对您的情况的变通方法:1.声明需要在类范围内的匿名类内部访问的iDaysAlive,caBirthDate,caCurrentDate和其他变量2.重构actionPerformed(ActionEvent e)以调用处理程序方法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM