Friday, May 22, 2009

Rapid application development with Jython and JFace (part III – main menu and actions)

In first part of this series I showed how to create hello world application with Jython and JFace. In second part we added event listers and layouts. In this part we will add main menu and action. Menu This useful thing by which user can trigger commands and then application will do it's stuff. In order to have it in your application you should write class that will inherits from the MenuManager class. Add method to construct menu. And the last thing: you need to call addMenuBar() method to your application's constructor. Good now you have menu, right? Not jet, first you have to write some actions. Luck use your Actions! All action classes should inherit from Action (org.eclipse.jface.action.Action) class. Action is abstraction above event listeners. Actions are easy to implement and you reduce code size by using them. We will implement exit application action in todays example application. Code:
"""
Hello world application with Jython and JFace
Part III - Main menu and actions 
GUID of this code snippet: 7f75fc86-d78c-4ce1-8e28-97bb4f5d5b31
Author: Darius Kucinskas (c) 2008-2009
Email: d[dot]kucinskas[eta]gmail[dot]com
Blog: http://blog-of-darius.blogspot.com/
License: GPL
"""
from org.eclipse.swt import *
from org.eclipse.swt.SWT import *
from org.eclipse.swt.widgets import *
from org.eclipse.swt.layout import *
from org.eclipse.jface.window import *
from org.eclipse.jface.action import *

# Skip this for now
# Draw Lithuanian flag (I use it as icon for this example)
from org.eclipse.swt.graphics import *
def drawIcon(display):
    image = Image(display, 16, 16)
    gc = GC(image)
    gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT))
    gc.fillRectangle(0, 0, 16, 16)
    gc.setBackground(Color(display, 253, 185, 19))
    gc.fillRectangle(0, 1, 16, 5)
    gc.setBackground(Color(display, 0, 106, 68))
    gc.fillRectangle(0, 6, 16, 10)
    gc.setBackground(Color(display, 193, 39, 45))
    gc.fillRectangle(0, 11, 16, 15)
    gc.dispose()
    return image

class ExitAction(Action):
    """ This is simple quit application action.
    
    All action classes should inherit from Action (org.eclipse.jface.action.Action) class.
    """
    
    def __init__(self, app):
        """ constructor of ExitAction
        
        arguments:
        app - in order to do anything useful I am passing 
        object of my application.    
        """
        self.app = app
        self.text = "E&xit@Ctrl+Q"
        self.toolTipText = "Exit the application"
        
    def run(self):
        """ run() method of action. Every action class should have one.
        This time it closes application.
        """
        if self.app != None:
            self.app.close()

class MainMenuManager(MenuManager):
    """ MenuManager is responsible for constructing  menu """
    
    def __init__(self, app):
        """constructor of MainMenuManager
        
        arguments:
        app - in order to do anything useful I am passing 
        object of my application.    
        """
        # let parent class to do it's stuff first
        MenuManager.__init__(self)
        self.app = app
        
    def createMainMenu(self):
        """ creates menu """
        mainMenu = MenuManager("")
        fileMenu = MenuManager("&File")       
        mainMenu.add(fileMenu)
        
        # add Exit action to file menu 
        fileMenu.add(ExitAction(self.app))
        
        return mainMenu   

class App(ApplicationWindow):
    """ Your second JFace application in jython """
        
    def __init__(self, shell):
        """ application constructor """
        # let parent class to do it's stuff first
        ApplicationWindow.__init__(self, shell)
        
        # lets add menu
        self.addMenuBar()
    
    def dispose(self):
        """ dispose resources here """
        pass
        
    def createContents(self, parent):
        """ 
        Creates the main window's contents
        parent - the main window
        return - control
        """
        self.getShell().setImage(drawIcon(Display.getCurrent())) 
        self.getShell().text = 'Third Jython & JFace example'
        
        panel = Composite(parent, SWT.BORDER)
        # set layout as one column grid
        panel.setLayout(GridLayout(1, True))
        
        label = Label(panel, SWT.CENTER)
        label.text = 'Hello, World'
        label.setLayoutData(GridData(SWT.CENTER, SWT.CENTER, False, False, 1, 1))
        
        # you can use action instead of button        
        ActionContributionItem(ExitAction(self)).fill(panel)
        
        return panel
    
    def createMenuManager(self):
        """ create main menu """
        return MainMenuManager(self).createMainMenu()
    
