'Open a JPanel after pressing a button in a JFrame [duplicate]
I know this question has been asked, but I failed to find a solution.
I created a JFrame
for Login and I want after the button "Cont Nou" is pressed to open a new window with the jpanel for the new account, but do not know how to da the initial frame to disappear and appear the frame with the jpanel.Do you have any idea? thank you!
This is what i did till now:
This is the JFrame
with the login:
public class LogIn extends JFrame implements ActionListener{
private JLabel labelEmail;
private JLabel labelParola;
private JTextField textFieldEmail;
private JPasswordField textFieldParola;
private JButton buttonLogin;
private JButton buttonContNou;
public LogIn (){
super();
this.setSize(400,200);
this.setTitle("Login");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setResizable(false);
this.setupComponents();
}
private void setupComponents(){
labelEmail = new JLabel("Email: ");
labelParola = new JLabel("Parola: ");
textFieldEmail = new JTextField();
textFieldParola = new JPasswordField();
buttonContNou = new JButton("Cont Nou");
buttonLogin = new JButton("Login");
labelEmail.setBounds(30,30,50,20);
labelParola.setBounds(30,70,50,20);
textFieldEmail.setBounds(100,30,185,20);
textFieldParola.setBounds(100,70,185,20);
buttonContNou.setBounds(185,110,100,20);
buttonLogin.setBounds(100,110,75,20);
buttonLogin.addActionListener(this);
buttonContNou.addActionListener(this);
this.add(labelEmail);
this.add(labelParola);
this.add(textFieldEmail);
this.add(textFieldParola);
this.add(buttonLogin);
this.add(buttonContNou);
}
public static void main(String[] args){
LogIn login= new LogIn();
login.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(buttonLogin)){
boolean toateDateleOk =true;
textFieldEmail.setBackground(Color.WHITE);
textFieldParola.setBackground(Color.WHITE);
if(textFieldEmail.getText().length()==0){
textFieldEmail.setBackground(Color.RED);
toateDateleOk =false;
}
if(textFieldParola.getPassword().length==0){
textFieldParola.setBackground(Color.RED);
toateDateleOk =false;
}
if(!toateDateleOk)
return ;
else
System.out.println("Incepe Procesul de logare");
if(e.getSource().equals(buttonContNou)){
//this.dispose();
//dispose();
//new NewAccountPanel().setVisible(true);
//new secondTab().show();
}
}
}
}
Solution 1:[1]
Let's start with, you should avoid, wherever possible, extending directly from a top level container, like JFrame
. This ties you down to a single use component, you couldn't, for example, re-use the login controls in another window (as part of a large component hierarchy) or within an applet context. You're also not adding any new functionality to the class itself.
You should also limit the number of windows you are push onto your user, as it can become confusing quickly. Take a look at The Use of Multiple JFrames, Good/Bad Practice? for more details.
Instead, you should consider using a MVC (Model-View-Controller) design to reduce the amount of coupling between classes and exposure of your components to unwarrented/undesirable modifications.
Contract (view)
Lets start by defining the contracts, this defines what each element in the process can is expected to do and the information which is passed around
View
This defines the core functionality of each view in your application. Each view can have a controller (as defined by C
) and is expected to provide a JComponent
as the base representation, which is used to physically add the view to the Container
public interface View<C> {
public JComponent getView();
public void setController(C controller);
public C getController();
}
LoginView
This defines what information the login view is expected to provide, in this example, we provide the username and password information as well as a means by which the controller can tell the view that the login attempt failed. This allows the view to reset the view and display an error message if required
public interface LoginView extends View<LoginController> {
public String getUserName();
public char[] getPassword();
public void loginFailed(String errorMessage);
}
LoginController
This defines the expected actions a controller for the login view can expected to occur, this are called by the view to tell the controller it should do something...
public interface LoginController {
public void performLogin(LoginView view);
public void loginCanceled(LoginView view);
}
ApplicationView
I've not provided an example of this, but you can imagine that you'd need to provide the details you might like to provide for interested parties to extract details from the view.
Implementation
LoginPane
This is the basic LoginView
implementation...
public class LoginPane extends JPanel implements LoginView {
private JTextField userName;
private JPasswordField password;
private JButton okButton;
private JButton cancelButton;
private LoginController controller;
public LoginPane() {
setLayout(new GridBagLayout());
userName = new JTextField(10);
password = new JPasswordField(10);
okButton = new JButton("Ok");
cancelButton = new JButton("Cancel");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = GridBagConstraints.WEST;
add(new JLabel("User name: "), gbc);
gbc.gridy++;
add(new JLabel("Password: "), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 2;
add(userName, gbc);
gbc.gridy++;
add(password, gbc);
gbc.gridwidth = 1;
gbc.gridy++;
add(okButton, gbc);
gbc.gridx++;
add(cancelButton, gbc);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
getController().performLogin(LoginPane.this);
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
getController().loginCanceled(LoginPane.this);
}
});
}
@Override
public String getUserName() {
return userName.getText();
}
@Override
public char[] getPassword() {
return password.getPassword();
}
@Override
public void loginFailed(String errorMessage) {
JOptionPane.showMessageDialog(this, errorMessage, "Login failed", JOptionPane.ERROR_MESSAGE);
}
@Override
public void setController(LoginController controller) {
this.controller = controller;
}
@Override
public JComponent getView() {
return this;
}
@Override
public LoginController getController() {
return controller;
}
}
ApplicationPane
The basic application View
public class ApplicationPane extends JPanel implements View {
public ApplicationPane() {
setLayout(new GridBagLayout());
add(new JLabel("Welcome to my awesome application"));
}
@Override
public JComponent getView() {
return this;
}
@Override
public void setController(Object controller) {
// What ever controller you want to use...
}
@Override
public Object getController() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
#Putting it all together...
We'll, that's a lot of info, but how do you use it?
public class CoreApplicationCPane extends JPanel {
protected static final String LOGIN_VIEW = "View.login";
protected static final String APPLICATION_VIEW = "View.application";
private LoginView loginView;
private ApplicationPane applicationView;
private CardLayout cardLayout;
public CoreApplicationCPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
loginView = new LoginPane();
applicationView = new ApplicationPane();
add(loginView.getView(), LOGIN_VIEW);
add(applicationView.getView(), APPLICATION_VIEW);
loginView.setController(new LoginController() {
@Override
public void performLogin(LoginView view) {
// Do what ever you need to do...
String name = view.getUserName();
char[] password = view.getPassword();
//...
cardLayout.show(CoreApplicationCPane.this, APPLICATION_VIEW);
}
@Override
public void loginCanceled(LoginView view) {
SwingUtilities.windowForComponent(CoreApplicationCPane.this).dispose();
}
});
cardLayout.show(this, LOGIN_VIEW);
}
}
This is basically where everything gets plugged together. The LoginView
and ApplicationView
's are instantiated and added to the main view and the controller's are plugged in.
Take a look at:
for more details.
For a more detail example, take a look at Java and GUI - Where do ActionListeners belong according to MVC pattern?
Solution 2:[2]
You know how you called
setVisible(true);
?
Try
setVisible(false);
Solution 3:[3]
You can use the JFrame's dispose()
method to close the current JFrame.
Also, you can instantiate a new JFrame and set it visible:
JFrame newFrame = new JFrame();
newFrame.setVisible(true);
this.dispose();
(UPDATE) NOTICE: Although I mentioned the how to do it (as this was asked), this does not mean it is the best approach to follow. This is considered a bad practice, as having multiple JFrames can be a nightmare for maintainance and is considered user unfriendly. For more information, look here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | arcy |
Solution 3 | Community |