Saturday, March 05, 2011

Upgrading to SyntaxHighlighter 3.0

I have now upgraded this blog to use SyntaxHighlighter 3.0. This version allows you to add titles to your code blocks and select code without line numbers.

This is how you can upgrade too:

1. Download SyntaxHighlighter v3.0
You can download it here.
If you don't have a place to upload, you can use the free hosted version here.

2. Link to CSS and Javascript
Open your webpage's HTML file and add links to the SyntaxHighlighter's CSS and JavaScript files. For optimal results, place these lines at the very end of your page, just before the closing body tag.

<link href='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83//styles/shThemeEmacs.css' rel='stylesheet' type='text/css'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shLegacy.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJava.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushSql.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPython.js' type='text/javascript'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.js' type='text/javascript'/>   
<script type="text/javascript">
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
</script>
It is not necessary to add the js files for all languages - just for the ones you will be using.

3. Add Code
Now add the code you wish to highlight in your webpage, surrounded by the <pre> tag. Set the class attribute to the language alias e.g. brush:java

<pre title="Test SyntaxHighlighter 3" class="brush: java;">
public void printHello(){
    System.out.println("Hello World");
}
</pre>
4. View Page
View the webpage in your browser and you should see your syntax highlighted code snippet as:
public void printHello(){
    System.out.println("Hello World");
}

Sunday, February 20, 2011

XPaths with xmllint

xmllint is a command-line XML tool used to validate and pretty-print XML documents. More importantly, it offers an interactive shell mode which allows you to use xpaths to print out elements. For example, //body will print out the body element of an HTML document.

I wrote a useful bash function, which uses xmllint to evaluate xpaths really easily:

xpath()
{
    if [ $# -ne 2]; then
        echo "Usage: xpath xpath file"
        return 1
    fi
    xmllint --shell $2 <<< "cat $1" | sed '/^\/ >/d'
}
Example:
sharfah@starship:~> xpath "//body" index.html
<body>Hello World!</body>

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! :)