Java Swing Workers 和组合框问题

发布于 2024-11-06 23:20:07 字数 6658 浏览 0 评论 0原文

我正在使用 Swing 构建一个使用数据库的应用程序。 我有一个奇怪的问题,我不知道如何解决。

在某个面板中,我有一个组合框,我想使用数据库查询来填充记录。 完成构建包含组合框的 JPanel 后,我正在执行一个 Worker,

private void populateLists(){
    GetSimpleRecordsWorker worker = new GetSimpleRecordsWorker(Tables.characters,panelLeftDetails);
    worker.execute();
}

doInBackground 执行 SELECT 查询,并在获取结果后 - 在 Worker 的 done() 方法中 -更新面板的模型并调用面板的refreshFromModel

charI.setSimpleModel(simpleModel);
charI.refreshFromModel();

refreshFromModel 执行以下操作:

private void refreshFromSimpleModel(){
    charSelectCombo.removeAllItems();
    Pair[] pairs = simpleModel.getRecords();
    for (int i=0; i<pairs.length; i++){
        charSelectCombo.addItem(pairs[i]);
    }
    charSelectCombo.setSelectedItem(null);
}

现在,问题是,在完成refreshFromModel 后 - GUI 卡住/冻结。 我不知道为什么! 奇怪的是,在不同的框架中,我使用相同的方法 - 而且它的工作没有任何问题

另外,如果我尝试 removeAll 而不是 removeAllItems 它可以工作,但 ComboBox 会丢失箭头并且表现得很奇怪。

我已经在调试器中获取了帧跟踪 - 像removeSourceEvent或Unsafe.park之类的东西都在那里。

 GUI.GuiHandler at localhost:53547 (Suspended)  
Daemon System Thread [Attach Listener] (Suspended)  
Daemon System Thread [Signal Dispatcher] (Suspended)    
Daemon System Thread [Finalizer] (Suspended)    
    Object.wait(long) line: not available [native method]   
    ReferenceQueue<T>.remove(long) line: not available  
    ReferenceQueue<T>.remove() line: not available  
    Finalizer$FinalizerThread.run() line: not available 
Daemon System Thread [Reference Handler] (Suspended)    
    Object.wait(long) line: not available [native method]   
    Reference$Lock(Object).wait() line: 485 
    Reference$ReferenceHandler.run() line: not available    
Thread [AWT-Shutdown] (Suspended)   
    Object.wait(long) line: not available [native method]   
    Object.wait() line: 485 
    AWTAutoShutdown.run() line: not available   
    Thread.run() line: not available    
Daemon System Thread [Java2D Disposer] (Suspended)  
    Object.wait(long) line: not available [native method]   
    ReferenceQueue<T>.remove(long) line: not available  
    ReferenceQueue<T>.remove() line: not available  
    Disposer.run() line: not available  
    Thread.run() line: not available    
Daemon Thread [AWT-Windows] (Suspended) 
    WToolkit.eventLoop() line: not available [native method]    
    WToolkit.run() line: not available  
    Thread.run() line: not available    
