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.
Related
I want to create a shop by having a main JPanel that each component inside it is a JPanel with an image, label and button.
I did tried using a JList but the problem with the JList its only holds the rendering of the component and because of that the button isn't working and its only an image. I can walk around and use MouseEvent but it feels wrong for me and I am sure that there is a better solution for it.
I want that the components will change their positions depend on the frame size, like in the JList.
For example, if I change from the width of the screen the positions of the components will change from this:
to this:
I do have an idea by using GridLayout or GridBagLayout in the paintComponent (because it calls every rendering. If you know another method that calls every rendering int the JPanel I would like to know) and changing the positions of the components by changing the layout variables inside the paintComponent.
I did surfed the internet to find a solution but I only found that people used JTable but I don't see it working here.
each component inside it is a JPanel with an image, label and button.
Makes sense.
changing the positions of the components by changing the layout variables inside the paintComponent.
The paintComponent() method has nothing to do with changing the layout of the panels. You should not be playing with the paintComponent() method.
I do have an idea by using GridLayout or GridBagLayout
You are correct to use a layout manager, but unfortunately, none of the default layout managers will wrap automatically at a random number of components.
The layout managers are invoked automatically as the frame is resized.
So you can use the Wrap Layout which is an extension to the FlowLayout that will allow random wrapping.
I am coding a piano in java using rectangles from the java.awt.graphics library. I am using a mouselistener to play the sound of each individual key when the mouse clicks a certain area on the JFrame.
How would I add a shape to the panel upon clicking, repaint, then repaint the keyboard back over top when the user releases the mouse?
Consider adding JLabels to a JPanel that uses GridLayout. Give each JLabel a MouseListener and either swap ImageIcons on mousePress/mouseRelease or change the JLabel's background with press and release. If you go the latter route, you'll want to make sure that the JLabels opaque property is set to true so that the background colors show.
Then for the black keys, you can add the above JPanel to a JLayeredPane and on top of this, add another JPanel that holds the black keys that function in the same way.
Also, you'll want to take care to "play" any notes in a background thread, such as can be obtained with a SwingWorker so as not to tie up the Swing event thread and completely freeze your program.
Consider solution: source
It might not be exactly what you're after, but it might give you an idea of how to approach your problem. It took me a long time to figure out how to use JLayeredPane without setting a null layout, but in the end this was the best I could come up with. Also, assumed some naming conventions for your sound files. :p
I've implemented a custom JPanel, whose paint method I've extended to do a lot of manual rendering in full screen mode. Now I would like to integrate another JComponent to this (in my case a JPanel that contains a JScrollpane with a JTextPane as its viewport) that should appear on top of my first panel, but because my custom rendering pipeline is complex, adding the JComponent to my panel and having it painted the traditional way through the AWT system is not an option (I tried and it's quirky at best, not functional at worst), so my question is: is it possible to manually order the JComponent to be painted at one point in my program by calling its regular paint method without tying it to a JContainer and if yes, how do I do this?
Thanks in advance for your answers.
See the LabelRenderTest.java source on this thread. The label is eventually drawn to screen, but it is painted to BufferedImage before ever being displayed.
The important line of the source is..
textLabel.setSize(textLabel.getPreferredSize());
You can take a look at CellRendererPane and see how for example BasicTableUI paints component images with it.
Yes, just call the normal paint method on the object and pass the Graphics you want it to paint on. However, this is just going to paint it and it sounds like you want it to possibly scroll which means you will need to add it to your custom JPanel. In that case just add the panel and you a layout manager that will place the component where you need it.
You should set size for the component. Then to position it use your Graphics' translate(x,y) to position the component in desired Point.
if there is any container higher level in the hierarchy you can use
validate(); repaint();
pair to do that.
if not you can change it's size or bounds ( like +1 , -1 ) at the end to make it repaint itself.
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.
I have a JPanel with one component that I want to place in an absolute sense, whereas the rest of the components are placed according to a layout manager.
Is there a simple way to do this?
Are you saying you want a component painted over top of all the other components? If so then you would need to use a JLayeredPane.
Why don't you post a SSCCE that demonstrates what you want to do?
You can add components to a frame as you would do normally and make the frame visible. Then you can add this random component and use setBounds on the component. As long as you don't revalidate() the panel or resize the frame we will be able to see how you intend to position this component relative to all the other components.
You might also want to look at OverlayLayout, seen here. For some reason it's excluded from the conventional gallery, but it may be of interest.
You can do this with only needing one JPanel using MigLayout