Saturday, January 22, 2011

stackoverflow - 10k rep

I've finally crossed the 10k reputation milestone on stackoverflow! I thought I'd take this opportunity to reflect back on my time as a member of this famous programming Q & A site.

Even though I was one of the first people to join stackoverflow when the beta version came out two years ago, I did not become an active participant until much more recently. I have found this site to be a great way of helping people with programming difficulties and also as a great learning resource. During my time here, I have:

  • answered 546 questions
  • asked 46 questions
  • participated across 609 tags (mainly java, unix, bash and xml)
  • received 35 badges - 2 gold, 10 silver and 23 bronze
I have really enjoyed being a member of stackoverflow. For me, it has not simply been a quest for a high reputation, but more about learning new technologies and picking up advice from other experts on the site. I like to take on challenging questions, rather than the easy ones, because it pushes me to do research into areas I have never looked at before, and I learn so much during the process. As a result, I have dabbled with certain libraries that I haven't used before, such as Apache Lucene.

It's hard juggling work and stackoverflow. The only times I get to use it are during the weekends and in the evenings after work. Most of the questions have already been answered by then! However, I still like browsing the questions and checking out the answers.

Anyway, I need to get back to it now. Let's see how fast I can make it to 20k!

Saturday, January 08, 2011

A Paginated JList

If you have a large JList and don't want to scroll through it, it might be a better idea to "paginate" it i.e. display the list in "pages" of a few rows at a time and allow users to flip back and forth between them. To do this, I have written a Java Swing component called PaginatedList, which looks like this:

You pass in a JList and specify a page size (the page size is 10 in this example) and it returns a PaginatedList which you can add onto another JComponent as normal. The code is shown below:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListModel;


/**
 * A paginated JList. Only displays a specific number of rows
 * and allows you to page back and forth through the list.
 * with the help of a toolbar.
 */
public class PaginatedList extends JPanel {

  private final int pageSize;
  private final JList list;
  private final ListModel model;
  private final int lastPageNum;
  private int currPageNum;
  private JLabel countLabel ;
  private JButton first, prev, next, last;

  /**
   * @param list the source list
   * @param pageSize the number of rows visible
   */
  public PaginatedList(JList list, int pageSize) {
      super();
      this.pageSize = pageSize;
      this.list = list;
      this.model = list.getModel();

      //work out how many pages there are
      this.lastPageNum = model.getSize() / pageSize +
                        (model.getSize() % pageSize != 0 ? 1 : 0);
      this.currPageNum = lastPageNum > 0 ? 1 : 0;

      setLayout(new BorderLayout());
      countLabel = new JLabel() ;
      add(countLabel, BorderLayout.NORTH);
      add(list, BorderLayout.CENTER);
      add(createControls(), BorderLayout.SOUTH);
      updatePage();
  }

  private JPanel createControls() {
      first = new JButton(new AbstractAction("<<") {
          public void actionPerformed(ActionEvent e) {
              currPageNum = 1;
              updatePage();
          }
      });

      prev = new JButton(new AbstractAction("<") {
          public void actionPerformed(ActionEvent e) {
              if (--currPageNum <= 0)
                  currPageNum = 1;
              updatePage();
          }
      });

      next = new JButton(new AbstractAction(">") {
          public void actionPerformed(ActionEvent e) {
              if (++currPageNum > lastPageNum)
                  currPageNum = lastPageNum;
              updatePage();

          }
      });

      last = new JButton(new AbstractAction(">>") {
          public void actionPerformed(ActionEvent e) {
              currPageNum = lastPageNum;
              updatePage();
          }
      });

      JPanel bar = new JPanel(new GridLayout(1, 4));
      bar.add(first);
      bar.add(prev);
      bar.add(next);
      bar.add(last);
      return bar;
  }

  private void updatePage() {

      //replace the list's model with a new model containing
      //only the entries in the current page.
      if(model.getSize() != 0){
          final DefaultListModel page = new DefaultListModel();
          final int start = (currPageNum - 1) * pageSize;
          int end = start + pageSize;
          if (end >= model.getSize()) {
              end = model.getSize();
          }
          for (int i = start; i < end; i++) {
              page.addElement(model.getElementAt(i));
          }
          list.setModel(page);
      }

      //update the label
      countLabel.setText("Page " + currPageNum + "/" + lastPageNum);

      // update buttons
      final boolean canGoBack = currPageNum > 1;
      final boolean canGoFwd = currPageNum != lastPageNum;
      first.setEnabled(canGoBack);
      prev.setEnabled(canGoBack);
      next.setEnabled(canGoFwd);
      last.setEnabled(canGoFwd);
  }

  public static void main(String args[]) throws Exception {

      // create 100 elements of dummy data.
      String[] data = new String[101];
      for (int i = 0; i < data.length; i++) {
          data[i] = "Item "+ (i + 1);
      }

      // create a paginated list with page size 20
      PaginatedList list = new PaginatedList(new JList(data), 10);

      // add it to a frame
      JFrame f = new JFrame("Paginated List Demo");
      f.add(list);
      f.setSize(100, 100);
      f.pack();
      f.setVisible(true);
  }
}

Saturday, January 01, 2011

fahd.blog in 2010

Happy 2011!
I'd like to wish everyone a great start to an even greater new year!

During 2010, I posted 47 new entries on fahd.blog, which is 23% more than in 2009. In addition to more posts, I am thrilled that I have more readers from all over the world too! Thanks for reading!

Top 5 posts of 2010:

I'm going to be writing a lot more this year, so stay tuned for more great techie tips, tricks and hacks! :)