if __name__ == "__main__":
    """ The application entry point """
    display = Display()
    shell = Shell(display)
    
    app = App(shell)
    
    # Voodoo of SWT message loop
    try:
        app.setBlockOnOpen(True)
        app.open()
    finally:
        if app != None:
            app.dispose()
    
    display.dispose()
May the Jython force be with you!

Saturday, May 16, 2009

Rapid application development with Jython and JFace (part II – event listener and layout)

In first part of this series I showed how to create hello world application with Jython and JFace. Now we will add event listers and layouts. What application is good for if it is not reacting to user input? Events Listeners are special kind of classes and you will derive your class from it in order to be able to react to user actions. So we created MyListener listener. We pass reference to application object to constructor (so we could do many interesting things with it later then event happened). We yest close application on event in MyListener handleEvent method. We connected button 'Close' with MyListener. Event will be fired then user will press this button. Layouts Layouts are used to organize widgets on the screen in desired order. This time we put all widgets in grid which is one column width and two rows in height. Code:
"""
Hello world application with Jython and JFace
Part II - Event listeners and layouts 
GUID of this code snippet: 53029f4d-a208-4f45-920c-07d81167daee
Author: Darius Kucinskas (c) 2008-2009
Email: d[dot]kucinskas[eta]gmail[dot]com
Blog: http://blog-of-darius.blogspot.com/
License: GPL
"""
from org.eclipse.swt import *
from org.eclipse.swt.SWT import *
from org.eclipse.swt.widgets import *
from org.eclipse.swt.layout import *
from org.eclipse.jface.window import *

class MyListener(Listener):
 """ Class for event listener """
 
 def __init__(self, app):
  self.app = app

 def handleEvent(self, event):
  """ Close application if button is pressed """
  self.app.close()
   
class SWTApp(ApplicationWindow):
    """ Your second JFace application in jython """
        
    def __init__(self, shell):
        """ application constructor """
        ApplicationWindow.__init__(self, shell)
    
    def dispose(self):
        """ dispose resources here """
        pass
        
    def createContents(self, parent):
        """ 
        Creates the main window's contents
        parent - the main window
        return - control
        """ 
        self.getShell().text = 'Second Jython & JFace App'
        
        panel = Composite(parent, SWT.BORDER)
        panel.setLayout(GridLayout(1, True))
        """ set layout as one column grid """
        
        label = Label(panel, SWT.CENTER)
        label.text = 'Hello, World'
        label.setLayoutData(GridData(SWT.CENTER, SWT.CENTER, False, False, 1, 1))
                
        button = Button(panel, SWT.PUSH)
        button.text = 'Close'
        button.setLayoutData(GridData(SWT.CENTER, SWT.CENTER, False, False, 1, 1))
        button.addListener(SWT.Selection, MyListener(self))
        """ set listener which will react on event (button pressing) """
        
        return panel

if __name__ == "__main__":
    """ The application entry point """
    display = Display()
    shell = Shell(display)
    
    app = SWTApp(shell)
    try:
        app.setBlockOnOpen(True)
        app.open()
    finally:
        if app != None:
            app.dispose()
    
    display.dispose()
Execute your program: Now execute your application. There it is, your second Jython and JFace application.

Friday, May 15, 2009

Rapid application development with Jython and JFace (part I)

In this series of articles I'll show you how to create applications with jython and jface. I assume that you know syntax of python if not please first visit this fine tutorial here or any other. We'll start by setting up environment needed for development and will create the simplest jface application which will be foundation for further development.

