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 123710 - [60cat] Master/Detail Sampe Form Generated can not be instantiated in GUI builder
Summary: [60cat] Master/Detail Sampe Form Generated can not be instantiated in GUI bui...
Status: VERIFIED FIXED
Alias: None
Product: guibuilder
Classification: Unclassified
Component: Binding (show other bugs)
Version: 6.x
Hardware: All All
: P1 blocker (vote)
Assignee: issues@guibuilder
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-12-09 20:48 UTC by wobster
Modified: 2008-04-08 14:45 UTC (History)
0 users

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
.java file of modified template (6.39 KB, text/plain)
2007-12-10 09:32 UTC, Jan Stola
Details
.java file of modified template (6.39 KB, text/plain)
2007-12-10 09:34 UTC, Jan Stola
Details
.form file of modified template (14.50 KB, text/xml)
2007-12-10 09:41 UTC, Jan Stola
Details
NetBeans attributes file for the template. (1.10 KB, text/xml)
2007-12-10 09:42 UTC, Jan Stola
Details

Note You need to log in before you can comment on or make changes to this bug.
Description wobster 2007-12-09 20:48:18 UTC
I generated a master/detail view in the NetBeans using the wizard. I can see the form in the GUI builder, but if I try
to add it to the Palette or drag the class to another Form, I get this error:

ALL [null]: The component cannot be instantiated. Please make sure it is a JavaBeans component.

INFO [org.netbeans.modules.form.BeanSupport]: Cannot create default instance of: org.austinjug.Registrants

javax.persistence.PersistenceException: No resource files named
META-INF/services/javax.persistence.spi.PersistenceProvider were found. Please make sure that the persistence provider
jar file is in your classpath.

	at javax.persistence.Persistence.findAllProviders(Persistence.java:167)

	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:103)

	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)

	at org.austinjug.Registrants.initComponents(Registrants.java:35)

	at org.austinjug.Registrants.<init>(Registrants.java:20)

	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

	at java.lang.Class.newInstance0(Class.java:355)

	at java.lang.Class.newInstance(Class.java:308)

	at org.netbeans.modules.form.CreationFactory.createDefaultInstance(CreationFactory.java:163)

[catch] at org.netbeans.modules.form.BeanSupport.createBeanInstance(BeanSupport.java:81)

	at org.netbeans.modules.form.BeanSupport.getDefaultInstance(BeanSupport.java:107)

	at org.netbeans.modules.form.MetaComponentCreator$4.run(MetaComponentCreator.java:1262)

	at org.netbeans.modules.form.FormLAF$2.run(FormLAF.java:232)

	at org.openide.util.Mutex.doEventAccess(Mutex.java:1223)

	at org.openide.util.Mutex.readAccess(Mutex.java:284)

	at org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:217)

	at org.netbeans.modules.form.MetaComponentCreator.prepareClass(MetaComponentCreator.java:1256)

	at org.netbeans.modules.form.MetaComponentCreator.precreateVisualComponent(MetaComponentCreator.java:210)

	at org.netbeans.modules.form.HandleLayer$NewComponentDrag.init(HandleLayer.java:2636)

	at org.netbeans.modules.form.HandleLayer$NewComponentDrag.<init>(HandleLayer.java:2631)

	at org.netbeans.modules.form.HandleLayer$NewComponentDropListener.dragEnter(HandleLayer.java:2916)

	at java.awt.dnd.DropTarget.dragEnter(DropTarget.java:337)

	at sun.awt.dnd.SunDropTargetContextPeer.processEnterMessage(SunDropTargetContextPeer.java:295)

	at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEnterEvent(SunDropTargetContextPeer.java:759)

	at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:727)

	at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:30)

	at java.awt.Component.dispatchEventImpl(Component.java:4267)

	at java.awt.Container.dispatchEventImpl(Container.java:2116)

	at java.awt.Component.dispatchEvent(Component.java:4240)

	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)

	at java.awt.LightweightDispatcher.trackMouseEnterExit(Container.java:4111)

	at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4049)

	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3911)

	at java.awt.Container.dispatchEventImpl(Container.java:2102)

	at java.awt.Window.dispatchEventImpl(Window.java:2429)

	at java.awt.Component.dispatchEvent(Component.java:4240)

	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)

	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)

	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)

	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)

	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)

	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)

	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Comment 1 Jan Stola 2007-12-09 22:26:54 UTC
It is not possible to instantiate and use entity manager in the IDE because the IDE itself is not set up as standalone 
JPA application. It doesn't have the correct persistence.xml in its META-INF directory and the GUI Builder doesn't have 
any persistence provider on the classpath. It is also a bad idea to attempt to connect to some database and load data 
inside the IDE.

