问题描述
我使用自定义JComboBox作为JTable中的单元格编辑器。当用户使用键盘控件进入单元格时,它会尝试打开弹出窗口。这会导致以下错误:
I am using a custom JComboBox as a cell editor in a JTable. When the users gets to the cell using keyboard controls it tries to open the popup. This causes the following error:
java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:1964)
at java.awt.Component.getLocationOnScreen(Component.java:1938)
at javax.swing.JPopupMenu.show(JPopupMenu.java:887)
at javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:191)
at javax.swing.plaf.basic.BasicComboBoxUI.setPopupVisible(BasicComboBoxUI.java:859)
at javax.swing.JComboBox.setPopupVisible(JComboBox.java:796)
我有看到一些文章声明这是一个已知问题,解决方案是设置:
I have seen some articles stating that this is a known problem and the solution is to set:
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
但这并没有帮助。这应该做什么呢?
This however does not help. What is this supposed to do anyways?
我读到的关于此问题的所有主题和文章对于问题的性质都非常模糊。
All the threads and articles I have read about this are very vague about the nature of the problem.
有没有人对这个问题出现的原因有什么了解?我的组合框是非常自定义的,所以它有助于理解问题的基础,所以我可以修复代码。
Does anyone have any insight into the nature of why this problem occurs? My combobox is very custom so it would help to understand the basis of the problem so I can fix the code.
这是在组合框上的焦点获得事件上触发的捕获并调用setPopupVisible(true);
This is triggered on a focus gained event on the combo box which is captured and call setPopupVisible(true);
public void focusGained(java.awt.event.FocusEvent e)
{
//if focus is gained then make sure we show the popup if it is suppose to be visible
setPopupVisible(true);
//and highlight the selected text if any
comboTextEditor.setCaretPosition(comboTextEditor.getText().length());
comboTextEditor.moveCaretPosition(0);
}
顺便说一句,我在Java 1.7_40中获得与Java 1.6_45相同的结果
By the way I get the same results in Java 1.7_40 as Java 1.6_45
完整堆栈跟踪:
Exception in thread "AWT-EventQueue-1" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:1964)
at java.awt.Component.getLocationOnScreen(Component.java:1938)
at javax.swing.JPopupMenu.show(JPopupMenu.java:887)
at javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:191)
at javax.swing.plaf.basic.BasicComboBoxUI.setPopupVisible(BasicComboBoxUI.java:859)
at javax.swing.JComboBox.setPopupVisible(JComboBox.java:796)
at com.mbs.generic.view.swing.combobox.AutoCompleteComboBox$1.focusGained(AutoCompleteComboBox.java:185)
at java.awt.AWTEventMulticaster.focusGained(AWTEventMulticaster.java:203)
at java.awt.Component.processFocusEvent(Component.java:6179)
at java.awt.Component.processEvent(Component.java:6046)
at java.awt.Container.processEvent(Container.java:2039)
at java.awt.Component.dispatchEventImpl(Component.java:4653)
at java.awt.Container.dispatchEventImpl(Container.java:2097)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:901)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:513)
at java.awt.Component.dispatchEventImpl(Component.java:4525)
at java.awt.Container.dispatchEventImpl(Container.java:2097)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:648)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:607)
at java.awt.EventQueue$1.run(EventQueue.java:605)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:621)
at java.awt.EventQueue$2.run(EventQueue.java:619)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:618)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
thanks
推荐答案
首先,让我解释一下 comboBox.putClientProperty(JComboBox.isTableCellEditor,Boolean.TRUE);
呢。通常情况下,将鼠标悬停在某个项目上或按下键盘上的箭头键会立即选择 JComboBox
上的项目。由于来自 JComboBox
的选择事件将导致单元格编辑过程停止,因此此行为不适用于表格单元格。因此,当设置此特殊客户端属性项时,将在弹出列表中显示选中但尚未在 JComboBox
上设置。只有已提交的项目(通过单击或Enter键)将更改 JComboBox
上的选定项目,然后导致编辑结束。至少,这适用于 BasicLookAndFeel
及其派生词。
First, let me explain what comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
does. Normally, hoovering the mouse over an item or pressing the arrow keys on the keyboard will cause the selection of items on the JComboBox
immediately. Since selection events from the JComboBox
will cause the cell edit process to stop, this behavior is not suitable for table cells. So when setting this special client property items will be shown selected inside the popup list but not set on the JComboBox
yet. Only committed items (via click or Enter key) will change the selected item on the JComboBox
causing the end of the edit then. At least, this holds for BasicLookAndFeel
and its derivatives.
你遇到的问题完全不同。正如异常消息和堆栈跟踪清楚地说,外观尝试打开与 JComboBox
相关联的 JPopupMenu
(按照您的要求)但它无法确定弹出菜单的屏幕位置,因为您的 JComboBox
未在屏幕上显示。它想要 JComboBox
的位置的原因是它打开了相对于 JComboBox
的新窗口。
The problem you have is completely different. As the exception message and the stack trace clearly say, the look and feel tries to open the JPopupMenu
associated with the JComboBox
(as you requested) but it can’t determine the on-screen location for the popup menu because your JComboBox
is not shot showing on the screen. The reason why it wants the location of the JComboBox
is that it opens the new window relative to the JComboBox
.
剩下的问题是你从 JComboBox
focusGained 的原因>屏幕上没有显示(或者你认为的原因)。
The remaining question is why you received a focusGained
from a JComboBox
that is not showing on the screen (or why you thought you did).
这篇关于jcombobox作为单元格编辑器java.awt.IllegalComponentStateException:必须在屏幕上显示组件以确定其位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!