Debuggable swing code in eclipse

February 27, 2011

The classes inside rt.jar (as shipped by Oracle) were built without the -g flag (to make the download smaller). That is a good idea, until you try to debug swing code (inside eclipse, for instance) and realize that variable names are not available. A quick solution for this problem is to build the classes yourself, using the -g flag. Here is how (using win7 + cygwin and I assume the content of JAVA_HOME is the JDK installation path):

cd ~
mkdir src
cd src
mkdir classes
cp %JAVA_HOME%/src.zip .
cp %JAVA_HOME%/jre/lib/rt.jar .
unzip src.zip
find -name *.java > files.txt
javac @options.txt @files.txt 2>&1 | grep “.*[A-Z].*\.java:[0-9]*: [^w]“
cd classes
jar cvf debug.jar *

Now, here is the content for options.txt (put this file in ~src/):

-d classes
-g
-verbose
-J
-Xmx512m
-cp rt.jar
-nowarn
-source 1.6
-Xlint:none

After you are done, you can copy the jar file to your eclipse project, and under Debug Configurations > Classpath tab > Bootstrap Entries add debug.jar on top of JRE system.

References found during the research for this post are here


Custom JTooltip

October 10, 2010

Okay, this is going to be quick as I am a little short on time lately. This blog entry was motivated by me trying to create a custom JTooltip. I didn’t want custom borders or colors, as described in Swing Hacks. I actually wanted to add some components to the JTooltip, so that users could interact with it and provide input. After reading the relevant part of swing’s source code, I set out googling for ideas. It turned out to be quite difficult to find any interesting/simple ideas. Hence, this blog post.

In the end, what we need to do is to subclass JTooltip. This subclass should build and layout the desired components. Then an instance of this class has to be returned by the component that will own the tooltip. An example follows:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolTip;

public class CustomTooltipSample extends JFrame {
    private CustomLabel m_label;

    public CustomTooltipSample() {
        setTitle("Custom tooltip sample");
        setSize(300, 200);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        m_label = new CustomLabel("My Label");
        m_label.setToolTipText("Yo, I am a tooltip with components!"); // activate tooltips for this component
        add(m_label);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                JFrame frame = new CustomTooltipSample();
                frame.setVisible(true);
            }
        });
    }

    private static class CustomLabel extends JLabel {
        private CustomTooltip m_tooltip;

        public CustomLabel(String text) {
            super(text);
        }

        @Override public JToolTip createToolTip() {
            if (m_tooltip == null) {
                m_tooltip = new CustomTooltip();
                m_tooltip.setComponent(this);
            }
            return m_tooltip;
        }
    }

    private static class CustomTooltip extends JToolTip {
        private JLabel m_label;
        private JButton m_button;
        private JPanel m_panel;

        public CustomTooltip() {
            super();
            m_label = new JLabel();
            m_button = new JButton("See, I am a button!");
            m_panel = new JPanel(new BorderLayout());
            m_panel.add(BorderLayout.CENTER, m_label);
            m_panel.add(BorderLayout.SOUTH, m_button);
            setLayout(new BorderLayout());
            add(m_panel);
        }

        @Override public Dimension getPreferredSize() {
            return m_panel.getPreferredSize();
        }

        @Override public void setTipText(String tipText) {
            if (tipText != null && !tipText.isEmpty()) {
                m_label.setText(tipText);
            } else {
                super.setTipText(tipText);
            }
        }
    }
}

That’s it. Now you can use your creativity to customize the tooltip. Happy coding!


How would you compute powers?

July 20, 2010

Okay, I admit, it blew me away. I just love when I learn more efficient ways to implement elementary algorithms. At first, I answered this question in the most straightforward way. Check it out in the snippet below:

    /** power: linear implementation */
    private static int power(int x, int n) {
        int result = 1;
        for(int i = 0; i < n; ++i) {
            result *= x;
        }
        return result;
    }

Later, I learned a better (and ingenious) implementation while reading this book. The idea is beautifully simple: instead of the iteration, define a recursive function F(x, n) = { if n = 0 return 1; if n is even return f(x*x, floor(n/2)); if n is odd return x*f(x*x, floor(n/2)) }. That’s it! The implementation runs in logarithmic time, which can be proved by solving the recurrence relation derived from F (using repeated substitution). Check out the Java implementation below.

    /** power: logarithmic implementation */
    private static int power(int x, int n) {
        if(n == 0) {
            return 1;
        } else if(n % 2 == 0){
            return power(x*x, n/2);
        } else {
            return x * power(x*x, n/2);
        }
    }

My 2 cents on reading code

July 10, 2010

Hi There! I have recently started working on a new application that is very complex. There is a huge code base developed in a technology that I was not familiar with. Since then, I have been looking forward to learn somebody else’s experience on reading code and, during my research, I bumped into very nice articles here, here, here, and here. As I have had to read a lot of code myself I found the readings instructive as I could relate to many points mentioned in the posts. So I got inspired and decided to express my own opinions on the matter.

Reading code is challenging. In my opinion the most important thing is to understand what is going on in terms of abstractions.

First of all, you have to know what the piece of code you are reading does. The better way to do that is to understand the domain of the application. For example, if you are working on a financial application and you don’t know what an Options contract is, you will have a hard time even understanding what the application is supposed to do.

Second, you have to get the idea behind the implementation: how the code achieves the goal? In order to do that I think there are two approaches: Firstly, if you are very experienced, chances are that you will already have seen some similar way of solving the given problem before and therefore you will pick it up real quick.

