Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Still More Perl Lightning Articles
by Phil Crow, Josh McAdams, Steven Schubiger, chromatic | Pages: 1, 2, 3, 4

Swinging with Perl

Phil Crow

Perl does not have a native graphical user interface (GUI) toolkit. So we use all manner of existing GUI tools in front of our Perl applications. Often we use a web browser. We have long had Perl/Tk and other libraries based on C/C++. Now we can also use Java's Swing toolkit with similar ease.

In my sample application, when the user presses a button, Perl evaluates an arithmetic expression from the input text box. The result appears in another text box. I'll show the code for this application a piece at a time with a discussion after each piece. To see the whole thing, look in the examples directory of the Java::Swing distribution.

    #!/usr/bin/perl
    use strict; use warnings;

    BEGIN {
        $ENV{CLASSPATH} .= ':/path/to/Java/Swing/java'
    }

Java::Swing needs certain Java classes to be in the class path before it loads, so I've appended a path to those classes in a BEGIN block (this block must come before using Java::Swing).

    use Java::Swing;

This innocuous statement magically sets up namespaces for each Java Swing component, among other things.

    my $expression  = JTextField->new();
    my $answer      = JTextField->new( { columns => 10 } );
    my $submit      = JButton   ->new("Evaluate");
    my $frame       = JFrame    ->new();
    my $root_pane   = $frame->getContentPane();
    my $south_panel = JPanel->new();

After using Java::Swing, you can refer to Swing components as Perl classes. You can even pass named parameters to their constructors, as shown for the second JTextField.

    $south_panel->add(JLabel->new("Answer:"), "West");
    $south_panel->add($answer,                "Center");
    $south_panel->add($submit,                "East");

    $root_pane->add($expression,  "North");
    $root_pane->add($south_panel, "South");

    $frame->setSize(300, 100);
    $frame->show();

Most work with the components is the same as in any Java program. If you don't understand the above code, consult a good book on Swing (like the one from O'Reilly).

    my $swinger = Java::Swing->new();

This creates a Java::Swing instance to connect event listeners and to control the event loop.

    $swinger->connect(
        "ActionListener", $submit, { actionPerformed => \&evaluate }
    );

    $swinger->connect(
        "WindowListener", $frame, { windowClosing => \&ending }
    );

Connection is simple. Pass the listener type, the object to listen to, and a hash of code references to call back as events arrive.

    $swinger->start();

Start the event loop. After this, the program passively waits for event callbacks. It stops when one of the callbacks stops the event loop.

    sub evaluate {
        my $sender_name = shift;
        my $event       = shift;

        $answer->setText(eval $expression->getText());
    }

My evaluation is simple. I retrieve the text from the expression JTextField, eval it, and pass the result to setText on the answer JTextField. Using eval raises possible security concerns, so use it wisely.

    sub ending {
        $swinger->stop();
    }

When the user closes the window, I stop the event loop by calling stop on the Java::Swing instance gained earlier. This kills the program.

With Java::Swing, you can build Swing apps in Perl with some important bits of syntactic sugar. First, you don't need to have separate Java files or inline sections. Second, you can pass named arguments to constructors. Finally, you can easily connect event listeners to Perl callback code.

Pages: 1, 2, 3, 4

Next Pagearrow