Reputation: 1
Java newbie here. I'm in the process of building a mass mailer program for my business to use (services like Mailchimp charge up to $250 per blast of the size I need). Right now, I am in the process of designing a GUI for the program. All of the email-sending code is finished and tested.
I have JMenuItems using ActionListeners to call another class which facilitates switching of JPanels. I've heard CardLayout is a simpler way to do this, but I want to learn it from the ground up, so to speak, that way I can program more snippets to improve efficiency at the office.
In my code, the class MenuAction is setting the JPanel panel == the panel associated with each menu item, then running the changePanel method to facilitate the swap and re-render of the JFrame. Or in theory, this is what I thought would happen. What did I screw up? Is there a way to perform this function without using cardlayout?
import java.lang.*;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
public class EBlast extends JFrame{
EBlast(){
/*Create Frame*/
JFrame f = new JFrame("Email Blaster 1.0");
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*Create Menu Bar Buttons*/
JMenuBar mainmenu = new JMenuBar();
JMenu jmHome = new JMenu("Home");
JMenu jmOptions = new JMenu("Options");
JMenuItem jmiNew = new JMenuItem("New");
JMenuItem jmiSent = new JMenuItem("Sent");
jmOptions.add(jmiNew);
jmOptions.add(jmiSent);
JMenu jmMailer = new JMenu("Mailer");
JMenuItem jmiTrans = new JMenuItem("Transmission Status");
JMenuItem jmiStop = new JMenuItem("Stop");
jmMailer.add(jmiTrans);
jmMailer.add(jmiStop);
JMenu jmEmailList = new JMenu("Email Lists");
JMenuItem jmiNewList = new JMenuItem("New List");
JMenuItem jmiSavedList = new JMenuItem("Saved Lists");
JMenuItem jmiDoNot = new JMenuItem("Do Not Email List");
jmEmailList.add(jmiNewList);
jmEmailList.add(jmiSavedList);
jmEmailList.add(jmiDoNot);
/*Define Panels*/
JPanel jpMain = new JPanel();
jpMain.setBackground(Color.BLACK);
JPanel jpNew = new JPanel();
jpNew.setBackground(Color.RED);
JPanel jpSent = new JPanel();
jpSent.setBackground(Color.BLUE);
JPanel jpTrans = new JPanel();
jpTrans.setBackground(Color.ORANGE);
JPanel jpStop = new JPanel();
jpStop.setBackground(Color.WHITE);
JPanel jpNewList = new JPanel();
jpNewList.setBackground(Color.YELLOW);
JPanel jpSavedList = new JPanel();
jpSavedList.setBackground(Color.GREEN);
JPanel jpDoNot = new JPanel();
jpDoNot.setBackground(Color.PINK);
/*Add Menu Bar Buttons*/
mainmenu.add(jmHome);
mainmenu.add(jmOptions);
mainmenu.add(jmMailer);
mainmenu.add(jmEmailList);
/*Redirect MenuBar Clicks to class MenuAction*/
jmiNew.addActionListener(new MenuAction(jpNew));
jmiSent.addActionListener(new MenuAction(jpSent));
jmiTrans.addActionListener(new MenuAction(jpTrans));
jmiStop.addActionListener(new MenuAction(jpStop));
jmiNewList.addActionListener(new MenuAction(jpNewList));
jmiSavedList.addActionListener(new MenuAction(jpSavedList));
jmiDoNot.addActionListener(new MenuAction(jpDoNot));
/*Fill and Render JFrame*/
f.setJMenuBar(mainmenu);
f.setVisible(true);
f.setLayout(new BorderLayout());
}
public class MenuAction implements ActionListener{
JPanel panel;
MenuAction(JPanel pnl){
this.panel = pnl;
}
@Override
public void actionPerformed(ActionEvent e){
changePanel(panel);
}
}
public void changePanel(JPanel panel) {
getContentPane().removeAll();
getContentPane().add(panel, BorderLayout.CENTER);
getContentPane().doLayout();
update(getGraphics());
repaint();
revalidate();
}
public void actionPerformed(ActionEvent ae) {
String comStr = ae.getActionCommand();
System.out.println(comStr + " Selected");
}
public static void main(String args[]) {
new EBlast();
}
}
Upvotes: 0
Views: 773
Reputation: 324098
The problem is your code has 2 JFrames.
Your class "is a" JFrame.
In the constructor of the class you create a new JFrame and you add all the components to this frame which is then made visible.
However, your ActionListener tries to update the class JFrame which is not visible anywhere.
Your class should NOT be extending a JFrame.
One way (not the best), is to just pass in the JFrame as a parameter to your MenuAction so the Action has access to the frame. Then the changePanel(...) method should be part of the MenuAction. That is the code for the Action should be completely contained in the Action.
Also, the basic code for adding/removing a component from a visible GUI is:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
So basically, the whole class should be redesigned. That is why you learn to do things the standard way first. Concentrate on the basics, not on gimmicks.
Upvotes: 1