1

我正在尝试从 ActionListener 更改 JComboBox 的值,但没有运气。

我有一个 JComboBox,它在更改时会更改 CardLayout(切换到另一个 GUI)。

我有一个带有用户选项的菜单栏,我想自动更改 JComboBox selectedItem。本质上,我的最终愿望是让菜单栏可以更改 CardLayout(但我无法使用我的 ActionListener 更改卡布局)。

看起来代码无法从内部侦听器类中找到 JComboBox。

任何帮助,包括供我阅读的参考资料,将不胜感激。

这是我当前的代码(仍在开发中):

package inventorytrackingsystem;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.rmi.*;

public class InventoryTrackingSystem implements ItemListener {
  JPanel mainPanel;
  JFrame frame;

  JPanel cards; //a panel that uses CardLayout
  final static String MAINPANEL = "Main";
  final static String CHECKITEMSPANEL = "Check Items";
  final static String NEWITEMPANEL = "New Item";
  final static String CHECKOUTITEMPANEL = "Check Out Item";
  final static String ITEMINFOPANEL = "Item Information";
  JPanel comboBoxPane;
  private JComboBox cb;
  static String comboBoxItems[] = {MAINPANEL,CHECKITEMSPANEL,NEWITEMPANEL,CHECKOUTITEMPANEL,ITEMINFOPANEL};

  public static void main(String[] args) {
    final InventoryTrackingSystem ITS = new InventoryTrackingSystem();
    /* Use an appropriate Look and Feel */
    try {
      UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
    } catch (IllegalAccessException ex) {
      ex.printStackTrace();
    } catch (InstantiationException ex) {
      ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
      ex.printStackTrace();
    }
    /* Turn off metal's use of bold fonts */
    UIManager.put("swing.boldMetal", Boolean.FALSE);

    //Schedule a job for the event dispatch thread:
    //creating and showing this application's GUI.
//    javax.swing.SwingUtilities.invokeLater(new Runnable() {
//      public void run() {
        ITS.createAndShowGUI();
//      }
//    });

  }

  public void addComponentToPane(Container pane) {
    //Put the JComboBox in a JPanel to get a nicer look.
    comboBoxPane = new JPanel(); //use FlowLayout
    cb = new JComboBox(comboBoxItems);
    cb.setEditable(false);
    cb.addItemListener(this);
    comboBoxPane.add(cb);

    //Create the "cards".
    JPanel main = new guiBuilder().buildGui("main");
    JPanel checkItems = new guiBuilder().buildGui("checkItems");
    JPanel newItems = new guiBuilder().buildGui("newItems");
    JPanel checkOutItems = new guiBuilder().buildGui("checkOutItems");
    JPanel itemInfo = new guiBuilder().buildGui("itemInfo");

    //Create the panel that contains the "cards".
    cards = new JPanel(new CardLayout());
    cards.add(main, MAINPANEL);
    cards.add(checkItems, CHECKITEMSPANEL);
    cards.add(newItems, NEWITEMPANEL);
    cards.add(checkOutItems, CHECKOUTITEMPANEL);
    cards.add(itemInfo, ITEMINFOPANEL);

    pane.add(comboBoxPane, BorderLayout.PAGE_START);
    pane.add(cards, BorderLayout.CENTER);
  }

  public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
  }

  /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private void createAndShowGUI() {
      //Create and set up the window.
      frame = new JFrame("Inventory Tracking System");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      frame.setLayout(new BorderLayout());
      Menu m1 = new Menu("Options");

      MenuItem mi1_0 = new MenuItem("Main Page");
        mi1_0.setActionCommand("main");
        mi1_0.addActionListener(new menuListener());

      MenuItem mi1_1 = new MenuItem("Check Item");
        mi1_1.setActionCommand("checkItem");
        mi1_1.addActionListener(new menuListener());
      MenuItem mi1_2 = new MenuItem("Add New Item");
        mi1_2.setActionCommand("addItem");
        mi1_2.addActionListener(new menuListener());
      MenuItem mi1_3 = new MenuItem("List All Items");
        mi1_3.setActionCommand("listAllItems");
        mi1_3.addActionListener(new menuListener());
      MenuItem mi1_4 = new MenuItem("Exit");
        mi1_4.setActionCommand("exit");
        mi1_4.addActionListener(new menuListener());

      Menu m2 = new Menu("Help");
      MenuItem mi2_0 = new MenuItem("About");
        mi2_0.setActionCommand("about");
        mi2_0.addActionListener(new menuListener());

      m1.add(mi1_0);
      m1.add(mi1_1);
      m1.add(mi1_2);
      m1.add(mi1_3);
      m1.add(mi1_4);

      m2.add(mi2_0);

      MenuBar mb = new MenuBar();
      frame.setMenuBar(mb);
      mb.add(m1);
      mb.add(m2);

      //Create and set up the content pane.
      InventoryTrackingSystem setGUI = new InventoryTrackingSystem();
      setGUI.addComponentToPane(frame.getContentPane());

      //Display the window.
      frame.pack();
      frame.setVisible(true);

      frame.setSize(500, 500);
      frame.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent we){
          System.exit(0);
        }
        public void windowClosed(WindowEvent we){
          System.exit(0);
        }
      });

    }

    class menuListener implements ActionListener{
      public void actionPerformed(ActionEvent ev){
        String thisAction=ev.getActionCommand();

        if(thisAction.equals("main")){
          cb.setSelectedItem(MAINPANEL);
        }else if(thisAction.equals("checkItem")){
          //change GUI
        }else if(thisAction.equals("addItem")){
          //change GUI
        }else if(thisAction.equals("listAllItems")){
          //change GUI
        }else if(thisAction.equals("exit")){
          System.exit(0);
        }else if(thisAction.equals("about")){
          JOptionPane.showMessageDialog(frame, "About This App");
        }
      }
    }
}

我尝试使用菜单时遇到的错误如下:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
  at inventorytrackingsystem.InventoryTrackingSystem$menuListener.actionPerformed(InventoryTrackingSystem.java:161)
  at java.awt.MenuItem.processActionEvent(MenuItem.java:627)
  at java.awt.MenuItem.processEvent(MenuItem.java:586)
  at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:337)
  at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:325)
  at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:646)
  at java.awt.EventQueue.access$000(EventQueue.java:84)
  at java.awt.EventQueue$1.run(EventQueue.java:602)
  at java.awt.EventQueue$1.run(EventQueue.java:600)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
  at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
  at java.awt.EventQueue$2.run(EventQueue.java:616)
  at java.awt.EventQueue$2.run(EventQueue.java:614)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
  at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
  at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
  at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
  at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
  at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
BUILD SUCCESSFUL (total time: 6 seconds)
4

3 回答 3

3

根本问题似乎与您实例化 InventoryTrackingSystem 的两个实例有关。一个实例中的 cb 字段已设置,而另一个实例中的同一字段仍为空。我不确定你为什么要设置这个类的两个实例,但我怀疑如果你检查你会发现你的问题。

祝你好运。

于 2011-11-30T21:13:42.770 回答
1

如果,正如我所怀疑的,你的 NPE 是从这两行之一抛出的:

if(thisAction.equals("main")){           
    cb.setSelectedItem(MAINPANEL); 

那么要么thisAction为空,要么cb为空。检查出来,然后回来更新。祝你好运!

于 2011-11-30T21:03:43.660 回答
0

@colby 是对的。您创建的第二个实例 setGUI 没有创建 cb 对象。如果您的意图只是调用 addComponentToPane() 来构造不同的面板并添加到卡片,那么您可以简单地调用如下,无需创建对象

addComponentToPane(frame.getContentPane());

于 2011-11-30T21:26:08.547 回答