Hello,
I’m having trouble avoiding static ontexts when trying to cross-reference instances of different objects (like trying to modify a property of object A from object B ) in Vaadin.
The way I get around this in desktop applications is by instantiating the main class, but this can not be done in Vaadin (or can it?). Here’s my specific problem:
In my mainUI I have 3 buttons: one to login, one to logout, and one to register (for new users), and one label which is initially empty, that will display the user name, once logged in. For the login and register actions, I create a CustomComponent Class implementing the View interface, and I load them in a panel in the mainUI as needed. And then there’s another CustomComponent class which corresponds to the main application view.
The main UI:
[code]
public class MainUI extends UI{
Button bLogin;
Button bLogout;
Button bRegister;
Label lName;
@Override
protected void init(VaadinRequest request) {
bLogin = new Button("Login");
bLogout = new Button("Logout");
bRegister = new Button("Register");
lName = new Label();
bLogout.setVisible(false); //Logout button is not visible until user logs in.
getNavigator().addView(MainView.VIEW_NAME, MainView.class);
getNavigator().addView(Login.VIEW_NAME, Login.class);
getNavigator().addView(Register.VIEW_NAME, Register.class);
}
}
[/code]Now, when the user logs in, I want to
- Register the user name in a session property
- Make the Logout and Register buttons invisible
- Load the main view in mainUI
So in the Login class I have:
[code]
public class Login extends CustomComponent implements View {
Button bSubmmit; //Button to submit user and password
public Login(){ //Constructor
bSubmmit.addClickListener(new ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
/*
...Do stuff to validate credentials, etc...
*/
String userName = (...get user name from database...)
getSession().setAttribute("user", userName);
MainUI.bLogout.setVisible(true);
MainUI.bLogin.setVisible(false);
MainUI.bRegister.setVisible(false);
MainUI.lName.setValue(userName);
getUI().getNavigator().navigateTo(MainView.VIEW_NAME);
});
}
}
[/code]In order for this to work, I need to declare the Button and Label variables as static, otherwise I would get the error "
non-static variable bLogout can not be referenced from a static context
". This is because I am referencing the variables directly in MainUI and not in an instance of MainUI. (Can I instantiate the main UI? Should I?).
So now, in the main class I need to have:
[code]
public class MainUI extends UI{
static static Button bLogin;
static Button bLogout;
static Button bRegister;
static Label lName;
(etc…)
[/code]Now, when a new user registers, I want him to be automatically logged in with the credentials he provides, so instead of re-writing the same logic (hide Logind and Register buttons, etc.) in the Register class, I would like to implement a method which does this, and then simply call the method from the Login class once loged in, and from the Register class once registered.
Since I’m going to call this method both from Login and Register classes, lets say I create the method in the MainUI class. Again, since I have no instance of MainUI, I need to declare the method as static:
[code]
public class MainUI extends UI{
static static Button bLogin;
static Button bLogout;
static Button bRegister;
static Label lName;
(...DO STUFF...)
public static void setRegistered(boolean registered){
if (registered){
bLogin.setVisible(false);
bRegister.setVisible(false);
bLogout.setVisible(true);
lName.setText(getSession().getAttribute("user"));
getUI().getNavigator().navigateTo(MainView.VIEW_NAME);
}
}
(...DO STUFF...)
}
[/code]But now I get the error with the getSession() and the getUI() methods:
"
non-static method getSession() can not be referenced from a static context
".
Like I said, I usually instantiate the main class in desktop applications to deal with the static/non-static contexts. Should I instantiate the MainUI class? Otherwise, what is the best way around this in Vaadin?
Thanks.