Is there a way to change the default background painting of all instances of a swing component (a JPanel for example) to paint with a gradient background? Or would I need to create an extension of JPanel that paints with a gradient and then use that instead of JPanel everywhere in my app?
IMHO, it would be easier to just subclass the Swing component and override its paintComponent method to do the gradient painting. And then, as you said, use this custom component throughout the application.
It could be tricky using the UI properties since they may not be consistent across all LaFs.
It is not entirely clear what scope you intend. Did you mean by class (so all JPanel instances follow the new painting scheme), or do you mean all components in a Container (e.g. everything in Frame)?
There are possibilities to do this depending on component class, the places where you can hook into are the Look and Feel, and on a by component instance base, either the paintComponent() method, or if you need to replace the standard look of an existing component where you can not overwrite the method because you have no control over it, by providing your own UI class (look at Component.setUI) after the component has been created.
Except for the overwrite paintComponent approach neither is simple to implement. For most applications the simple approach is the best :)
Related
just beginning to learn java and was playing around with Jframes, Jpanels and Graphics and was wondering why is it that we must override the getPreferredSize and PaintComponent method to make a graphics object appear in the Jpanel that has been added to a Jframe?
You don't "need" to, but it sure will help.
A base component (like JPanel and JComponent) has a preferredSize of 0x0, which, when used with some layout managers, makes the component virtually invisible (in fact, the painting sub system won't even paint a component which has a size of 0x0).
In everyday use, they calculate their preferredSize through the layout manager that is applied to them, which uses the child components to calculate the result.
So, in the absence of child components, you need to provide appropriate sizing hints, so when you use something like JFrame#pack, you don't end up with a "flat packed" window or sit around for a few hours wondering why you awesome component won't show up
My question is whether the use of setOpaque(false), which I've come to use with JPanel to layout UI in Swing, impacts painting performance more than keeping everything opaque (where isOpaque() returns true).
I'm not very familiar with how Swing renders UI but I would guess that if a JComponent is not opaque it would be harder to render what's behind the component then to simply paint an opaque background on the component.
Yes it does add extra work when painting but I doubt you would have to worry about it.
Basically, whenever you repaint a component that is transparent you need to go up the chain to find a parent that is not opaque and then paint that component first, before painting the child component.
So the bottom line is don't worry about it. If you have a reason to use transparency then use it. If you don't have a reason then you shouldn't be using it.
You may want to check out Background With Transparency. It goes into a little more detail on what the opaque property means and how it affects painting and the problem you will have if you do use a transparent background.
Can we draw things on any Swing GUI component? If yes then Why should we use a panel as
a canvas for drawings rather than a label or a button?
Start by taking a look at Perfoming Custom Painting for details about how painting is done in Swing
The second part of your question depends on what it is you want to achieve.
Generally speaking, you shouldn't paint directly onto existing components because painting is actually done by the UI delegate. If you want to change the look and feel of these components, you should consider creating a custom UI delegate to perform the painting as you need. This ensures that the painting is done correctly.
This doesn't stop you from overriding its paintComponent method, but with complex controls like buttons, lists, tables and trees, you may find it difficult to achieve the results you want.
Equally, tables, trees and lists use renderers to provide customised output
Lets assume a label is a price tag and a panel is a piece of paper. Do you usually paint() on buttons and price tags in real life? :)
Labels and Buttons have a lot of extra "features" and capabilities that will probably get in your way or bite you with bugs. JPanel is, almost literally, a clean slate on which to start.
I have a functioning Java applet which can be embedded into a web page and wish to now add some swing components for additional functions. However whenever I add a component like a JLabel, it simply does not appear on the viewport/canvas unless I remove my entire paint method. The latter option allows me to add swing components but naturally I then cannot render any shapes. It appears to resemble an eXclusive OR (XOR), either one but not the other.
Is there anyway in a native Java applet to add swing components and still maintain the paint(Graphics g) method. Please note that I am inheriting from Applet and not JApplet.
If you override paint method in applet then there is no simple way.
What you could do instead of overriding paint in applet.
Extend JComponent instead and do the custom drawing there.
create JPanel that contains all the needed swing components including the component from earlier step.
Add that panel to applet which is using default paint method.
I suggest that you add the components to a separate panel that doesn't override paint. By overridding paint, you are customizing the way the component is drawn, so the layout manager and the components it has to manage do not count, it's only the implementation of paint you wrote that dictates how stuff is rendered.
So, your applet would contain a panel with the components and a panel that does the custom painting.
At the end of your paint method, call super.paint(g).
I was able to visualise the components over the applet canvas by invoking
paintComponents(g);
Thus the components are thereafter painted AFTER the actual paint(Graphics g) method completes its epoch.
I just looked a the source code from JSlider SourceCode
and if found a lot of repaint()'s as expected, because of the Template Pattern.
But my problem is i didn't find the paint method, which actually paints the JSlider.
Can anybody explain me how this component will be painted?
Swing components are typically painted by their associated UI class. The UI class is specific to each Look And Feel. This is how you get JSlider to have a "native" feel or even a custom feel on different platforms. Each Swing component has a UI class, JSlider has SliderUI which has several flavors such as: MetalSliderUI, WindowsSliderUI, and SynthSliderUI.
You didn't find a paint method in JSlider because the paint method is in the parent class, JComponent. JComponent's paint methods (paint, paintComponent, repaint, etc) do some setup but then delegates the work to the UI class, which is provided by JSlider. There is an entire method chain that takes place in Swing for correctly painting/sizing components.
If we knew what you were trying to do we might be able to help you out.