I am brand new to coding and this community has been very beneficial. This is my first time asking after reading different related questions I still don't seem to get it.
So, when I hit loginButton (setup in another class called LoginPage) it shows the "welcomePage" card, the welcomePage (card) has two buttons backButton and drawButton. Jpanel is the main container, added to a Jframe (also set up in class LoginPage). I am trying to paint and setbackground(color); on the welcomePage when a drawButton is clicked, but for some reason, the paint shows and disappears immediately while the background changes. Also when I put the paintComponent(welcomepanel.getGraphics()); method in a while loop without "break;", the paint does stay but the window gets stuck (doesn't close) and the background doesn't change (why is that?).
public class WelcomePage implements ActionListener{
JPanel welcomepanel = new JPanel();
JButton backButton = new JButton("Back");
JButton drawButton = new JButton("DRAW");
//Other codes elided
WelcomePage (String userID) {
drawButton.addActionListener(this);
backButton.setBounds(50, 100, 100, 25);
backButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoginPage.cardLayout.show(LoginPage.container, "loginpage");
}
});
drawButton.setBounds(0, 0, 100, 25);
drawButton.addActionListener(this);
welcomepanel.setSize(420, 420);
welcomepanel.add(backButton); //backs to the previous page (card)
welcomepanel.add(drawButton);
} //end constructor
public void paintComponent(Graphics g) {
g = welcomepanel.getGraphics();
g.drawString("CHASE", 200, 90);
g.setColor(Color.yellow);
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (row % 2 == col % 2) {
g.setColor(Color.GRAY);
} else
g.setColor(Color.RED);
g.fillRect(100 + col * 40, 100 + row * 40, 40, 40);
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("DRAW")) {
welcomepanel.setBackground(Color.black);
paintComponent(welcomepanel.getGraphics());
// while (true) {paintComponent(welcomepanel.getGraphics());}
welcomepanel.repaint();
welcomepanel.revalidate();
}
}
} //end class WelcomePage
What am I doing wrong?
I've tried extending the welcompage to Jpanel and directly drawing on it and that works but I instead want a particular instance of Jpanel (welcomepanel) to get the drawing.
My second question is, I want to ultimately create a GUI that "teachers" would use to add Quiz type questions and Students would use to take those quizzes, I'd determine who is who based on their login credentials or combo box selection or something. Is it a good idea to navigate through the different activities using CardLayout and with Jpanel as the main container or should I use something else?
Update:Update this time I used anonymous class in actionperformed method but when the drawButton is clicked still doesn't draw:
WelcomePage.java:
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
public class WelcomePage implements ActionListener {
JPanel welcomepanel = new JPanel();
JLabel welcomeLabel = new JLabel("QUIZ");
JButton backButton = new JButton("Back");
JButton drawButton = new JButton("DRAW");
JButton whiteButton = new JButton("white");
WelcomePage(String userID) {
///super();
// welcomepanel.setLayout(new GroupLayout(welcomepanel));
welcomeLabel.setBounds(100, 0, 200, 35);
welcomeLabel.setFont(new Font(null, Font.BOLD, 25));
welcomeLabel.setText("Welcome " + userID);
backButton.setBounds(50, 100, 100, 25);
// backButton.setHorizontalAlignment(JButton.SOUTH);
backButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loginPage.cardLayout.show(loginPage.container, "loginpage");
}
});
drawButton.setBounds(0, 0, 100, 25);
drawButton.addActionListener(this);
whiteButton.setBounds(200, 200, 100, 25);
whiteButton.addActionListener(this);
welcomepanel.setSize(420, 420);
welcomepanel.add(welcomeLabel);
welcomepanel.add(backButton);
welcomepanel.add(drawButton);
welcomepanel.add(whiteButton);
}
/**
* Invoked when an action occurs.
*
* @param e the event to be processed
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("DRAW")) {
welcomepanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("CHASE", 200, 90);
g.setColor(Color.yellow);
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (row % 2 == col % 2) {
g.setColor(Color.GRAY);
} else
g.setColor(Color.RED);
g.fillRect(100 + col * 40, 100 + row * 40, 40, 40);
}
}
}
};
welcomepanel.setBackground(Color.black);
welcomepanel.repaint();
welcomepanel.revalidate();
} else if (e.getActionCommand().equals("white")) {
welcomepanel.setBackground(Color.blue);
}
}
}
I created a new instance of the welcomepage in the actionperformed method in the following class and called welcomepages' welcomePanel to get a "welcome page" that greats the user. All I wanted is when I hit the drawButton the paintcomponent method to get executed as defined in welcomepages' actionperformed method. I wanted to explore the possibility of using different Jpanels declared in a single class. Feel free to comment on any other part of my code as well.
loginPage.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
public class loginPage implements ActionListener {
static JFrame frame = new JFrame();
static JPanel container = new JPanel();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
JButton loginButton = new JButton("Login");
JButton resetButton = new JButton("Reset");
JButton logoutButton = new JButton("Logout");
JButton hoemButton = new JButton("HOME");
static CardLayout cardLayout = new CardLayout();
JTextField userIDField = new JTextField();
JPasswordField userPasswordField = new JPasswordField();
JLabel IdLabel = new JLabel("userID:");
JLabel userPasswordLabel = new JLabel("password:");
JLabel messageLabel = new JLabel();
HashMap<String, String> loginInfo = new HashMap<>(); //to hold the copy of the constructors' parameter value so it can be globally available for methods such as getters
loginPage(HashMap<String, String> copyOfLoginInfo) {
this.loginInfo = copyOfLoginInfo; //@parra value copied into a global variable
// this.container.setLayout(new BorderLayout());
container.setLayout(cardLayout);
IdLabel.setBounds(50, 100, 75, 25);
IdLabel.setLocation(50, 100);
userIDField.setBounds(125, 100, 200, 25);
userPasswordLabel.setBounds(50, 150, 75, 25);
userPasswordField.setBounds(125, 150, 200, 25);
loginButton.setBounds(125, 200, 100, 25);
loginButton.setFocusable(false);
loginButton.addActionListener(this);
hoemButton.setBounds(0, 0, 100, 25);
logoutButton.setBounds(310, 0, 100, 25);
logoutButton.setFocusable(false);
resetButton.setBounds(220, 200, 100, 25);
resetButton.setFocusable(false);
resetButton.addActionListener(this);
messageLabel.setBounds(125, 250, 250, 35);
messageLabel.setFont(new Font(null, Font.ITALIC, 25));
setPanel1();
panel1.add(loginButton);
panel1.add(resetButton);
panel1.add(hoemButton);
panel1.add(IdLabel);
panel1.add(userIDField);
panel1.add(userPasswordLabel);
panel1.add(userPasswordField);
panel1.add(messageLabel);
panel2.add(logoutButton);
setPanel2();
//add panals to the JPanel container with their identifier string
container.add(panel1, "loginPageage");
container.add(panel2, "logoutpage");
//this show method of cardLayout determines which panel..
// ...should be shown at the start of the application, identifier string is used here
cardLayout.show(container, "loginPageage");
//when login is clicked go to logout page (panal 2)
hoemButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(container, "logoutpage");
}
});
//when logout is clicked go back to loginPageage
logoutButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(container, "loginPageage");
}
});
//add container to Jframe:
frame.add(container);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(520, 520);
frame.setLocationRelativeTo(null); //sets the window in the middle of pc screen
//frame.setLayout(null); //this will make the cardlayout not show!!
frame.setVisible(true);
frame.setResizable(false);
}
/**
* Invoked when an action occurs.
*
* @param e the event to be processed
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == resetButton) {
userIDField.setText("");
userPasswordField.setText("");
}
if (e.getSource() == loginButton) {
String userID = userIDField.getText(); //gets user id text
String password = String.valueOf(userPasswordField.getPassword()); //gets the password from the password field and then converts it into a string
if (loginInfo.containsKey(userID)) {
if (loginInfo.get(userID).equals(password)) {
messageLabel.setForeground(Color.cyan);
messageLabel.setText(String.format("%30s", "Login SUCCESSFUL"));
WelcomePage w = new WelcomePage(userID);
//add instance of welcome page to the Jpanel container, and
container.add(w.welcomepanel, "WelcomeP");
cardLayout.show(container, "WelcomeP");
}
else {
messageLabel.setForeground(Color.red);
messageLabel.setText(String.format("%34s", "Invalid password!"));
}
} else {
messageLabel.setForeground(Color.red);
messageLabel.setText(String.format("%33s", "username not found!"));
}
}
}
void setPanel1() {
panel1.setLayout(new BorderLayout()); //equivalent to setManaged(false)??
panel1.setBounds(100, 100, 420, 420);
panel1.setBackground(new Color(150, 150, 150));
panel1.setBorder(BorderFactory.createBevelBorder(1));
}
void setPanel2(){
panel2.setLayout(new BorderLayout()); //equivalent to setManaged(false)??
panel2.setSize(420, 420);
panel2.setBackground(Color.green);}
}
UserInfo.java
import java.util.HashMap;
public class UserInfo {
HashMap<String, String> credentials = new HashMap<>();
UserInfo () {
credentials.put("user", "user");
}
protected HashMap<String, String> getCredentials() {
return credentials;
}
}
Main.java:
public class Main {
public static void main(String[] args) {
UserInfo users = new UserInfo();
loginPage loginP = new loginPage(users.getCredentials());
}
}

super.paintComponent(g);as the first statement in the overriden method. Also keep your questions to 1 per post, as asking multiple because less useful to others - David KroukamppaintComponentis not even overriding a valid method as your class is not aJPanelId suggest posting a minimal reproducible example for better help sooner. - David Kroukamp