在ActionListener中访问另一个类时出现NullPointerException

时间:2011-09-03 10:54:50

标签: java swing awt jcombobox actionlistener

我试图以标准方式将一个ActionListener添加到JButton:在方法之外我有private Actions listener;并在我放置的方法内部

listener = new Actions(); // Create the action listener object 

    // Add action listeners to the necessary components
    isDatabaseDefault.addActionListener(listener);
    addEntry.addActionListener(listener);
    editEntry.addActionListener(listener);
    deleteEntry.addActionListener(listener);
    addDatabase.addActionListener(listener);
    editDatabase.addActionListener(listener);
    deleteDatabase.addActionListener(listener);

并且工作正常,没有发现错误 - 这是ActionListener类:

package engines;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;

import graphicalUI.Tabs;

public class Actions implements ActionListener, SoftwareProperties{
    // Create objects to access methods
    private DatabaseManagement database;
    private Tabs tabs;

    public Actions(){
        this.database = new DatabaseManagement();
        this.tabs = new Tabs();
    }

    // Method that is called when a button is clicked
    public void actionPerformed(ActionEvent e) {
        // Check the source of the action
        if(e.getActionCommand().equals("Make a new database")){
            System.out.println("Null pointer exception");
            String location = database.makeNewDatabase();
            if(location==null){
                JOptionPane.showMessageDialog(null, "Error: Your new database was not successfully created. Please try again if you like.", applicationName, JOptionPane.WARNING_MESSAGE);
                return;
            }
                        tabs.updateDatabaseMCombo();
            tabs.setDatabaseManagementContent(location, true);
        }
    }

}

当我按下按钮但“Null Pointer Exception”打印出来时,database.makeNewDatabase();会运行,但只要它到达tabs类中的任何一个方法,我就会收到以下错误:

  

线程“AWT-EventQueue-0”中的异常java.lang.NullPointerException     在graphicUI.Tabs.updateDatabaseMCombo(Tabs.java:148)at   engines.Actions.actionPerformed(Actions.java:31)at   javax.swing.AbstractButton.fireActionPerformed(未知来源)at   javax.swing.AbstractButton $ Handler.actionPerformed(Unknown Source)at   javax.swing.DefaultButtonModel.fireActionPerformed(未知来源)at   javax.swing.DefaultButtonModel.setPressed(未知来源)at   javax.swing.plaf.basic.BasicButtonListener.mouseReleased(未知   来自java.awt.AWTEventMulticaster.mouseReleased(未知来源)     在java.awt.Component.processMouseEvent(未知来源)at   javax.swing.JComponent.processMouseEvent(未知来源)at   java.awt.Component.processEvent(未知来源)at   java.awt.Container.processEvent(未知来源)at   java.awt.Component.dispatchEventImpl(未知来源)at   java.awt.Container.dispatchEventImpl(未知来源)at   java.awt.Component.dispatchEvent(未知来源)at   java.awt.LightweightDispatcher.retargetMouseEvent(未知来源)at   java.awt.LightweightDispatcher.processMouseEvent(未知来源)at   java.awt.LightweightDispatcher.dispatchEvent(未知来源)at   java.awt.Container.dispatchEventImpl(未知来源)at   java.awt.Window.dispatchEventImpl(未知来源)at   java.awt.Component.dispatchEvent(未知来源)at   java.awt.EventQueue.dispatchEventImpl(未知来源)at   java.awt.EventQueue.access $ 000(未知来源)at   java.awt.EventQueue $ 3.run(未知来源)at   java.awt.EventQueue $ 3.run(未知来源)at   java.security.AccessController.doPrivileged(Native Method)at   java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知   来源)at   java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知   来自)java.awt.EventQueue $ 4.run(未知来源)at   java.awt.EventQueue $ 4.run(未知来源)at   java.security.AccessController.doPrivileged(Native Method)at   java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知   来自)java.awt.EventQueue.dispatchEvent(未知来源)at   java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源)     at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)     在java.awt.EventDispatchThread.pumpEventsForHierarchy(未知   来自java.awt.EventDispatchThread.pumpEvents(未知来源)     at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at   java.awt.EventDispatchThread.run(未知来源)

但奇怪的是,当我从同一个类运行这些方法时,它们完美地工作!这是updateDatabaseMCombo()方法:

public void updateDatabaseMCombo(){
        System.out.println("is this method running");
        int sIndex = selectDatabase.getSelectedIndex(); // Get the number value of the selected item
        String selectedItem = selectDatabase.getItemAt(sIndex); // Get the string of the selected item
        System.out.println(selectedItem);
        availableDBs4DM = db.getAvailableDatabases4DB(null); // Get a list of available databases to manage
        selectDatabase.removeAllItems(); // Remove all the current items in the combo
        // Loop through the array and manually add each item
        for(String item : availableDBs4DM)
            selectDatabase.addItem(item);
        // Select the item that was previously selected 
        int search = -1; // Initialise variable to hold the search results
        for(int s = 0; s < availableDBs4DM.length; s++){
            // If a match is found, update the search variable and stop searching
            if(availableDBs4DM[s].equals(selectedItem)){
                search = s;
                break;
            }
        }

        if(search != -1){
            // If the database that was previously selected is still in the JCombobox
            selectDatabase.setSelectedIndex(search);
        }else{
            // Select the default database
            db.setTranslationDefaultDB(selectDatabase);
        }
    }

所以有人可以解释为什么我会收到这个错误吗?

BTW,selectDatabase已初始化为JComboBox<String>对象。


更新


好的,经过一些调试后,我发现我的NullPointerException是因为我只是声明方法的变量,就像private JComboBox<String> selectDatabase;一样,我实际上是用不同的方法初始化它,如下所示:

package test;
import java.awt.FlowLayout;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;

import test2.Runner;


public class DBCombo {
    private JComboBox<String> combo = new JComboBox<String>();

    public JPanel makePanel(){
        JPanel panel = new JPanel(new FlowLayout());

        String[] options = {"Why", "will", "this", "not", "work"};
        combo.setModel(new DefaultComboBoxModel<String>(options));

        panel.add(combo);

        Runner main = new Runner();

        JButton doRead = new JButton("Read");
        doRead.addActionListener(main);

        panel.add(doRead);

        return panel;
    }

    public void getComboData(){
        System.out.println(combo.getItemCount());
    }
}

package test2;


import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;

import test.DBCombo;


public class Runner implements ActionListener {
    public static void main(String[] args){
        JFrame frame = new JFrame("Test");

        DBCombo dbc = new DBCombo();

        frame.setContentPane(dbc.makePanel());
        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e){
        new DBCombo().getComboData();
    }
}

任何想法都是谁?

我现在认为这是因为动作监听器和方法在不同的包中......

1 个答案:

答案 0 :(得分:2)

好吧,不幸的是,这并不是我想到的或者想要做的,但我至少现在已经开始工作了!

事实证明,由于某种原因,我仍然不知道,除Tabs类本身之外的任何其他类调用updateDatabaseMCombo()setDatabaseManagementContent(String, boolean)都会生成空指针!所以,我只是点了点子弹并将actionlistener放在Tabs类中......

哦,好吧,这不像我的最终用户会知道任何不同。