Jython

Jython, lest you do not know of it, is the most compelling weapon the Java platform has for its survival into the 21st century:-) [Sean McGrath, CTO, Propylon]

Download Jython

What are your waiting for? Go and download jython from here now! Installation is easy jest execute command java -jar jython_installer-2.5.0.jar and follow instructions.

SWT: The Standard Widget Toolkit

SWT is an open source widget toolkit for Java designed to provide efficient, portable access to the user-interface facilities of the operating systems on which it is implemented. I recommend using prepared SWT packages from your Eclipse installation. You are using Eclipse right?

Needed jar files are the following:

  • org.eclipse.swt.gtk.linux.x86_3.4.0.xxx.jar
  • org.eclipse.swt_3.4.0.xxx.jar
  • org.eclipse.jface_3.4.0.xxx.jar
  • org.eclipse.core.commands_3.4.0.xxx.jar
  • org.eclipse.osgi_3.4.0.xxx.jar
  • org.eclipse.equinox.common_3.4.0.xxx.jar

Setting environment

To be able to run Jython/SWT/JFace application you should properly set your classpath (or configure your Eclipse IDE). If your are using Linux operating system you should execute the following commands:

CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.swt.gtk.linux.x86_3.4.0.xxx.jar"
CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.swt_3.4.0.xxx.jar"
CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.jface_3.4.0.xxx.jar"
CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.core.commands_3.4.0.xxx.jar"
CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.osgi_3.4.0.xxx.jar"
CLASSPATH=$CLASSPATH:"[path to jar]/org.eclipse.equinox.common_3.4.0.xxx.jar"
export CLASSPATH
For Windows execute the following command:
set CLASSPATH=.;[path to jar]\org.eclipse.swt.win32.win32.x86_3.4.xxx.jar;[path to jar]\org.eclipse.swt_3.4.xxx.jar;[path to jar]\org.eclipse.jface_3.4.xxx.jar;[path to jar]\org.eclipse.core.commands_3.4.xxx.jar;[path to jar]\org.eclipse.osgi_3.4.xxx.jar;[path to jar]\org.eclipse.equinox.common_3.4.xxx.jar

Code:
"""
Hello world application with Jython and JFace
GUID of this code snippet: cb4f368e-3b6b-42fe-ab1d-6f80e77ee3f5 
Author: Darius Kucinskas (c) 2008-2009
Email: d[dot]kucinskas[eta]gmail[dot]com
Blog: http://blog-of-darius.blogspot.com/
License: GPL
"""

from org.eclipse.swt import *
from org.eclipse.swt.SWT import *
from org.eclipse.swt.widgets import *
from org.eclipse.jface.window import *

class SWTApp(ApplicationWindow):
    """ Your first JFace application in jython """
    
    def __init__(self, shell):
        """ application constructor """
        ApplicationWindow.__init__(self, shell)
    
    def dispose(self):
        """ dispose resources here """
        pass
    
    def createContents(self, parent):
        """ 
        Creates the main window's contents
        parent - the main window
        return - control
        """ 
        self.getShell().text = 'First Jython & JFace App'
        self.label = Label(parent, SWT.CENTER)
        self.label.text = 'Hello, World'
        return self.label

if __name__ == "__main__":
    """ The application entry point """
    display = Display()
    shell = Shell(display)
    
    app = SWTApp(shell)
    try:
        app.setBlockOnOpen(True)
        app.open()
    finally:
        if app != None:
            app.dispose()
    
    display.dispose()

Save this code in file swtapp.py.

Execute your program:

Now execute your application: jython swtapp.py. There it is, your first jython and jface application.

Wednesday, May 13, 2009

Implementation of sort algorithms in python (part II – merge sort)