Thread [AWT-EventQueue-0] (Suspended)   
    EventQueue.removeSourceEvents(Object, boolean) line: not available  
    WindowsComboBoxUI$WindowsComboBoxRenderer(Component).removeNotify() line: not available 
    WindowsComboBoxUI$WindowsComboBoxRenderer(Container).removeNotify() line: not available 
    WindowsComboBoxUI$WindowsComboBoxRenderer(JComponent).removeNotify() line: not available    
    CellRendererPane(Container).remove(int) line: not available 
    CellRendererPane(Container).remove(Component) line: not available   
    WindowsComboBoxUI(BasicComboBoxUI).getSizeForComponent(Component) line: not available   
    WindowsComboBoxUI(BasicComboBoxUI).getDisplaySize() line: not available 
    WindowsComboBoxUI(BasicComboBoxUI).getMinimumSize(JComponent) line: not available   
    AutoCompleteComboBox(JComponent).getMinimumSize() line: not available   
    FlowLayout.minimumLayoutSize(Container) line: not available 
    JPanel(Container).minimumSize() line: not available 
    JPanel(Container).getMinimumSize() line: not available  
    JPanel(JComponent).getMinimumSize() line: not available 
    BoxLayout.checkRequests() line: not available   
    BoxLayout.minimumLayoutSize(Container) line: not available  
    JPanel(Container).minimumSize() line: not available 
    JPanel(Container).getMinimumSize() line: not available  
    JPanel(JComponent).getMinimumSize() line: not available 
    BoxLayout.checkRequests() line: not available   
    BoxLayout.preferredLayoutSize(Container) line: not available    
    JPanel(Container).preferredSize() line: not available   
    JPanel(Container).getPreferredSize() line: not available    
    JPanel(JComponent).getPreferredSize() line: not available   
    BorderLayout.layoutContainer(Container) line: not available 
    JPanel(Container).layout() line: not available  
    JPanel(Container).doLayout() line: not available    
    JPanel(Container).validateTree() line: not available    
    JPanel(Container).validateTree() line: not available    
    JPanel(Container).validateTree() line: not available    
    JLayeredPane(Container).validateTree() line: not available  
    JRootPane(Container).validateTree() line: not available 
    JRootPane(Container).validate() line: not available 
    RepaintManager.validateInvalidComponents() line: not available  
    SystemEventQueueUtilities$ComponentWorkRequest.run() line: not available    
    InvocationEvent.dispatch() line: not available  
    EventQueue.dispatchEvent(AWTEvent) line: not available  
    EventDispatchThread.pumpOneEventForFilters(int) line: not available 
    EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: not available  
    EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: not available 
    EventDispatchThread.pumpEvents(int, Conditional) line: not available    
    EventDispatchThread.pumpEvents(Conditional) line: not available 
    EventDispatchThread.run() line: not available   
Thread [DestroyJavaVM] (Suspended)  
Daemon System Thread [D3D Screen Updater] (Suspended)   
    Object.wait(long) line: not available [native method]   
    D3DScreenUpdateManager.run() line: not available    
    Thread.run() line: not available    
Daemon System Thread [TimerQueue] (Suspended)   
    Object.wait(long) line: not available [native method]   
    TimerQueue.run() line: not available    
    Thread.run() line: not available    
Thread [Thread-3] (Suspended)   
    Thread.sleep(long) line: not available [native method]  
    JDCConnectionPool$ConnectionReaper.run() line: 93   
Daemon Thread [SwingWorker-pool-1-thread-1] (Suspended) 
    Unsafe.park(boolean, long) line: not available [native method]  
    LockSupport.park(Object) line: not available    
    AbstractQueuedSynchronizer$ConditionObject.await() line: not available  
    LinkedBlockingQueue<E>.take() line: not available   
    ThreadPoolExecutor.getTask() line: not available    
    ThreadPoolExecutor$Worker.run() line: not available 
    Thread.run() line: not available    

非常感谢。

I'm using Swing to build an application that uses a database.
I have a weird problem that I don't understand how to solve.

In a certain panel, I have a comboBox which I want to populate with records using DB query.
after finishing constructing the JPanel which hold the comboBox, I'm executing a Worker

private void populateLists(){
    GetSimpleRecordsWorker worker = new GetSimpleRecordsWorker(Tables.characters,panelLeftDetails);
    worker.execute();
}

Its doInBackground does a SELECT query and after getting the result - in the Worker's done() methods - updates the panel's model and calls the panel's refreshFromModel.

charI.setSimpleModel(simpleModel);
charI.refreshFromModel();

refreshFromModel does the following :

private void refreshFromSimpleModel(){
    charSelectCombo.removeAllItems();
    Pair[] pairs = simpleModel.getRecords();
    for (int i=0; i<pairs.length; i++){
        charSelectCombo.addItem(pairs[i]);
    }
    charSelectCombo.setSelectedItem(null);
}

