在JMenuItem上更改JPanels单击(ActionListener未激活)

时间:2016-04-20 21:55:09

标签: java swing jmenu jmenuitem

Java新手在这里。我正在建立一个群发邮件程序供我的公司使用(像Mailchimp这样的服务,每次爆炸我需要的费用高达250美元)。现在,我正在为程序设计GUI。所有的电子邮件发送代码都已完成并经过测试。

我有JMenuItems使用ActionListeners调用另一个类来促进JPanel的切换。我听说过CardLayout是一种更简单的方法,但是我想从头开始学习它,可以这么说,我可以编写更多的片段来提高办公室的效率。

在我的代码中,类MenuAction正在设置JPanel面板==与每个菜单项关联的面板,然后运行changePanel方法以便于交换和重新呈现JFrame。或者从理论上讲,这就是我认为会发生的事情。我搞砸了什么?有没有办法在不使用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();
	}
}




1 个答案:

答案 0 :(得分:1)

问题是您的代码有2个JFrame。

  1. 您的课程“是”JFrame。

  2. 在类的构造函数中,您创建一个新的JFrame,然后将所有组件添加到此框架中,然后使其可见。

  3. 但是,ActionListener会尝试更新在任何地方都看不到的类JFrame。

    您的课不应该扩展JFrame。

    一种方式(不是最好的方法)是将JFrame作为参数传递给MenuAction,以便Action可以访问该帧。然后,changePanel(...)方法应该是MenuAction的一部分。那就是Action的代码应该完全包含在Action中。

    此外,从可见GUI添加/删除组件的基本代码是:

    panel.remove(...);
    panel.add(...);
    panel.revalidate();
    panel.repaint();
    

    所以基本上,整个班级应该重新设计。这就是为什么你学会先用标准方法做事的原因。专注于基础知识,而不是噱头。