I am continuing my quest to implement all sort algorithms in python programming language. In this post I have implemented merge sort algorithm. Enjoy! (Previous post is available here).
"""
Merge sorting algorithms implemented in python
GUID of this code sniped: 83d44e30-e7b4-439e-b9eb-7dae165bf1af 
Author: Darius Kucinskas (c) 2008-2009
Email: d[dot]kucinskas[eta]gmail[dot]com
Blog: http://blog-of-darius.blogspot.com/
License: GPL
"""
def merge(left, right):
    r = []
    
    while len(left) > 0 and len(right) > 0:
        if left[0] <= right[0]:
            r.append(left[0])
            left = left[1:]
        else:
            r.append(right[0])
            right = right[1:]
            
    if len(left) > 0:
        r.extend(left)

    if len(right) > 0:
        r.extend(right)
    
    return r
    
def merge_sort(l):
    size = len(l)
    if size <= 1:
        return l

    middle = (size/2) - 1
    
    left = l[:middle+1]
    right = l[middle+1:]

    left = merge_sort(left)
    right = merge_sort(right)

    r = []
    if left[len(left) - 1] > right[0]:
        r = merge(left, right)
    else:
        r = merge(right, left)

    return r

if (__name__ == "__main__"):
    l = [i for i in range(10000)]
    print "sorted list"
    print l

    random.shuffle(l)
    print "unsorted original list"
    print l

    t1 = time.clock()
    lsorted = merge_sort(l)
    t2 = time.clock()
    print "soted list:"
    print lsorted
    print "merge sort time: %f " % (t2 - t1,)

Friday, May 8, 2009

Implementation of sort algorithms in python

I have found Wikipedia page about sorting algorithms. They are described in pseudo code, it is so easy to convert those in python code, so that I am hooked and can’t stop… :) Here is code, enjoy!
import random
import time

"""
Example of sorting algorithms implemented in python
GUID of this code sniped: 41ea3d8f-2330-4ddd-9e9d-ecd536ab4f4d 
Author: Darius Kucinskas (c) 2008-2009
Email: d[dot]kucinskas[eta]gmail[dot]com
Blog: http://blog-of-darius.blogspot.com/
License: GPL
"""

"""
simple bubble sort
"""
def bubble(l):
    sort_again = True
    while sort_again:
        sort_again = False

        i = 0
        size = len(l) - 1
        while i < size:
            if l[i] > l[i + 1]:
                swap(l, i, i + 1)
                sort_again = True
            i = i + 1

"""
insertion sort
"""
def insertion_sort(l):
    i = 0
    size = len(l) - 1
    while i < size:
        v = l[i]
        j = i - 1

        while j > 0 and l[j] > v:
            l[j + 1] = l[j]
            j = j - 1

        l[j + 1] = v
        i = i + 1

"""
shell sort
"""
def shell_sort(l):
    size = len(l)
    inc = int(size/2)

    while inc > 0:
        i = inc
        while i < size - 1:
            tmp = l[i]
            j = i
            while j >= inc and l[j - inc] > tmp:
                l[j] = l[j - inc]
                j = j - inc
            l[j] = tmp
            i = i + 1
        inc = int(inc/2.2)

"""
simple quicksort in python
"""
def quicksort1(l):
    if len(l) < 1:
        return l

    less = []
    greater = []

    pivot = l[len(l) / 2]
    l.remove(pivot)

    for i in l:
        if i < pivot:
            less.append(i)
        else:
            greater.append(i)

    return quicksort1(less) + [pivot] + quicksort1(greater)

def swap(l, a, b):
    tmp = l[a]
    l[a] = l[b]
    l[b] = tmp

if (__name__ == "__main__"):
    l = [i for i in range(10000)]
    print "sorted list"
    print l

    random.shuffle(l)
    print "unsorted original list"
    print l
    l2, l3, l4 = l[:], l[:], l[:]

    t1 = time.clock()
    bubble(l)
    t2 = time.clock()
    print "soted list l:"
    print l
    print "bubble sort time: %f " % (t2 - t1,)

    t1 = time.clock()
    insertion_sort(l2)
    t2 = time.clock()
    print "soted list l2:"
    print l2
    print "insertion sort time: %f " % (t2 - t1,)

    t1 = time.clock()
    shell_sort(l3)
    t2 = time.clock()
    print "soted list l3:"
    print l3
    print "shell sort time: %f " % (t2 - t1,)

    t1 = time.clock()
    lsorted = quicksort1(l4)
    t2 = time.clock()
    print "soted list l4:"
    print lsorted
    print "quick sort #1 time: %f " % (t2 - t1,)

