What is causing slow performance in my JTabbedPane-based Swing application?

南楼画角 提交于 2019-12-11 02:20:35

问题


I have a Swing application for creating RPG characters. It has a nested JTabbedPane architecture, so there is a HeroTabsPanel which has HeroPanels and each of those has some more tabs like Stats, Items etc.

So the GUI is comprised of the upper tabbed pane for heroes, the lower tabbed pane for current hero tab and an EditViewPanel which displays an EditingView corresponding to each Tab when the tab is selected.

Performance has been bad from the start, but when I added the upper level hero-tabs (to have multiple heroes in editing simultaneously), switching between tabs became even slower. It takes a few minutes for something to be displayed in the new JFrame after all the code has finished adding components. Could this be the layout?

I am using MigLayout with absolute positioning. Actually, before I added upper tabs, there had been some “Unstable Cyclic Dependency in absolute-linked values!” issues, but now there aren’t somehow.

In stateChanged() I have what amounts to this:

editViewPanel.activateView(currentTab.getLinkedView());

And in activateView():

removeAll();
currentView = heroView;
add(currentView, "pos 0 0");
currentView.refresh();
revalidate();

But like I said, all the code execution is finished in reasonable time, I've done my profiling, but after it is done, there a delay of considerable length, up to a few minutes in the case of first time adding to a new JFrame.

Another issue is that when I need to update a panel within the lower tabbedpane, especially StatsPanel which is made up of string-int elements added for each parameter in a few columns, I get yet another large delay. It also depends on MigLayout and for some reason (bad design, I know) has absolute positioning as well. But I have changed it so that no components are removed/added after initialization, only setText() is used and still there is a big delay after the code is finished executing.

I’m planning to use SwingWorkers but I would like to understand the problem better before I start solving it. I suspect it's simple, but I am a bit incredulous about how big the delays it's causing are. I'd appreciate some hints/examples about SwingWorkers.

I can add more code if you have some general idea where the issue might hide.

Any suggestions are welcome, thanks!


回答1:


I never encountered a Swing UI which was slow due to the number of JComponents visible. What I do often see is a sluggish UI because the UI thread is used/abused to perform all kinds of work not related to UI updates.

In Swing, there is only one thread on which you may update the UI, and that same thread is responsible for painting the UI (the Event Dispatch Thread). If you block this thread by e.g. performing calculations on it, the UI will not be able to repaint or react on user input while your calculation is running. That is why you must perform all heavy work on a worker thread. This is clearly explained in the Concurrency in Swing tutorial.

Not 100% sure that is what happening in your case, but it definitely sounds like it. If you want to be sure, take a thread dump while you are waiting for your UI and see what the thread named AWT-EventQueue-0 is doing at that moment. If it really takes 5 minutes before your UI is updated, you must be able to locate fairly quickly what is blocking the UI.




回答2:


Ok, I finally worked it out by going through the EDT dump. The freeze was due to layout, unlikely though it had seemed. MigLayout was trying to figure out the sizes of all the components every time new tab was selected, and probably for all the components in all the tabs on init. The solution is simply to override getPreferredSize() for the JTabbedPanel implementation. @Robin, thanks for the thread dump hint!



来源:https://stackoverflow.com/questions/26441804/what-is-causing-slow-performance-in-my-jtabbedpane-based-swing-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!