This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 215528 - GUI Editor shouldn't set layout by default for Beans
Summary: GUI Editor shouldn't set layout by default for Beans
Status: RESOLVED FIXED
Alias: None
Product: guibuilder
Classification: Unclassified
Component: Code (show other bugs)
Version: 7.2
Hardware: PC Mac OS X
: P2 normal (vote)
Assignee: issues@guibuilder
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-13 15:41 UTC by fommil
Modified: 2012-11-08 02:54 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description fommil 2012-07-13 15:41:44 UTC
When I use the palette to add my own widgets, which extend JPanel, the GUI Editor insists on setting a LayoutManager for them. It shouldn't - I have gone to great lengths to ensure they are using the manager that is right for them. The GUI editor should mind its own business!

This is a bug, there should be an option to not set an explicit LayoutManager and this should be the default when inserting a user-defined visual component.
Comment 1 fommil 2012-07-14 19:07:44 UTC
The more I think about the lack of a "don't add a Layout", the crazier I think it is! Suddenly, a lot of really weird bugs I've experienced when using third party Components make a lot of sense - Netbeans is essentially resetting their Layout!

For this reason, I'd like to bump up the priority of this because it is a serious failing of the GUI Editor when using any custom or third party Components.
Comment 2 Tomas Pavek 2012-07-18 17:02:41 UTC
Are the components in question meant to be used as containers, or not? I.e. are they intended for having other components added to them?

Can you please attach or point us to a sample custom component that exhibits this problem? So we have a clear case for reproducing the problem, and later for verification? Thanks
Comment 3 fommil 2012-07-18 19:45:19 UTC
Test case is trivial, create any custom Component, e.g.

public class MyComponent extends javax.swing.JPanel { }

or

public class MyComponent extends javax.swing.JComponent { }

and then add it to a JFrame using "Choose Bean".

The GUI Editor will assign it a LayoutManager: with my defaults this is the Java 6 GroupLayout.

It is common practice for designers of custom widgets to extend JPanel, even if they do not intend their widgets to be used as containers. This is just a fact, regardless of whether or not it is the technically correct way to do things. (Incidentally, what would you rather people were to extend in order for their widgets to not be considered "container like").


My custom components are entirely self managed and it is no business of NetBeans' to go changing those custom layout values. (This is because they are dynamically created using logic which is best coded directly). I'm just using the GUI Editor to drop them into the right place.

If NetBeans must insist on displaying the LayoutManager in the Navigator, then it should be calling getLayout() to work out what it is - and be prepared to receive a LayoutManager type which isn't registered with the GUI Editor. Then if the user wants to change it, they can.

(Of course, it makes sense to talk about setting a LayoutManager for many J2SE Swing classes, just don't touch non-standard ones!)
Comment 4 Tomas Pavek 2012-07-19 15:04:48 UTC
If you do not intend to use the components as containers, you should specify that in the BeanInfo for the component. It is done by setting the "isContainer" property in BeanDescriptor provided by the BeanInfo to Boolean.FALSE. For instance see example in bug 23318. Then the GUI builder will not try to set its layout to the component since it will not be considered a container.
Comment 5 fommil 2012-07-19 15:08:36 UTC
That is a horrid approach to take.

The GUI Editor should at least offer an option not to touch the LayoutManager, or better yet - isContainer should be FALSE by default if there is no BeanInfo, since most custom components are *not* containers.
Comment 6 fommil 2012-07-19 15:12:38 UTC
Your proposed approach doesn't work if the custom components are third party.

The NetBeans-generated BeanInfo for my class is 1,000 lines long. Creating BeanInfos is simply not acceptable.
Comment 7 Tomas Pavek 2012-07-19 15:50:27 UTC
> isContainer should be FALSE by default if there is no BeanInfo

No, if the component extends java.awt.Container, the GUI builder must assume it is a container, and the opposite needs to be expressed explicitly. This is the convention used since JComponent was made, extending Container.

> The NetBeans-generated BeanInfo for my class is 1,000 lines long.

Do not try to generate it. Look at the example I gave you. The BeanInfo class you need can have just a few lines, only providing BeanDescriptor with one attribute.

> Your proposed approach doesn't work if the custom components are third party.

It's not a proposed approach. It's in place for more than 10 years ;). I still would like to see a meaningful example of a component that gets screwed by NetBeans because treated as container. I'm not saying it does not exist, just would like to see it. The example you provided:

  public class MyComponent extends javax.swing.JPanel { }

is just an empty panel. The difference of having GroupLayout instead of the default FlowLayout here is just in the preferred size (even empty FlowLayout imposes some size - is it used for that purpose?). Note that once such a panel would have some sub-components (initially), the GUI builder would not treat it as a container and it would work fine for you.

