3
votes

The following code continues to give me:

Cannot refer to a non-final variable textBoxPassword inside an inner class defined in a different method Login.java /ChurchWebLogin/src/com/gwt/churchweb/churchweblogin/client line 61

package com.gwt.churchweb.churchweblogin.client;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.Window;

public class Login extends Composite {

    public Login() {

        VerticalPanel verticalPanel = new VerticalPanel();
        initWidget(verticalPanel);
        verticalPanel.setSize("329px", "186px");

        Label lblNewLabel = new Label("Sign into your account");
        lblNewLabel.setStyleName("gwt-Login-SigninLabel");
        verticalPanel.add(lblNewLabel);

        FlexTable flexTable = new FlexTable();
        verticalPanel.add(flexTable);
        flexTable.setWidth("308px");

        Label lblNewLabel_1 = new Label("Username:");
        lblNewLabel_1.setStyleName("gwt-Label-Login");
        flexTable.setWidget(0, 0, lblNewLabel_1);
        lblNewLabel_1.setWidth("72px");

        TextBox textboxUsername = new TextBox();
        textboxUsername.setStyleName("gwt-LoginTextBox");
        flexTable.setWidget(0, 1, textboxUsername);
        textboxUsername.setWidth("204px");

        Label lblNewLabel_2 = new Label("Password:");
        lblNewLabel_2.setStyleName("gwt-Label-Login");
        flexTable.setWidget(1, 0, lblNewLabel_2);
        lblNewLabel_2.setWidth("66px");

        TextBox textBoxPassword = new TextBox();
        textBoxPassword.setStyleName("gwt-LoginTextBox");
        flexTable.setWidget(1, 1, textBoxPassword);
        textBoxPassword.setWidth("204px");
        flexTable.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_LEFT);
        flexTable.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_LEFT);

        CheckBox chckbxRememberMeOn = new CheckBox("Remember me on this computer");
        chckbxRememberMeOn.setStyleName("gwt-Checkbox-Login");
        flexTable.setWidget(2, 1, chckbxRememberMeOn);

        Button btnSignIn = new Button("Sign In");
        btnSignIn.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (textboxUsername.getText().length() == 0
                        || textBoxPassword.getText().length() == 0) {
                        Window.alert("Username or password is empty."); 
                    }
            }
        });

        btnSignIn.setStyleName("gwt-Login-SigninButton");
        flexTable.setWidget(3, 1, btnSignIn);



    }


}
3
In addition to the link, the 'accept' is a way of thanking those that help you. Clicking the up-arrow next to the posting is another way. This assumes the comment is useful... - Tony Ennis

3 Answers

6
votes
final TextBox textboxUsername = new TextBox();

and

final TextBox textBoxPassword = new TextBox();

should fix it.

Java requires references to variables from inner classes to be final variables (for reasons of concurrency management, I suppose).

4
votes

Local variables must be declared final if they are used in inner classes. You should write:

final TextBox textBoxPassword = new TextBox();
2
votes

Anonymous class instances should be able to access the surrounding scope’s local variables and parameters. However, an instance might outlive the method in which it was conceived (as a result of storing the instance’s reference in a field), and try to access local variables and parameters that no longer exist after the method returns.

Because Java cannot allow this illegal access, which would most likely crash the virtual machine, it lets an anonymous class instance only access local variables and parameters that are declared final. Upon encountering a final local variable/parameter name in an anonymous class instance, the compiler does one of two things:

  • If the variable’s type is primitive (int or double, for example), the compiler replaces its name with the variable’s read-only value.
  • If the variable’s type is reference (String, for example), the compiler introduces, into the classfile, a synthetic variable (a manufactured variable) and code that stores the local variable’s/parameter’s reference in the synthetic variable.