The other approach is to find out what is the flow and what are the classes involved. If you are a UML guy you would draw sequence and class diagrams. The way I do that is to find the event that triggers the code (thanks to swingspy I have been able to do that in Swing apps), put a breakpoint there and start debugging. During the process, keep writing the flow and the classes using pencil and paper. Once you are done, start analyzing your notes and draw a nice diagram. After that I usually have a rough understanding of what is going on and who is doing what and when.

I think this very useful because, specially in Object Oriented systems, there is a tendency of going back and forth between superclasses , subclasses, interface implementations etc. It is very easy to get lost or confused.

Finally and most important, you have to be fluent in the vocabulary. By vocabulary I mean components, algorithms and data structures used in the language. For example, it would be very difficult for a person to read code that uses hashtables to solve a problem if this person does not know what it is and how it works. Similarly, if you are working on a Swing project and you have to read code that uses a JTable, you have to understand how it works. If you don’t it is going to take you a lot of time to figure out what is going on and chances are you will miss something and end up adding bugs to the code.

Note: A friend of mine told me that he loves this so called Archeology job: reading a piece of code for hours trying to figure out what the heck was going on in the mind of the programmer that wrote the code. I am giving it a shot and to my amazement, it is quite fun – it’s like playing detective. Thanks Marcus :)


Collatz Conjecture

June 2, 2010

The Collatz conjecture – also known as the 3n+1 problem – provides an interesting programming exercise. The first time I saw it was in the book Programming Challenges and you can also try to submit your solution to the UVa online judge.

The fastest solution I could come up with uses recursion and caching to store previously calculated cycles. The idea is simple: calculate the number of cycles just once for any given number.

The implementation looks a little bit weird because you cannot use long variables to index arrays in Java, as opposed to C and C++. For this reason, my solution only caches values that are sufficiently small.

In any case, here is my solution. Please let me know if you see any possible improvements.

/**
 * Implements a simple cycle calculator for the Collatz conjecture. It uses
 * recursion and array based caching.
 */
public final class Collatz {
    private static final int MAX_SIZE = 1000000;
    private static int[] cache = new int[MAX_SIZE];

    /**
     * Prevents instantiation.
     */
    private Collatz() {}

    /**
     * Calculates the number of cycles for a given number.
     */
    public final static int cyclesForNumber(long n) {
        // Try to return the number of cycles from cache
        if (n < MAX_SIZE) {
            int cycles = cache[(int) n];
            if (cycles > 0) {
                return cycles;
            }
        }

        // Calculate the number of cycles for n
        int cycles = 0;
        if (n == 1) {
            cycles = 1;
        } else if ((n & 1) == 0) {
            cycles = 1 + cyclesForNumber(n >> 1);
        } else {
            cycles = 1 + cyclesForNumber(3 * n + 1);
        }

        // Store it in the cache and return
        if (n < MAX_SIZE) {
            cache[(int) n] = cycles;
        }
        return cycles;
    }

    public static void main(String[] args) {
        long t0 = System.currentTimeMillis();
        int num1 = 1;
        int num2 = 999999;
        int max = 0;
        for (int i = num1; i <= num2; ++i) {
            int cycles = Collatz.cyclesForNumber(i);
            if (cycles > max) {
                max = cycles;
            }
        }
        System.out.println("cycles: " + max);
        long dt = System.currentTimeMillis() - t0;
        System.out.println("elapsed time: " + dt);
    }
}

LEAD and the Web 2.0 experience for corporations

September 29, 2009

Companies are still struggling to keep the pace with new technologies and on how it can be used to straighten their relationship with customers. The Web 2.0 has arrived and from a corporate standpoint there is much to be done in order to leverage the new media capabilities. Customers can now use the Internet to express their opinions, influencing other customers and advertising, for the good or for the bad, services and products from companies in a very wide range of businesses.

One of the most staggering aspects of this phenomenon is the communication capabilities and the impact it can bring on the decision making of a customer. In the underpinning of this new facet lies the ease-of-use and broad audience to Web 2.0 sites such as Youtube, Facebook and Twitter, just to name a few.
One of the possible approaches for corporations to manage the Web 2.0 experience is LEAD (Listen, Experiment, Apply and Develop). In short, it suggests a way for companies to leverage Web 2.0 resources engaging customers and receiving a most valuable feedback on their products and services.

Listen to what people are saying about your business on-line. Implement a formal process in order to find out what your customers think, how they are reviewing your products and services, what are their suggestions and how you could make them happier.

Experiment with Web 2.0 technologies, engaging your customers on-line. Try to go where your customers are, create an on-line profile on Facebook, try to open new communication channels with your customers and bring their experiences and suggestions to your attention. Make them see that your company is present in their on-line experience, make it easier for them to communicate to you.

Apply your experiments. Make your website integrate to on-line communities, make sure it is more relevant on content searches, make it easier for customers to tag your content. Doing that you increase the range of possibilities customers can get information about your company.

Develop your marketing capabilities using Web 2.0. Make it a fundamental part of your integrated advertising program. Make use of the data available from your customer and use tools such as quantitative analysis and micro-blogging to find out what are your customers needs and to explore new products and services.

The Web 2.0 allows for an extra level of communication as many more resources are available for content creation and consumption. There are many success cases of companies using quantitative analysis and on-line communities to improve the service provided to their customers. Be one of them and help to identify and develop even more opportunities for your business bringing it to the new cloud. Welcome to the Web 2.0!


Follow

Get every new post delivered to your Inbox.