I have a problem where I have several similar JPanels, that are contained vertically in a main JPanel. My issue comes where I will have buttons that will only interact with the child JPanel that is currently selected (clicked on).
I have a controller that takes the main JPanel, how can I have a method that will return only the selected JPanel?
This is very difficult. By default, JPanels are not focusable (they can't receive keyboard focus).
You could try ascertain the current panel that contains the current focusable component by using KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); and using the resulting Component's getParent method, but this is no guarantee, as the focused component may be contained in another container, contained within the container your interested in...
A better idea might be to have some kind of model that connected the buttons or actions to the child panels...?
Related
I have a JFrame as my main class and made it focusable, given it a MouseListener and added some JPanels.
In the JPanels I have Environment classes that display images. Each JPanel only covers a part of the JFrame, and the Environments likewise cover a part of their parent JPanel.
I need to know how to properly capture MouseEvents and pass them down through the chain to the correct Environment so they can be dealt with properly and update the corresponding image associated with that area
Are there methods built into the JFrame and JPanel that can at least get me as deep as the JPanels or would I have to implement them myself?
I don't want to have to implement handlers for all the different MouseEvents, just pass the object down so that it can be handled at the lowest level.
Any suggestions would be appreciated
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?
I have problem with panels. I have one main panel main_panel, at top I have ComboBox,
based on selected item in combobox I need to show one of two panels under (bith have lot of buttons on positions x,y. if selected_item_1 then panel_1 visible,if selected_item_2 thenpanel two visible). How to add button to child_panel on exact position locX,locY?
CardLayout is ideal for this type of behaviour.
A CardLayout object is a layout
manager for a container. It treats
each component in the container as a
card. Only one card is visible at a
time, and the container acts as a
stack of cards. The first component
added to a CardLayout object is the
visible component when the container
is first displayed.
It's a job for CardLayout. besides, if content must change according to a selection, maybe you should go the JTabbedPane way ...
How do you refresh a JPanel on the panel change from container CardLayout?
Use the show() method. From the Java API:
Flips to the component that was added to this layout with the specified name, using addLayoutComponent. If no such component exists, then nothing happens.
CardLayout#first(), next(), and previous() do something similar.
Sometimes, when I've made a panel swap like this (though not that I can remember on CardLayout, but it's been a while since I used it), I've also needed to pack the frame again. If that doesn't work, you can call revalidate(), which lets Swing know that the component needs to be redrawn.
You may also want to consider using a tabbed pane, as it does a lot of this for you; I started out a project trying to use CardLayout and decided to use a the tabbed pane instead. Depends on what you want to do, of course.
Is there an actionlistener or something that I can have it reload/refresh my data on that screen?
Assuming you have a model that supplies data to your view (panel), two approaches are common:
Arrange for your model to extend Observable and your view to register as an Observer.
Arrange for your model to manage an EventListenerList, in effect creating you own analog of ActionEvent.
In either approach, use the listener of the control that switches views tell the model to update its registered observers/listeners. The example in How to Use CardLayout uses a JComboBox and itemStateChanged(). There's additional discussion here.
Is there an actionlistener or
something that I can have it
reload/refresh my data on that screen?
You can use an AncestorListener. It fires when a component is added to a Container. So when you swap cards the event is fired. You would need to add the listener to each panel you add to the CardLayout:
Another problem with the CardLayout is that the panel doesn't gain focus when it is swapped. I use this approach to set focus on the panel. Check out Card Layout Focus.
panel.addAncestorListener(...);
The show() method does the trick of switching panels, but it doesn't "refresh" the data. Is there an actionlistener or something that I can have it reload/refresh my data on that screen?
Is it possible to place a child component inside a JButton and make it transparent to a subset of mouse events so that:
The child component receives MouseMotionEvents (so it can respond by modifying a displayed image)
Clicking still depresses the JButton "behind" the child component
If you add the child component to the button but make no other changes, clicking in the area occupied by the child does not activate the button.
I know this can be achieved by creating a new class that extends JButton but I would prefer to use a child component which has already been written.
Note: this is purely for cosmetic reasons. The child component only changes its own appearance. It does not perform any other actions in response to clicks. There is just one Action, triggered by the button in the normal way.
Yes, it is possible but probably there are better ways to change the appearance of a JButton on mouse over. You can extend a ButtonUI to do that. However, if you want to drop a component over a JButton, you should pass other mouse events (e.g clicks) to the underlying JButton.
JXLayer is just the thing you need. Check out https://jxlayer.dev.java.net/
The project site has several good articles about JXLayer's usage for many different use cases.