Now, the problem is, after it finish refreshFromModel - the GUI stuck/freeze.
I HAVE NO IDEA WHY!
Weird is, in a different frame, I use the same methodology - and it works with no problems.

Also, if I try removeAll instead of removeAllItems it works but the ComboBox loses its arrow and acts weird.

I've taken the frame trace in the debugger - things like removeSourceEvent or Unsafe.park are there.

 GUI.GuiHandler at localhost:53547 (Suspended)  
Daemon System Thread [Attach Listener] (Suspended)  
Daemon System Thread [Signal Dispatcher] (Suspended)    
Daemon System Thread [Finalizer] (Suspended)    
    Object.wait(long) line: not available [native method]   
    ReferenceQueue<T>.remove(long) line: not available  
    ReferenceQueue<T>.remove() line: not available  
    Finalizer$FinalizerThread.run() line: not available 
Daemon System Thread [Reference Handler] (Suspended)    
    Object.wait(long) line: not available [native method]   
    Reference$Lock(Object).wait() line: 485 
    Reference$ReferenceHandler.run() line: not available    
Thread [AWT-Shutdown] (Suspended)   
    Object.wait(long) line: not available [native method]   
    Object.wait() line: 485 
    AWTAutoShutdown.run() line: not available   
    Thread.run() line: not available    
Daemon System Thread [Java2D Disposer] (Suspended)  
    Object.wait(long) line: not available [native method]   
    ReferenceQueue<T>.remove(long) line: not available  
    ReferenceQueue<T>.remove() line: not available  
    Disposer.run() line: not available  
    Thread.run() line: not available    
Daemon Thread [AWT-Windows] (Suspended) 
    WToolkit.eventLoop() line: not available [native method]    
    WToolkit.run() line: not available  
    Thread.run() line: not available    
Thread [AWT-EventQueue-0] (Suspended)   
    EventQueue.removeSourceEvents(Object, boolean) line: not available  
    WindowsComboBoxUI$WindowsComboBoxRenderer(Component).removeNotify() line: not available 
    WindowsComboBoxUI$WindowsComboBoxRenderer(Container).removeNotify() line: not available 
    WindowsComboBoxUI$WindowsComboBoxRenderer(JComponent).removeNotify() line: not available    
    CellRendererPane(Container).remove(int) line: not available 
    CellRendererPane(Container).remove(Component) line: not available   
    WindowsComboBoxUI(BasicComboBoxUI).getSizeForComponent(Component) line: not available   
    WindowsComboBoxUI(BasicComboBoxUI).getDisplaySize() line: not available 
    WindowsComboBoxUI(BasicComboBoxUI).getMinimumSize(JComponent) line: not available   
    AutoCompleteComboBox(JComponent).getMinimumSize() line: not available   
    FlowLayout.minimumLayoutSize(Container) line: not available 
    JPanel(Container).minimumSize() line: not available 
    JPanel(Container).getMinimumSize() line: not available  
    JPanel(JComponent).getMinimumSize() line: not available 
    BoxLayout.checkRequests() line: not available   
    BoxLayout.minimumLayoutSize(Container) line: not available  
    JPanel(Container).minimumSize() line: not available 
    JPanel(Container).getMinimumSize() line: not available  
    JPanel(JComponent).getMinimumSize() line: not available 
    BoxLayout.checkRequests() line: not available   
    BoxLayout.preferredLayoutSize(Container) line: not available    
    JPanel(Container).preferredSize() line: not available   
    JPanel(Container).getPreferredSize() line: not available    
    JPanel(JComponent).getPreferredSize() line: not available   
    BorderLayout.layoutContainer(Container) line: not available 
    JPanel(Container).layout() line: not available  
    JPanel(Container).doLayout() line: not available    
    JPanel(Container).validateTree() line: not available    
    JPanel(Container).validateTree() line: not available    
    JPanel(Container).validateTree() line: not available    
    JLayeredPane(Container).validateTree() line: not available  
    JRootPane(Container).validateTree() line: not available 
    JRootPane(Container).validate() line: not available 
    RepaintManager.validateInvalidComponents() line: not available  
    SystemEventQueueUtilities$ComponentWorkRequest.run() line: not available    
    InvocationEvent.dispatch() line: not available  
    EventQueue.dispatchEvent(AWTEvent) line: not available  
    EventDispatchThread.pumpOneEventForFilters(int) line: not available 
    EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: not available  
    EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: not available 
    EventDispatchThread.pumpEvents(int, Conditional) line: not available    
    EventDispatchThread.pumpEvents(Conditional) line: not available 
    EventDispatchThread.run() line: not available   
