Issue2389

classification
Title: InternalFrameLister vs InternalFrameAdapter
Type: behaviour Severity: major
Components: Documentation Versions: Jython 2.7
Milestone:
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: darjus, kensingtoncat, zyasoft
Priority: Keywords:

Created on 2015-09-03.19:44:48 by kensingtoncat, last changed 2015-10-09.03:17:21 by darjus.

Files
File name Uploaded Description Edit Remove
__main__.py kensingtoncat, 2015-09-03.23:43:04 contains implementation of listener and adapter
Messages
msg10212 (view) Author: alan ross (kensingtoncat) Date: 2015-09-03.19:44:47
In 2.5, a jython class that was derived from an InternalFrameAdapter -- a convenience class -- could be added as an InternalFrameListener to internal frames.
In 2.7, the events (I only tested closing, and closed) are not caught.

The workaround now is to derive from an InternalFrameListener and implement all the abstract listener functions.

Adapter classes that I derive from that implement a single interface
works as expected. 
However, I not checked whether all "convenience" adapter classes that implement multiple interfaces suffer from this issue -- or is this a one-off problem.
msg10214 (view) Author: Jim Baker (zyasoft) Date: 2015-09-03.20:41:32
This was changed in 2.7 beta 4 per NEWS:

    - Abstract methods of an inherited class or interface from Java
      now raise NotImplementedError, instead of returning None (in
      Java, null) or some "zero", if they are not implemented in the
      extending Python class.

It should be straightforward to provide a class decorator -- or
equivalently, a function on classes -- that supports the original
behavior. Maybe even put this decorator in jythonlib?

@jythonlib.NotImplementedMethodsReturnNone
class MyAdapter(InternalFrameAdapter):
    def internalFrameActivated(self, e):
		print e

or perhaps have a slightly more precise decorator, let's call it
NotImplementedVoidMethodsDoNothing. Completely explicit here - void
methods per above are for side effects, so not doing anything can be
quite reasonable.
msg10215 (view) Author: alan ross (kensingtoncat) Date: 2015-09-03.20:51:47
The issue is that the InternalFrameAdapter class does implement *all* the InteralFrameListener methods -- albeit with a do-nothing, no-op.
ie "An abstract adapter class for receiving internal frame events. The methods in this class are empty."
So this class has by default all the methods implemented already.

So the question remains why it does not behave like 2.5
msg10216 (view) Author: Jim Baker (zyasoft) Date: 2015-09-03.21:47:33
Alan, thanks for the clarification re InternalFrameAdapter. Looks like I misread your original bug report. To my knowledge, there are only two significant changes in the underlying proxy handling in Jython:

NotImplementedError for abstract methods
super resolution, with a recent committed bug fix for __init__/constructors

Neither seems to apply here.

Do you have any more details on what is breaking? In particular, test code demonstrating the bug would be helpful.
msg10219 (view) Author: alan ross (kensingtoncat) Date: 2015-09-03.21:59:48
I will distill the problem into a small test case after labor day.
msg10220 (view) Author: alan ross (kensingtoncat) Date: 2015-09-03.23:43:04
I hope this is helpful....

After more careful testing, I condensed an example and discovered some interesting behavior. In all cases, the examples work in 2.5
See the attached __main__.py file.

When I used the InternalFrameLister base and implemented the class methods, THE LISTENER WORKS. I even externally defined the method implementations -- see example. The listener works.

When I used the InternalFrameAdapter base and implemented only one class method, THE ADAPTER WORKS.

However, when I used the InternalFrameAdapter base and implemented one class method externally, THE ADAPTER DOES NOT WORK.
This mimicks the software that I first detected the problem.
so:
## works in 2.5   does not work in 2.7
def externalMethod( e ) :  print "HELLO"
class MyAdapter( javax.swing.InternalFrameAdapter ):
    def __init__(self):
        self.internalFrameClosing = externalMethod
msg10314 (view) Author: Darjus Loktevic (darjus) Date: 2015-10-07.10:30:01
Hey Alan,

I don't think what you're doing with external would work. The java bytecode is generated when parsing the class, so unless there's already a concrete implementation, i don't thing this will get passed.

If you want to use "external" method, put them on the class not the instance

def internalFrameClosing(self, e):       print "External Adapter Event: Frame Closing"
class MyInternalFrameAdapterExternalMethods(javax.swing.event.InternalFrameAdapter):
    internalFrameClosing = internalFrameClosing

This works.

If you want to dynamically override:

def internalFrameClosing(self, e):       print "External Adapter Event: Frame Closing"
class MyInternalFrameAdapterExternalMethods(javax.swing.event.InternalFrameAdapter):
    def __init__(self):
        self.internalFrameClosing = someOtherFrameClosing

    internalFrameClosing = internalFrameClosing

Should also work. Does any of this make sense?
msg10333 (view) Author: alan ross (kensingtoncat) Date: 2015-10-08.15:48:13
The error is really related to careless programming in the software I am supporting. Although it code worked in 2.5, the error in 2.7 was a clarion to cleanup the software. Refactoring solved much of the issues I was running into.
msg10340 (view) Author: Darjus Loktevic (darjus) Date: 2015-10-09.03:17:20
Glad to hear that Alan. Resolving
History
Date User Action Args
2015-10-09 03:17:21darjussetstatus: open -> closed
messages: + msg10340
2015-10-08 15:48:13kensingtoncatsetmessages: + msg10333
2015-10-07 10:30:01darjussetnosy: + darjus
messages: + msg10314
2015-09-03 23:43:05kensingtoncatsetfiles: + __main__.py
messages: + msg10220
2015-09-03 21:59:48kensingtoncatsetmessages: + msg10219
components: + Documentation, - Core
2015-09-03 21:47:33zyasoftsetmessages: + msg10216
2015-09-03 20:51:47kensingtoncatsetmessages: + msg10215
2015-09-03 20:41:33zyasoftsetnosy: + zyasoft
messages: + msg10214
2015-09-03 19:44:48kensingtoncatcreate