Forum: JRuby Anonymous class with JRuby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
7b2f46e2e18ef5291685bd8502f5de14?d=identicon&s=25 4wai (Guest)
on 2009-06-04 11:35
(Received via mailing list)
Hi all,
    I have some questions about anonymous class with JRuby.
I want to have some code like
JPanel p = new JPanel() {
    public void paint(Graphics g) {
    //draw something
    }
};
new JFrame().getContentPane().add( p);

with JRuby

I try

p = JPanel.new
def p.paint(g)
  //draw something
end
JFrame.new.getContentPane.add p

but the code inside paint() didn't run.

how can these be achieved?
Ede2aa10c6462f1d825143879be59e38?d=identicon&s=25 Charles Oliver Nutter (Guest)
on 2009-06-04 21:22
(Received via mailing list)
4wai wrote:
>
> but the code inside paint() didn't run.
>
> how can these be achieved?

Because the JPanel has its own paint method, by the time you've
constructed it here it's already too late to replace it. Java won't see
anything we add after the fact. I think this would work:

p = Class.new(JPanel) do
   def paint(g) ... end
end.new

Since now you're explicitly creating a new subclass and overriding paint
from the parent.

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
8efc2a6ab6c2d06439b368e605d7ccde?d=identicon&s=25 4wai (Guest)
on 2009-06-05 04:19
(Received via mailing list)
It works~
thanks alot

On Fri, Jun 5, 2009 at 3:21 AM, Charles Oliver Nutter <
8efc2a6ab6c2d06439b368e605d7ccde?d=identicon&s=25 4wai (Guest)
on 2009-06-05 05:49
(Received via mailing list)
I've got another problem, seems the paint method cannot access the
variable
outside

img = BufferedImage.new
panel = Class.new JPanel do
  def paint (g)
    g.drawImage img, 0, 0, nil
  end
end.new

When the panel paint method is called, a exception throws

Exception in thread "AWT-EventQueue-0" alarm.rb:27:in `paint': undefined
local variable or method `img' for #<#<Class:01x51f266>:0x88884e>
(NameError)
    from :1
    ...internal jruby stack elided...
    from #<Class:01x51f266>.paint(:1)
    from (unknown).(unknown)(:1)
Ede2aa10c6462f1d825143879be59e38?d=identicon&s=25 Charles Oliver Nutter (Guest)
on 2009-06-05 18:38
(Received via mailing list)
4wai wrote:
> I've got another problem, seems the paint method cannot access the
> variable outside
>
> img = BufferedImage.new
> panel = Class.new JPanel do
>   def paint (g)
>     g.drawImage img, 0, 0, nil
>   end
> end.new

Ok, you can do one of three things:

1. store the image in a constant

This would allow it to be accessed from your method and would have
little to no perf impact on the code. But of course ideally your img
would be a constant value. Alternatively you could store it into an
instance variable of some constant-referenced container.

Depending on how likely you are to need to replace/re-set img, this may
or may not be an option.

2. use define_method

img = BufferedImage.new
panel = Class.new JPanel do
   define_method :paint do |g|
     g.drawImage img, 0, 0, nil
   end
end.new

Because you're using all blocks here, the outer img variable will be
visible to the define_method version of paint. The down side is that
define_method tends to have reduced performance compared to a normal
method (for now...we have some ideas on how to improve it).

3. just define a real class and put the value into it

This is probably the cleanest option. Just define this JPanel subclass
elsewhere as a real named class and pass the img into its constructor or
into an attribute writer. Then use it as a normal ivar.

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
This topic is locked and can not be replied to.