Swing components twitch when resizing JFrame - java

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.

Related

Java Swing - More efficient to draw in multiple panels or a single panel

If one has the choice between doing all rendering in a single JPanel or rendering across multiple JPanels (with override paintComponent) and one is not using any other Swing component such as JButtons, JTextBoxes, JComboBoxes, etc (other than the JFrame that the panel or panels reside in). If one is only drawing using drawLine, drawRectangle, fillRect, etc. Is it more efficient to draw everything in one panel or spread the drawing out over multiple panels? Assume that the code complexity is the same either way and reducing lag / improving response time is important.
It is slightly more efficient.
However, consider using several panels and rely on the layout managers to handle sizing etc. It will most likely simplify your code. If you are using one panel only you will have to handle resizing yourself.
In programming, don't optimise before you know performance is a problem. Measure!
Swing will only paint a component when it needs to.
If the entire frame is repainted every time a property changes, then keep the logic together in a single place for ease of maintenance.
If it is logical to break the panel down into sub components, then you can repaint individual sub components as necessary.
For example, this is the way a JTable works. You can have a hundred row in the table, but if you only change the data in one row, then only that row is repainted.

Swing JScrollPane resets scroll position when updating

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.

Java: MouseEvent on transparent JPanel

I have a LayeredPane with two JPanels, all in a JFrame. Both JPanels are set to be transparent with setOpaque(false). However, I would like to capture mouse events on the (top, if it makes a difference) transparent panel. Is this possible, or should I just do it from the underlying JFrame? (It would definitely work to capture from the JFrame; it just makes more logical sense to capture the events from the transparent frame).
You can capture mouse events on whichever JPanel has a MouseListener attached to it, and is not encumbered by components that also have MouseListeners added, and who are laying on or above the original JPanel. This looks like a situation perfect for creating a small test class that is the most simple of GUI's, that has none of the bells and whistles of your GUI, but that illustrates your problem and hopeful solution.
Also, please know that the transparency does not play into any of this at all except as a distraction.

How do I repaint after tooltip disappears?

I've created an applet which has one large panel to display data surrounded by several controls (buttons, textfields, etc.). The large panel contains several layers of labels which I render myself.
The controls all have tooltips associated with them, and some of these tooltips overlap the main panel. When they disappear, they leave a hole in the main panel image until the main panel is repainted.
Now mind you, this does not always happen. It only occurs when the cursor is in a certain range. If you get far enough to either the left or right (no difference noted for changes along the Y axis), the holes are painted over when the tooltip disappears.
I'm not well-versed on how tooltips and repainting are supposed to work, and if this is a sign that there's something dreadfully wrong with my program, but if I can just call repaint on the main panel whenever the tooltip disappears, I should be fine. Is there something I can override in tooltip to make this happen?
I'm using Swing
Thanks.
To answer your question (after you found a solution by the comments): Swing has some quite elaborate repaint management built in. When a tooltip disappears, the rectangle below it is repainted.
Now, which components have to be repainted? All those who overlap with the given rectangle, and are not themselves hidden (in the region in question) by other components - but only opaque components count here. (This is the whole reason we need the opaque property on JComponent - to optimize repainting.)
Your label declared itself being opaque, but did not really paint its whole area on a paintComponent, and such the region of the tooltip which should have been covered by the label stayed unpainted.
Declaring your label to be partly transparent caused also the concerning region of the component behind it to be repainted.

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?

Categories