Re: Can your GUI framework do this?

Martin,
I’m one of the contributors to Monkeybars, which is our JRuby GUI
framework that sits on top of Swing.
Here’s how Monkeybars handles this:

  1. A component consisting of a series of existing components hooked
    together to act as a single widget
    In Swing, it is typical to inherit from the component that gets you
    closest to what you want, and add stuff to there. What you are
    thinking of is probably a JPanel. While you could inherit from a
    JPanel, put in the functionality or other components that you wanted,
    and drop it in where you wanted to use it, we feel there’s a better
    way. Monkeybars uses MVC’s delegation of responsibilities to help us
    out with testing and keep the code more sensible. As such, we felt
    the best way to approach this would be by providing mechanisms that
    allow one MVC tuple (your top level window) to nest other MVC tuples
    (reusable components). This means that controllers communicate with
    other controllers. Views interact with simple view components
    directly, but not complicated “partials”.
    Here’s your example: An icon widget, that combines a picture and a
    textfield
    underneath, with config options to turn either off or size the image,
    make the text editable, etc"

In Monkeybars, the picture/text field grouping would be handled by its
own model, view, and controller. This is how you’d tie that in:
class MainView < ApplicationView

nesting defines how the component will be added or removed when

add_nested_controller or

remove_nested_controller is called. This nesting is one of the

simpler ones that just drops in the

component as is. There are more complicated variations that allow

you to write all code you want to

determine layout specific arguments, positioning, and layout

validation.
nest :sub_view => :image_name, :view => :image_name_panel
end