Tuesday, May 5, 2009

back to the roots – linked list in C

I just had great fun to remember how to code linked list in C. I did it jest for propose of exercise. Next time I’ll try to do quick sort for linked list and will examine glibc if I have enough time for this exercise. Good lack and enjoy great game of coding ;)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

/**
 * Example of linked list in C
 * GUID of this code sniped: 75c6b760-1fa9-4b94-8f8d-53e5e4d6a20c
 * Author: Darius Kucinskas (c) 2008-2009
 * Email: d[dot]kucinskas[eta]gmail[dot]com
 * Blog: http://blog-of-darius.blogspot.com/
 * License: GPL
 */

typedef struct llnode LLNODE;

struct llnode
{
    void* data;
    LLNODE* next;
    LLNODE* prev;
};

int myprintstr(void* str)
{
    printf("'%s'\n", (char*)str);
    return 0;
}

int myfindstr(void *listdata, void *searchdata)
{
    return strcmp((char*)listdata, (char*)searchdata);
}

LLNODE* my_list_alloc0()
{
    LLNODE* n = malloc(sizeof(LLNODE));
    if (n == NULL)
    {
        return NULL;
    }

    memset(n, 0, sizeof(LLNODE));
    return n;
}

LLNODE* my_list_append(LLNODE* tail, void* data)
{
    LLNODE* n = my_list_alloc0();
    if (n == NULL)
    {
        printf("bad malloc my_list_append\n");
        return NULL;
    }

    n->data = data;

    if (tail != NULL)
    {
        assert(tail-<next == NULL);
        tail->next = n;
        n->prev = tail;
    }

    return n;
}

LLNODE* my_list_prepend(LLNODE* head, void* data)
{
    LLNODE* n = my_list_alloc0();
    if (n == NULL)
    {
        printf("bad malloc my_list_prepend\n");
        return NULL;
    }

    n->data = data;

    if (head != NULL)
    {
        assert(head->prev == NULL);
        n->next = head;
        head->prev = n;
    }

    return n;
}

int my_list_foreach(LLNODE* head, int(*func)(void*))
{
    LLNODE* p = head;
    while(p != NULL)
    {
        if (func(p->data) != 0)
        {
            return -1;
        }

        p = p->next;
    }
    return 0;
}

LLNODE* my_list_find(LLNODE* head, int (*func)(void*, void*), void* data)
{
    LLNODE* p = head;
    while(p != NULL)
    {
        if (func(p->data, data) == 0)
        {
            return p;
        }

        p = p->next;
    }

    return NULL;
}

void my_list_swap(LLNODE* p1, LLNODE* p2)
{
    void* p = p2->data;
    p2->data = p1->data;
    p1->data = p;
}

int my_list_sort_bubble(LLNODE** head, int(*func)(void*, void*))
{
    int sort_again = 1;

    while(sort_again == 1)
    {
        LLNODE* p = *head;
        sort_again = 0;

        while((p != NULL) && (p->next != NULL))
        {
            LLNODE* p2 = p->next;

            if (strcmp(p->data, p2->data) > 0)
            {
                my_list_swap(p, p2);
                sort_again = 1;
            }

            p = p->next;
        }
    }

    return 0;
}

void my_list_free1(LLNODE* node)
{
    assert(node != NULL);
    if (node == NULL)
    {
        return;
    }

    if (node->data != NULL)
    {
        free(node->data);
    }

    free(node);
}

