Home » Archived » Visual Editor (VE) » Class cast exception on customizer OK click
Class cast exception on customizer OK click [message #91123] |
Sat, 14 May 2005 20:33  |
Eclipse User |
|
|
|
Originally posted by: no.ddress.here
Suddenly getting the error below any time I click VE's OK button on my
customizer. My code seems to complete entirely. The property sheet
gets updated with the correct values. No code is generated, though.
Any idea the cause? Suggestions on how to debug/determine what class is
causing the problem? What is the minimum necessary VE part of CVS that
I should check out to support debugging this?
!ENTRY org.eclipse.ve.java.core 2 0 2005-05-14 17:24:14.231
!MESSAGE Exception thrown.
!STACK 0
java.lang.ClassCastException:
org.eclipse.ve.internal.java.core.TypeReferenceCellEditor
at
org.eclipse.ve.internal.java.core.CustomizeJavaBeanAction.cu stomizerOK
(CustomizeJavaBeanAction.java:234)
at org.eclipse.ve.internal.java.core.CustomizeJavaBeanAction.ru n
(CustomizeJavaBeanAction.java:137)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:996 )
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection
(ActionContributionItem.java:538)
at org.eclipse.jface.action.ActionContributionItem.access$2
(ActionContributionItem.java:488)
at org.eclipse.jface.action.ActionContributionItem$5.handleEven t
(ActionContributionItem.java:400)
at org.eclipse.swt.widgets.EventTable.sendEvent
(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:842)
at org.eclipse.swt.widgets.Display.runDeferredEvents
(Display.java:2894)
at org.eclipse.swt.widgets.Display.readAndDispatch
(Display.java:2527)
at org.eclipse.ui.internal.Workbench.runEventLoop
(Workbench.java:1570)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1534)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench
(Workbench.java:306)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench
(PlatformUI.java:143)
at org.eclipse.ui.internal.ide.IDEApplication.run
(IDEApplication.java:103)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run
(PlatformActivator.java:228)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run
(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run
(EclipseStarter.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:315 )
at org.eclipse.core.launcher.Main.basicRun(Main.java:268)
at org.eclipse.core.launcher.Main.run(Main.java:942)
at org.eclipse.core.launcher.Main.main(Main.java:926)
|
|
|
Re: Class cast exception on customizer OK click [message #91286 is a reply to message #91123] |
Mon, 16 May 2005 16:11   |
Eclipse User |
|
|
|
Hi Gerald,
> Suddenly getting the error below any time I click VE's OK button on my
> customizer. My code seems to complete entirely. The property sheet
> gets updated with the correct values. No code is generated, though.
What occurs with the customizer is that before it opens the VE keeps a
map of all of the current property values. On confirm they are
retrieved from the bean (using the property's get method) and compared
against the values on the way in to see what changed. As you are aware
we're changing this to have another contract where we listen to the
property change events to determine what has changed, but even with this
change (not yet released) the end result would be that the VE has built
up a list of all properties that it thinks have changed.
Now it has to generate code for all of them. For example, if you
altered a color property all the customizer does is swop in a new color
object, the VE however has to code-generate a method like
mybean.setFont(java.awt.Color.red);
To do this means the VE has to perform some alchemy to go from a Java
object to the string of code that will re-create it. For this is uses
the java.beans.PropertyEditor for said property. It cranks one up for
each changed property and does a setValue(Object) followed by a
getJavaInitializationString(), hence working out the method argument to
the set method.
Not all property editors are java.beans.PropertyEditor instances however
and the VE has some custom cell editors that run inside Eclipse. One of
these is TypeReferenceCellEditor and is used in places like
java.awt.Checkbox.checkboxGroup or javax.swing.JTable.tableModel. The
editor shows a list of available instances in the VE class being edited
that conform to the interface and let you select one or drop a new one.
There is also an interface called
org.eclipse.ve.internal.java.core.IJavaCellEditor that these are meant
to implement, and you have found a defect where the
TypeReferenceCellEditor does not implenent it. Please open a priority 1
defect and we'll try to get this fixed for our next milestone build.
However, working out what code to generate for the property that has
changed is going to be difficult. I don't know the property in question
that has changed, but before your customizer has opened look at the
property sheet and select the editor on each of them and see which ones
have a sort of combo/dialog experience (the combo selecting instances
implemeting the property's type and the dialog letting you add new
ones). Assume that one of these if something like
public MyObject getMyProperty();
public void setMyProperty(MyObject object);
and you go and alter MyObject using your customizer, what could we use
to generate the correct code ? By default we could realize that the
property changed and do something like
myBean.setMyProperty(new MyObject());
but the problem is that this is just gonna crank up a default instance
which isn't what you want. you would want something like
myBean.setMyProperty(new MyObject("Stuff", true, 1, "foobar"));
or something.
Another thing we could do is serialize your JavaBean and there is some a
flag "hiddenState" on the BeanDescriptor that allows the IDE to
serialize the entire JavaBean being customized we don't support this.
First cause .ser files are dodgy and brittle, and also cause we prefer
to code generate archival code.
MyObject myObject = new MyObject();
myObject.setAProperty(true);
myBean.setMyProperty(myObject);
however this could be tricky. I guess we could realize that myProperty
changes (cause you signal the event or we detect it has changed) and
then instantiate a template using a null constructor (if one exists) and
then walk the properties to see what has changed, and then so on and so
forth because in theory the graph could recurse.
Another problem that Rich pointed out to me is that we don't support
cross references. This would be where you had a property whose archival
code represented another property. Do you have this kind of scenario
where the initString for one property should actually contain a
reference to a field that is part of your class itself ?
> What is the minimum necessary VE part of CVS that
> I should check out to support debugging this?
Log onto dev.eclipse.org and /home/tools and user id of anonymous. Then
check out ve-dev-base.
Best regards,
Joe
|
|
|
Re: Class cast exception on customizer OK click [message #91330 is a reply to message #91286] |
Mon, 16 May 2005 17:13   |
Eclipse User |
|
|
|
Originally posted by: no.ddress.here
Joe,
Thanks for the explanation. It is certainly all very tricky to get it
right for all purposes! But, here is the trickiest part of the problem
I am having - the one property that is causing the exception is an
absolutely ordinary String property!
The problem property (named slot) is one of a group of three (slot, row,
column) that are set by my customizer. Row and column work exactly as
expected. The code in my customizer and bean for all purposes relevant
to VE is identical for all three properties (or at least should be and
are to my eye). The getters and setters are all of type String. I am
not providing a custom PropertyEditor for any of the three properties.
All three are identically specified in my beaninfo.
I have verified that the strings actually passed do not contain improper
characters. The correct and proper strings do show up in the property
sheet after OK is clicked. The VE property value cache (for lack of a
better term) does apparently get updated correctly (the visual editor
works as though the OK completed successfully).
Still, the class cast exception is thrown and no actual code is written
to my target bean if the sting value for slot is changed by my
customizer.
(FWIW, I even tried specifing SwingStringEditor.class as the slot String
property editor, but that prevented the customizer from being
recognized. Is specifying both a customizer and a property editor in a
single beaninfo not permitted?)
VE is seeing a distinction between the properties that I am not. Either
a very subtle bug in VE or more likely a difference I have overlooked in
my code. Bottom line, knowing the class type that is causing the class
cast exception could provide a worthwhile hint at the problem.
Unfortunately, the ve-dev-base and ve-all projects check out with
compile errors (I started a separate thread asking about that) which
prevents me from running the workbench in debug mode.
Any further thoughts about what could be the problem with my one errant
property?
Thanks,
Gerald
|
|
| | | |
Re: Class cast exception on customizer OK click [message #91687 is a reply to message #91615] |
Wed, 18 May 2005 12:18  |
Eclipse User |
|
|
|
Originally posted by: no.ddress.here
To be clear, I am trying to be consistent with the bean spec so the bean
is portable *and* not use the proprietary extensions of any IDE.
My bean is a container that fully encapsulates its own proprietary,
third-party layout manager - it does not require the IDE to generate any
user level code for the layout manager. The bean customizer generates a
set of string and boolean properties that do need to be represented in
the user level code. The bean uses these internally to configure the
embedded layout manager. As far as the IDE is concerned, these are all
simple, independent properties.
Other IDEs have required a known layout manager to be set in the
property sheet for my bean. They then generated user level code to
match the presumed type of the layout manager; user level code that my
bean simply ignores. VE goes further and requires that the layout
manager object remains .equal() or it will throw an exception.
In article <d6f1h9$71g$1@news.eclipse.org>, winchest@uk.ibm.com says...
> Hi Gerald,
>
> > Going from a null layout manager to a FormLayout layout manager during
> > the customizer run will always cause VE to throw the exception.
>
> We should not throw an exception so please open a bugzilla test case and
> we'll fix it
Is going from a known to a completely unknown (to VE) layout manager a
bug?
Ideally, VE could support an "embedded" pseudo-layout manager that is
just a property sheet tag to signal VE to not generate any user level
layout code (no layoutData, bounds, size, or location method calls for
contained objects) and to ignore unknown layout manager types returned
by getLayout().
I will add a bug/enhancement request for an "embedded" pseudo-layout
manager. You may change it as you see fit.
> The VE can be
> extended by actually contributing dialogs or menu contributions and
> property editors that can leverage its model of the JavaBeans
Nice, but unfortunately, not portable. (Of course, if I had a big
underwriter, I could be easily convinced to make the leap and add VE
specific enhancements.)
> and you will get a lot more power than the customizer spec itself provides ?
This is a design choice that, in this particular case, resolves as
actually best handled through a customizer. A single, integrated
customizer-based design view is better than a whole bunch of little
property editor pop-ups.
> > I have now set up a proxy layout manager object so that VE will never
> > detect any change in the actual layout manager. Back to everything
> > appearing to work as expected.
>
> This worries me as it sounds like a kludge.
Sounds like? It is a kludge. But, it is a simple, clean and elegant
kludge. In the book of kludge patterns, it is identified as the kludge
of invisibility, which is one of the set of 14 authoritatively preferred
kludge patterns.
Best of all, VE seems to be happy with it.
|
|
|
Re: Class cast exception on customizer OK click [message #607776 is a reply to message #91123] |
Mon, 16 May 2005 16:11  |
Eclipse User |
|
|
|
Hi Gerald,
> Suddenly getting the error below any time I click VE's OK button on my
> customizer. My code seems to complete entirely. The property sheet
> gets updated with the correct values. No code is generated, though.
What occurs with the customizer is that before it opens the VE keeps a
map of all of the current property values. On confirm they are
retrieved from the bean (using the property's get method) and compared
against the values on the way in to see what changed. As you are aware
we're changing this to have another contract where we listen to the
property change events to determine what has changed, but even with this
change (not yet released) the end result would be that the VE has built
up a list of all properties that it thinks have changed.
Now it has to generate code for all of them. For example, if you
altered a color property all the customizer does is swop in a new color
object, the VE however has to code-generate a method like
mybean.setFont(java.awt.Color.red);
To do this means the VE has to perform some alchemy to go from a Java
object to the string of code that will re-create it. For this is uses
the java.beans.PropertyEditor for said property. It cranks one up for
each changed property and does a setValue(Object) followed by a
getJavaInitializationString(), hence working out the method argument to
the set method.
Not all property editors are java.beans.PropertyEditor instances however
and the VE has some custom cell editors that run inside Eclipse. One of
these is TypeReferenceCellEditor and is used in places like
java.awt.Checkbox.checkboxGroup or javax.swing.JTable.tableModel. The
editor shows a list of available instances in the VE class being edited
that conform to the interface and let you select one or drop a new one.
There is also an interface called
org.eclipse.ve.internal.java.core.IJavaCellEditor that these are meant
to implement, and you have found a defect where the
TypeReferenceCellEditor does not implenent it. Please open a priority 1
defect and we'll try to get this fixed for our next milestone build.
However, working out what code to generate for the property that has
changed is going to be difficult. I don't know the property in question
that has changed, but before your customizer has opened look at the
property sheet and select the editor on each of them and see which ones
have a sort of combo/dialog experience (the combo selecting instances
implemeting the property's type and the dialog letting you add new
ones). Assume that one of these if something like
public MyObject getMyProperty();
public void setMyProperty(MyObject object);
and you go and alter MyObject using your customizer, what could we use
to generate the correct code ? By default we could realize that the
property changed and do something like
myBean.setMyProperty(new MyObject());
but the problem is that this is just gonna crank up a default instance
which isn't what you want. you would want something like
myBean.setMyProperty(new MyObject("Stuff", true, 1, "foobar"));
or something.
Another thing we could do is serialize your JavaBean and there is some a
flag "hiddenState" on the BeanDescriptor that allows the IDE to
serialize the entire JavaBean being customized we don't support this.
First cause .ser files are dodgy and brittle, and also cause we prefer
to code generate archival code.
MyObject myObject = new MyObject();
myObject.setAProperty(true);
myBean.setMyProperty(myObject);
however this could be tricky. I guess we could realize that myProperty
changes (cause you signal the event or we detect it has changed) and
then instantiate a template using a null constructor (if one exists) and
then walk the properties to see what has changed, and then so on and so
forth because in theory the graph could recurse.
Another problem that Rich pointed out to me is that we don't support
cross references. This would be where you had a property whose archival
code represented another property. Do you have this kind of scenario
where the initString for one property should actually contain a
reference to a field that is part of your class itself ?
> What is the minimum necessary VE part of CVS that
> I should check out to support debugging this?
Log onto dev.eclipse.org and /home/tools and user id of anonymous. Then
check out ve-dev-base.
Best regards,
Joe
|
|
|
Re: Class cast exception on customizer OK click [message #607779 is a reply to message #91286] |
Mon, 16 May 2005 17:13  |
Eclipse User |
|
|
|
Joe,
Thanks for the explanation. It is certainly all very tricky to get it
right for all purposes! But, here is the trickiest part of the problem
I am having - the one property that is causing the exception is an
absolutely ordinary String property!
The problem property (named slot) is one of a group of three (slot, row,
column) that are set by my customizer. Row and column work exactly as
expected. The code in my customizer and bean for all purposes relevant
to VE is identical for all three properties (or at least should be and
are to my eye). The getters and setters are all of type String. I am
not providing a custom PropertyEditor for any of the three properties.
All three are identically specified in my beaninfo.
I have verified that the strings actually passed do not contain improper
characters. The correct and proper strings do show up in the property
sheet after OK is clicked. The VE property value cache (for lack of a
better term) does apparently get updated correctly (the visual editor
works as though the OK completed successfully).
Still, the class cast exception is thrown and no actual code is written
to my target bean if the sting value for slot is changed by my
customizer.
(FWIW, I even tried specifing SwingStringEditor.class as the slot String
property editor, but that prevented the customizer from being
recognized. Is specifying both a customizer and a property editor in a
single beaninfo not permitted?)
VE is seeing a distinction between the properties that I am not. Either
a very subtle bug in VE or more likely a difference I have overlooked in
my code. Bottom line, knowing the class type that is causing the class
cast exception could provide a worthwhile hint at the problem.
Unfortunately, the ve-dev-base and ve-all projects check out with
compile errors (I started a separate thread asking about that) which
prevents me from running the workbench in debug mode.
Any further thoughts about what could be the problem with my one errant
property?
Thanks,
Gerald
|
|
|
Re: Class cast exception on customizer OK click [message #607781 is a reply to message #91330] |
Tue, 17 May 2005 06:10  |
Eclipse User |
|
|
|
Hi Gerald,
> Thanks for the explanation. It is certainly all very tricky to get it
> right for all purposes! But, here is the trickiest part of the problem
> I am having - the one property that is causing the exception is an
> absolutely ordinary String property!
If possible could you send me the minimum set of code required to
re-create the problem. We should not be invoking the logic that throws
the class case unless the property has changed and it might be easier
for me to just re-create the problem here and see what's going on.
> (FWIW, I even tried specifing SwingStringEditor.class as the slot String
> property editor, but that prevented the customizer from being
> recognized. Is specifying both a customizer and a property editor in a
> single beaninfo not permitted?)
Not sure why - you should be able to have a property editor and a
customizer independently - one comes from the PropertyDescriptor and the
other from the BeanDesriptor and there is no conflict I can see from the
code
Best regards,
Joe Winchester
|
|
|
Re: Class cast exception on customizer OK click [message #607786 is a reply to message #91358] |
Tue, 17 May 2005 13:56  |
Eclipse User |
|
|
|
In article <d6cfvc$bd1$1@news.eclipse.org>, winchest@uk.ibm.com says...
> Hi Gerald,
>
> > Thanks for the explanation. It is certainly all very tricky to get it
> > right for all purposes! But, here is the trickiest part of the problem
> > I am having - the one property that is causing the exception is an
> > absolutely ordinary String property!
>
> If possible could you send me the minimum set of code required to
> re-create the problem. We should not be invoking the logic that throws
> the class case unless the property has changed and it might be easier
> for me to just re-create the problem here and see what's going on.
My test cases worked, which is why I needed to trace VE itself to see
the class type that was causing the exception. Seems that, although
provoked in response to a change in the slot property, VE was actually
having trouble with the specific object type FormLayout as the layout
manager. Either I did not earlier notice the problem or VE is able to
handle some limited changes to the layout manager object without
throwing the exception.
Going from a null layout manager to a FormLayout layout manager during
the customizer run will always cause VE to throw the exception.
I have now set up a proxy layout manager object so that VE will never
detect any change in the actual layout manager. Back to everything
appearing to work as expected.
> > (FWIW, I even tried specifing SwingStringEditor.class as the slot String
> > property editor, but that prevented the customizer from being
> > recognized. Is specifying both a customizer and a property editor in a
> > single beaninfo not permitted?)
>
> Not sure why - you should be able to have a property editor and a
> customizer independently - one comes from the PropertyDescriptor and the
> other from the BeanDesriptor and there is no conflict I can see from the
> code
It was a quick try on my part and something else might have been causing
the problem. I will go back and check as soon as I have a chance.
Very much appreciate all the help!
Gerald
|
|
|
Re: Class cast exception on customizer OK click [message #607799 is a reply to message #91434] |
Wed, 18 May 2005 05:22  |
Eclipse User |
|
|
|
Hi Gerald,
> Going from a null layout manager to a FormLayout layout manager during
> the customizer run will always cause VE to throw the exception.
We should not throw an exception so please open a bugzilla test case and
we'll fix it, or else just append to the existing bugzilla you already
opened about customizers.
Having said that a customizer switching layouts is gonna be tricky to
get right. The VE has quite a bit of code so that when a layout is
switched the old layoutData objects are removed (or bounds/size/location
if going from null) and new layoutData (or bounds/size/location method
calls) are created based on a best fix to try to keep the controls at
the same size. This works well going into a layout manager like Grid or
null where the composite can pretty much put things whereever it wants.
All of this switching however involves affecting properties of the
Controls on the Composite which makes me think that your customizer is
not just setting properties it is actually manipulating child controls.
If this is the case then cause the JavaBeans spec doesn't really
support relationships between objects it's going to be difficult for the
VE to detect such changes to your bean and do anything meaningful.
Is your intention that your customizer dialog is portable across GUI
builders and must conform to the customizer spec ? The VE can be
extended by actually contributing dialogs or menu contributions and
property editors that can leverage its model of the JavaBeans and you
will get a lot more power than the customizer spec itself provides ?
> I have now set up a proxy layout manager object so that VE will never
> detect any change in the actual layout manager. Back to everything
> appearing to work as expected.
This worries me as it sounds like a kludge. If we don't detect the
change and don't code generate then when the class is compiled and run
how is your change actually affected and if the .java file is closed and
re-opened how has the change been persisted ?
On another note - I got a very nice e-mail back from the Sun engineer
who looks after the JavaBeans specification on an earlier point you
raised about whether getAdditionalBeanInfo() should be an explicit and
fully inclusive set of properties or whether it should be merged with
implicitly defined properties. I said that I thought the VE followed
the spec and you rebuked that other IDEs had different behavior to the
VE. The Sun enginner's comments are:
"Hi Joe,
I agree that the spec is as you interpret it: "as soon as any property
descriptors are returned in the result array then this is the explicit
set for that JavaBean."
The easiest approach I can think of for your user is to take advantage
of the BeanInfo.getAdditionalBeanInfo() API. A BeanInfo describing only
the property with the custom editor could be returned, and still allow
the "main" BeanInfo class to return null from getPropertyDescriptors().
My testing indicates that this will work.
A more complicated approach would be to break the Bean into a superclass
and a subclass. A BeanInfo would be provided only for the superclass,
specifying the PropertyEditor. The remainder of the Bean's code would
be in the subclass. The Introspector would pick up the editor from the
parent's BeanInfo, and introspect the rest for the subclass"
Best regards,
Joe Winchester
|
|
|
Re: Class cast exception on customizer OK click [message #607804 is a reply to message #91615] |
Wed, 18 May 2005 12:18  |
Eclipse User |
|
|
|
To be clear, I am trying to be consistent with the bean spec so the bean
is portable *and* not use the proprietary extensions of any IDE.
My bean is a container that fully encapsulates its own proprietary,
third-party layout manager - it does not require the IDE to generate any
user level code for the layout manager. The bean customizer generates a
set of string and boolean properties that do need to be represented in
the user level code. The bean uses these internally to configure the
embedded layout manager. As far as the IDE is concerned, these are all
simple, independent properties.
Other IDEs have required a known layout manager to be set in the
property sheet for my bean. They then generated user level code to
match the presumed type of the layout manager; user level code that my
bean simply ignores. VE goes further and requires that the layout
manager object remains .equal() or it will throw an exception.
In article <d6f1h9$71g$1@news.eclipse.org>, winchest@uk.ibm.com says...
> Hi Gerald,
>
> > Going from a null layout manager to a FormLayout layout manager during
> > the customizer run will always cause VE to throw the exception.
>
> We should not throw an exception so please open a bugzilla test case and
> we'll fix it
Is going from a known to a completely unknown (to VE) layout manager a
bug?
Ideally, VE could support an "embedded" pseudo-layout manager that is
just a property sheet tag to signal VE to not generate any user level
layout code (no layoutData, bounds, size, or location method calls for
contained objects) and to ignore unknown layout manager types returned
by getLayout().
I will add a bug/enhancement request for an "embedded" pseudo-layout
manager. You may change it as you see fit.
> The VE can be
> extended by actually contributing dialogs or menu contributions and
> property editors that can leverage its model of the JavaBeans
Nice, but unfortunately, not portable. (Of course, if I had a big
underwriter, I could be easily convinced to make the leap and add VE
specific enhancements.)
> and you will get a lot more power than the customizer spec itself provides ?
This is a design choice that, in this particular case, resolves as
actually best handled through a customizer. A single, integrated
customizer-based design view is better than a whole bunch of little
property editor pop-ups.
> > I have now set up a proxy layout manager object so that VE will never
> > detect any change in the actual layout manager. Back to everything
> > appearing to work as expected.
>
> This worries me as it sounds like a kludge.
Sounds like? It is a kludge. But, it is a simple, clean and elegant
kludge. In the book of kludge patterns, it is identified as the kludge
of invisibility, which is one of the set of 14 authoritatively preferred
kludge patterns.
Best of all, VE seems to be happy with it.
|
|
|
Goto Forum:
Current Time: Tue Jun 17 04:43:23 EDT 2025
Powered by FUDForum. Page generated in 0.28523 seconds
|