How to debug Java Swing Layouts - java

There is one method which prints layout information for particulat components. I knew one method is there but I forgot the name.
When you call that method for Swing component it displays layout information in detail for that component just like dumpstacktrace call.
Any idea? What is that method name? I read it in one book but forgot it. Or let me know some good ways to debug Java Swing layout.

When your JFrame is visible press CTRL+SHIFT+F1 and see the console output for the tree hierarchy of components and layouts.

I don't know about a specific method for this by you can do this with a key press at runtime.
Take a look at page: Troubleshooting AWT
It provides the following debugging tip:
To dump the AWT component hierarchy, press Ctrl+Shift+F1.
It also provides other tips for layout debugging under the section "Problems With Layout" and there is another section dedicated to swing "Troubleshooting Swing"

Each Container (and this includes all JComponents) has a getLayout() method which will return the layout manager that has been set for this component or null if none are set (but remember that many are given default managers). You can also getComponents() to return an array of the components held. If you want to see all layout managers, you'd have to write a recursive method to go through all the components held, check that they inherit from Container and then call the above methods.

Related

setLocation() does not always work with JLabel objects inside a panel with no layout manager, is this a bug?

So I've search these forums for an answer to this question and can't seem to find one.
First let me state that I completely understand why going with a null layout manager is a bad idea and in this case I basically have no choice. I'm working with a legacy code base and it would be very time consuming to try and write a custom layout manager to perform the correct layout. Some relevant info:
The size of this component never changes
This size of the child components never change once they have been added to the parent
Only the number and location of child components change when a user action dictates they should
This code is not localized
I can't post code examples as the code is production software and would be too lengthy for this forum
The code flow is as follows:
When the parent component is created the layout is set to null in the constructor.
When a user action dictates that they want to display information the child components are created and added to the parent.
Then the correct location for each component is determined and the location is changed via setLocation().
One of the types of child components are 1 or more JLabel objects. This is the object I'm having problems with. In certain cases the call to the JLabel's setLocation() function will have values of x= 52 and y = 0 yet the JLabel gets put at the location x = 0, y = 0. I've already confirmed that the location isn't being reset to 0,0 by some other area of the code so now I'm left with the thought that maybe there is some obscure bug in the Java implementation that is causing the problem. Otherwise, why would it not respect the call to setLocation()?
I am going to confirm the setBounds() isn't being called on the JLabel by any other area of the code. Are there any other calls that could affect the position of a component when a layout manager is NOT being used?
With absolute positioning you have to consider three steps, you've already done the first step by setting the layout to null.
The next step is whenever you add a component to the container, you've to use setBounds(x,y,width,height) method on that component.
You only used setLocation() method without setting the size of the button, you have to use setSize(width,height) method also if you want the button to be displayable.
After all, don't forget to call the Component class's repaint() method.
I have done some experiments with setLocation() in java
https://dl.dropboxusercontent.com/u/27670533/ani_test.rar
this are the src file take a good look at the them maybe it helps

Managing JInternalFrames in a Swing MDI

When creating an MDI Swing GUI, I have a number of JInternalFrames that are added to a JDesktopPane in a JFrame. I make these internal frames invisible by adding setVisible(false) in the constructor, after the initComponents method (as the GUI builder automatically sets these frames visible in this method).
At runtime, the user can choose to open and close the JInternalFrames by invoking listeners that call setVisible(true) and setVisible(false), depending on the current state of the frames. I like how the previous position and state of an internal frame remains intact using this design. However, something tells me this must be terribly wrong, even though I haven't seen any drawbacks yet.
So, my question is: is this poor design?
In the context of a Multiple Document Interface (MDI), this approach is quite reasonable. In addition, you can use the JInternalFrame method setSelected() to highlight a particular frame. To ease navigation, this and other methods can be used in Action, as shown here.

JDesktopPane - how to get active frame

How to get active (having focus) frame (JInternalFrame) that is inside JDesktopPane? I need it for my MDI notepad (not that anybody would use that, just a training project). Looking at api, I see only functions to get all JInternalFrames, not active one.
Use JDekstopPane.getSelectedFrame() method (From doc: currently active JInternalFrame in this JDesktopPane, or null if no JInternalFrame is currently active.) or JDesktopPane.getAllFrames() to get list of all JInternalFrames currently displayed in the desktop and check isSelected() method.
Make a List<JInternalFrame> and check isSelected() as you iterate though it.
Addendum: See also this example that uses Action to select an internal frame from a menu.
Have you looked at the Java tutorial titled How to Use Internal Frames? In your code you need an InternalFrameListener (API) (Tutorial) and listen to activate/deactivate events. Activated means the internal frame was brought to the top; deactivated means it's no longer on top. Since JDesktopPane extends JLayeredPane you can also set the z-order of components added to it.
Don't iterate over all the panes - use events.
If for some reason you prefer to poll your UI rather than use an event-driven approach you can call getSelectedFrame which returns the active JInternalFrame. I'm not sure why no one else mentioned it.

Getting correct sizing behaviour in a custom Swing component

I'm creating a custom Swing component that inherits from JPanel.
What is the right way to override/implement the various sizing methods (getPreferredSize, setPreferredSize, getMinimumSize etc.) in order to get "good behaviour", particularly with regards to:
Working with different layout managers
Behaving correctly when setPreferredSize() is called
Reacting appropriately when a border is set via setBorder()
Don't inherit from JPanel unless your component is a composite of several subcomponents. In most cases inheriting from JComponent is enough.
As far as resizing goes... override getPreferredSize, getMinimumSize and getMaximumSize methods to get an appropriate behavior in layout managers.
If your component is a composite of subcomponents in most cases preferred size is already defined by combination of your subcomponents so you don't have to override this one.
Although rather annoying: that depends, on the layoutmanager in this case. Usually the layoutmanager can best be used along with constaints to get a good layout.
I've used GridBagLayout, and after getting used to it, I found it worked pretty well using right GridBagConstraint for each component.
Sometimes a good visual ui designer can help too, like the one from Netbeans, or you could consider a paid one like Swing Designer or JFormDesigner. Can save you some time fiddling with pixels.

What does Container.validate() method do?

There seems to be many methods in Java awt Container class that are related to validate. Apparently they don't do data validation. Is it useful for a Swing developer in any cases? Some of the methods:
validate(), invalidate(), validateTree(), isValid() etc.
Citing the API doc:
The validate method is used to cause a
container to lay out its subcomponents
again. It should be invoked when this
container's subcomponents are modified
(added to or removed from the
container, or layout-related
information changed) after the
container has been displayed.
Validation in a Swing context concerns requesting a component to lay-out its sub-components after one of these is modified.
For example, suppose you implement a custom JDialog with a button "Show Filters". Upon clicking this button, you might want to add an additional "filter" panel to the south of the JDialog. Upon adding the new sub-panel you would be required to call validate() on the JDialog to cause it to lay-out the new panel correctly.

Categories

Resources