The first time I show my Component, it takes a few seconds to show. I am using a card layout. When I switch to a card for the first time is when I experience the slowness. Every time after that, it is almost instant.
I have two questions about this:
For Swing components, is there a way to kick this off early, for example, during application load?
What is happening under the hood that causes the first display to take longer than all the others.
Related
I'm developing an application for a deposit ATM. Almost everyone has used one of these at least once in their life so it's safe to say you know what I'm talking about.
I'm currently doing the GUI and I think I should use multiple JFrames.
My reasons:
Each frame is set to respond to certain, different conditions - smart card reader sends a signal, timeout occurs, click occurs, different parts of the machine send various signals to which the app must respond and display an appropriate message
Since this is an embedded device the user has zero ability to interact with the os of the machine beyond using this one program. I think this sets aside considerations of esthethics - multiple windows in taskbar.
The Fullscrean mode does a great job of conceiling everything else going on in the background.
What I dislike:
I get a screen flicker when switching from one frame to another. This might not be related to the general topic of the question and might just be because I'm disposing of frames everytime the program switches away from them instead of setting them to be invisible.
Any thoughts on the subject are welcome.
You should use a single JFrame, and have multiple JPanels for the various "screens" you want to show. To change "screen", just remove from the JFrame the JPanel currently shown and add the new one.
EDIT:
To make the switch, you can use CardLayout as LayoutManager of your frame. It shows one panel at a time and allows you to easily switch between them.
It's no real advantage to use multiple JFrames, when you can use a single one and have multiple content panes for it.
This should prevent any useless flickering and make sure that only one of your "screens" is visible at the same time.
I am using a RecyclerView to display data that gets polled from a website (=> completely changes at once).
I already created an ItemAnimator class that has the animation I want but I need to know what is the best way to time the animations to wait for the previous one to finish.
This is what I'm trying to achieve: http://www.google.com/design/spec/animation/meaningful-transitions.html#meaningful-transitions-hierarchical-timing
We've had a lot of success using setStartDelay (or setStartOffset, depending on which animators you are using). Have a delay variable that starts at 0, and as you walk through your children creating their animations, set the start delay to the current value and add some increment, such as 100 ms.
I've been working on the exact same animation. I've put it to the side for the time being, but got a pretty good effect at normal speed. When I slowed it down for debugging, I've got a strange bug that causes certain items to be animated multiple times. Also, scrolling up doesn't quite work if the animation hasn't completed, but that isn't a bug likely to be run into at normal speed.
Here's my code: https://github.com/halfjew22/AnimateRecyclerGrid
Essentially, what I did was I looked at the pattern in the Material Animation. Based off of that pattern, I put together a for loop that spawns a runnable that is given coordinates (based off the value in the for loop) and told to animate the view with those coordinates.
Like I said, I didn't quite finish the project, but it works fairly well as an alpha or proof of concept. I know it's been a while since you asked this question, but let me know if you'd like to work on finishing this up together.
Let me know if that helps you out.
I've created a custom RecyclerView adapter class which does more or less what OP wanted to achieve i.e. animates RecyclerView's items sequentially (in order, one after the other).
The adapter class is shared publicly on github as a gist here.
From the description:
"This adapter aims to create a sequential RecyclerView items' animation.
They're appearing in order, top to bottom. The animation works when the RecyclerView is first created and does NOT work when items are scrolled down."
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!
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.
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!
I'm looking to make a simple(for now) stopwatch application in java which I would eventually like to port to android devices, but first I'm just working on a simple computer run version and I'm wondering what I should do as far as displaying the elapsed time on the screen, so for I just have a JPanel with start and stop buttons, What would be the best way to actually display the time? I feel like simply drawing the numbers and erasing them is slow and inefficient, how can I do this so that the GUI is rapidly updated with the correct current time? I know how to compute the elapsed time using System.currentTimeMillis(), I'm just looking for the best way to display the time on screen that can be updated rapidly. I'd like to show it to at least the hundredth of a second which means the screen needs to be changing that often. Any suggestions?
Should I just use a JLabel?
You can separate Hours, Minutes, Seconds, Milliseconds into different `JLabel's.
So using Timer or ExecutorService you would update JLabel with Seconds and Milliseconds very often.
Other JLabels update only when needed, i.e. a minute elapsed.
As a general rule, should a program with multiple sections create everything at startup or should it wait to create each part when it is actually needed?
My specific case is a Java kiosk-style application that has multiple different sections. Each section is a different JPanel (with different buttons / JTables / JLabels / etc.) that does a specific task. This is an unfinished project that I haven't touched in a while, but I'm going to complete it and I'm looking at the code and trying to refactor what I think I should have done otherwise.
So far, the program is creating every single JPanel at startup, so whenever an user clicks on one of the button that changes which JPanel is shown, it it loaded instantly since it's already created. So far, I don't think it would matter that much performance-wise, but I'd like to know what is standard practice in this case.
I would not load all on start up, as it might make start up slow and also some panels are loaded which are not required. For example you have 4 panels loaded contact, about, pics, and feeds. Suppose you load all 4 at start up, what if user just visited only 2 of them and then close the application. Sometimes it is possible that user wants see only one panel but he has to wait for all panels to load at start up. So I will suggest to load panels as they are required. Load only primary data on frame, and then when user clicks on a button for first time which loads a panel, show a progress bar until that panel is loaded, and from the next time he clicks on button just display the panel with out waiting as it is loaded already by first click.
If your application is getting data from internet then loading all data on start up will also cost extra band width and data charges.
It depends on you project need.
If response time is important for end user , then your approach is correct.
else create the jpanel on demand
I think it depends a lot on how much it costs to create that JPanel. If it contains a JTable with a lot of information that it receives, for example, from a MySQL server over the network, then the cost of creating that JPanel is quite big.
In this case, I would create it only when it is needed. Maybe that JPanel is never needed while the program is running, so why spend all that time and resources creating it ?