2016-01-13 73 views
1

我需要爲表格的每一行顯示動態數據集,所以我使用DefaultCellEditor(JComboBox)並使用PopupMenuListener將數據加載到他的DefaultComboBoxModel中。 我的問題是:當我點擊一個表的單元格時,JComboBox不顯示彈出列表和應用程序拋出異常。 我使用Java 7.如何修復JTable的java.awt.IllegalComponentStateException和JComboBox單元格編輯器?

如何解決?

代碼示例:

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(); 
      } 
     }); 
    } 
} 

完整堆棧跟蹤:

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) 
+0

我發現這裏另一個解決方案[link](http://stackoverflow.com/a/31626214/3183202) – guest

回答

3

簡單的解決方法是改變模型,而不是將元素添加到現有的一個:

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