1

JComboBox の値を ActionListener から変更しようとしていますが、うまくいきません。

変更すると CardLayout が変更される (別の GUI に切り替えられる) JComboBox があります。

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 の 2 つのインスタンスをインスタンス化するという事実に関連しているようです。一方のインスタンスの cb フィールドは設定されていますが、他方のインスタンスの同じフィールドはまだ null です。なぜこのクラスの 2 つのインスタンスを設定しているのかはわかりませんが、調査すれば問題が明らかになると思います。

幸運を。

于 2011-11-30T21:13:42.770 に答える
1

If, as I suspect, your NPE is being thrown from one of these two lines:

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

then either thisAction is null, or cb is null. Check those out and then come back and update. Good luck!

于 2011-11-30T21:03:43.660 に答える
0

@colbyは正しいです。作成する2番目のインスタンスsetGUIには、cbオブジェクトが作成されていません。addComponentToPane()を呼び出してさまざまなパネルを作成し、カードに追加するだけの場合は、次のように呼び出すだけで、オブジェクトを作成する必要はありません。

addComponentToPane(frame.getContentPane());

于 2011-11-30T21:26:08.547 に答える