As i wrote in the title, I've this problem with JPanel.
My page is structured as a mainJPanel, another JPanel inside the main (where I paint a background) and some component added to this background panel.
Everytime I interact with something (for example i click a button) the background of the components fade to a lighter version of themselves.
I really can't figure out why.
mainPanel have setOpaque(false) and setLayout(null);
backgroundPanel have setOpaque(false) and setLayout(null) (i painted the background when i create the class backgroundPanel that extends JPanel, with an override of the method paintComponent);
all the components that becomes lighter have setOpaque(true) and setLayout(null);
the background of this components are a custom grey (rgb(232,232,232)).
Thank you all
Using setOpaque(false) should not cause a problem (ie. JLabels are non opaque). It sounds like a painting problem when using transparent colors.
Check out Background With Transparency for an explanation of the problem and a couple of solutions.
Related
I'm trying to paint over every component in my Swing application.
what I have:
jButton b = new JButton();
b.addActionListener(e -> fillEntireScreen())
f.add(b);
f.setVisible()...f.setSize()...f.setDefaultCloseOperation()...
where fillEntireScreen() simply is an animation that expands over the screen. I override Component's paintComponent(), painting over the frame, not a panel or anything.
fileEntireScreen() works without the button, but does not work when I add the button, as the animation is behind the button.
how can I paint over the button?
Thanks!
Use a glassPane instead - See How to Use Root Panes for more details and How can I paint in an specific JPanel when more than one in same frame- Java for an example.
Alternatively you could use a JLayer, but's more complicated and may not suit your needs. See How to Decorate Components with the JLayer Class
I have an LWJGL OpenGL Display showing up inside an AWT Canvas, which in turn is inside a Swing JPanel that is used as content pane for a Swing JFrame. At some point in the program, I want to switch the AWT Canvas containing the Display for a JComponent, so that instead of having something like that:
JFrame > JPanel > Canvas > Display
I have something like so:
JFrame > JPanel > JComponent
However, even though I remove the Canvas from the JPanel and add the JComponent, then revalidate the JPanel and repaint it, the Display still shows until I CTRL-ALT-SUPPR to task manager (my JFrame is set Undecorated and ExtendedState is JFrame.EXTENDED_BOTH, so it is full screen). At which point, the JComponent shows up like nothing ever happened..
I'll share the part of my code that does the transition so you can maybe help me point out what I have done wrong:
public static void switchTo(Container container){
pan.removeAll();
container.setBounds(0, 0, Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
pan.add(container);
frame.getContentPane().validate();
pan.revalidate();
pan.repaint();
}
where pan is my JPanel and frame is my JFrame.
I have also tried directly setting my JComponent as my JFrame's content pane, but that gives the exact same result.
The only way I managed to make it function correctly was by calling destroy() on the Display beforehand; however, I need to keep the OpenGL context running so that I don't have to re-initialize the Display and reload every texture when switching back to the Display, which would be quite a long process given the number of textures I have.
Thank you very much for any answer, I hope I made myself clear!
I added a background image to a JFrame using a JLabel. But there are other JLabels in a panel added to the particular JFrame. After adding this background image all over the JFrame, other JLabels are not visible. How do I get them be visible?
Several options:
Make the JLabel opaque and make it the contentPane, giving it a decent layout, give it a decent getPreferredSize() override that makes sense in the context of your problem (JLabel's own override for this method won't work for you, since it depends on text and icons that the label holds and not on components added).
And then add other components to it -- to the JLabel.
Or:
Use a JPanel as the background image displayer
Display the image in its paintComponent(...) method override.
Give it decent layout manager(s) and if needed, a getPreferredSize() override.
Also:
Take care that some added components, such as other JPanels, are set to be non-opaque.
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.
In short, my need is to have a background Image in my java app, and upon some event, create some other graphics on top of that image.
I was thinking I would use a JPanel to draw the background image in, add it at to my JFrame the start of program, and then add other JPanels on top of that upon certain events. The problem is Swing gives the JPanels added first the highest Z index, so what should be my background is showing up on top of everything.
Is there any way to control the Z index/order of the JPanels, or am I going about this completely wrong?
You can use the setComponentZOrder() to handle Z-Order in your application.
Resources :
JavaDoc - Container.setComponentZOrder
oracle.com - Mixing heavy and light components
Sounds strange to add mutiple JPanels and use z-order. I would suggest you either simple add ONE JPanel with the paintComponent(Graphics g) method overwritten, where you draw the correct image according to your events.
Or use the CardLayout, and add JLabels (with different images), then when your event triggers, use
CardLayout cl = (CardLayout)getLayout();
cl.show(this, "card3");
to show the correct JLabel.
The JLayeredPane is designed for just this purpose. It allows you to control the Z-order of components.
I was thinking I would use a JPanel to
draw the background image in, add it
at to my JFrame the start of program,
Sounds reasonable.
and then add other JPanels on top of
that upon certain events. The problem
is Swing gives the JPanels added first
the highest Z index, so what should be
my background is showing up on top of
everything.
Adding a panel to a panel is just like adding another component to the panel. The child component will be painted on top of the parent panel. There is no need to play around with Z-Order.
The key is to set a layout manager on the panel with the image. Then each panel you add to the image panel must be made non-opaque so that the background image will be painted.
Maybe the Background Panel can help you out. It automatically makes any component added directly to the panel non-opaque.