I've been working with JFrame recently and had a simple login, register and popup frames work when I had them in a single class. I wanted to make it nicer and not all packed inside one class so I made a class for the frames, buttons, panels, variables and the main class. My problem is that The frames themselves are working fine and loading up and displaying, but the ActionListeners on the buttons aren't working at all. Nothing changes when I hit a button etc. I'm fairly new to Java and very new to the JFrames and JButtons. Is there anything I can be doing to make this simpler or make my code look better? The code will be in each seperate class:
Right now nothing is running, even the "This is running" in main before it's supposed to call LoginScreen() doesn't run. I'm not sure what I changed to make this happen?
Main Class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class myGame {
public static void main(String[] args){
buttons myButtons = new buttons();
frames myFrames = new frames();
panels myPanels = new panels();
variables myVariables = new variables();
System.out.println("This is running");
myFrames.loginScreenFrame();
System.out.println("This is also running"); }
}
frames class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class frames{
public JFrame loginScreenFrame(){
variables myVariables = new variables();
panels myPanels = new panels();
buttons myButtons = new buttons();
myVariables.loginFrame.setSize(300,125);
myVariables.loginFrame.setLocation(550,250);
myVariables.loginFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Container content = myVariables.loginFrame.getContentPane();
content.add(myPanels.loginScreenPanel(), BorderLayout.CENTER);
content.add(myPanels.loginScreenButtonsPanel(), BorderLayout.SOUTH);
myButtons.registerButton.addActionListener(myButtons.registerListener);
myVariables.loginFrame.setVisible(true);
return myVariables.loginFrame;
}
public JFrame registerFrame(){
variables myVariables = new variables();
panels myPanels = new panels();
myVariables.registerFrame.setSize(400,125);
myVariables.registerFrame.setLocation(550,250);
myVariables.registerFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = myVariables.registerFrame.getContentPane();
content.add(myPanels.registerScreenPanel(), BorderLayout.CENTER);
content.add(myPanels.registerScreenButtonsPanel(), BorderLayout.SOUTH);
myVariables.registerFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
myVariables.registerFrame.setVisible(true);
return myVariables.registerFrame;
}
}
Buttons Class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class buttons{
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JButton cancelButton = new JButton("Cancel");
JButton checkUsernameButton = new JButton("Check Username");
public void actionListeners(){
variables myVariables = new variables();
frames myFrames = new frames();
panels myPanels = new panels();
ActionListener cancelListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
frames myFrames = new frames();
myFrames.registerFrame().dispose();
}
};
ActionListener usernameListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
}
};
ActionListener passwordListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
}
};
ActionListener passwordCheckListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
}
};
ActionListener checkUsernameListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
variables myVariables = new variables();
if (myVariables.usernameAndPassword.get(myVariables.username) == null){
JPanel okButtonPanel = new JPanel();
final JFrame invalidUsernameFrame = new JFrame();
invalidUsernameFrame.setSize(400,75);
invalidUsernameFrame.setLocation(550,250);
JButton okButton = new JButton("Ok");
Container invalidUsernameContainer = invalidUsernameFrame.getContentPane();
okButtonPanel.add(okButton);
JLabel invalidUsernameLabel = new JLabel();
invalidUsernameLabel.setText(" Username is Available!");
invalidUsernameContainer.add(invalidUsernameLabel);
invalidUsernameContainer.add(okButtonPanel, BorderLayout.SOUTH);
invalidUsernameFrame.setVisible(true);
ActionListener okListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
myGame mainClass = new myGame();
invalidUsernameFrame.dispose();
}
};
okButton.addActionListener(okListener);
}
else{
JPanel okButtonPanel = new JPanel();
final JFrame invalidUsernameFrame = new JFrame();
invalidUsernameFrame.setSize(400,75);
invalidUsernameFrame.setLocation(550,250);
JButton okButton = new JButton("Ok");
Container invalidUsernameContainer = invalidUsernameFrame.getContentPane();
okButtonPanel.add(okButton);
JLabel invalidUsernameLabel = new JLabel();
invalidUsernameLabel.setText(" Username is not Available");
invalidUsernameContainer.add(invalidUsernameLabel);
invalidUsernameContainer.add(okButtonPanel, BorderLayout.SOUTH);
invalidUsernameFrame.setVisible(true);
ActionListener okListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
myGame mainClass = new myGame();
invalidUsernameFrame.dispose();
}
};
okButton.addActionListener(okListener);
}
}
};
ActionListener registerListener = new ActionListener(){
public void actionPerformed(ActionEvent ae){
frames myFrames = new frames();
myFrames.registerFrame();
}
};
cancelButton.addActionListener(cancelListener);
myVariables.usernameField.addActionListener(usernameListener);
myVariables.passwordField.addActionListener(passwordListener);
myVariables.passwordCheckField.addActionListener(passwordCheckListener);
registerButton.addActionListener(registerListener);
checkUsernameButton.addActionListener(checkUsernameListener);
}
}
Panels Class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class panels{
buttons myButtons = new buttons();
frames myFrames = new frames();
variables myVariables = new variables();
public JPanel loginScreenPanel(){
buttons myButtons = new buttons();
frames myFrames = new frames();
variables myVariables = new variables();
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,2));
panel.add(new JLabel("Username:"));
panel.add(myVariables.usernameFrame);
panel.add(new JLabel("Password:"));
panel.add(myVariables.passwordFrame);
return panel;
}
public JPanel loginScreenButtonsPanel(){
JPanel buttons = new JPanel();
buttons.add(myButtons.loginButton);
buttons.add(myButtons.registerButton);
buttons.add(myButtons.cancelButton);
return buttons;
}
public JPanel registerScreenPanel(){
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,2));
panel.add(new JLabel("Username:"));
panel.add(myVariables.usernameField);
panel.add(new JLabel("Password:"));
panel.add(myVariables.passwordField);
panel.add(new JLabel("Re-Enter Password:"));
panel.add(myVariables.passwordCheckField);
return panel;
}
public JPanel registerScreenButtonsPanel(){
JPanel buttons = new JPanel();
buttons.add(myButtons.registerButton);
buttons.add(myButtons.checkUsernameButton);
buttons.add(myButtons.cancelButton);
return buttons;
}
}
New Code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ExampleGame {
java.util.HashMap<String,char[]> usernamesAndPasswords = new java.util.HashMap<String,char[]>();
public static void main(String[] args) {
new ExampleGame();
}
public ExampleGame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
LoginPane pane = new LoginPane();
storeInfo info = new storeInfo();
int result = JOptionPane.showOptionDialog(null, pane, "Login", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, new String[]{"Login", "Cancel"}, 0);
if (result == 0) {
User user = pane.getUser();
// Perform the login...
usernamesAndPasswords = info.storeInfo(user.name, user.password, usernamesAndPasswords);
System.out.println("Name entered: " + user.name);
System.out.print("Password entered: ");
System.out.println(user.password);
System.out.println(usernamesAndPasswords.get(user.name));
}
}
});
}
public class LoginPane extends JPanel {
private JTextField userName;
private JPasswordField password;
public LoginPane() {
userName = new JTextField(10);
password = new JPasswordField(10);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel("Username:"), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(userName, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.fill = GridBagConstraints.NONE;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(password, gbc);
}
public User getUser() {
return new User(userName.getText(), password.getPassword());
}
}
public class User {
private String name;
private char[] password;
public User(String name, char[] password) {
this.name = name;
this.password = password;
}
}
public class storeInfo{
public java.util.HashMap storeInfo(String name, char[] password, java.util.HashMap <String, char[]> usernamesAndPasswords){
usernamesAndPasswords.put(name, password);
return usernamesAndPasswords;
}
}
}
I added a class to your example to get it to store the values in a HashMap, I'm wondering if I did this right or if there is some other better way to do it? Right now it does store the values in a HashMap, but it gives me a warning: Note: ExampleGame.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
I read up on the links you gave, some of it didn't make sense but I think for the most part it did. just before I start going to try and get this to work I want to make sure I did that HashMap right.
Also do I have your permission to use the code you made? I could make something similar myself but it probably wouldn't be as nice and clean.
Basically, you have a tightly coupled bowl of spaghetti which in it's current state, probably can't be untangled.
The main problem you have is the fact that you are creating new instance of
frames
,panels
,buttons
andvariables
all over the place. This means that from one part of your application to the next, they are all using their own instance of these classes, which don't relate to each other.The other problem is that many of these parts of the application actually shouldn't need direct access to the objects that you are try to access.
Instead, start by breaking down you application into usable components/elements, with defined responsibilities.
For example, the UI parts should gather information which is feed back into the system for processing. The processing layer shouldn't care where this information came from, only that it conforms to it's needs.
For example...
The following simply generates a login dialog which will return a
User
object which represents the username and password that the user typed in (this is a very basic example, so validation is light)The login dialog does not care about how the login process occurs, only it is only responsible for getting the information
Equally, no other part of the application needs access to the fields within the
LoginPane
, they should only care about the resultYou should take a look at the Model-View-Control pattern
Program to interface