From: Michael H. <hag...@jp...> - 2002-01-18 14:11:41
|
Hello, Is there a way to access jython's "callable-to-listener" conversion explicitly? I would like to do this: class C: def __init__(self): # ... b = JComboBox(actionPerformed=self.doIt) # ... def doIt(self, e): # ... but it doesn't work because JComboBox (oddly) defines an actionPerformed method. (See http://aspn.activestate.com/ASPN/Mail/Message/Jython-users/541301 for more information.) Is there a way to access jython's "callable-to-listener" conversion explicitly? If so, I could do b = JComboBox(actionListener=jython_coersion(actionPerformed=self.doIt)) which is not quite as terse as the original, but at least better than having to define a python wrapper class to do the trick (and probably a bit faster, too). Ideally this would be spelled b = JComboBox(actionListener=ActionListener(actionPerformed=self.doIt)) but unfortunately this produces an error TypeError: can't instantiate interface (java.awt.event.ActionListener) Thanks, Michael -- Michael Haggerty JPK Instruments hag...@jp... |
From: Kevin B. <kb...@ca...> - 2002-01-18 21:34:44
|
Michael Haggerty wrote: > > Is there a way to access jython's "callable-to-listener" conversion > explicitly? You can (cheat a lot and) actually modify the JComboBox.__dict__: """ adapter.py - demo how to explicitly create an adapter for a Java interface. This adds the capability to set 'actionPerformed=callable' in a JComboBox constructor. Note that this hides the 'JComboBox.actionPerformed' method which caused the trouble in the first place, but you're not supposed to do anything with that method, so it is probably OK... *WARNING* This is a hack - it works for Jython 2.1, but probably won't work with future releases. """ from org.python.core import PyBeanEventProperty, PyBeanEvent def addEventProperty( objectClass, addMethodName, eventName, eventClass ): """Add the ability to call 'method=callable' in a constructor call. objectClass - class to modify addMethodName - objectClass method to add a listener eventName - name of event listener property ('actionListener') eventClass - class of event listener interface """ # code stolen from PyJavaClass.addEvent addMethod = objectClass.getMethod( addMethodName, [eventClass] ) # add support for assigning individual event handlers in constructor for eventMethod in eventClass.getMethods(): prop = PyBeanEventProperty( eventName, eventClass, addMethod, eventMethod ) objectClass.__dict__.__setitem__( prop.__name__, prop ) # add support for assigning 'whateverListener=WhateverListenerImpl' event = PyBeanEvent(eventName, eventClass, addMethod); objectClass.__dict__.__setitem__(event.__name__, event); # demo code from javax.swing import JComboBox, JFrame from java.awt.event import ActionListener from java.awt import Dimension, BorderLayout def showWidget( widget, name="Demo" ): f = JFrame( name ) p = f.getContentPane() p.add( widget, BorderLayout.NORTH ) f.setSize( 300, 300 ) f.show() def test(): # allow JComboBox( actionPerformed=callable ) addEventProperty( JComboBox, 'addActionListener', 'actionListener', ActionListener ) def doit( event ): print "doit:", event jc = JComboBox( range( 10 ), actionPerformed=doit ) showWidget( jc ) Cool. :-) kb |
From: Samuele P. <ped...@bl...> - 2002-01-18 22:20:08
|
Hi. Without messing with the internals one can do: <adapter.py> import new _adapt_u=0 def adapt(listenerClass, **bindings): global _adapt_u _adapt_u +=1 return new.classobj("_%s" % _adapt_u,( listenerClass,),bindings)() </adapter.py> then one can do: >>> from javax.swing import JButton,JFrame >>> f=JFrame("exp") >>> from java.awt.event import ActionListener >>> def doIt(self,e): print "ok!" ... >>> from adapter import adapt >>> b=JButton("Ok",actionListener=adapt(ActionListener,actionPerformed=doIt)) >>> f.contentPane.add(b) [snipped output] >>> f.pack() >>> f.visible=1 # click on the button >>> ok! regards, Samuele Pedroni. ----- Original Message ----- From: Kevin Butler <kb...@ca...> To: Michael Haggerty <hag...@jp...> Cc: <jyt...@li...> Sent: Friday, January 18, 2002 10:34 PM Subject: Re: [Jython-users] Explicitly creating listeners from callables > Michael Haggerty wrote: > > > > Is there a way to access jython's "callable-to-listener" conversion > > explicitly? > > You can (cheat a lot and) actually modify the JComboBox.__dict__: > > """ > adapter.py - demo how to explicitly create an adapter for a Java interface. > > This adds the capability to set 'actionPerformed=callable' in a JComboBox > constructor. > > Note that this hides the 'JComboBox.actionPerformed' method which > caused the trouble in the first place, but you're not supposed to do > anything with that method, so it is probably OK... > > *WARNING* This is a hack - it works for Jython 2.1, but probably won't work > with future releases. > """ > from org.python.core import PyBeanEventProperty, PyBeanEvent > > def addEventProperty( objectClass, addMethodName, eventName, eventClass ): > """Add the ability to call 'method=callable' in a constructor call. > objectClass - class to modify > addMethodName - objectClass method to add a listener > eventName - name of event listener property ('actionListener') > eventClass - class of event listener interface > """ > # code stolen from PyJavaClass.addEvent > addMethod = objectClass.getMethod( addMethodName, [eventClass] ) > > # add support for assigning individual event handlers in constructor > for eventMethod in eventClass.getMethods(): > prop = PyBeanEventProperty( > eventName, > eventClass, > addMethod, > eventMethod > ) > objectClass.__dict__.__setitem__( prop.__name__, prop ) > > # add support for assigning 'whateverListener=WhateverListenerImpl' > event = PyBeanEvent(eventName, eventClass, addMethod); > objectClass.__dict__.__setitem__(event.__name__, event); > > > > # demo code > from javax.swing import JComboBox, JFrame > from java.awt.event import ActionListener > from java.awt import Dimension, BorderLayout > def showWidget( widget, name="Demo" ): > f = JFrame( name ) > p = f.getContentPane() > p.add( widget, BorderLayout.NORTH ) > f.setSize( 300, 300 ) > f.show() > > > def test(): > # allow JComboBox( actionPerformed=callable ) > addEventProperty( > JComboBox, > 'addActionListener', > 'actionListener', > ActionListener > ) > > def doit( event ): > print "doit:", event > > jc = JComboBox( range( 10 ), actionPerformed=doit ) > showWidget( jc ) > > > > Cool. :-) > > kb > > _______________________________________________ > Jython-users mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-users > |
From: Kevin B. <kb...@ca...> - 2002-01-19 00:21:21
|
Samuele Pedroni wrote: > > def adapt(listenerClass, **bindings): > global _adapt_u > _adapt_u +=1 > return new.classobj("_%s" % _adapt_u,( listenerClass,),bindings)() [snip] > >>> b=JButton("Ok",actionListener=adapt(ActionListener,actionPerformed=doIt)) I like it. :-) Could we even go one step further, and make the __init__ method for a Java Interface be something very like 'adapt'? (The current __init__ behavior (throw TypeError) is not generally useful.) This would allow a nicer syntax: >>> b=JButton("Ok",actionListener=ActionListener( actionPerformed=doIt )) And would facilitate anonymous classes for other non-Event uses (which I've wanted before, but can't think of examples right now!) kb |