So, if you want to use the master/detail panel as a bean then you have to modify it to overcome these limitations. 
java.beans.Beans.isDesignTime() method will help you to do that. This method can be used by any bean (e.g. by 
master/detail panel in your case) to find out whether the bean is inside the IDE or not. Hence, you should modify your 
template not to do any JPA stuff in the IDE.

For example, change the following line in the constructor
    entityManager.getTransaction().begin();
to
    if (!Beans.isDesignTime()) {
        entityManager.getTransaction().begin();
    }

You also have to modify the initialization of 'entityManager' field:
1. Select entityManager in Inspector window (it is under Other components).
2. Invoke Customize Code action.
3. Enter 'if (!Beans.isDesignTime()) {' before the (guarded) default code of the GUI builder.
4. Enter '}' below the default code generated by the GUI builder.
5. Make sure that the last combo-box on the left is set to 'post-create'.
6. Press OK.

Modify the initialization of 'query' in the same way.

Modify the initialization of 'list' in the similar way e.g. from
    list = ... <default code>
to
    if (Beans.isDesignTime()) {
        list = java.util.Collections.emptyList();
    } else {
        list = ... <default code>
    }

This is more a misunderstanding than a defect, but I agree that it can be confusing and the need for the modification 
is annoying. I believe that the changes described above will not have any negative impact on the master/detail panels 
not used as beans. Hence, we can generate them automatically for every master/detail form to simplify life of 
developers who would like to use the panels as beans => keeping this issue as enhancement request.
Comment 2 wobster 2007-12-09 23:36:14 UTC
Thanks for the detailed description, I'll try out your changes. 

I'm doing a short demo of the NetBeans Swing Application and Bean Binding framework at the local Java  Users Group here
in Austin and wanted to be able to show how easy it was to create a simple application and then add a master/detail view
after the fact (rather than using the wizard to auto-generate the whole application at once.) I imagine the code from
the master/detail Swing Application wizard should have the logic you mentioned right? 

In general, I think that any form that NetBeans generates should interoperate with the GUI builder without change. 

Also, the error message about not being able to instantiate the bean is also very vague. I had to look in the NetBeans
log file to see what the actual problem was. I think the stack trace should be easily accessible from the error dialog
so that it is more obvious to users who many not know to look in the log file.

Thanks!
Comment 3 wobster 2007-12-10 02:29:20 UTC
It is going to take me too long during the demo to make these changes. I only have 5 minutes to do the entire thing. I
noticed that there is a template for the master/detail form, but it doesn't define everything in the guarded blocks.
That gets generated from somewhere else. Is there a way I can modify the generation code somewhere so that I won't have
to type all this stuff during the demo. (I'll mention that I had to modify the template to get this to work in a WYSIWYG
manner.)
Comment 4 wobster 2007-12-10 03:08:18 UTC
I hit one roadblock with your suggested approach. It looks like:

org.jdesktop.application.ResourceMap resourceMap =
org.jdesktop.application.Application.getInstance(demo2.Demo2App.class).getContext().getResourceMap(Registrants.class);
query = entityManager.createQuery(resourceMap.getString("query.query")); // NOI18N

is part of the same code block. There are many dependencies in the subsequent code on the "resourceMap" variable. So if
I use the "preConstruction" "postConstruction" route to put in the isDesignTime() code, the resourceMap is out of scope.

I modifed the code manually outside the IDE and was able to verify that the changes would enable the master/detail view
to be included in other GUI components within the GUI builder (as long as I don't regenerate the code again.)

This is what the code needed to look like:

        if(!Beans.isDesignTime()) {
            entityManager = javax.persistence.Persistence.createEntityManagerFactory("tagsPU").createEntityManager();
        }

        org.jdesktop.application.ResourceMap resourceMap =
org.jdesktop.application.Application.getInstance(demo2.Demo2App.class).getContext().getResourceMap(Registrants.class);

        if (!Beans.isDesignTime()) {
            query = entityManager.createQuery(resourceMap.getString("query.query")); // NOI18N
        }

        if(Beans.isDesignTime()) {
            list = Collections.emptyList();
        } else {
            list = org.jdesktop.observablecollections.ObservableCollections.observableList(query.getResultList());
        }
Comment 5 Jan Stola 2007-12-10 09:36:17 UTC
Created attachment 54060 [details]
.java file of modified template
Comment 6 Jan Stola 2007-12-10 09:36:18 UTC
Created attachment 54061 [details]
.java file of modified template
Comment 7 Jan Stola 2007-12-10 09:41:09 UTC
Created attachment 54066 [details]
.form file of modified template
Comment 8 Jan Stola 2007-12-10 09:42:08 UTC
Created attachment 54067 [details]
NetBeans attributes file for the template.
Comment 9 Jan Stola 2007-12-10 10:03:31 UTC
> Also, the error message about not being able to instantiate the bean is also very vague.
> I had to look in the NetBeans log file to see what the actual problem was.
> I think the stack trace should be easily accessible from the error dialog
> so that it is more obvious to users who many not know to look in the log file.

I share this opinion, we showed the stack trace in some older releases. Unfortunately, our human interface engineers 
(supported by some quality engineers) forced us to hide the exception. They belive that it usually doesn't help the 
user because it makes him/her to think that it is a defect in the GUI builder itself.

> Is there a way I can modify the generation code somewhere so that
> I won't have to type all this stuff during the demo. (I'll mention
> that I had to modify the template to get this to work in a WYSIWYG manner.)

