Java: MouseEvent on transparent JPanel - java

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.

Related

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.

Is it appropriate to extend JPanel to create a drawing surface for a 2D game?

I'm converting a 2D game from an Applet to a JFrame. I know I should add a JPanel to a JFrame and use the JPanel as my drawing surface but I'm not sure exactly what I should be subclassing. I was trying it with JFrame but I've read that it's usually unnecessary and a bad idea to extend JFrame (I wasn't adding any extra functionality anyway, so that makes sense). I need to override the paintComponent() method of JPanel so right now I'm leaning towards extending JPanel. Is there a better way of creating a 2D game surface or is extending JPanel and adding that to a JFrame an appropriate way to do it?
No, there is no better way, that's a very good option.
If you would extend a JFrame (the other option), your animation would blink on most windows family OS.
JPanel is a pure swing component and reacts better in java than a peered component like a JFrame.
Your choice is good, go ahead and have fun programming.
update
My knowledge in this area has grown since I originally answered the question and I agree with #Snicolas that you should use a JPanel.
JPanel (because it's a swing component) has builtin support for double buffering (AWT does not) and has better performance (so I hear, but I have no first hand experience with this).
You may find this article useful: http://www.oracle.com/technetwork/java/painting-140037.html#swing
original answer:
I recommend you subclass Canvas or Component or JComponent. My preference is Canvas. You should read the 2d graphics tutorial.
update
Use Canvas because it receives all the user input events and doesn't have the baggage of being a container. read more. Panels don't receive all mouse input events, for instance.

How can I change colors of components when the mouse is pressed in a JFrame in Java?

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

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