void my_list_free(LLNODE* head)
{
    assert(head != NULL);
    if (head == NULL)
    {
        return;
    }

    LLNODE* p = head;
    while(p != NULL)
    {
        LLNODE* node = p;
        p = p->next;

        my_list_free1(node);
    }
}

unsigned long my_list_length(LLNODE* head)
{
    assert(head->prev == NULL);

    LLNODE* p = head;
    unsigned long count = 0;

    while(p != NULL)
    {
        count++;
        p = p->next;
    }

    return count;
}

long my_list_index(LLNODE *head, int (*func)(void*, void*), void* data)
{
    LLNODE* p = head;
    long index = 0;

    while(p != NULL)
    {
        if (func(p->data, data) == 0)
        {
            return index;
        }

        index++;
        p = p->next;
    }

    return -1;
}

LLNODE* my_list_concat(LLNODE* head1, LLNODE* head2)
{
    if ((head1 == NULL) || (head2 == NULL))
    {
        return NULL;
    }

    LLNODE* p = head1;
    while(p->next != NULL)
    {
        p = p->next;
    }

    p->next = head2;
    head2->prev = p;

    return head1;
}

int main(int argc, char** argv)
{
    LLNODE* head, *head2 = NULL;
    LLNODE* tail = NULL;

    tail = my_list_append(NULL, "first");
    if (tail == NULL)
    {
        printf("Failed to create new list");
        return 0;
    }
    head = tail;// save head of list

    // test of prepend
    head = my_list_prepend(head, "xxx");

    tail = my_list_append(tail, "second");
    tail = my_list_append(tail, "fird");
    tail = my_list_append(tail, "aac");
    tail = my_list_append(tail, "aaa");
    tail = my_list_append(tail, "test_very_long_string_jest_in_case!!!");
    tail = my_list_append(tail, "aab");
    tail = my_list_append(tail, "aba");
    tail = my_list_append(tail, "abb");

    printf("--- list: ---\n");
    my_list_foreach(head, myprintstr);
    printf("--- end of list ---\n");

    printf(" length of list: %ld \n", my_list_length(head));

    // sort
    my_list_sort_bubble(&head, myfindstr);
    printf("--- list after sort: ---\n");
    my_list_foreach(head, myprintstr);
    printf("--- end of list ---\n");

    // find test
    LLNODE* f1 = my_list_find(head, myfindstr, (void*)"test");
    if (f1 == NULL)
        printf("test not found\n");
    else
        printf("found '%s'\n", (char*)f1->data);

    // fins test
    LLNODE* f2 = my_list_find(head, myfindstr, (void*)"second");
    if (f2 == NULL)
        printf("test not found\n");
    else
        printf("found '%s'\n", (char*)f2->data);

    printf("Find index of 'xxx': %ld\n", my_list_index(head, myfindstr, (void*)"xxx"));
    printf("Find index of 'aba': %ld\n", my_list_index(head, myfindstr, (void*)"aba"));
    printf("Find index of 'test': %ld\n", my_list_index(head, myfindstr, (void*)"test"));

    // test concat
    tail = my_list_append(NULL, "ccc");
    if (tail == NULL)
    {
        printf("Failed to create new list");
        return 0;
    }
    head2 = tail;// save head of list
    tail = my_list_append(tail, "cbc");
    tail = my_list_append(tail, "cbb");
    tail = my_list_append(tail, "ddd");
    tail = my_list_append(tail, "ddc");
    tail = my_list_append(tail, "dcd");
    tail = my_list_append(tail, "dcc");
    tail = my_list_append(tail, "eee");
    tail = my_list_append(tail, "eed");

    head = my_list_concat(head, head2);
    printf("--- list after concat: ---\n");
    my_list_foreach(head, myprintstr);
    printf("--- end of list ---\n");

    // sort
    my_list_sort_bubble(&head, myfindstr);
    printf("--- list after sort: ---\n");
    my_list_foreach(head, myprintstr);
    printf("--- end of list ---\n");

    my_list_free(head);

    return 0;
}