【问题标题】:Adding item to JComboBox from different class从不同的类将项目添加到 JComboBox
【发布时间】:2011-11-20 12:58:56
【问题描述】:

我一直在尝试在将新项目添加到后端数据库时更新 JComboBox。

在实际代码中,有一个单独的类来处理添加对话框,当添加新项目时,它会更新数据库,然后应该通过调用在主目录中接受字符串的方法将相同的项目添加到下拉菜单中图形用户界面类。 (试图遵循模型-视图-控制器)。

下面是一个触发错误的最小示例,尽管在实际应用程序中它会静默失败。

我知道它与对象的实例有关。此外,为了填充列表,我正在使用 addItem() 迭代列表,以确保它正常工作并且 ComboBox 是可变的。

感谢汤姆的帮助

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class TestComboBox extends JPanel implements ActionListener{

JComboBox moduleList = new JComboBox(new DefaultComboBoxModel());
TestComboBox testComboBox;
JFrame frame;

public void actionPerformed(ActionEvent e){
    if("additem".equals(e.getActionCommand())){
        addItem("Item");
    }
    if("additemfail".equals(e.getActionCommand())){
        testComboBox.addItemFail("Item Fail");
    }
}

public void addItem(String item){
    moduleList.addItem(item);
}

public void addItemFail(String item){
    testComboBox = new TestComboBox();
    moduleList.addItem(item);
}


protected JPanel createPanel(){
    JPanel panel = new JPanel(false);

    String[] getModuleList = {"MODULE 1", "MODULE 2"};
    moduleList = new JComboBox(new DefaultComboBoxModel(getModuleList));
    panel.add(moduleList);

    JButton additem = new JButton("Add Item");
    additem.setActionCommand("additem");
    additem.addActionListener(this);
    panel.add(additem);

    JButton additemfail = new JButton("Add Item Fail");
    additemfail.setActionCommand("additemfail");
    additemfail.addActionListener(this);
    panel.add(additemfail);

    return panel;
}

public void createAndShowGui(){
    testComboBox = new TestComboBox();
    frame = new JFrame("JComboTest");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.add(testComboBox.createPanel());
    frame.setSize(450, 150);
    frame.setVisible(true);
}

public static void main(String[] args){
    TestComboBox t = new TestComboBox();
    t.createAndShowGui();
}
}

抛出的异常

线程“AWT-EventQueue-0”中的异常 java.lang.NullPointerException 在 TestComboBox.actionPerformed(TestComboBox.java:16) 在 javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2012) 在 javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335) 在 javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:404) 在 javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) 在 javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:253) 在 java.awt.Component.processMouseEvent(Component.java:6268) 在 javax.swing.JComponent.processMouseEvent(JComponent.java:3267) 在 java.awt.Component.processEvent(Component.java:6033) 在 java.awt.Container.processEvent(Container.java:2045) 在 java.awt.Component.dispatchEventImpl(Component.java:4629) 在 java.awt.Container.dispatchEventImpl(Container.java:2103) 在 java.awt.Component.dispatchEvent(Component.java:4455) 在 java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4633) 在 java.awt.LightweightDispatcher.processMouseEvent(Container.java:4297) 在 java.awt.LightweightDispatcher.dispatchEvent(Container.java:4227) 在 java.awt.Container.dispatchEventImpl(Container.java:2089) 在 java.awt.Window.dispatchEventImpl(Window.java:2517) 在 java.awt.Component.dispatchEvent(Component.java:4455) 在 java.awt.EventQueue.dispatchEventImpl(EventQueue.java:649) 在 java.awt.EventQueue.access$000(EventQueue.java:96) 在 java.awt.EventQueue$1.run(EventQueue.java:608) 在 java.awt.EventQueue$1.run(EventQueue.java:606) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) 在 java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116) 在 java.awt.EventQueue$2.run(EventQueue.java:622) 在 java.awt.EventQueue$2.run(EventQueue.java:620) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) 在 java.awt.EventQueue.dispatchEvent(EventQueue.java:619) 在 java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275) 在 java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200) 在 java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) 在 java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185) 在 java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177) 在 java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

【问题讨论】:

  • 第 16 行是 testComboBox = new TestComboBox();,为什么地狱在世界上......,你再次从自身重新创建类
  • 问题是一个空变量。错误消息告诉您是哪条线路导致了问题。因此,查看该行使用的所有变量并确定哪个为空。然后您需要更改代码以确保当您尝试访问它时该变量不为空。

标签: java swing user-interface jcombobox


【解决方案1】:

您应该在 actionPerformed 方法中调用 addItemFail("Item Fail"); 而不是 testComboBox.addItemFail("Item Fail");

编辑:并且您不应该在 addItemFail 方法中再次重新创建同一类的对象(再次这样做有什么意义?)

【讨论】:

    【解决方案2】:

    您的问题是您的类在自身内部创建了另一个自身的类实例。首先,您创建一个 TestComboBox(TCB),其中包含指向另一个 Null 的 TestCombobox 的链接,因为您没有将其设置为任何其他地方。

    第一个 TCB (A) 是您的 t,带有一个空 TCB 链接,在 main() 中创建。

    这个 TCB 链接是通过在 createAndShowGui() 中创建一个新的 TCB (B)(其中包含另一个空 tcb 链接)来设置的。这一个也是获得所有面板和所有听众的那个。

    因此,当您在面板中按下该按钮时,actionevent 会被 B 触发并被 B 拾取,因为它是唯一具有侦听器的事件。但随后它会尝试访问 B 中为 null 的 TCB 链接,从而导致 nullpointerexception。

    更令人困惑的是,您的 addItemFail 创建了另一个 TCB,该 TCB 被添加到 B。

    我对您的建议是重新考虑和重新设计它。目前太混乱了。此外,代码中没有一条注释使得代码背后的原始意图更加难以理解。您将希望摆脱类内所有新创建的 TCB 创建。

    【讨论】:

    • 感谢您的建议,我试图创建一个简短的、自包含的、正确的(可编译的)示例,我现在意识到它并不能准确地反映问题。它现在正在工作。在原始代码中,我有两个类,一个包含 JComboBox,另一个包含文本字段。包含类的 JComboBox 有一个更新方法,我认为问题在于包含类的文本字段创建了包含类的 JComboBox 的新实例,这意味着更新已执行但未显示。是一种从特定类实例调用方法的方法吗?
    • 当然。您只需要一个指向该特定类实例的链接,该链接可从您要调用该方法的位置到达。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2015-10-22
    • 2011-11-15
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多