8×8 cubicles,
fagged faces,
hokey smiles,
killed my nerves..
at sixteenth hour..
I became a wind..
now.. awaiting to break away..
from this man-made labyrinth..
Search the blog
Living History
8×8 cubicles,
fagged faces,
hokey smiles,
killed my nerves..
at sixteenth hour..
I became a wind..
now.. awaiting to break away..
from this man-made labyrinth..
When we build a Java Swing application, the GUI design could end up being a very time consuming process. The perfectly aligned components of a data entry form may look awful on a screen with a different resolution. Aligning buttons with proper spacing could become a never ending struggle.
However many IDEs like Netbeans have nice WYSIWYG GUI builders to help developers to easily build Swing based screens. But everything comes with a price
. If we use those GUI builders we could end up having IDE generated code with comments like:
/**
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
The WARNING sign reminds the consequences that we will have to face by using an IDE to build the Swing screens. These consequences may include but not limited to the points specified below.
Here is a screen shot of the form once we add all the components.
package com.jayanath.swingtest;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import com.jeta.forms.components.panel.FormPanel;
import com.jgoodies.forms.factories.ButtonBarFactory;
/**
* <p>Class to show how to use the Swing GUI components designed using
* Abeille form designer. This will also demonstrate of how to use
* JGoodies button factories to generate uniform button panels.</p>
*
* @author jayanath.amaranayake
*/
public class UserInfo {
//these constants were generated by selecting "Form-->Export Names" on the Abeille form designer.
//after hit the OK button on the dialog, it copies these constants on to the clipboard.
//then we can simply paste them here.
public static final String ID_BUTTONBAR = "buttonBar"; //com.jeta.forms.components.label.JETALabel
public static final String ID_FIRSTNAME = "firstName"; //javax.swing.JTextField
public static final String ID_LASTNAME = "lastName"; //javax.swing.JTextField
public static final String ID_STREET1 = "street1"; //javax.swing.JTextField
public static final String ID_STREET2 = "street2"; //javax.swing.JTextField
public static final String ID_CITY = "city"; //javax.swing.JTextField
public static final String ID_COUNTRYCOMBO = "countryCombo"; //com.jeta.forms.components.label.JETALabel
public static final String ID_MALERADIOBTN = "maleRadioBtn"; //javax.swing.JRadioButton
public static final String ID_FEMALERADIOBTN = "femaleRadioBtn"; //javax.swing.JRadioButton
public static final String ID_ZIP = "zip"; //javax.swing.JTextField
/**
* Populate a panel using the Abeille form designer
* @return a JPanel instance
*/
public JPanel populateMainPanel(){
//the FormPanel derived from JPanel
FormPanel mainPanel = new FormPanel("userInfo.xml");
//let's create a combo box with values and add it to the panel
String [] countries = new String []{"Sri Lanka", "USA", "China"};
JComboBox countryCombo = new JComboBox(countries);
//now we can simply swap the label that we put in the place where
//we need to set the actual combo box. Likewise we can swap any component
//on the panel.
mainPanel.getFormAccessor().replaceBean(ID_COUNTRYCOMBO, countryCombo);
//let's set some default values to other components
//this shows you how to access any of the component
//the API supports many default component types
JTextField street1 = mainPanel.getTextField(ID_STREET1);
street1.setText("Patroon Drive");
JRadioButton mRadioBtn = mainPanel.getRadioButton(ID_MALERADIOBTN);
mRadioBtn.setSelected(true);
//we will use the ButtonBarFactory to generate our buttons panel
//this JGoodies API provides many useful methods.
//first, let's create our buttons
JButton okBtn = new JButton("OK");
JButton canBtn = new JButton("Cancel");
JButton regBtn = new JButton("Register me later");
//now generate the button bar panel
JPanel btnPanel = ButtonBarFactory.buildCenteredBar(okBtn, canBtn, regBtn);
//next, we can replace the buttonBar label with this new button bar panel
mainPanel.getFormAccessor().replaceBean(ID_BUTTONBAR, btnPanel);
//finally, let's add a nice boarder to our panel
Border etchBorder = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
Border titleBorder = BorderFactory.createTitledBorder(etchBorder, "User Information Form");
mainPanel.setBorder(titleBorder);
return mainPanel;
}
/**
* @param args
*/
public static void main(String[] args) {
UserInfo uInfo = new UserInfo();
JFrame frame = new JFrame("Panel created using Abeille form designer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(uInfo.populateMainPanel());
frame.pack();
frame.setVisible(true);
}
}
Here is the what we see when we run the application.(figure 4)
[Figure 4]
Note the buttons are evenly spaced and properly sized.
package com.jayanath.swingtest;
import java.awt.Dimension;
import javax.swing.JFrame;
/**
* User Info panel GUI generated using the GUI builder
* @author jayanath.amaranayake
*/
public class UserInfoPanel extends javax.swing.JPanel {
/** Creates new form UserInfoPanel */
public UserInfoPanel() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jTextField1 = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
jTextField2 = new javax.swing.JTextField();
jLabel3 = new javax.swing.JLabel();
jRadioButton1 = new javax.swing.JRadioButton();
jRadioButton2 = new javax.swing.JRadioButton();
jLabel5 = new javax.swing.JLabel();
jLabel6 = new javax.swing.JLabel();
jLabel7 = new javax.swing.JLabel();
jLabel8 = new javax.swing.JLabel();
jLabel9 = new javax.swing.JLabel();
jLabel10 = new javax.swing.JLabel();
jToggleButton1 = new javax.swing.JToggleButton();
jToggleButton2 = new javax.swing.JToggleButton();
jToggleButton3 = new javax.swing.JToggleButton();
jComboBox1 = new javax.swing.JComboBox();
jTextField3 = new javax.swing.JTextField();
jTextField4 = new javax.swing.JTextField();
jTextField5 = new javax.swing.JTextField();
jTextField6 = new javax.swing.JTextField();
setBorder(javax.swing.BorderFactory.createTitledBorder("User Information Form"));
jLabel1.setText("First Name");
jTextField1.setText("First Name");
jTextField1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jTextField1ActionPerformed(evt);
}
});
jLabel2.setText("Last Name");
jTextField2.setText("Last Name");
jLabel3.setText("Gender");
jRadioButton1.setText("Male");
jRadioButton2.setText("Female");
jLabel6.setText("Street 1");
jLabel7.setText("Street 2");
jLabel8.setText("City");
jLabel9.setText("Zip Code");
jLabel10.setText("Country");
jToggleButton1.setText("OK");
jToggleButton2.setText("Cancel");
jToggleButton3.setText("Register me later");
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
jTextField3.setText("Street 1");
jTextField4.setText("Street 2");
jTextField5.setText("City");
jTextField6.setText("Zip Code");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(145, 145, 145)
.addComponent(jToggleButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jToggleButton2)
.addGap(18, 18, 18)
.addComponent(jToggleButton3))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addComponent(jLabel2)
.addComponent(jLabel3))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(jRadioButton1)
.addGap(18, 18, 18)
.addComponent(jRadioButton2))
.addComponent(jTextField2, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
.addComponent(jTextField1))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 48, Short.MAX_VALUE)
.addComponent(jLabel5)
.addGap(28, 28, 28))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel6)
.addComponent(jLabel8)
.addComponent(jLabel10)
.addComponent(jLabel7))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jComboBox1, 0, 222, Short.MAX_VALUE)
.addComponent(jTextField3, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE)
.addComponent(jTextField5, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE)
.addComponent(jTextField4, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE))
.addGap(12, 12, 12)
.addComponent(jLabel9)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jTextField6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(81, 81, 81))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(25, 25, 25)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(120, 120, 120)
.addComponent(jLabel5))
.addGroup(layout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addGroup(layout.createSequentialGroup()
.addGap(38, 38, 38)
.addComponent(jLabel2)
.addGap(27, 27, 27)
.addComponent(jLabel3))
.addGroup(layout.createSequentialGroup()
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(24, 24, 24)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jRadioButton1)
.addComponent(jRadioButton2))))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel6)
.addGroup(layout.createSequentialGroup()
.addGap(38, 38, 38)
.addComponent(jLabel7))
.addGroup(layout.createSequentialGroup()
.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jTextField4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel8)
.addComponent(jTextField6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jTextField5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel9))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel10)
.addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jToggleButton1)
.addComponent(jToggleButton2)
.addComponent(jToggleButton3))))
.addContainerGap())
);
}// </editor-fold>
private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
// Variables declaration - do not modify
private javax.swing.JComboBox jComboBox1;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JRadioButton jRadioButton1;
private javax.swing.JRadioButton jRadioButton2;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
private javax.swing.JTextField jTextField5;
private javax.swing.JTextField jTextField6;
private javax.swing.JToggleButton jToggleButton1;
private javax.swing.JToggleButton jToggleButton2;
private javax.swing.JToggleButton jToggleButton3;
// End of variables declaration
/**
* This is the only method I wrote, everything else is generated by the
* IDE
* @param arg
*/
public static void main(String arg[]) {
UserInfoPanel panel = new UserInfoPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
The IDEs are very capable of generating Swing based screens and they are great in prototyping and building small Swing applications. Unlike the IDEs the Abeille Form Designer externalizes the GUI design code in to an XML file hence allow to maintain cleaner and more maintainable code.
There are other powerful Swing GUI building tools available but they are not FREE. If possible I would use something like JFormDesigner but the license fee is 160 USD per user. Hence I would rather use Abeille Form Designer when possible.
The Forms Designer has two components: the designer and the forms runtime (formsrt.jar). The designer is licensed with the LGPL. The runtime has a BSD license. You may use and distribute forms created by the Forms Designer in commercial applications. Forms Designer License: http://www.gnu.org/copyleft/lesser.html Forms Runtime License: http://www.opensource.org/licenses/bsd-license.php
Year 2009 ended as an eventful year. We had few road trips and got a chance to travel through many states.
Trip One: Willimantic,Connecticut -> Baltimore, Maryland -> Washington DC -> Fall Creek Fall, Tenessee -> Drive over Great Smokey Mountains -> Polar bears & Pandas, Mempis, -> Village Creek Camping, Arkansas -> Norman, Oklahoma and Cowboys
Trip Two: Norman,Oklahoma -> Rio Grande rail road, Colorado -> Santafe, New Mexico -> Sandia Peak Tramway, New Mexico
Trip Three: Norman Oklahoma ->St.Louis, Missouri ->Columbus,Ohio -> Albany, New York.
While we were on the road,
Also I got a chance to buy a nice little internet radio, Logitech Squeezebox Radio. It is small yet powerful, feature rich.. well worth for every $ I paid.
“Google Gmail, Google Chrome browser, Google Calendar… very soon a Google OS.. how easy it is to find everything in one place from one company…. but..”
I started to use Gmail somewhere in mid 2005 and it became my primary email by simply replacing Yahoo mail. Hotmail, AOL and Yahoo are just the history for me as well as for many millions out there. In late 2008 Google Chrome came in to the picture with its unique and sleek interface. Even though I was widely using Firefox I started to use Chrome as an alternative browser. After few months, Now I’m typing this post using Chrome as my default browser. I’m not using most of the Firefox plugins and addons so I felt like I found yet another browser with slightly better performance from Google.
About few days back Google announced that they will be taking their next step by introducing a new operating system, Google Chrome OS. Yes there were enough and more rumours about a Google OS well before they introduced the Androide. I think it will be great (well.. not for Microsoft and Apple ) as it’s going to be a free and open source product based on Linux kernel.
While eagerly waiting to try out this new OS, I started to realize that one day Im going to be a total dependent of this gigantic company, “Google” in the cyber space. I know that I’m not alone and there are many millions who followed the same path, unintentionally. A few questions would reveal this dependence.
This means, Google has all my information and if needed it could disable my account, use all my information and simply leave me nothing if I don’t have any backups locally.
The bottom line is we are unintentionally funnelling our information in to one single (may be two, if we consider the Facebook owned by Microsoft ) company and it is yet another giant with its best interests on profits at the end.
When I bought my Lenovo R61 it came with a pre installed Vista Basic edition. I replaced Vista with various linux flavours like openSUSE, Fedora, Debian ,CentOS etc. Finally I found Arch Linux and I think its the best distro for me. I had Arch as my main OS and had windowsXP on a Virtual Machine till end of Feb, 09. However I had to install windowsXP by removing Arch due to some software packages that demanded nothing but Windows. This time I kept some free space to set up a dual boot. About a week back I managed to do a fresh Arch Linux installation.
For a change, I picked up KDE 4.2 instead of the usual GNOME . I used it for few days and I felt like I’m missing something, the clean and simple GNOME
. The all new KDE 4.2 is appealing but I think its not for me. I tried KDE even with some other distros like Kubuntu, OpenSUSE but always wanted to go back to GNOME.
I enjoyed setting up the new Arch and felt very happy about the improvements that it gained during the past few months.
Few things that are noteworthy.
At the same time I had a look in to OS x86 project. I would love to try that on a separate machine if I get a chance.

Text To Speech (TTS) is a default feature in myriad of electronic devices including portable GPS systems. TTS on the computer is very useful in reviewing documents. Reading through the same document over and over may not help much in identifying errors and missing punctuations, specially if you are the writer. TTS comes in handy at this point.
Hope the following would help someone to try out and enjoy TTS on WinXP.
Check the availability of Text To Speech feature:
Open Start–>Control Panel–>Speech.
Go to the Text To Speech Tab.
Verify the availability of voice engines from the drop down list.
Grab a good Natural Voice Engine:
The microsoft default voice engins are nearly useless in real world. You will realize this, soon after hearing the sample voice
I found some good free voice engines from Cepstral. You can try them for free.
Their free version does not expire. However it promotes you to purchase the licensed version in every minute or so. Of course it is annoying enough to either purchase it or to get rid of it
The right tool to remove the message (The License key
) is available for $29.99 on there web site, if it is affordable for you.
After downloading and installing the Cepstral voice you can set it as the default voice by using the same Start–>Control Panel–>Speech window.
The Cepstral comes with a SwiftTalker, a text editor with integrated TTS feature. It is very usefull to quick edits and reviews.
Check the Cepstral menu on Start–>Programs–>Cepstral for SwiftTalker.
Use the TTS on Adobe Reader:
Go to Documents–>Accessibility Setup Assistant and follow the instructions to setup the TTS options.
Go to Edit–>Preferences.
Select Reading from the Categories list
On the Read Out Loud Options section, remove the check mark of Use default voice and select the new voice engine that we installed from the voice drop down list.
Go to View>Read Out Loud, enable the TTS function. This will also enable the other related sub menus to start, pause and stop.
Now you can listen to your PDF document.
Further reading : Planet PDF

“The President of General Motors announced Monday his plans to discontinue production of its celebrated Pontiac brand and cut 21,000 factory jobs by next year as part of a massive restructuring effort to get more government aid.” - Los Angeles Times
Pontiac G6 is a great car to drive ( well .. not to own by my self .. as it will quickly eat up my money for GAS
).
I got a chance to drive this beast on I-70 from Kansas city airport to Manhattan,KS and easily hit 130 mph without even feeling the speed. It was an awesome driving experience !!.
With ![]()
As a visual person, I always rely on drawing diagrams when ever I try to learn something. Mind Maps (back then I didn’t know this term
) were very helpful during my undergrads and I used them a lot for tutoring as well. Few months back I found XMind, a wonderful tool for mind mapping. The free version is more than enough for studies with plenty of features. However there was a one limitation with the free version. It does not allow to save the mind maps in PDF format. This feature is only available in XMinde Pro version.
Fortunately I found PDFCreator, yet another free and open source tool. Once installed it acts as a pseudo printer. You can set it as your default printer and when ever you send anything to print, it will generate a nice PDF file for you.
With this approach I managed to get the maximum usage from my favourite mind mapping tool.
Recently I was configuring a new application on Windows XP and found that the configuration files could not handle the folder paths with spaces. I couldn’t get away with escape characters. However I found a solution in Windows itself after a small search.
There is an option for the famous dir command to display the short names generated by the system for non -8dot3 file names.
C:\> dir /x

Life…
The uncertainty..
That’s its beauty..
The turns and twists.. rises and falls
Least you expect.. The harder it hits..
Never you could know…
The next turn of its flow..
Faster you run..
More you would miss.. the true sense of life..
Slow down a bit..
Release the tense and grip..
A moment of silence..
A moment of peace..
Unleashes the wisdom..
You never meant to reach..