Yes, you can modify it, but it is not straightforward. Hence, I prepared the needed
files for you. Place the attached MasterDetailForm.java, MasterDetailForm.form and .nbattrs
files into config\Templates\GUIForms directory in your user-dir and restart the IDE.
These files will override the default definition of the master/detail template.
(MasterDetailForm.java is attached twice because I had some network problems;
both attachments should be the same)

> I hit one roadblock with your suggested approach. It looks like:
> org.jdesktop.application.ResourceMap resourceMap = ...
> query = entityManager.createQuery(resourceMap.getString("query.query")); // NOI18N
> is part of the same code block.

Thanks for bringing this out. I didn't notice that because I tried it in normal (non-app-framework) java project. I 
will consider this issue while making changes into master/detail template. The attached files contain a workaround for 
that. The 'query' property is marked non-resourceable (e.g. not to use the resource map) in the attached template.
Comment 10 Jan Stola 2007-12-10 11:17:54 UTC
Fixed - the master/detail template can be used as a bean in the GUI builder by now.

Modified files:
/cvs/form/j2ee/src/org/netbeans/modules/form/j2ee/EntityManagerCreator.java
new revision: 1.5; previous revision: 1.4
/cvs/form/j2ee/src/org/netbeans/modules/form/j2ee/QueryCreator.java
new revision: 1.5; previous revision: 1.4
/cvs/form/j2ee/src/org/netbeans/modules/form/j2ee/QueryResultListCreator.java
new revision: 1.8; previous revision: 1.7
/cvs/form/j2ee/src/org/netbeans/modules/form/j2ee/resources/templates/MasterDetailForm_java
new revision: 1.8; previous revision: 1.7
Comment 11 wobster 2007-12-10 14:33:17 UTC
>> Also, the error message about not being able to instantiate the bean is also very vague.
>> I had to look in the NetBeans log file to see what the actual problem was.
>> I think the stack trace should be easily accessible from the error dialog
>> so that it is more obvious to users who many not know to look in the log file.
>
>I share this opinion, we showed the stack trace in some older releases. Unfortunately, our human interface engineers 
>(supported by some quality engineers) forced us to hide the exception. They believe that it usually doesn't help the 
>user because it makes him/her to think that it is a defect in the GUI builder itself.

By not showing the trace, I thought the GUI builder was broken since I had no reason to believe that the form was not a
JavaBean (default constructor, implements serializable, get/set for properties, etc.) The HI guys usually assume that
the users are idiots and would rather give them an "idiot light" indication than any real meaningful information. I
think anybody programming in Java and using an NetBeans would not qualify them as an idiot. The dialog could always say
"The following error occurred by trying to instantiate your bean: ..." so that the users wouldn't get confused.

BTW, thanks for fixing this so quickly! I'll download the build later today to get your changes for the demo tomorrow.
Comment 12 Jan Stola 2007-12-10 15:11:18 UTC
> I'll download the build later today to get your changes for the demo tomorrow.

Do not forget that this issue contains updated master/detail template that can be used with NetBeans 6.0 (in case there 
is something odd with the latest build; you know, it is a development build ...) Good luck with the demo!
Comment 13 wobster 2007-12-14 04:41:53 UTC
Just wanted to let you know that the modified MasterDetailForm files worked great in NB 6.0 and I was able to demo the
capability of dragging the newly generated and unmodified class onto my existing GUI flawlessly at the AustinJUG
Christmas party.

Thanks again!

Rob
Comment 14 kate 2008-04-08 14:45:31 UTC
verified for 200804040802