class MainController < ApplicationController
def load
@text_image_controller = TextImageController.create_instance
# this will kick off the nesting for any nesting with a sub_view
of :image_name
add_nested_controller :image_name, @text_image_controller
end
end

  1. A component built ‘from scratch’ atop a canvas, that is, handling
    its own drawing and event management
    Since we’re using Swing, one could override the paintComponent method
    on the Swing component used in the view. We’ve done some of this to
    render real-time animated graphs with peak bars and graph transitions.
    We even have it so each graph bar has it’s own tooltip text.
    Here’s your example: A speedometer-type dial with a configurable range
    and tick interval
    In this case, I’d write my own view component by hand (typically we
    use a designer for it).
    A speedometer could be made by using some of the Java2D stuff out
    there during paintComponent. The needle could be drawn with simple
    line methods where you specify start and end coordinates. The ticks
    could be drawn similarly as partial lines. I’d imagine some trig would
    be involved in the calculations. I would also check to see if any Java
    folks had already done this, as Java/Swing have been around for a long
    time.

  2. A component combining a canvas and existing widgets
    I’d want to make the painted canvas widget into a nested controller,
    so my canvas wouldn’t have to care about stomping on other components
    when it redraws itself.
    For your example: A box that holds a component and paints a customised
    border around it
    This is actually pretty simple in Monkeybars. You can just set the
    boarder of many (if not all) Swing components. We have a live example
    using this that you can run via Java Web Start here:
    http://www.happycamperstudios.com/monkeybars/twit/Twit-and-Twitter.jnlp
    Here’s the snippet that makes the drop-shadow border happen:
    @image = Java::javax.swing.JLabel.new
    @image.border = Java::org.jdesktop.swingx.border.DropShadowBorder.new
    The drop shadow comes from the SwingX library.
    I’d also like to note that example won us the GUI part of the script
    bowl competition at Java One (us being JRuby).

  3. A container that takes a collection of widgets and lays them out
    according to some userdefined algorithm
    There’s a ton of ways to do this using Swing using Layouts.
    Your example: A pure-ruby implementation of a wrapbox
    (http://zem.novylen.net/ruby/wrapboxdemo.png)
    This works out of the box just by using a FlowLayout in your
    container. That can be as simple as this:
    @main_view_component.layout = Java::javax::swing::FlowLayout.new

Some other stuff:
Monkeybars has a lot of options for configuring view mappings. View
mappings define how data moves from your model to the components in
your view, as well as how your components’ data moves into your model.

One thing that was really important to us in Monkeybars was that for
moderate to large projects, a large update method in a controller that
intimately knew about the components used made testing incredibly
painful. We designed Monkeybars such that most communication between
the view and controller is done through the model via the mappings
mentioned above. Controllers may also send signals to the view for
lightweight or secondary renderings. There is no direct communication,
however. This makes testing super easy.

You could write Java if you wanted, but we haven’t run into
occurrences where Java (the language) is needed. You could write all
of your designs by hand in Ruby, which is fine. My preferred approach
is to use a designer tool, such as Netbeans.
Do you really want to lay something like this out by hand?
http://www.happycamperstudios.com/monkeybars/charlotte%20interface.png

Swing is a part of Monkeybars. We provide some simplified ways to
communicate with it (such as implicit event handlers). However,
Monkeybars doesn’t shield you from Swing. This is both a pro and a
con. Swing is a powerful library, but it also has a lot of quirks.
Thanks to the folks at JRuby, we have Rubyized methods to all of our
Java proxies, and some nice implicit type conversions that make
integrating with Java look fairly natural. Monkeybars just makes Swing
more palatable, and provides a nice quarantine zone to place all of
your Swing code (in the view).

You’re in JRuby, and that means you’re in Java. Java buys you a built-
in JIT engine. JRuby’s team has told everyone to flag occurrences
where MRI is faster as bugs. You also can run your code on any machine
with Java installed, and it’s hard to find machines without Java.
Monkeybars itself is just a jar that happens to be a library. No Ruby
installation is needed! Leveraging Rawr you can also wrap your jars
in .exes or .app files. You can even use Java Web Start to hand
someone a link and the app will auto-install/update and run. You could
also integrate Monkeybars into your existing Java app, and start
writing all of your new code in Ruby. Java also has a lot of mature
code out there, as it has been around for a long time. One personal
experience I had was using SNMP. Ruby’s SNMP library is great for
getting you started, but falls apart when you need to use the more
secure SNMPv3. SNMP4J has been around for a while, and is still active.

I know a lot of the Ruby community has some bitterness towards Java,
but this isn’t Java the language we’re using here, it’s Java the
platform. I encourage anyone interested in GUI development to take a
peak at our examples and screencasts:
http://monkeybars.rubyforge.org/
http://monkeybars.rubyforge.org/tutorials.html

-Logan

I know a lot of the Ruby community has some bitterness towards Java,
but this isn’t Java the language we’re using here, it’s Java the
platform.

I dont think there is any bitterness. Just when you use ruby for long
you will feel that Java is more verbose, and less flexible. Other than
that, I dont think there is any real “bitterness” or similar.

Realistically I think Ruby should rather be compared to i.e. perl, php,
python.

The static languages (Java C C++ C# D) out there are always much more
verbose compared to ruby.

On Thu, Jun 26, 2008 at 7:13 AM, Marc H. [email protected]
wrote:

The static languages (Java C C++ C# D) out there are always much more
verbose compared to ruby.

D actually does a pretty good job of supplying “high level” features
like rich datatypes with literal constructors and full fledged lexical
closures. Those two can add up to a huge verbosity reduction.

martin

On Wed, Jun 25, 2008 at 2:44 PM, Logan B. [email protected]
wrote:

Martin,
I’m one of the contributors to Monkeybars, which is our JRuby GUI framework
that sits on top of Swing.
Here’s how Monkeybars handles this:

Thanks for the examples - Monkeybars looks pretty cool.

  1. A container that takes a collection of widgets and lays them out
    according to some userdefined algorithm
    There’s a ton of ways to do this using Swing using Layouts.
    Your example: A pure-ruby implementation of a wrapbox
    (http://zem.novylen.net/ruby/wrapboxdemo.png)
    This works out of the box just by using a FlowLayout in your container. That
    can be as simple as this:
    @main_view_component.layout = Java::javax::swing::FlowLayout.new

Yes, but my point was, can you define your own Layout in ruby?

You could write Java if you wanted, but we haven’t run into occurrences
where Java (the language) is needed. You could write all of your designs by
hand in Ruby, which is fine. My preferred approach is to use a designer
tool, such as Netbeans.
Do you really want to lay something like this out by hand?
http://www.happycamperstudios.com/monkeybars/charlotte%20interface.png

Actually, I do :slight_smile: My preferred approach is to build widgets from the
bottom up, so that if I want to experiment with the layout later I can
do it easily in the code. Does netbeans use the “interface definition
file” approach or does it generate actual code from your UI?

You’re in JRuby, and that means you’re in Java. Java buys you a built-in JIT
engine. JRuby’s team has told everyone to flag occurrences where MRI is
faster as bugs. You also can run your code on any machine with Java
installed, and it’s hard to find machines without Java. Monkeybars itself is
just a jar that happens to be a library. No Ruby installation is needed!
Leveraging Rawr you can also wrap your jars in .exes or .app files.

This is indeed a huge plus.

I know a lot of the Ruby community has some bitterness towards Java, but
this isn’t Java the language we’re using here, it’s Java the platform. I
encourage anyone interested in GUI development to take a peak at our
examples and screencasts:

No real bitterness - it’s just a language I’d prefer not to use. The
JVM itself I’m all for.

martin

Martin DeMello wrote:

Yes, but my point was, can you define your own Layout in ruby?

Yes you can define a new Swing layout manager with 100% Ruby code, just
as
you can do most anything doable in Java from JRuby. I would say though,
that is is highly unlikely that you would need to do so. There are a
great
variety of layout managers and most are pretty sophisticated, I surely
wouldn’t take on writing a non-trivial one myself. If you are looking
for a
very flexible layout manager designed for people doing layouts by hand
I’d
suggest the MiG layout manager (http://www.miglayout.com/). You can see
the
author’s presentation at this year’s Java One here:
Oracle Java Technologies | Oracle

Martin DeMello wrote:

bottom up, so that if I want to experiment with the layout later I can
do it easily in the code. Does netbeans use the “interface definition
file” approach or does it generate actual code from your UI?

Netbeans generates straight Java code, which you normally would never
need
to touch. As for building a widget from the “bottom up” do you have any
examples? I’ve built several “widgets” using the graphical deisgner.
In
Swing they tend to be JPanel + some components + logic (the logic of
course
would all be in Ruby) which makes the visual designer even more useful.
If
you’re doing a super custom component involving doing your own drawing,
that
is accomplished easily enough in straight Ruby code. In either of these
situations I fail to see how having a visual designer in any way slows
you
down.

David