简体   繁体   English

如何使用JComboBox单元格编辑器修复JTable的java.awt.IllegalComponentStateException?

[英]How to fix java.awt.IllegalComponentStateException for JTable with JComboBox cell editor?

I need to show dynamic data set for each row of a table, so I use DefaultCellEditor(JComboBox) and load data to his DefaultComboBoxModel using PopupMenuListener. 我需要为表的每一行显示动态数据集,因此我使用DefaultCellEditor(JComboBox)并使用PopupMenuListener将数据加载到他的DefaultComboBoxModel。 My problem is: when I click a cell of table, JComboBox doesn't show popup list and app throws exception. 我的问题是:当我单击表格的单元格时,JComboBox不显示弹出列表,应用程序抛出异常。 I use Java 7. 我使用Java 7。

How to fix it? 怎么解决?

Code sample: 代码示例:

import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class TestTable extends JFrame implements PopupMenuListener
{
    public TestTable()
    {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        String[] data = new String[]{"A", "B"};        
        DefaultTableModel mdlTable = new DefaultTableModel();
        mdlTable.addColumn("Col");
        for (int i = 0; i < 3; i++) {
            mdlTable.addRow(data);
        }
        JTable tbl = new JTable(mdlTable);

        TableColumnModel mdlColumn = tbl.getColumnModel();
        TableColumn clm = mdlColumn.getColumn(0);
        DefaultComboBoxModel mdlComboBox = new DefaultComboBoxModel();
        JComboBox cmb = new JComboBox(mdlComboBox);
        cmb.addPopupMenuListener(this);
        clm.setCellEditor(new DefaultCellEditor(cmb));

        setContentPane(new JScrollPane(tbl));
        setSize(200, 200);
        setVisible(true);
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e)
    {
        JComboBox cmb = (JComboBox) e.getSource();
        DefaultComboBoxModel mdl = (DefaultComboBoxModel) cmb.getModel();
        mdl.removeAllElements();

        String[] data = new String[]{"A", "B", "C", "D"};

        for (String item : data) {
            mdl.addElement(item);
        }
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
    {
    }

    @Override
    public void popupMenuCanceled(PopupMenuEvent e)
    {
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TestTable();
            }
        });
    }
}

Full stack trace: 完整堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
    at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:2048)
    at java.awt.Component.getLocationOnScreen(Component.java:2022)
    at javax.swing.JPopupMenu.show(JPopupMenu.java:942)
    at javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:208)
    at javax.swing.plaf.basic.BasicComboPopup.togglePopup(BasicComboPopup.java:1128)
    at javax.swing.plaf.basic.BasicComboPopup$Handler.mousePressed(BasicComboPopup.java:825)
    at java.awt.Component.processMouseEvent(Component.java:6513)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6281)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4872)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4698)
    at javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(BasicTableUI.java:948)
    at javax.swing.plaf.basic.BasicTableUI$Handler.adjustSelection(BasicTableUI.java:1110)
    at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(BasicTableUI.java:1038)
    at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:280)
    at java.awt.Component.processMouseEvent(Component.java:6513)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6281)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4872)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4698)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4489)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4698)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:740)
    at java.awt.EventQueue.access$300(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:699)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:713)
    at java.awt.EventQueue$4.run(EventQueue.java:711)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:710)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

A simple workaround is changing the model, instead of adding elements to the existing one: 一个简单的解决方法是更改​​模型,而不是向现有模型添加元素:

@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
    JComboBox<String> cmb = (JComboBox<String>) e.getSource();
    cmb.setModel(new DefaultComboBoxModel<>(new String[]{"A", "B", "C", "D"}));
}

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

相关问题 当我单击JTable中的JComboBox问题时出现java.awt.IllegalComponentStateException - java.awt.IllegalComponentStateException when I click on JComboBox in JTable problem jcombobox作为单元格编辑器java.awt.IllegalComponentStateException:必须在屏幕上显示组件以确定其位置 - jcombobox as cell editor java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location java.awt.IllegalComponentStateException - java.awt.IllegalComponentStateException 在MATLAB中遇到Java错误“java.awt.IllegalComponentStateException” - Encounter a Java error “java.awt.IllegalComponentStateException” in MATLAB 线程“ AWT-EventQueue-0”中的异常java.awt.IllegalComponentStateException:该框架是可显示的 - Exception in thread “AWT-EventQueue-0” java.awt.IllegalComponentStateException: The frame is displayable 焦点问题使用JComboBox作为JTable中的单元格编辑器 - focus issue using a JComboBox as a cell editor in a JTable 在JTable中使用JComboBox作为单元格编辑器并保存更改 - Using JComboBox as Cell Editor in JTable and saving changes 如何将JComboBox添加到JTable单元格? - How to add a JComboBox to a JTable cell? 在JTable单元格编辑器中自动完成JComboBox - Auto-complete JComboBox in JTable cell editor 在使用JComboBox作为单元格编辑器的JTable单元格中编辑焦点 - Editing focus in a JTable cell that uses a JComboBox as a cell editor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM