Swing JScrollPane resets scroll position when updating - java

I have a JPanel view inside a JScrollPane. The Jpanel paints some shapes which has to change dynamically in order to reflect a changing datamodel.
I have implemented a timer that should repaint the JPanel/JScrollPane which works fine unless that it resets the scroller. The scroller has to remain at its position (where the user has scrolled to).
I have tried to repaint the JPanel, the JScrollPane, the viewport of the JScrollPane etc, but noting seem to solve this problem.
Do you have a hint? The code is quite large so it is hard to isolate an example.

On the swing timer do not much concerning the GUI, just scrollPane.repaint(50L);. Especially refrain where not needed from layouting calls: (in)validate.

I have now isolated the code only to find out that it works isolated. It seem to be related to the context (a very complex form) that it is put in. Now a SSCCE is completely impossible, but any input is still appreciated.

Related

How to force-refresh/repaint a JScrollPane?

I am adding lots of components (JPanels, JLabels etc.) into a JScrollPane programagically at the start of my program based on some stuff from a database.
It seems that this procedure is too fast for the GUI(?), so the JScrollPane does not always update correctly, i.e the scroll bars are not visible even though the inner JPanel is bigger than the visible area.
Resizing the Window (JFrame) fixes the problem, as I assume Java is re-printing the components when they are resized.
As a test, I have added a debug-button that I can click after the startup of the program has finished. I am trying to force the JScrollPane to "refresh" itself.
I have tried doing:
scrollpane.repaint();
scrollpane.validate();
scrollpane.revalidate();
None of them seems to work. However, if I change the border (or any other layout related to the JScrollPane), it refreshes correctly.
scrollpane.setBorder(new LineBorder(Color.RED));
So I basically have 2 questions.
What is the command for forcing the scrollpane to "refresh"? Obviously it is doing some kind of "repaint" thing when I am adding the border. How can I run that only?
Is there a way of "pausing" the printing of components as they are added and resume it again after I added all the wanted components? As it is now, I basically "see" the components being added on the screen (even though it is really fast). It would be better if I can add all the components I want and THEN tell the program to print it to the screen/JFrame.
The basic code for adding components to a visible panel is:
panel.add(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Adding a component does nothing because the component still has a zero size so there is nothing to paint. When you invoke the revalidate() method the layout manager gets invoked so components will now have a location/size. The repaint() will then paint the components. The revalidate() will also cause the scrollbars to show when required. This of course assumes you are using layout managers.
The components are added to the panel so you invoke the methods on the panel, not the scrollpane.
In my case only
frame.pack();
helped to get the scrollbars on the JScrollPane, when the enclosed JPanel was resized dynamically.

Swing components twitch when resizing JFrame

I have an undecorated JFrame which has a lot of components inside it (such as JSplitPanes, JPanels with GridBagLayouts, BoxLayouts, BorderLayouts etc). The code of building this JFrame is 2500 lines length, so I wouldn't place it here, or it's simpled version, sorry.
When I drag the JFrame by right or bottom side, it resizes OK, but when I drag it by left or top side, the components inside the JFrame are twitching a lot, so it looks very ugly.
My question is: Why does it happen? How can I prevent it (if I can)? Does anyone fix that in own practice?
UPD: I've written my own resizer for JFrame. It works OK for other windows, which have less amount of components.
Resizing the frame implicitly validates the enclosed Container, which causes doLayout() to be invoked on the affected components each time the size changes. You can see a similar effect in repeated calls to paintComponent() when resizing this AnimationTest. As you observe, using thousands of components scales poorly. As an alternative, leverage the flyweight pattern to render only visible cells, as is done in JTable, JTree, JList, etc. If you can't use one of these, CellRendererPane, seen here, may help.

Render Newly Visible Portion Upon Scrolling on JScrollPane

I have a large JPanel embedded in a JScrollPane. When I move the scrollbar, I notice that the visible portion does not render itself and I get glitches. Whereas when I resize the frame, I can see the new visible portions rendered. So I need to know which methods are fired upon frame resize to repaint the view. What listeners/methods should I use?
So I need to know which methods are fired upon frame resize
You don't need to know that. All you need to do is change the value of the scrollbar or the position of viewport and the component should repaint itself properly. If it is not painting properly, then you have a problem with something else. Maybe
incorrect custom painting code
the code is not invoked on the EDT
If those suggestsion doen't help then you need to post a proper SSCCE that demonstrates the problem because we can't keep guessing what your code is doing.
Did you revalidate the panel?
It might be that something is not right in the code of yours.
I have been using lots of scrolls and never had an issue as you describe.
Maybe a code sample showing the problem would be nice.
Good luck, Boro

JPanels, Listeners and Threads

For a school project I'm writing a BlackJack card game in JAVA.
After a few steps within the program, my whole computer system slows down/stutters and some areas within the JFrame turn black. No repainting seems te be happening.
I will give you some program details in words rather then submitting the code.
I have done some extensive extending of almost every GUI component to give it the look and feel that I want. Almost every child of JComponent that I use has got its paintComponent rewriten with custom image backgrounds and anti-aliasing where applicable.
In my (custom) JFrame I load an extended version of JPanel. This panel holds all the GUI components for that screen. When I want to switch screen (go to a different part of the program), I switch to another extended version of JPanel. I do this by removing all elements from the JFrame and add the new panel. These different panels implements ActionListeners and FocusListeners.
At this point my thoughts are leaning towards a thread handling issue. My theory for the moment is this: When a panel is constructed for display in the JFrame (each on different stages within te program), the previous constructed panels aren't realy 'destroyed', and the Listeners of those panels remain active.
My question for you people is, wether this theory holds ground... And in that case, is there a way to 'kill' these panels or at least stop the listening?
If my theory doesn't make sense, what else could be causing these symptoms? Could it be the extensive overwriting of the paintComponent methods?
Any ideas would be highly appriciated!
Regards Wilco
When a panel is constructed for display in the JFrame (each on different stages within te program), the previous constructed panels aren't realy 'destroyed', and the Listeners of those panels remain active.
No. Events are only dispatched to the component that has focus. It a comonents doesn't have focus then it won't received system generated events like KeyEvents and MouseEvents. So if a panel isn't visible then it won't receive events.
I switch to another extended version of JPanel. I do this by removing all elements from the JFrame and add the new panel.
This is not the best design. It is better to use a Card Layout which was designed for this purpose.
Almost every child of JComponent that I use has got its paintComponent rewriten with custom image backgrounds and anti-aliasing where applicable
Then you probably have problems with your custom painting. What happens when you just use the standard components without custom painting?

Java JPanel redraw issues

I have a Java swing application with a panel that contains three JComboBoxes that do not draw properly.
The combox boxes just show up as the down arrow on the right side, but without the label of the currently selected value.
The boxes will redraw correctly if the window is resized either bigger or smaller by even one pixel.
All of my googling has pointed to calling revalidate() on the JPanel to fix this, but that hasn't worked for me.
Calling updateUI() on the JPanel has changed it from always displaying incorrectly to displaying incorrectly half of the time.
Has anyone else seen this and found a different way to force a redraw of the combo boxes?
Can you give us some more information on how you add the combo boxes to the JPanel? This is a pretty common thing to do in Swing so I doubt that it's a JVM issue but I guess anything is possible.
Specifically, I would double check to make sure you're not accessing the GUI from any background threads. In this case, maybe you're reading the choices from a DB or something and updating the JComboBox from a background thread, which is a big no-no in Swing. See SwingUtils.invokeLater().

Categories