Thread [DestroyJavaVM] (Suspended)  
Daemon System Thread [D3D Screen Updater] (Suspended)   
    Object.wait(long) line: not available [native method]   
    D3DScreenUpdateManager.run() line: not available    
    Thread.run() line: not available    
Daemon System Thread [TimerQueue] (Suspended)   
    Object.wait(long) line: not available [native method]   
    TimerQueue.run() line: not available    
    Thread.run() line: not available    
Thread [Thread-3] (Suspended)   
    Thread.sleep(long) line: not available [native method]  
    JDCConnectionPool$ConnectionReaper.run() line: 93   
Daemon Thread [SwingWorker-pool-1-thread-1] (Suspended) 
    Unsafe.park(boolean, long) line: not available [native method]  
    LockSupport.park(Object) line: not available    
    AbstractQueuedSynchronizer$ConditionObject.await() line: not available  
    LinkedBlockingQueue<E>.take() line: not available   
    ThreadPoolExecutor.getTask() line: not available    
    ThreadPoolExecutor$Worker.run() line: not available 
    Thread.run() line: not available    

Lot of thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦醒灬来后我 2024-11-13 23:20:07

它的 doInBackground 执行 SELECT 查询,并在获得结果后 - 更新面板的模型并调用面板的refreshFromModel。

DB查询是在doInBackground()中完成的。

模型的更新需要在process()方法中完成。

有关详细信息,请阅读 Swing 教程中有关并发的部分。

its doInBackground does a SELECT query and after getting the result - updates the panel's model and calls the panel's refreshFromModel.

The DB query is done in the doInBackground().

The updating of the model need to be done in the process() method.

Read the section from the Swing tutorial on Concurrency for more information.

时光清浅 2024-11-13 23:20:07

向组合框中添加 100,000 个项目可能是问题的根源。

您还必须想知道一个用户如何能够处理组合框中的 100,000 个项目。

JComboBox 通常不应该处理如此大量的项目。

优化代码的一种可能方法是显式调用 setPrototypeDisplayValue(),这样,您就可以避免 JComboBox 检查其所有模型项的尺寸来计算其自己的尺寸。这可能是您的系统看起来冻结的当前原因。

Adding 100,000 items to your combo box is probably the root of your problem.

You also have to wonder how one user could possibly deal with 100,000 items in a combo box.

JComboBox is normally not supposed to deal with such a big number of items.

One possible way to optimize your code would be to explicitly call setPrototypeDisplayValue(), this way, you avoid JComboBox checking the dimensions of ALL its model items to compute its own dimensions. That's probably the current reason why your system looks frozen.

意中人 2024-11-13 23:20:07

我知道您正在寻找带有大量建议的自动完成功能。

也许您可以查看 glazedlists 库。它的核心功能是提供可观察列表,但它非常灵活。您可以做的一件事是基于这样的列表构建 ComboBoxModel 并启用组合框的自动完成功能(通过 AutoCompleteSupport 类)。

此方法可以提供一种避免 addItem 中任何与 ComboBox 相关的性能问题的方法。该部分将被移至釉面列表中。

I understand you are looking for autocomplete functionality with a massive amount of suggestions.

Perhaps you can have a look at the glazedlists library. Its core function is to provide observable lists, but it is very flexible. One of the things you can do is build a ComboBoxModel based on such a list and enable autocompletion for a combobox (through the AutoCompleteSupport class).

This approach may provide a way to avoid any ComboBox-related performance issues in addItem. That part would be moved into glazedlists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文