include Java
import javax.swing.JButton
import javax.swing.JFrame
class JButton
def initialize(name, &block)
super(name)
# Not using the block yet, but will later.
end
end
class GUI < JFrame
def initialize
super('Title')
ok_button = JButton.new('OK') { puts 'pressed OK' }
content_pane.add(ok_button)
pack
self.default_close_operation = JFrame::EXIT_ON_CLOSE
end
end
GUI.new.visible = true
---
Mark Volkmann
http://www.ociweb.com/mark
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
Can you show the full NPE trace? And try against 1.4RC1, some of this
has been cleaned up.
- Charlie
> On Wed, Oct 7, 2009 at 1:37 PM, Mark Volkmann <ma...@ociweb.com> wrote:
> > Here's a short bit of code from a larger application that is giving me a
> > NullPointerException in convertRubyToJavaInt. I can't figure out why it is
> > doing that. The problem disappears if you comment out the block that is
> > being passed to the JButton initialize method. That's on the line that sets
> > ok_button. Any idea what is going on here?
>
> Can you show the full NPE trace? And try against 1.4RC1, some of this
> has been cleaned up.
Sure! See below. Note how "pressed OK" is output. That seems wrong because
it's in a block that I pass to the JButton initialize method, but don't
execute. The code is identical to that in my previous email.
Swing$ jruby gui.rb
pressed OK
org/jruby/javasupport/JavaUtil.java:922:in `convertRubyToJavaInt':
java.lang.NullPointerException: null (NativeException)
from org/jruby/gen/org/jruby/gen/InterfaceImpl271097958.gen:13:in
`getIconWidth'
from javax/swing/SwingUtilities.java:890:in `layoutCompoundLabelImpl'
from javax/swing/SwingUtilities.java:817:in `layoutCompoundLabel'
from javax/swing/plaf/basic/BasicGraphicsUtils.java:262:in
`getPreferredButtonSize'
from apple/laf/CUIAquaButton.java:450:in `getPreferredSize'
from javax/swing/JComponent.java:1624:in `getPreferredSize'
from java/awt/BorderLayout.java:690:in `preferredLayoutSize'
from java/awt/Container.java:1558:in `preferredSize'
... 10 levels...
from gui.rb:15:in `initialize'
from gui.rb:22:in `new_proxy'
from gui.rb:22
Swing$ jruby -v
jruby 1.4.0RC1 (ruby 1.8.7 patchlevel 174) (2009-09-30 80c263b) (Java
HotSpot(TM) Client VM 1.5.0_19) [i386-java]
--
R. Mark Volkmann
Object Computing, Inc.
On Wed, Oct 7, 2009 at 9:37 PM, Mark Volkmann <ma...@ociweb.com> wrote:
> Here's a short bit of code from a larger application that is giving me a
> NullPointerException in convertRubyToJavaInt. I can't figure out why it is
> doing that. The problem disappears if you comment out the block that is
> being passed to the JButton initialize method. That's on the line that sets
> ok_button. Any idea what is going on here?
Sure, the way you construct the OK button is not 100% correct. You
provide a block to the constructor, but JButton's two-arg constructor
is JButton(text, *icon*). So, essentially, instead of icon you supply
a block, and when the Frame tries to layout itself, it asks the "icon"
to report its width via getIconWidth(), and that block gets confused.
:)
The fix is simple, instead of:
ok_button = JButton.new('OK') { puts 'pressed OK' }
do
ok_button = JButton.new('OK')
ok_button.add_action_listener { puts 'pressed OK!' }
This should work.
Thanks,
--Vladimir
> Hi Mark,
>
> On Wed, Oct 7, 2009 at 9:37 PM, Mark Volkmann <ma...@ociweb.com> wrote:
>> Here's a short bit of code from a larger application that is giving
>> me a
>> NullPointerException in convertRubyToJavaInt. I can't figure out
>> why it is
>> doing that. The problem disappears if you comment out the block
>> that is
>> being passed to the JButton initialize method. That's on the line
>> that sets
>> ok_button. Any idea what is going on here?
>
> Sure, the way you construct the OK button is not 100% correct. You
> provide a block to the constructor, but JButton's two-arg constructor
> is JButton(text, *icon*). So, essentially, instead of icon you supply
> a block, and when the Frame tries to layout itself, it asks the "icon"
> to report its width via getIconWidth(), and that block gets confused.
> :)
Interesting. However, this code worked with an earlier version of
JRuby. I wonder what changed. That JButton constructor isn't new.
> The fix is simple, instead of:
> ok_button = JButton.new('OK') { puts 'pressed OK' }
>
> do
>
> ok_button = JButton.new('OK')
> ok_button.add_action_listener { puts 'pressed OK!' }
>
> This should work.
Thanks! That does work, but I thought it was more elegant to be able
to pass to the constructor the block of code I want to execute when
the button is pressed.
---
Mark Volkmann
http://www.ociweb.com/mark
On Fri, Oct 9, 2009 at 2:47 PM, Mark Volkmann <ma...@ociweb.com> wrote:
> Interesting. However, this code worked with an earlier version of JRuby. I
> wonder what changed.
Indeed, it stopped working since July 2008, after one of Charlie's
commits that fixed various java-integration bugs.
Before that, the code worked somewhat, but was printing 'pressed OK'
when container tried to obtain the size of the button. :)
So it seems that it worked before due to bugs in JRuby.
> Thanks! That does work, but I thought it was more elegant to be able to pass
> to the constructor the block of code I want to execute when the button is
> pressed.
Well, yeah, for this particular case, yes, but hard to figure out what
to do in general case, not to mention that there could be multiple
listeners and different users would like to do different things.
Thanks,
--Vladimir
We do need to fix this so it doesn't NPE...that should not happen. At
worse it should provide a type error of some kind.
> Interesting. However, this code worked with an earlier version of JRuby. I
> wonder what changed. That JButton constructor isn't new.
I'm not sure this ever worked...it doesn't seem possible. How early
was that other version? The issue here is that we're trying to force
the block to act like it's an Icon, when of course that's a little
absurd. Passing a block to JButton.new never would have worked in the
past, unless some other library added a block version of "new" that
wired up the action listener for you.
>> ok_button = JButton.new('OK')
>> ok_button.add_action_listener { puts 'pressed OK!' }
>
> Thanks! That does work, but I thought it was more elegant to be able to pass
> to the constructor the block of code I want to execute when the button is
> pressed.
JRuby handles blocks passed to Java by trying to implement an
interface for the last argument. That's all it has ever done, and
before this time last year it pretty much just ignored it.
- Charlie
Ahh...interesting. Well if we fixed that NPE it might start "working"
again, but obviously it's not the expected result. Which commit was
it?
- Charlie
git bisect points to: c306f7f4b19162a83c1fa8f3b983e7e6c70083d9:
"Wire in closure-conversion logic for constructors, add specs for it,
and add more specs (and fix bugs discovered)"
Thanks,
--Vladimir
Another possible breaker is Rubeus...It actively made a whole
framework around suppluing blocks to all Swing component constructors
(I am not sure how it is implemented yet to know):
http://code.google.com/p/rubeus/source/browse/trunk/examples/nyanco_viewer/nyanco_viewer_rubeus.rb
-Tom
--
blog: http://blog.enebo.com twitter: tom_enebo
mail: tom....@gmail.com
I'm pretty sure they monkey-patched "new" on those Java classes to
take blocks and run them, so they'd probably be fine.
- Charlie
Filed http://jira.codehaus.org/browse/JRUBY-4087 for it. Marked as
minor since the block-to-Icon is unexpected and wouldn't be useful
even if this was working.
- Charlie