简体   繁体   English

无法从jcombobox中删除第一个元素

[英]can't remove first element from jcombobox

I cannot remove the first element from jcombobox. 我无法从jcombobox中删除第一个元素。 my code is as follows, 我的代码如下

JComboBox cBox= cBox= new JComboBox();
...    
while (cBox.getItemCount() > 0)
  cBox.removeItemAt(0);

For a test run, i had 3 items in the cBox. 为了进行测试,我在cBox中有3个项目。 When it gets to removeItemAt(0), the debug goes haywire going in to some File access code which is absolutely not related. 当到达removeItemAt(0)时,调试进入了混乱状态,进入了一些绝对不相关的文件访问代码。 Does this twice then gets the below exception. 这样做两次,然后得到以下异常。 I tried removeAllItems() which directly gets the same exception. 我尝试了removeAllItems()直接获得相同的异常。 However, removeItem(1) works as it should until theres only 1 element left. 但是,removeItem(1)可以正常工作,直到只剩下1个元素。 The exception doesn't crash the app and i can see no items in the combobox after so it worked a little. 异常不会使应用程序崩溃,并且我在组合框中看不到任何项目,因此它工作了一些。 What exactly am i doing wrong. 我到底在做什么错。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at util.Gui$4.actionPerformed(Gui.java:111)
at javax.swing.JComboBox.fireActionEvent(Unknown Source)
at javax.swing.JComboBox.contentsChanged(Unknown Source)
at javax.swing.AbstractListModel.fireContentsChanged(Unknown Source)
at javax.swing.DefaultComboBoxModel.setSelectedItem(Unknown Source)
at javax.swing.DefaultComboBoxModel.removeElementAt(Unknown Source)
at javax.swing.JComboBox.removeItemAt(Unknown Source)
at util.Gui.prepareSubLists(Gui.java:164)
at util.Gui$3.actionPerformed(Gui.java:97)
at javax.swing.JComboBox.fireActionEvent(Unknown Source)
at javax.swing.JComboBox.setSelectedItem(Unknown Source)
at javax.swing.JComboBox.setSelectedIndex(Unknown Source)
at javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Isn't your conditional statement wrong? 您的条件陈述不是错误的吗? Replace while with if , as such 更换whileif ,因为这样

if(cBox.getItemCount() > 0){
  cBox.removeItemAt(0);
}

Here's an SSCCE : 这是一个SSCCE

public final class JComboBoxDemo {
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                createAndShowGUI();             
            }
        });
    }

    public static void createAndShowGUI(){
        final JFrame frame = new JFrame("JComboBox Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(JComboPane.newInstance());
        frame.setSize(new Dimension(250, 100)); // for demonstration purposes only
        //frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static final class JComboPane extends JPanel{
        private JComboPane(){
            super();
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            JCenteredComboBox comboBox = JCenteredComboBox.newInstance();
            JCenteredButton button = JCenteredButton.newInstance(comboBox);
            add(comboBox);
            add(button);
        }

        public static final JComboPane newInstance(){
            return new JComboPane();
        }

        private static final class JCenteredComboBox extends JComboBox{
            private JCenteredComboBox(){
                super(new String[]{"Item 1", "Item 2", "Item 3"});
                setAlignmentX(Component.CENTER_ALIGNMENT);
            }

            public static final JCenteredComboBox newInstance(){
                return new JCenteredComboBox();
            }
        }

        private static final class JCenteredButton extends JButton{
            private JCenteredButton(final JComboBox comboBox){
                super("Remove First Item");
                setAlignmentX(Component.CENTER_ALIGNMENT);
                addActionListener(new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if(comboBox.getItemCount() > 0){
                            comboBox.removeItemAt(0); // your logic
                        }
                    }
                });
            }

            public static final JCenteredButton newInstance(final JComboBox comboBox){
                return new JCenteredButton(comboBox);
            }
        }
    }
}

在此处输入图片说明

When you run this, pressing the JButton will remove the first item in the JComboBox . 运行此命令时,按JButton将删除JComboBox中的第一项。 You can keep pressing this until it is empty. 您可以一直按住它直到它为空。

This exception may happen because an event is triggered when a combo item is removed and in this event handling method you still refer to combobox items. 可能会发生此异常,是因为在删除组合项时触发了一个事件,并且在此事件处理方法中,您仍然引用组合框项。

For example when you delete somewhere (other than in actionPeformed()) in your code the last item from a combo box with combo.removeItemAt(0) or removeAllItems() then still the event actionPerformed will be fired/executed. 例如,当您删除代码中某个地方(而不是actionPeformed())时,使用combo.removeItemAt(0)或removeAllItems()从组合框中删除最后一个项目,则仍将触发/执行actionPerPered事件。 But very often the actionPerformed() method contains code to react on user actions (user clicked somewhere on the combobox). 但是很多时候,actionPerformed()方法包含对用户操作(用户在组合框上的某个位置单击)作出反应的代码。 So, when the last item has been deleted there is no more item in the combobox and any reference to an item or index in actionPerformed() will cause an exception. 因此,删除最后一个项目后,组合框中将没有其他项目,并且对actionPerformed()中的项目或索引的任何引用都将导致异常。

The solution to this is to move the code from actionPerformed to eg mouseClicked() or another event handler depending on what you want to do. 解决方案是根据您要执行的操作,将代码从actionPerformed移至mouseClicked()或其他事件处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM