Saturday, August 31, 2013

Initialization-on-demand holder idiom


See Singleton Pattern here...
 
package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static class HelperHolder {

        public static Helper helper = new Helper();
    }

    public static Helper getHelper() {
        return HelperHolder.helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Here as the helper object is static, an alternative is used - initialization-on-demand holder idiom. This is based on the fact that inner classes are not loaded until they are referenced.

Eager initialization


See Singleton Pattern here...

If the program will always need an instance, or if the cost of creating the instance is not too large in terms of time/resources, the programmer can switch to eager initialization, which always creates an instance.


Singleton.java
 
package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static final Helper helper = new Helper();

    public static Helper getHelper() {
        return helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Output:
Created Helper Object

Advantages:
  • The instance is not constructed until the class is used.
  • There is no need of synchronization, which means all the threads will see the same instance even without expensive locking mechanism.
  • The final keyword means that the instance cannot be redefined, ensuring that one (and only one) instance ever exists.

Double-checked locking and Lazy initialization


Lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. 

This is generally accomplished by maintaining a flag indicating whether the process has taken place. Each time the desired object is summoned, the flag is tested. If it is ready, it is returned. If not, it is initialized on the spot. In multithreaded code, access to the flag must be synchronized to guard against a race condition.

Read more about lazy initialization here...

Let us consider Singleton Pattern again.

Singleton.java


package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static Helper helper = null;

    public static Helper getHelper() {
        if (helper == null) {
            synchronized (Singleton.class) {
                if (helper == null) {
                    helper = new Helper();
                }
            }
        }
        return helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Note: This method uses double-checked locking, which should NOT be used prior to JSE 5.0, as it is vulnerable to subtle bugs. The problem is that an out-of-order write may allow the instance reference to be returned before the Singleton constructor is executed.

The above code does NOT work in the presence of either optimizing compilers or shared memory multiprocessors.

The helper field can have a reference before completely creating an object of Helper class.
Thus, a thread which invokes getHelper() could see a non-null reference to a Helper object, but see the default values for fields of the Helper object, rather than the values set in the constructor. This occurs due to compiler based re-orderings (for optimization) or on a multi-processor system, the memory writes may get re-ordered.


Fixing Double-Checked Locking using Volatile

JDK5 and later extends the semantics for volatile so that the system will not allow a write of a volatile to be reordered with respect to any previous read or write, and a read of a volatile cannot be reordered with respect to any following read or write.

With this change, the Double-Checked Locking idiom can be made to work by declaring the helper field to be volatile. This does not work under JDK4 and earlier.


Singleton.java
package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static volatile Helper helper = null;

    public static Helper getHelper() {
        if (helper == null) {
            synchronized (Singleton.class) {
                if (helper == null) {
                    helper = new Helper();
                }
            }
        }
        return helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Another solution: 
Here the local variable result, which seems unnecessary, ensures that in cases where helper is already initialized, the volatile field is only accessed once, which can improve the method's overall performance by as much as 25 percent.

package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static volatile Helper helper = null;

    public static Helper getHelper() {
        Helper result = helper;
        if (result == null) {
            synchronized (Singleton.class) {
                result = helper;
                if (result == null) {
                    helper = result = new Helper();
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Read more about Double-Checked Locking here...

Singleton Pattern


In software engineering, the singleton pattern is a design pattern that restricts a class from creating more than one object (Instantiation is restricted to one object). 
Such a design is generally used in a software system which operates more efficiently when only one object exists. It is useful when exactly one object is needed to coordinate actions across the system.

Read more about singleton pattern here...

Java implementation


  • Single Threaded version

Helper.java


package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Helper {

    public Helper() {
        System.out.println("Created Helper Object");
    }
} 

Singleton.java

package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private Helper helper = null;

    public Helper getHelper() {
        if (helper == null) {
            helper = new Helper();
        }
        return helper;
    }

    public static void main(String[] args) {
        Singleton instance1 = new Singleton();        
        Helper helper1 = instance1.getHelper();
        Helper helper2 = instance1.getHelper();
        Helper helper3 = instance1.getHelper();
    }
}

Output:
Created Helper Object


  • Multi-threaded version
Singleton.java


package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static Helper helper = null;

    public static Helper getHelper() {
        if (helper == null) {
            helper = new Helper();
        }
        return helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Output:
Created Helper Object
Created Helper Object
Created Helper Object

Note: The output may vary depending on the execution of threads. Sometimes you will get only two lines in the output.

The above is not a desired output. The Helper object should be created only once. 


  • Corrected multi-threaded version
Singleton.java
package me.dhanoop.singleton;

/**
 *
 * @author dhanoopbhaskar
 */
public class Singleton {

    private static Helper helper = null;

    public static synchronized Helper getHelper() {
        if (helper == null) {
            helper = new Helper();
        }
        return helper;
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                Singleton.getHelper();
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }
}

Output:
Created Helper Object

Note: The code above performs synchronization every time getHelper() is called. The double-checked locking idiom tries to avoid synchronization after the helper is allocated.

Software Design Pattern


A software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished or completed design. It is actually a description or template for solution to a problem.

Design patterns are of many types, such as:
  • Algorithm strategy patterns
  • Computational design patterns
  • Execution patterns
  • Implementation strategy patterns
  • Structural design patterns
Read more about design patterns here...

Thursday, August 29, 2013

[SOLVED] Missing verify.dll

Error: The program can't start because verify.dll is missing from your computer. Try reinstalling the program to fix this problem.

This error also occurred when I tried to run a program using Java Virtual Machine Launcher.





The permanent solution to this error is adding the path JDK_HOME\jre\bin (C:\Java\jdk1.7.0\jre\bin; - in my case) to the System Environment Variable- Path

[SOLVED] Could not open jvm.cfg

Error: could not open 'C:\Java\jre7\lib\i386\jvm.cfg'
This error occurred when I tried to run a program using Java Virtual Machine Launcher.




Solution:
As a temporary fix what I did was searching for the file jvm.cfg (which was found somewhere under JDK_HOME) and made the file available in the path mentioned in the error message. 

The following is the content of the file jvm.cfg

 
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

The permanent solution to this error is adding the path JDK_HOME\jre\bin (C:\Java\jdk1.7.0\jre\bin; - in my case) to the System Environment Variable- Path

Java - Avoid multiple occurrence of some character in a String


The following is a Java method/function which avoids multiple occurrence (in a row) of some character in an input String. The parameters to the method (i.e., inputs) to the method/function include: 
(1) input - The parent String under consideration 
(2) character - The character of which multiple occurrence (in a row) should be avoided.
 
public static String avoidMultipleOccurrence(String input, char character) {        
        if (input == null) {  
            return null;  
        }  
        if (input.length() == 0) {  
            return "";  
        }
        StringBuilder output = new StringBuilder();  
        output.append(input.charAt(0));        
        for (int idx = 1; idx < input.length(); idx++) {  
            if (Character.toString(input.charAt(idx)).equals(
                                                       "" + character)) {  
                if(input.charAt(idx) != input.charAt(idx-1)) {  
                    output.append(input.charAt(idx));  
                }  
            } else {  
                output.append(input.charAt(idx));  
            }  
        }  
        return output.toString();  
}

Sample Input: "theeee insaneeeee teeeeechieeeee" 
Character selected: 'e' 
 
public static void main(String[] args) {
        System.out.println(avoidMultipleOccurrence(
                "theeee insaneeeee teeeeechieeeee", 'e'));
}

Output: the insane techie

Thursday, August 22, 2013

GATE 2014 - Syllabus for Computer Science and Information Technology (CS)


ENGINEERING MATHEMATICS

Mathematical Logic: Propositional Logic; First Order Logic.
Probability: Conditional Probability; Mean, Median, Mode and Standard Deviation; Random Variables; Distributions; uniform, normal, exponential, Poisson, Binomial.
Set Theory & Algebra: Sets; Relations; Functions; Groups; Partial Orders; Lattice; Boolean Algebra.
Combinatory: Permutations; Combinations; Counting; Summation; generating functions; recurrence relations; asymptotics.
Graph Theory: Connectivity; spanning trees; Cut vertices & edges; covering; matching; independent sets; Colouring; Planarity; Isomorphism.
Linear Algebra: Algebra of matrices, determinants, systems of linear equations, Eigen values and Eigen vectors.
Numerical Methods: LU decomposition for systems of linear equations; numerical solutions of non-linear algebraic equations by Secant, Bisection and Newton-Raphson Methods; Numerical integration by trapezoidal and Simpson’s rules.
Calculus: Limit, Continuity & differentiability, Mean value Theorems, Theorems of integral calculus, evaluation of definite & improper integrals, Partial derivatives, Total derivatives, maxima & minima.

COMPUTER SCIENCE AND INFORMATION TECHNOLOGY

Digital Logic: Logic functions, Minimization, Design and synthesis of combinational and sequential circuits; Number representation and computer arithmetic (fixed and floating point).
Computer Organization and Architecture: Machine instructions and addressing modes, ALU and data-path, CPU control design, Memory interface, I/O interface (Interrupt and DMA mode), Instruction pipelining, Cache and main memory, Secondary storage.
Programming and Data Structures: Programming in C; Functions, Recursion, Parameter passing, Scope, Binding; Abstract data types, Arrays, Stacks, Queues, Linked Lists, Trees, Binary search trees, Binary heaps.
Algorithms: Analysis, Asymptotic notation, Notions of space and time complexity, Worst and average case analysis; Design: Greedy approach, Dynamic programming, Divide-and-conquer; Tree and graph traversals, Connected components, Spanning trees, Shortest paths; Hashing, Sorting, Searching. Asymptotic analysis (best, worst, average cases) of time and space, upper and lower bounds, Basic concepts of complexity classes – P, NP, NP-hard, NP-complete.
Theory of Computation: Regular languages and finite automata, Context free languages and Push-down automata, Recursively enumerable sets and Turing machines, Undecidability.
Compiler Design: Lexical analysis, Parsing, Syntax directed translation, Runtime environments, Intermediate and target code generation, Basics of code optimization.
Operating System: Processes, Threads, Inter-process communication, Concurrency, Synchronization, Deadlock, CPU scheduling, Memory management and virtual memory, File systems, I/O systems, Protection and security.
Databases: ER-model, Relational model (relational algebra, tuple calculus), Database design (integrity constraints, normal forms), Query languages (SQL), File structures (sequential files, indexing, B and B+ trees), Transactions and concurrency control.
Information Systems and Software Engineering: information gathering, requirement and feasibility analysis, data flow diagrams, process specifications, input/output design, process life cycle, planning and managing the project, design, coding, testing, implementation, maintenance.
Computer Networks: ISO/OSI stack, LAN technologies (Ethernet, Token ring), Flow and error control techniques, Routing algorithms, Congestion control, TCP/UDP and sockets, IP(v4), Application layer protocols (icmp, dns, smtp, pop, ftp, http); Basic concepts of hubs, switches, gateways, and routers. Network security – basic concepts of public key and private key cryptography, digital signature, firewalls.
Web technologies: HTML, XML, basic concepts of client-server computing.

Tuesday, August 20, 2013

Another Milestone


Within the time period from Aug 19, 2013 12:30 AM IST to Aug 19, 2013 11:30 PM IST, the blog had 1K+ hits :) Out of which 900+ were from United States!!!



From today, the 20th of August 2013, onwards the blog will be available under another domain - www.theinsanetechie.in :)

Thursday, August 15, 2013

Independence Day Wishes


വന്ദേ മാതരം!
സുജലാം സുഫലാം, മലയജ ശീതളാം,
സസ്യ ശ്യാമളാം, മാതരം!
ശുഭ്രജ്യോത്സ്ന പുളകിതയാമിണിം,
ഫുല്ലകുസുമിത ദ്രുമതല ശോഭിണിം ,
സുഹാസിനിം, സുമദുര ഭാഷിണിം ,

സുഖദാം, വരദാം ,മാതരം!
സപ്തകോടികാന്ത കള കള നിനാദ കരാളെ
ദ്വിസപ്തകോടി ഭുജൈര്‍ ധൃത-ഖാര കരവലെ

അബല കേണ മാ ഇതാ ബലെ
ബഹുബല ധരിണിം, നമാമി തരിണിം,
രിപുതളവാരിണിം മാതരം !

തുമി വിദ്യ, തുമി ധര്‍മ്മ,
തുമി ഹൃദി , തുമി മര്‍മ്മ ,
ത്വം ഹി പ്രാണ ശാരിരെ!

ബാഹുതെ തുമി മാ ശക്തി ,
ഹൃദയേ തുമി മാ ഭക്തി,
തോമര്യ പ്രതിമ ഗാരി മന്ദിരേ മന്ദിരേ!

ത്വം ഹി ദുര്‍ഗ്ഗ ദശപ്രഹരണ ധരിണി,
കമല, കമലാദളവിഹാരിണി,
വാണി, വിദ്യദായിനി നമാമി ത്വം,

നമാമി കമലം, അമലം, അതുലാം,
സുജലാം, സുഫലാം, മാതരം,
വന്ദേ മാതരം!

ശ്യാമളം, സരളം, സുസ്മിതം, ഭൂഷിതം,
ധരണിം, ഭരണിം, മാതരം!

ജയ്‌ ഹിന്ദ്‌ !



Mother, I bow to thee!
Rich with thy hurrying streams,
bright with orchard gleams,
Cool with thy winds of delight,
Dark fields waving Mother of might,
Mother free.
Glory of moonlight dreams,
Over thy branches and lordly streams,
Clad in thy blossoming trees,
Mother, giver of ease
Laughing low and sweet!
Mother I kiss thy feet,
Speaker sweet and low!
Mother, to thee I bow.

Who hath said thou art weak in thy lands
When the sword flesh out in the seventy million hands
And seventy million voices roar
Thy dreadful name from shore to shore?
With many strengths who art mighty and stored,
To thee I call Mother and Lord!
Though who savest, arise and save!
To her I cry who ever her foeman drove
Back from plain and Sea
And shook herself free.

Thou art wisdom, thou art law,
Thou art heart, our soul, our breath
Though art love divine, the awe
In our hearts that conquers death.
Thine the strength that nerves the arm,
Thine the beauty, thine the charm.
Every image made divine
In our temples is but thine.

Thou art Durga, Lady and Queen,
With her hands that strike and her
swords of sheen,
Thou art Lakshmi lotus-throned,
And the Muse a hundred-toned,
Pure and perfect without peer,
Mother lend thine ear,
Rich with thy hurrying streams,
Bright with thy orchard gleems,
Dark of hue O candid-fair

In thy soul, with jewelled hair
And thy glorious smile divine,
Lovilest of all earthly lands,
Showering wealth from well-stored hands!
Mother, mother mine!
Mother sweet, I bow to thee,
Mother great and free!

Jai Hind!

Wednesday, August 14, 2013

DCrypt - Encryption/Decryption application for Android


Released my "so called first" android application DCrypt today :) 


It is a simple android application for encryption and decryption of files using passphrase. Supported API levels are in the range 10 (min) and 17 (max).

To encrypt a file, what we need is to share the file to "DCrypt" and enter a passphrase. To decrypt the file, we have to share the encrypted file to the application and enter the passphrase. Obviously the passphrase for encryption and decryption should be the same.
Note that the file shredding is disabled by default. That means the original file won't be deleted even if you encrypt it. 
To enable file shredding, go to Settings-> Enable Shredding.

Please use the following e-mail id to report bugs if any: 
dhanoopbhaskar@gmail.com

Suggestions are most welcome :)

P.S: Detailed information about the application will be posted later!

(updation)
See more here...

Sunday, August 11, 2013

Java - Encryption and Decryption of an Image Using Blowfish Algorithm

 
EncryptFile.java
 
package com.java.blowfish;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author dhanoopbhaskar
 */
public class EncryptFile {

    KeyGenerator keyGenerator = null;
    SecretKey secretKey = null;
    Cipher cipher = null;

    public EncryptFile() {
        try {
            /**
             * Create a Blowfish key
             */
            keyGenerator = KeyGenerator.getInstance("Blowfish");
            secretKey = keyGenerator.generateKey();

            /**
             * Create an instance of cipher mentioning the name of algorithm
             *     - Blowfish
             */
            cipher = Cipher.getInstance("Blowfish");
        } catch (NoSuchPaddingException ex) {
            System.out.println(ex);
        } catch (NoSuchAlgorithmException ex) {
            System.out.println(ex);
        }
    }

    public static void main(String[] args) {
        String fileToEncrypt = "fileToEncrypt.jpg";
        String encryptedFile = "encryptedFile.jpg";
        String decryptedFile = "decryptedFile.jpg";
        String directoryPath = "C:/Users/dhanoopbhaskar/Desktop/blowfish/";
        EncryptFile encryptFile = new EncryptFile();
        System.out.println("Starting Encryption...");
        encryptFile.encrypt(directoryPath + fileToEncrypt,
                directoryPath + encryptedFile);
        System.out.println("Encryption completed...");
        System.out.println("Starting Decryption...");
        encryptFile.decrypt(directoryPath + encryptedFile,
                directoryPath + decryptedFile);
        System.out.println("Decryption completed...");
    }

    /**
     * 
     * @param srcPath
     * @param destPath
     *
     * Encrypts the file in srcPath and creates a file in destPath
     */
    private void encrypt(String srcPath, String destPath) {
        File rawFile = new File(srcPath);
        File encryptedFile = new File(destPath);
        InputStream inStream = null;
        OutputStream outStream = null;
        try {
            /**
             * Initialize the cipher for encryption
             */
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            /**
             * Initialize input and output streams
             */
            inStream = new FileInputStream(rawFile);
            outStream = new FileOutputStream(encryptedFile);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inStream.read(buffer)) > 0) {
                outStream.write(cipher.update(buffer, 0, len));
                outStream.flush();
            }
            outStream.write(cipher.doFinal());
            inStream.close();
            outStream.close();
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    /**
     * 
     * @param srcPath
     * @param destPath
     *
     * Decrypts the file in srcPath and creates a file in destPath
     */
    private void decrypt(String srcPath, String destPath) {
        File encryptedFile = new File(srcPath);
        File decryptedFile = new File(destPath);
        InputStream inStream = null;
        OutputStream outStream = null;
        try {
            /**
             * Initialize the cipher for decryption
             */
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            /**
             * Initialize input and output streams
             */
            inStream = new FileInputStream(encryptedFile);
            outStream = new FileOutputStream(decryptedFile);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inStream.read(buffer)) > 0) {
                outStream.write(cipher.update(buffer, 0, len));
                outStream.flush();
            }
            outStream.write(cipher.doFinal());
            inStream.close();
            outStream.close();
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }
}

Output: 
Starting Encryption... 
Encryption completed... 
Starting Decryption... 
Decryption completed...


Before Encryption

After Encryption


The method doFinal() should not be used in loop or repeatedly. If we have to encrypt/decrypt multiple blocks we use update() method.
 
outStream.write(cipher.update(buffer, 0, len));

After everything is done we call doFinal() method.
 
outStream.write(cipher.doFinal());

If we use doFinal repeatedly, the encryption will work without errors. But decryption will fail throwing exception - javax.crypto.BadPaddingException

See related posts:
Java - Encryption and Decryption of an Image Using Blowfish Algorithm (using password)
Java - Encryption and Decryption of an Image Using Another Image (Blowfish Algorithm)

Java - Blowfish Encryption Algorithm

 
BlowfishAlgorithm.java
 
package com.java.blowfish;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author dhanoopbhaskar
 */
public class BlowfishAlgorithm {

    KeyGenerator keyGenerator = null;
    SecretKey secretKey = null;
    Cipher cipher = null;

    public BlowfishAlgorithm() {
        try {
            /**
             * Create a Blowfish key
             */
            keyGenerator = KeyGenerator.getInstance("Blowfish");
            secretKey = keyGenerator.generateKey();

            /**
             * Create an instance of cipher mentioning the name of algorithm
             *     - Blowfish
             */
            cipher = Cipher.getInstance("Blowfish");
        } catch (NoSuchPaddingException ex) {
            System.out.println(ex);
        } catch (NoSuchAlgorithmException ex) {
            System.out.println(ex);
        }

    }

    /**
     *
     * @param plainText
     * @return cipherBytes
     */
    public byte[] encryptText(String plainText) {
        byte[] cipherBytes = null;
        try {
            /**
             * Initialize the cipher for encryption
             */
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            /**
             * Convert the text string to byte format
             */
            byte[] plainBytes = plainText.getBytes();
            /**
             * Perform encryption with method doFinal()
             */
            cipherBytes = cipher.doFinal(plainBytes);
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        }

        return cipherBytes;
    }

    /**
     *
     * @param cipherBytes
     * @return plainText
     */
    public String decryptText(byte[] cipherBytes) {
        String plainText = null;
        try {
            /**
             * Initialize the cipher for decryption
             */
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            /**
             * Perform decryption with method doFinal()
             */
            byte[] plainBytes = cipher.doFinal(cipherBytes);
            /**
             * Convert encrypted text to string format
             */
            plainText = new String(plainBytes);
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        }

        return plainText;
    }

    /**
     *
     * @param plainText
     * @return cipherText
     */
    public String encrypt(String plainText) {
        String cipherText = null;
        byte[] cipherBytes = encryptText(plainText);
        cipherText = bytesToString(cipherBytes);
        return cipherText;
    }

    /**
     * 
     * @param cipherText
     * @return plainText
     */
    public String decrypt(String cipherText) {
        String plainText = null;
        byte[] cipherBytes = stringToBytes(cipherText);
        plainText = decryptText(cipherBytes);
        return plainText;
    }

    public static void main(String[] args) {
        BlowfishAlgorithm blowfishAlgorithm = new BlowfishAlgorithm();
        String textToEncrypt = "Blowfish Algorithm";
        System.out.println("Text before Encryption: " + textToEncrypt);
        String cipherText = blowfishAlgorithm.encrypt(textToEncrypt);
        System.out.println("Cipher Text: " + cipherText);
        System.out.println("Text after Decryption: " + blowfishAlgorithm.decrypt(cipherText));
    }

    /**
     * 
     * @param rawText
     * @return plainText
     *
     * Perform Base64 encoding
     */
    private String bytesToString(byte[] rawText) {
        String plainText = null;
        plainText = Base64.encode(rawText);
        return plainText;
    }

    /**
     * 
     * @param plainText
     * @return rawText
     *
     * Perform Base64 decoding
     */
    private byte[] stringToBytes(String plainText) {
        byte[] rawText = null;
        try {
            rawText = Base64.decode(plainText);
        } catch (Base64DecodingException ex) {
            System.out.println(ex);
        }
        return rawText;
    }
}

Output: 
Text before Encryption: Blowfish Algorithm 
Cipher Text: tsNKEZdUIivNDDN287v9NIl8vCHTPrlT 
Text after Decryption: Blowfish Algorithm

Java - Advanced Encryption Standard (AES) Algorithm

 
AESAlgorithm.java
 
package com.java.aes;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author dhanoopbhaskar
 */
public class AESAlgorithm {

    KeyGenerator keyGenerator = null;
    SecretKey secretKey = null;
    Cipher cipher = null;

    public AESAlgorithm() {
        try {
            /**
             * Create a AES key
             */
            keyGenerator = KeyGenerator.getInstance("AES");
            secretKey = keyGenerator.generateKey();

            /**
             * Create an instance of cipher providing the following info
             * separated by slash.
             *
             *      - Algorithm name
             *      - Mode (optional)
             *      - Padding scheme (optional)
             *
             * NB:
             *      AES = Advanced Encryption Standard.
             *      ECB = Electronic Codebook mode.
             *      PKCS5Padding = PKCS #5-style padding.
             */
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        } catch (NoSuchPaddingException ex) {
            System.out.println(ex);
        } catch (NoSuchAlgorithmException ex) {
            System.out.println(ex);
        }

    }

    /**
     *
     * @param plainText
     * @return cipherBytes
     */
    public byte[] encryptText(String plainText) {
        byte[] cipherBytes = null;
        try {
            /**
             * Initialize the cipher for encryption
             */
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            /**
             * Convert the text string to byte format
             */
            byte[] plainBytes = plainText.getBytes();
            /**
             * Perform encryption with method doFinal()
             */
            cipherBytes = cipher.doFinal(plainBytes);
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        }

        return cipherBytes;
    }

    /**
     *
     * @param cipherBytes
     * @return plainText
     */
    public String decryptText(byte[] cipherBytes) {
        String plainText = null;
        try {
            /**
             * Initialize the cipher for decryption
             */
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            /**
             * Perform decryption with method doFinal()
             */
            byte[] plainBytes = cipher.doFinal(cipherBytes);
            /**
             * Convert encrypted text to string format
             */
            plainText = new String(plainBytes);
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        }

        return plainText;
    }

    /**
     *
     * @param plainText
     * @return cipherText
     */
    public String encrypt(String plainText) {
        String cipherText = null;
        byte[] cipherBytes = encryptText(plainText);
        cipherText = bytesToString(cipherBytes);
        return cipherText;
    }

    /**
     * 
     * @param cipherText
     * @return plainText
     */
    public String decrypt(String cipherText) {
        String plainText = null;
        byte[] cipherBytes = stringToBytes(cipherText);
        plainText = decryptText(cipherBytes);
        return plainText;
    }

    public static void main(String[] args) {
        AESAlgorithm desAlgorithm = new AESAlgorithm();
        String textToEncrypt = "AES Algorithm";
        System.out.println("Text before Encryption: " + textToEncrypt);
        String cipherText = desAlgorithm.encrypt(textToEncrypt);
        System.out.println("Cipher Text: " + cipherText);
        System.out.println("Text after Decryption: " + desAlgorithm.decrypt(cipherText));
    }

    /**
     * 
     * @param rawText
     * @return plainText
     *
     * Perform Base64 encoding
     */
    private String bytesToString(byte[] rawText) {
        String plainText = null;
        plainText = Base64.encode(rawText);
        return plainText;
    }

    /**
     * 
     * @param plainText
     * @return rawText
     *
     * Perform Base64 decoding
     */
    private byte[] stringToBytes(String plainText) {
        byte[] rawText = null;
        try {
            rawText = Base64.decode(plainText);
        } catch (Base64DecodingException ex) {
            System.out.println(ex);
        }
        return rawText;
    }
}

Output: 
Text before Encryption: AES Algorithm 
Cipher Text: rqDMYCW17enP8S7sio3Kbg== 
Text after Decryption: AES Algorithm

Saturday, August 3, 2013

Java - JButton in a JTable cell

Now we shall discuss how to include a JButton in a table cell.

ButtonJTable.java
 
/*
 * ButtonJTable.java
 *
 * Created on Aug 3, 2013, 02:57:58 PM
 */
package me.dhanoop.forblog;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

/**
 *
 * @author dhanoopbhaskar
 */
public class ButtonJTable extends javax.swing.JFrame {

    private JButton tableData = null;

    /** Creates new form ButtonJTable */
    public ButtonJTable() {
        initComponents();
        customizeTable();
    }

    /** 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")
    // 
    private void initComponents() {

        dbScrollPane = new javax.swing.JScrollPane();
        dbTable = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        dbTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Title 1"
            }
        ));
        dbScrollPane.setViewportView(dbTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// 

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ButtonJTable().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private javax.swing.JScrollPane dbScrollPane;
    private javax.swing.JTable dbTable;
    // End of variables declaration

    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "Button";
        String buttonString = "Click Me";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = buttonString;
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);
        tableData = new JButton(buttonString);
        tableData.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(new JFrame(), "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        dbTable.getColumnModel().getColumn(0).setCellEditor(new ButtonCellEditor(new JCheckBox()));
        dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {

            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                if (isSelected) {
                    setForeground(table.getSelectionForeground());
                    setBackground(table.getSelectionBackground());
                } else {
                    setForeground(table.getForeground());
                    setBackground(UIManager.getColor("Button.background"));
                }
                tableData.setText((value == null) ? "" : value.toString());
                return tableData;
            }
        });

        dbTable.updateUI();
    }
}

DBTableModel.java
 
package me.dhanoop.forblog;

import javax.swing.table.DefaultTableModel;

/**
 *
 * @author dhanoopbhaskar
 */
public class DBTableModel extends DefaultTableModel {

    public DBTableModel(Object[] columns) {
        super(columns, 0);
    }

    public DBTableModel(Object[][] data, Object[] columns) {
        super(data, columns);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return true;
    }
}

The following is the key snippet in the program. 
Here we do mainly two things: 
(1) Changing the CellEditor of the ColumnModel of the column at position 0 (zero) of the table
(2) Changing the CellRenderer of the ColumnModel of the column at position 0 (zero) of the table. 
Unlike JComboBox and JCheckBox, for JButton we don't have a suitable constructor. 

public javax.swing.DefaultCellEditor(javax.swing.JTextField); 
public javax.swing.DefaultCellEditor(javax.swing.JCheckBox); 
public javax.swing.DefaultCellEditor(javax.swing.JComboBox); 

The above are the ONLY available constructors for DefaultCellEditor. Hence we have to create fully customized DefaultCellEditor for JButton.
 
    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "Button";
        String buttonString = "Click Me";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = buttonString;
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);
        tableData = new JButton(buttonString);
        tableData.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(new JFrame(), "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        dbTable.getColumnModel().getColumn(0).setCellEditor(new ButtonCellEditor(new JCheckBox()));
        dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {

            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                if (isSelected) {
                    setForeground(table.getSelectionForeground());
                    setBackground(table.getSelectionBackground());
                } else {
                    setForeground(table.getForeground());
                    setBackground(UIManager.getColor("Button.background"));
                }
                tableData.setText((value == null) ? "" : value.toString());
                return tableData;
            }
        });

        dbTable.updateUI();
    }

Please find below an example of such a customized DefaultCellEditor

ButtonCellEditor.java
 
package me.dhanoop.forblog;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTable;

/**
 *
 * @author dhanoopbhaskar
 */
public class ButtonCellEditor extends DefaultCellEditor {

    private JButton button = null;
    private String buttonText = null;
    private boolean isClicked;

    public ButtonCellEditor(JCheckBox checkBox) {
        super(checkBox);
        button = new JButton();
        button.setOpaque(true);
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                fireEditingStopped();
            }
        });
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        if (isSelected) {
            button.setForeground(table.getSelectionForeground());
            button.setBackground(table.getSelectionBackground());
        } else {
            button.setForeground(table.getForeground());
            button.setBackground(table.getBackground());
        }
        buttonText = (value == null) ? "" : value.toString();
        button.setText(buttonText);
        isClicked = true;
        return button;
    }

    @Override
    public Object getCellEditorValue() {
        if (isClicked) {
            JOptionPane.showMessageDialog(button, "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
        }
        isClicked = false;
        return buttonText;
    }

    @Override
    public boolean stopCellEditing() {
        isClicked = false;
        return super.stopCellEditing();
    }

    @Override
    protected void fireEditingStopped() {
        super.fireEditingStopped();
    }
}




Java - JCheckBox in a JTable cell

 
Now we shall discuss how to include a JCheckBox in a table cell.

CheckBoxJFrame.java
 
/**
 * CheckBoxJFrame.java
 *
 * Created on Aug 2, 2013, 11:57:36 PM
 */

package me.dhanoop.forblog;

import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

/**
 *
 * @author dhanoopbhaskar
 */
public class CheckBoxJFrame extends javax.swing.JFrame {

    private JCheckBox tableData = null;
    /** Creates new form CheckBoxJFrame */
    public CheckBoxJFrame() {
        initComponents();
        customizeTable();
    }

    /** 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")
    // 
    private void initComponents() {

        dbScrollPane = new javax.swing.JScrollPane();
        dbTable = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        dbTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Title 1"
            }
        ));
        dbScrollPane.setViewportView(dbTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// 

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new CheckBoxJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JScrollPane dbScrollPane;
    private javax.swing.JTable dbTable;
    // End of variables declaration

    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "CheckBox";
        String checkString = "Gate Qualified?";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = checkString;
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);        
        tableData = new JCheckBox(checkString);
        tableData.setSelected(false);
        tableData.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                String result = "";
                if (tableData.isSelected()) {
                    result = "YES";
                } else {
                    result = "NO";
                }
                JOptionPane.showMessageDialog(new JFrame(), result, "Gate Qualified?", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        
        dbTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(tableData));
        dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {

            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                return tableData;
            }
        });
        
        dbTable.updateUI();
    }

}


DBTableModel.java
 
package me.dhanoop.forblog;

import javax.swing.table.DefaultTableModel;

/**
 *
 * @author dhanoopbhaskar
 */
public class DBTableModel extends DefaultTableModel {

    public DBTableModel(Object[] columns) {
        super(columns, 0);
    }

    public DBTableModel(Object[][] data, Object[] columns) {
        super(data, columns);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return true;
    }
}

The following is the key snippet in the program. Here we do mainly two things: 
(1) Changing the CellEditor of the ColumnModel of the column at position 0 (zero) of the table
(2) Changing the CellRenderer of the ColumnModel of the column at position 0 (zero) of the table.
 
    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "CheckBox";
        String checkString = "Gate Qualified?";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = checkString;
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);        
        tableData = new JCheckBox(checkString);
        tableData.setSelected(false);
        tableData.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                String result = "";
                if (tableData.isSelected()) {
                    result = "YES";
                } else {
                    result = "NO";
                }
                JOptionPane.showMessageDialog(new JFrame(), result, "Gate Qualified?", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        
        dbTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(tableData));
        dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {

            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                return tableData;
            }
        });
        
        dbTable.updateUI();
    }






Java - JComboBox in a JTable cell (with event handling)

 
Please refer to the previous post here...
The function customizeTable() has been modified in order to include event handling functionality in the combo box. 
 
    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "ComboBox";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = "select gender";
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);
        String[] gender = {"Male", "Female"};
        tableData = new JComboBox(gender);
        tableData.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String item = (String) tableData.getSelectedItem();
                JOptionPane.showMessageDialog(new JFrame(), item, "Selected Item", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        dbTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(tableData));
        dbTable.updateUI();
    }

For the JComboBox tableData to be accessible in the inner class' method actionPerformed() it should be declared in class level as below. (In the previous post, it's declared locally).
 
public class MainJFrame extends javax.swing.JFrame {
    private JComboBox tableData = null;
.
.
.






Java - JComboBox in a JTable cell

 
MainJFrame.java
 
/**
 * MainJFrame.java
 *
 * Created on Aug 2, 2013, 11:57:36 PM
 */

package me.dhanoop.forblog;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;

/**
 *
 * @author dhanoopbhaskar
 */
public class MainJFrame extends javax.swing.JFrame {

    /** Creates new form MainJFrame */
    public MainJFrame() {
        initComponents();
        customizeTable();
    }

    /** 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")
    // 
    private void initComponents() {

        dbScrollPane = new javax.swing.JScrollPane();
        dbTable = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        dbTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Title 1"
            }
        ));
        dbScrollPane.setViewportView(dbTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// 

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JScrollPane dbScrollPane;
    private javax.swing.JTable dbTable;
    // End of variables declaration

    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "ComboBox";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = "select gender";
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);
        String[] gender = {"Male", "Female"};
        JComboBox tableData = new JComboBox(gender);
        dbTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(tableData));
        dbTable.updateUI();
    }

}

DBTableModel.java
 
package me.dhanoop.forblog;

import javax.swing.table.DefaultTableModel;

/**
 *
 * @author dhanoopbhaskar
 */
public class DBTableModel extends DefaultTableModel {

    public DBTableModel(Object[] columns) {
        super(columns, 0);
    }

    public DBTableModel(Object[][] data, Object[] columns) {
        super(data, columns);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return true;
    }
}

The following is the key snippet in the program. What we do here is simply changing the CellEditor of the ColumnModel of the column at position 0 (zero) of the table.
 
    private void customizeTable() {
        Object[] columnNames = new Object[1];
        columnNames[0] = "ComboBox";
        Object[][] rowData = new Object[1][1];
        rowData[0][0] = "select gender";
        DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
        dbTable.setModel(tableModel);
        String[] gender = {"Male", "Female"};
        JComboBox tableData = new JComboBox(gender);
        dbTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(tableData));
        dbTable.updateUI();
    }

Here we use the following constructor of the class DefaultCellEditor.
 
public javax.swing.DefaultCellEditor(javax.swing.JComboBox);



In the next post we shall discuss on handling of various events in such combo boxes which are added to the table.

Sunday, July 21, 2013

Talend - Out of Memory Error and Java Heap Space Error

 
The Out of Memory Error and Java Heap Space Error are two of the usual errors which occur in the Talend jobs handling a large volume of data. These errors can be avoided to an extent by following some design guidelines.

(1) Keep in mind that tMap is a heavy component. Minimize its use in your jobs.

  • Avoid tMap if you need just simple transformations like trimming the string values, replacing null numbers by zeroes, etc. In its place you can use tJavaRow component.





  • If you want to get only a small set of columns from a huge collection avoid using a tMap. For that you can use a lighter component- tFilterColumns



  • Similarly, to filter rows you can use tFilterRow instead of a tMap
(2) Use store on disk option whenever necessary.
This option is available in tMap, tUniqRow, tSortRow, etc.
  • tMap
While using store on disk option in tMap the directory to store temporary data will be created automatically. This data will not be deleted or replaced on subsequent run(s) of the job. So it is advised to delete the temporary directory created using tFileDelete component from within the job. You can give that in On Subjob Ok of tPostJob component.


  • tUniqRow
In the case of tUniqRow the temporary directory should be created manually before the job run/or can be handled within the job. If the temporary directory is not available, the component tUniqRow will give out FileNotFoundException!

  • tSortRow
In the case of tSortRow the temporary directory will be created automatically (see the image below- a check box can be seen)


(3) The JVM arguments can be modified as and when needed.
-Xms256M - initial memory size available to JVM is 256 MB
-Xmx1024M - maximum memory size available to JVM is 1024 MB

Sunday, June 16, 2013

Google's Project Loon: Balloon-powered Internet access


The Google is introducing its new project named Project Loon to overcome the terrestrial challenges to Internet connectivity such as jungles, archipelagos, mountains, etc.

It is nothing but balloon-powered Internet access. A ring of balloons, flying around the globe on the stratospheric winds, provides Internet access to the earth below. These balloons are carried by the wind at altitudes twice as high as commercial planes and they beam Internet access to the ground at speeds similar to today’s 3G networks or faster. The team hopes that the balloons could become an option for connecting rural, remote, and under-served areas, and for helping with communications after natural disasters.

The major challenges include-
(1) Trying to keep the balloons in one place requires a system with major cost and complexity.
The idea they pursued was based on freeing the balloons and letting them sail freely on the winds. To control their path through the sky they use just wind and solar power- moving the balloons up or down to catch the winds they want them to travel in.

(2) How to manage a fleet of balloons sailing around the world so that each balloon is in the area we want it right when we need it.
This is solved with some complex algorithms and lots of computing power.



They say-
"We imagine someday you'll be able to use your cell phone with your existing service provider to connect to the balloons and get connectivity where there is none today. This is still highly experimental technology and we have a long way to go — we’d love your support as we keep trying and keep flying!"
Courtesy: Google Blog

Talend Equivalent for Index Function in Datastage

 
package routines;

public class UserString {

	public static int Index(String string, String substring, Integer instance) {
	    	int index = -1;
	    	if (string == null) {
	    		return 0;
	    	}
	    	if (substring == null) {
	    		return 0;
	    	}
	    	if (substring.equals("")) {
	    		return 1;
	    	}
	    	if (instance == null) {
	    		throw new UnsupportedOperationException("Instance is supposed to be NOT NULL!!");
	    	}
	    	if (!string.contains(substring)) {
	    		return 0;
	    	}
	    	
	    	index = string.indexOf(substring, 0);
	    	
	    	while (--instance > 0 && index != -1) {
	    		index = string.indexOf(substring, index + 1);
	    	}
	    	    	
	    	return ++index;
	}
}

Talend Equivalent for TRIM Function in Datastage

 
package routines;

public class UserString {

    /**
     * 
     * L Removes leading occurrences of character.
     * T Removes trailing occurrences of character.
     * B Removes leading and trailing occurrences of character.
     * R Removes leading and trailing occurrences of character, and reduces multiple occurrences to a single occurrence.
     * A Removes all occurrences of character.
     * F Removes leading spaces and tabs
     * E Removes trailing spaces and tabs
     * D Removes leading and trailing spaces and tabs, and reduces multiple spaces and tabs to single ones.
     */
    public static String TRIM(String str, String character, String option) {
    	String returnStr = "";
    	if (str == null) {
    		return null;
    	}
    	if (option.equals("L")) {
    		returnStr = str.replaceFirst("^" + character + "+", "");
    	} else if (option.equals("T")) {
    		returnStr = str.replaceAll("[" + character + "]+$", "");
    	} else if (option.equals("B")) {
    		returnStr = str.replaceFirst("^" + character + "+", "");
    		returnStr = returnStr.replaceAll("[" + character + "]+$", "");
    	} else if (option.equals("R")) {
    		returnStr = str.replaceFirst("^" + character + "+", "");
    		returnStr = returnStr.replaceAll("[" + character + "]+$", "");
    		returnStr = avoidMultipleOccurrence(returnStr, character);
    	} else if (option.equals("A")) {
    		returnStr = str.replaceAll(character, "");	
    	} else if (option.equals("F")) {
    		returnStr = TRIM(str, " ", "L");
    		returnStr = TRIM(returnStr, "\t", "L");
    	} else if (option.equals("E")) {
    		returnStr = TRIM(str, " ", "T");
    		returnStr = TRIM(returnStr, "\t", "T");
    	} else if (option.equals("D")) {
    		returnStr = TRIM(str, "", "F");
    		returnStr = TRIM(returnStr, "", "E");
    		returnStr = avoidMultipleOccurrence(returnStr, " ");
    		returnStr = avoidMultipleOccurrence(returnStr, "\t");
    	} 
    	return returnStr;
    }
    
    public static String TRIM(String str) {
    	return (str == null) ? null : TRIM(str, " ", "R");
    }
    
    public static String avoidMultipleOccurrence(String input, String character) {    	
    	if (input == null) {
    		return null;
    	}
    	if (input.length() == 0) {
    		return input;
    	}
    	StringBuilder output = new StringBuilder();
    	output.append(input.charAt(0));    	 
    	for (int idx = 1; idx < input.length(); idx++) {
    		if (Character.toString(input.charAt(idx)).equals(character)) {
	    	    if(input.charAt(idx) != input.charAt(idx-1)) {
	    	        output.append(input.charAt(idx));
	    	    }
    	    } else {
    	    	output.append(input.charAt(idx));
    	    }
    	}
    	return output.toString();
    }
}

Contact Form

Name

Email *

Message *