Posts Tagged ‘gtk’

Ruby-GTK behavior in JRuby-GTK (using Java’s GTK)

Friday, June 25th, 2010

When I first started playing around with JRuby, I quickly found out, that the GTK-extension for Ruby did not work with JRuby, since it was a native C-extension, which could not be loaded into Java.

To load GTK in JRuby anyway, I had to install the Java GTK on my Ubuntu machine. This is pretty easy – just fire off a “sudo aptitude install libjava-gnome-java” and your done…

Java’s GTK is a lot different from the Ruby version. First of all a lot of the Ruby-objects has optimized constructors. You can construct a window with a title by doing:

window = Gtk::Window.new("The title")

In Java this is not possible, so if you give the argument your app fails. This meant that JRuby wasnt able to handle some of my GTK-apps. I then decided to write a kind of wrapper, which would emulate the behavior of the Ruby-GTK in JRuby-GTK (Java’s GTK). This turned out to be a lot harder than I first thought.

First off I had to make dynamic events-classes for the connect-method, to first do it the Java-way and then call blocks in Ruby to turn it into the Ruby way – which I had never done before.

All in all I was able to get the following examples to work in JRuby with Java’s GTK loaded:

require "knj/jruby-gtk2/gtk2.rb"
require "knj/jruby-gtk2/gladexml.rb"

class WinAppEdit
	def initialize
		@glade = GladeXML.new("win_app_edit.glade"){|h|method(h)}
		@glade["window"].show_all
	end

	def on_btnSave_clicked
		print "Save clicked.\n"
	end

	def on_btnCancel_clicked
		print "Cancel clicked.\n"
	end

	def on_window_destroy
		print "Destroyed!\n"
		Gtk.main_quit
	end
end

WinAppEdit.new

Gtk.main

And the normal one:

require "knj/jruby-gtk2/gtk2.rb"

button = Gtk::Button.new("Test")
button.connect("clicked") do
	print "Clicked!\n"
end

win = Gtk::Window.new("Trala")
win.add(button)
win.show_all

win.connect("destroy") do
	print "Destroy!\n"
	Gtk.main_quit
end

Gtk.main

Why go through all of this, just so my Ruby-GTK applications can run through JRuby? Scalability, real threads, packaged Java-apps and so on…

The whole thing can be checked out at my account on GitHub:

http://github.com/kaspernj/knjrbfw

http://github.com/kaspernj/knjrbfw/blob/master/jruby-gtk2/gtk2.rb

http://github.com/kaspernj/knjrbfw/blob/master/jruby-gtk2/gladexml.rb

Be warned that this project is far from done – its actually more a proof of concept for myself :-)

Ruby and GTK on the N900

Sunday, January 10th, 2010

I finally compiled Ruby and GTK packages for the N900. It was a very big disappointment, when I found out that neither the official or the extras repositories had any ruby-gtk packages – even though Ruby itself had been packaged (but not optified).

Because of this, I decided to compile my own Ruby packages, which I have just tested on my phone (I cross-compiled them on my laptop).

Glade auto connect in JRuby

Sunday, November 15th, 2009

I have been playing a lot around with JRuby lately (since I was scared away from IronRuby by another lame Microsoft-patent). I have been really disappointed by the Gtk-implementation in Java – it really misses a lot of the good stuff from PHP-GTK – like the auto-connect functionality.

I decided I wanted to write my own Glade Auto Connect functionality to learn some more about JRuby – it turned out a bit harder than I expected. In the end I got it working with some of the basic widgets (GtkButton::Clicked, GtkWindow::destroy, GtkTreeViewSelection::changed and so on). I am adding support for more events as I continue my adventure into JRuby.

It works like this – when you want to spawn a new Glade-object, you do it through my function:

class MyWindow
  def initialize
    @glade = GladeAutoConnect("gladefile.glade", "window", self)
  end

  def on_window_destroy
    print "The window was closed!\n"
  end
end

No more connecting events manually – just write the event-names in the Glade-application directly. This functionality really shortens the code – which is what I like about Ruby: Less code to write. Right now it produces some eval-code though, which I plan to remove, when I learn more about how to dynamically make new classes in Ruby.

The code can bee seen here:
http://knjrbfw.kaspernj.org/jruby_gtk.rb

HowTo: Make a simple GtkWindow with IronRuby, GtkSharp, Glade and events (not Ruby-Gtk!)

Sunday, November 8th, 2009

To make this a lot easier for the ones of us using Ubuntu, I added IronRuby to my Ubuntu-repository. Read more about how to set it up here:

http://wiki.kaspernj.org/index.php/KnjUbuntuRepository

Afterwards do a: “sudo aptitude install ironruby glade libgtk2.0-cil libglade2.0-cil”.

While you are at it, install “glade” (”glade-3″ if you are using Jaunty, I think). Make a new project folder – I have called mine “IronRubyTest”. Make a small Glade-file (not GtkBuilder) with a label and a button. Remember the names – I called mine “window1″, “label1″ and “button1″.

To load the Glade-file, we have to import some modules first. To get the names of the modules, type “gacutil -l | grep gtk” and “gacutil -l | grep glade”. Type this in the beginning of your Ruby-code:

require "gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"
require "glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"

Be aware you properly have to use the lines, that you got from the “gacutil grep”-command.Its possible that yours can be different. Then type this afterwards in the Ruby-file:

include Gtk
include Glade


We are now ready to begin coding our class:

class MainWindow
  def initialize
    Application.init

    tha_glade = Glade::XML.new("test.glade", "window1", nil)
  end
end

Notice the “Application.init” – I guess this is to init the Gtk-stuff, like you would do in other languages when you are using Gtk.

The GladeXML-object is stored in the “tha_glade”-variable. “window1″ is the name of the Window, which can be set through Glade.

...
    tha_window = tha_glade.GetWidget("window1")
    tha_window.ShowAll
    tha_window.destroyed{|sender, e|
       Application.Quit
    }

    tha_button = tha_glade.GetWidget("button1")
    tha_button.clicked{|sender, e|
       tha_window.destroy
    }
...

We store the GtkWindow in the “tha_window” variable. Afterwards we attach some code to the destroy-event – we actually make the application kill itself, when we close the Window.

Further more we store the GtkButton in the “tha_button” variable. Afterwards we make the button close the window – which calls the other event and kills the application.

main_window = MainWindow.new
Application.run

The code here is placed at the very end of the file – not included in any function or class. This start our MainWindow-class, loads the window and everything and starts a loop, so our application doesnt end itself after loading the window and all.

The entire code can be seen here:

require "gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"
require "glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"

include Gtk
include Glade

class MainWindow
	def initialize
		Application.init

 		tha_glade = Glade::XML.new("test.glade", "window", nil)

		tha_window = tha_glade.GetWidget("window")
		tha_window.ShowAll
		tha_window.destroyed{|sender, e|
			Application.quit
		}

		tha_button = tha_glade.GetWidget("button1")
		tha_button.clicked{|sender, e|
			tha_window.destroy
		}
	end

	def on_button1_clicked(object, event)
		print "hmm\n"
	end
end

main_window = MainWindow.new
Application.run