The conditions for recognizing a component as a container are:
* It must extend java.awt.Container.
* The instance created by default constructor must be empty.
* There is no isContainer false attribute in BeanDescriptor.

If a component is recognized as non-container, the GUI builder won't touch its layout. This way you can avoid the problems. If it is considered a container, then the question is whether the GUI builder should set its own layout. It does that now, OTOH for custom containers it may have some merit not to do it.

> The GUI Editor should at least offer an option not to touch the LayoutManager,

I have not been arguing with this. I just tried to give you a way that works already now which you can use immediately for your components without waiting on possible fix on NetBeans side.
Comment 8 Tomas Pavek 2012-07-19 15:54:10 UTC
> (This is because they are dynamically created using logic which is
> best coded directly)

I see. So your components technically are containers after all, but filled in dynamically, not in the GUI builder. I understand it would be more convenient if the GUI builder does not set them with GroupLayout.
Comment 9 fommil 2012-07-19 16:09:18 UTC
My custom component meets your first two criteria, but as I have not created a BeanInfo, then the attribute "isContainer" is not defined and therefore returns "null".

Some examples? How about JButton? I could describe my components to you but I think that is a digression. Say they set their own layout and then place a bunch of other components, primarily dynamically at runtime (hence why they are empty at construction) or handle their painting by drawing primitives. Due to inadequacies in FlowLayout, I'm actually using WrapLayout, a 3rd party extension.

The reality is that any custom component in Swing realistically extends JPanel, despite breaking the JPanel documentation rules (this is simply poor API design on behalf of Swing).

I am very surprised that the default - in the absence of a BeanInfo - is to treat a JComponent as a container. It may be technically correct, but since most custom components are *not* containers, it is incorrect in practice.

Thanks for the BeanInfo link, that is a lot shorter - my JFrame and JPanel forms are not refreshing with this new information. Is there a way to do this?



= Somewhat related =

The necessity to create a BeanInfo in the first place, for such a trivial detail, is a massive overhead. I've submitted an RFE with Lombok to try to make this easier*

https://github.com/peichhorn/lombok-pg/issues/104

* Actually, even ignoring this issue report, such a feature in Lombok would serve to help one of my future contributions to SwingX, which might interest you! http://java.net/jira/browse/SWINGX-1502
Comment 10 Tomas Pavek 2012-07-19 16:28:56 UTC
> My custom component meets your first two criteria, but as I have not created
> a BeanInfo, then the attribute "isContainer" is not defined and therefore
> returns "null".

So they meet all three conditions (there is no "isContainer" with false value) and so are treated as containers (inconveniently for you).

> Thanks for the BeanInfo link, that is a lot shorter - my JFrame and JPanel
> forms are not refreshing with this new information. Is there a way to do this?

Note that components added to the form before you create the BeanInfo are already saved as containers. The recognition (and check for isCOntainer attribute) is only done when you add a new component to the form.

If re-adding is difficult, you may try to edit the form file (change "Container" element of the particular components to "Component" and delete "Layout" sub-element).
Comment 11 fommil 2012-07-19 16:47:05 UTC
ok, form edit (and then opening the file in GUI Editor and forcing an update of the .java by changing the size) worked. Thanks!
Comment 12 fommil 2012-08-05 18:13:04 UTC
I've encountered another problem with this bug.

I've added the latest SwingX (and its BeanInfo package) to the GUI Editor.

One of the Container components provides its own custom LayoutManager, JXTaskPaneContainer, but GUI Editor insists on setting one of the "officially supported" Layouts and that breaks the container.

Again, I believe having a "don't touch the layout" option would be preferable here.
Comment 13 Tomas Pavek 2012-11-07 13:36:36 UTC
Improved this as part of a bigger fix:
http://hg.netbeans.org/jet-main/rev/1196c3966367

Now the GUI builder does not change layout of custom containers (unless it is a JPanel sublass with the same default FlowLayout, or a window with the default BorderLayout). It should work for your case. Please let me know.

This also fixes the problem with the SwingX' JXTaskPaneContainer.

In the Set Layout menu it's now also possible to see which layout is default and return to it.
Comment 14 Quality Engineering 2012-11-08 02:54:25 UTC
Integrated into 'main-golden', will be available in build *201211080001* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/1196c3966367
User: Tomas Pavek <tpavek@netbeans.org>
Log: #215528, #212792, #80042, #70683: improved handling of custom layouts, incl. unknown, also allowing to set default layout, plus some other fixes