1. Computing

An ROT13 Encoder


One of the "Hello world" GUI applications I like to write is an ROT13 encoder. ROT13 is a (very) primitive encryption where each letter of the alphabet is rotated 13 places to the right and has the added benefit of being symmetrical, the decryption uses the same exact method. The application itself will have an input text field, a button and an output text field.

Note that this is still using Swing directly. There are ways of using WYSIWYG GUI editors with JRuby, but let's not get that involved quite yet.

Layout Managers

In learning how to use Swing, one of the most important things to learn is layout managers. Lacking a WYSIWYG GUI layout tool, you'll be working with the layouts yourself. And while it's possible to do everything manually, it's much more feasible to give all your components (AKA "widgets," as they're called in most other toolkits) to a layout manager and have it figure out where to put everything.

The layout for this application will be simple. There are two text fields and a button. And.. well, that's it, so let's just lay them out vertically. To do this we'll use a "Flow" layout. The flow layout is something very close to a work processor. It knows the width of each component and the width of the frame it and will try to make "lines" of components, when it runs out of room it moves down and makes another line. In our case, we'll be using a frame about as wide as any of the components, so each component will be on a line of its own. For more information about layout managers, see A Visual Guide to Layout Managers.

The two components we'll need for this application are the JTextField and the JButton. The JTextField is a common single line text field. We'll be using it for both input and output, once you've instantiated a JTextField, you can access (read or write) the text inside using the text attribute.

Things get a bit messier, but also quite easy in Ruby, when talking about the JButton. A JButton usually has to have some way of carrying over the state of the application into a detached callback function in Java. In JRuby, the callback can be a closure. If you'll recall, a closure inherits the binding of the scope it was declared in. This means it has access to all local variables in the scope it was defined, and this can hold the state of the application (in this case, a reference to the two text fields) for us.

The Code

require 'java'

import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.JButton
import javax.swing.JTextField
import java.awt.FlowLayout

class String
	def rot13
		tr 'A-Za-z','N-ZA-Mn-za-m'

class MainWindow < JFrame
	def initialize
		super "ROT13"
		setDefaultCloseOperation JFrame::EXIT_ON_CLOSE

		panel = JPanel.new(FlowLayout.new(FlowLayout::CENTER))
		input = JTextField.new(10)
		button = JButton.new("Encrypt")
		output = JTextField.new(10)

		panel.add input
		panel.add button
		panel.add output

		button.add_action_listener do|e|
			output.text = input.text.rot13

		add panel
		setSize 100, 130

		setVisible true


Things are more or less straightforward when you wrap your head around Swing (which is really pretty typical for a GUI toolkit). The top section first requires the java library, which gives us access to the import method. The import method is then used to bring access to a number of Java classes we'll need to use.

The rot13 method is a simple implementation using tr (short for "translate"). There are more straightforward methods, but this is easy to remember and implement, and only uses a single standard String method.

Onto the meat of the program. Since I need references to a number of the components later, I instantiate them all at once and assign them to local variables. Remember that these local variables act as the state for the callback closure. Next, I add them to the JPanel object (which is acting as a container for our layout manager).

Adding the callback for the JButton is simple using the add_action_listener method. It takes a single parameter called e here. We never use it, but it's an instant of ActionEvent. The only interesting event passed down by a JButton is the click event, so we don't need to worry about the actual event. The callback itself is straightforward.

And finally we add the panel to the frame, set the size, set the frame to visible (and hence all the components inside the frame) and on the very last line of the program, instantiate the frame.

  1. About.com
  2. Computing
  3. Ruby
  4. JRuby
  5. Building a Simple GUI Application with JRuby

©2014 About.com. All rights reserved.