Archive for the ‘Languages’ Category

August 21st, 2014  Posted at   Languages, Python

Recently I had the need to create a Windows application (EXE) from a Python script, in order to distribute it to some Windows boxes without Python installed. The script implemented a GUI using  the Tkinter libraries and I even created a cool logo for the app, so I could replace the default Tkinter logo.

The problem was that I would had to distribute the .exe and the logo (.gif) and it seemed kind of weird. So I thought… why not embed the logo in the script? I could use that to create real self-contained GUI apps in a single Python script!

I’ll share in this post how I achieved this. It’s quite easy.

For this example I’ve created a very simple logo (64×64 pixels) online using cooltext.com and I exported it in GIF format because it’s the appropriated one for this method. Here it is ‘mgx.gif’:

mgx.gif

We have to insert the bytes of the logo file into a Python variable in the script. The best way to do this is to use a byte encoding that outputs printable ASCII characters, so let’s use Base64. You could use many tools to achieve this, I will do it with the base64 command from Linux.

base64 mgx.gif

The command will output the bytes of the .gif encoded.

base64

Now we have to assign the Base64 string to a Python variable. We will use the power of sed and Regular Expressions to make our life easier. Suppose our variable will be called ‘logo’.

base64 mgx.gif | sed “s/^/logo += ‘/g;s/$/’/g”

base64_sed

To get our logo variable set in our Python script we just have to initialize it and then append the previous output.

logo = ''
logo +='R0lGODlhQABAAOf/AAABAAABBQUCBwAEHgQFEQowIHFwIFLQcGGwMFMgwHIQoFRAgHOg0KDwwI'
logo +='KwkKJgoHTA0KNg0LMRIMKQ8JXBQHYxIJVg4NPxcxENRBAOUhUSHxEKfBASMREMdRUPTRUKhBEO'
logo +='bhESWRUUOhkUNR4JlyMIoBgVQRkUbRcPqR0WVRYRwOsgcVuxsUlR4YaiIPvSEZZh8dTxoZhx8X'
logo +='jhUXxiIbgywSySEeeykcfh8Y0RocuSomOygiai8CAcwy4ZvB4grDYV1i8ifiomZioa3ikc1i8g'
logo +='qSsmhy4g0SklsjAjui0nni8pizYjtDUe6zQg4yQkojvi0przUpmjIlzDYj3TAwdjsh7y8sqSkp'
.......

Perfect. Once we have our variable set, the idea is to write those encoded bytes to a file in run time, and tell Tkinter to read that file as the main icon for our GUI. We can create the file in the same directory but I don’t like this approach because you don’t always have permission to do that. Besides, in my opinion, it’s weird to see that a logo appears in the script’s folder during execution.

I prefer to write it in a temporary file using the cross-platform library tempfile. Here is the code I used for the example.

iconfile = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
    try:
        iconfile.write(base64.b64decode(self.logo))
    finally:
        iconfile.close()

In the first line we use the method NamedTemporaryFile to obtain a temporary file with a name so we can read it later. We also set the delete option to False because otherwise the file is deleted as soon it is closed. Then, as you can see, we write the bytes we obtain after decoding our logo variable. Finally we close the file.

Just a couple of things before you see the final code. To obtain the real path generated for the temporary file we have to use the name attribute.

if os.path.isfile(iconfile.name):
    icon = PhotoImage(file=iconfile.name)

Finally it’s a good practice to tell the OS that we don’t need the file anymore when we close our application.

try:
    os.unlink(iconfile.name)
except:
    pass

You can view the whole example here –> embedicon.py

Here are some screenshots of the script in different operating systems.

embedded_xp

Windows XP

embedded_w7

Windows 7

embedded_ubuntu

Ubuntu

embedded_kali

Kali Linux

 

Enjoy :)

February 11th, 2012  Posted at   Java, Languages
,    |   No Comments

JTables are very useful for develop desktop applications but when it comes to customize properties at cell level it can be a little tricky. The key concept here is that we have to deal with Cell Renderers for each column. TableCellRenderer is an interface that forces to implement the following method:

Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)

The most common way to customize Cell Rendering is to create a class that extends a Component and implements TableCellRenderer. Most people use a simple JLabel. For example,  the following class will allow us to change the background of a single cell:

public class JLabelCellRenderer extends JLabel implements TableCellRenderer
{
  @Override
  public Component getTableCellRendererComponent(JTable table,Object value,
  boolean isSelected,boolean hasFocus, int row,int col)
  {
    JLabel label = (JLabel) value;
    setBackground(label.getBackground());
    setOpaque(true); /* Important to see the background color */
    return this;
  }
}

Now lets create our table and use our custom cell renderer:

JTable table = new JTable();
String[] columnNames = {"Red","Blue"}; /* Two columns */
JLabel[][] data = new JLabel[1][2]; /* One row, two columns */
data[0][0] = new JLabel("");
data[0][0].setBackground(Color.red);
data[0][1] = new JLabel("");
data[0][1].setBackground(Color.blue);
table.setModel(new DefaultTableModel(data, columnNames));
/* Now we use our new class for rendering cells */
table.getColumnModel().getColumn(0).setCellRenderer(new JLabelCellRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new JLabelCellRenderer());

Now we put it in a JFrame and the result is the following:

JTable 2 cell colors example
So it worked! Now you can improve the cell renderer and get more properties from the JLabel such as Font, Foreground, Border… etc.
I’ve developed a more complex but funnier example in which I’ve used most common methods and properties to customize the aspect of a JTable. A couple of screenshots are shown below so you can get the idea.

JTable example serious JTable example smiling

 

You can get the source code -> Smiley.java

and the executable jar file -> Smiley.jar

Enjoy.

February 9th, 2012  Posted at   Java, Languages
   |   No Comments

The other day I was trying to compile and run some swing example code using the command line and when I tried to execute I got the following error:

Exception in thread “main” java.lang.UnsupportedClassVersionError: Main : Unsupported major.minor version 51.0

I found on the Internet that version 51.0 corresponds to java 1.7 and then I realised that I have jdk 1.7 installed while my jre is 1.6.

I usually don’t care about this compatibilty issues because NetBeans takes care of this.

So the solution is to tell javac to compile it for 1.6:

javac -source 1.6 -target 1.6 MyClass.java

And then it worked like a charm.

NOTE:

This kind of error is due to version differences between the binaries and the virtual machine and can be solved like I wrote above. Having said that remember that if you have some incompatible source code between versions javac compiler will complain.

Enjoy.

December 28th, 2011  Posted at   Backtrack, Debian, Java, Languages, Linux
   |   No Comments

I think this is very useful. I know there are powerful script languages like python or ruby which, by the way, I strongly recommend you to learn. But maybe you feel comfortable (like me) using Java for simple and not so simple programs or scripts. I’m writing this post because the other day I wanted to create a word list file to use in Backtrack with specific restrictions that I had in mind. It had been long time without using Ruby and I had to refresh my knowledge about it to make it. But then I thought that I could have made the word list faster just with a few lines of Java. But of course we don’t want to use an IDE like Eclipse o NetBeans for this kind of programs, we just want our lovely console :).

Enough chatter let’s go to practice. We’re going to create a HelloWorld.java and run it all from the console.

First of all we need to install the Java Development Kit (JDK) in order to run the Java compiler (javac). We can use the one from Sun, but I’ll be using openjdk which is installed in my Backtrack.

If you don’t have it installed yet, just type:

apt-get install openjdk-6-jdk

or

apt-get install default-jdk

We are going to use the Java Compiler (javac) to create the binary file HelloWorld.class, the one that can be executed by the Java Virtual Machine (JVM).

Let’s write the source code. Use your favorite editor, I’ll use nano:

nano HelloWorld.java

And now the code:

/* Java Hello World from mendrugox */
 
public class HelloWorld
{
	public static void main(String[] args)
	{
		System.out.println("Hello World!");
	}
}

Save and close (Ctrl +x in nano).

Now we have our code in the HelloWorld.java file, let’s compile it:

javac HelloWorld.java

The file HelloWorld.class is created and now we can execute our program:

java HelloWorld

*Notice that I put HelloWorld and not HelloWorld.class.

 

We’re done.

Enjoy.

October 28th, 2011  Posted at   Java, Languages
,    |   No Comments

When we pack all our java classes, libraries and resources in a single .jar in order to share our application, if our code has references to resources using absolute or relative paths to the files in our working directory like for example:

ImageIcon image = new ImageIcon('/gui/images/logo.png');

We won’t be able to get this resource when executing our standalone .jar file. We’ll have to use the getResource() method from the class. Imagine that we are using Swing for creating a cool GUI for our application. Now we want to view our custom logo in our JFrame class instead the default one. And, of course, we want this to be working even when we distribute our app in a single .jar package. If our logo were located at /src/gui/images/logo.png,  this is the code that we’ll be using for our purpose inside the JFrame class:

private void customize()
{
    try
        {
            URL res = getClass().getResource("/gui/images/logo.png");
            ImageIcon image = new ImageIcon(res);
            setIconImage(image.getImage());
        }
        catch (Exception ex)
        {
            System.err.println(ex);
        }
}

The same way for any other resources like files or music :).

Enjoy.