# Introduction to Programming in Java



## JGuru (Sep 25, 2014)

*Introduction to Programming in Java*

Before you write your first Project in Java, you should know what is programming and how to become a better programmer.
You should start with the basics first. Java like C/C++, C# is a programming language used to write software to access
databases, e-commerce (Web), accounting, Image processing, etc.,

You should become familiar with the core concept of programming then you can apply yourself to write bigger monster programs.
You learn to write simple programs, and go on to write 100 lines, 200 lines, 500 lines, 1000 lines, 2000 lines, 5000 lines, 
10,000 lines and so on.Then you can apply the concepts to write a bigger project like Banking software, accounting software etc.,

*Level - I*

Q) Write a program to list the contents of a directory ?

Ans) To list the contents of a directory , use the java.io.File class Use the file.list() method.

List.java


```
import java.io.File;
import java.util.Date;

// List the current files in the directory similar to Windows console
public class List {

    String path = ".";
    File directory = new File(path);
    String[] content;
    File file;
    String fileName;

    public List() {
        // Get the current directory contents
        content = directory.list();
        for (int i = 0; i < content.length; i++) {
            fileName = content[i];
            file = new File(fileName);
            if (file.isFile()) {
                System.out.println("" + new Date(file.lastModified()) + "       " + file.length() + " " + fileName);
            } else {
                System.out.println("" + new Date(file.lastModified()) + "   " + "<DIR>   " + " " + fileName);
            }
        }
    }

    public static void main(String[] args) {
        new List();
    }
}
```

This program the contents of a directory . It prints the last modified (Time) , Size of the file, filename.
If it's a directory we display the <DIR> . We use the directory.list() method to get the list of files in the current directory.
The condition file.isFile() is true if it's a file, otherwise it's a directory!

Q) Write a program to list the contents of a directory recursively ?

TraverseDirectory.java


```
import java.io.File;

public class TraverseDirectory {

    public TraverseDirectory(String path) {
        visitAllDirsAndFiles(new File(path));
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            new TraverseDirectory(args[0]);
        } else {
            //Show the contents of the current directory
            new TraverseDirectory(".");
        }
    }

    // Process all files and directories under dir
    public static void visitAllDirsAndFiles(File dir) {
        if (dir != null) {
            if (dir.isDirectory()) {
                System.out.println(" <DIR> " + dir.getName());
                String[] children = dir.list();
                for (int i = 0; i < children.length; i++) {
                    visitAllDirsAndFiles(new File(dir, children[i]));
                }
            } else {
                System.out.println("   " + dir.getName());
            }
        }
    }
}
```

Here we define a method called visitAllDirsAndFiles() that takes a File as argument and processes it.
It uses recursion to display the contents of the directory. Recursion is a simple & effective technique in
programming to solve some problems. Some problems like directory listing, Factorial lend themselves well in
recursion.
This program take a cmd-line argument in the method main(). If you specify a argument then the specified directory
contents are displayed recursively, otherwise the it displays the contents of the current directory.

Also you should study Algorithms & Data-Structures thoroughly to program better. I recommend "Data Structures & Algorithms in Java" by Robert Lafore (Techmedia).
Here are lots of books available that discusses Algorithms & DataSructures in detail. Robert Sedgewick's Algorithms in C++ (Addison Wesley) and 
Algorithms, 4th Edition by Robert Sedgewick discusses algorithms & data structures in Java language. You should
also study "Java How To Program" by H M Deitel and P. J Deitel (Prentice Hall, 1997) contains a lot of code & exercises
and programs. "Core Java " by Cay S. Horstmann and Gary Cornell (Pearson Education) is a multi-volume series that discusses
AWT, debugging, Swing, etc., It's a excellent Java text book. Also if you want to become good programmer you should write
more programs, study more books. Apply yourself to develop better programs. 

Q) Write a program to copy a file ?


```
// copy.java

import java.io.*;

class CopyFile
{
   public static void main (String [] args) throws IOException
   {
      if (args.length != 2)
      {
          System.out.println ("usage: java CopyFile <srcfile> <dstfile>");
          return;
      }

      // Create file input stream attached to args [0] file.

      FileInputStream fis = new FileInputStream (args[0]);

      // Create file output stream attached to args [1] file.

      FileOutputStream fos = new FileOutputStream (args[1]);

      int ch;

      // While not eof (-1), read all characters from fis and
      // write these characters to the file associated with
      // fos.

      while ((ch = fis.read ()) != -1) {
      
         fos.write (ch);
      }
      // Close file associated with file input stream.
      fis.close ();
      // Close file associated with file output stream.
      fos.close ();
   }
}
```

java CopyFile <Source File> <Destination File>

We define a FileInputStream to take a argument (a String) read it's content using a while loop until the end.
FileOutputStream class is used to write a File to the disk. We use the read() method of the FileInputStream to
read a File. We use the write() method of the FileOutputStream to write the File to the disk.

Q) Write a method called CopyFile() that takes two arguments (String) Source & destination ?


```
public void copyFile(File src, File dst) throws IOException {
         remaining = (total - index);
         
         // We use Java NIO for faster file copying
         FileInputStream fIn;
         FileOutputStream fOut;
         FileChannel fIChan, fOChan;
         long fSize;
         MappedByteBuffer mBuf;
 
         try {
             fIn = new FileInputStream(src);
             fOut = new FileOutputStream(dst);
             // Get channels to the input and output files.
             fIChan = fIn.getChannel();
             fOChan = fOut.getChannel();
             // Get the size of the file.
             fSize = fIChan.size();
             // Map the input file to a buffer.
             mBuf = fIChan.map(FileChannel.MapMode.READ_ONLY,
                     0, fSize);
             // Write the buffer to the output file.
             fOChan.write(mBuf); // this copies the file
 
             // Close the channels and files.
             fIChan.close();
             fIn.close();
 
             fOChan.close();
             fOut.close();
         } catch (IOException exc) {
             System.err.println("Error copying File : " + src.toString());
         } catch (ArrayIndexOutOfBoundsException exc) {
         }
    }
```


```
// Copy a file using NIO. Requires JDK 7 or later. 
 import java.io.*; 
 import java.nio.*; 
 import java.nio.channels.*; 
 import java.nio.file.*; 
  
 public class NIOCopy { 
  
   public static void main(String args[]) { 
  
     if(args.length != 2) { 
       System.out.println("Usage: Copy from to"); 
       return; 
     } 
  
     try { 
       Path source = Paths.get(args[0]); 
       Path target = Paths.get(args[1]); 
  
       // Copy the file. 
       Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); 
  
     } catch(InvalidPathException e) { 
       System.out.println("Path Error " + e); 
     } catch (IOException e) { 
       System.out.println("I/O Error " + e); 
     } 
   } 
}
```
 
 Q) Write a program to copy the contents of the directory (entire directory contents)?

 Tip: ) Use recursion to accomplish the job!! (You do it Yourself!!)

 Q) Write a program to display the Fibonacci series?

    1 1 2 3 5 8 13 21 34 55

 Ans) The famous sequence of numbers called Fibonacci series.
 Each term is found by adding the two previous ones: 1+1 is 2, 1+2 is 3 ,2+3 is 5, 3+5 is 8 and so on.
 The Fibonacci has applications in diverse fields from Sorting methods in Computer Science.


```
public class Fibonacci {
 
     public static void main(String[] args) {
         long limit = 429406729;
         long next = 0;// next to the last term
         long last = 1;// last term
         long sum = 0;
 
         while (next < limit) {
             System.out.print(last + " ");
             sum = next + last; // Add last two terms
             next = last;// Variables move forward
             last = sum; // in the series
         }
     }
 }
```

Q) Write a program to display the Size of the directory in MB or GB also count the number of files & directories >


```
import java.io.File;
import java.text.NumberFormat;

public class GetDirSize {

    private int fileCount = 0;// Count the number of files
    private int dirCount = 0;// Count the number of directories
    private long fileSize = 0;
    private NumberFormat nFormat = NumberFormat.getInstance(); // To format the Numbers

    public GetDirSize(String directory) {
        System.out.println("Calculating, Please wait...");
        long dirSize = traverseDirectory(new File(directory));
        if (dirSize > 1000) {
            // Represent it in GB
            System.out.println("Size of the Directory : " + (double) dirSize / 1024 + " GB");
        } else {
            // Represent it in MB
            System.out.println("Size of the Directory : " + dirSize + " MB");
        }
        System.out.println(" No of Files = " + nFormat.format(fileCount) + ", No of Directories = " + nFormat.format(dirCount));
    }

    // Process the directory contents
    public long traverseDirectory(File dir) {
        if (dir != null) {
            //If it'a a directory
            if (dir.isDirectory()) {
                dirCount++;// Increment the count by 1
                // Get the files & directories of the directory
                String[] children = dir.list();
                if (children != null) {
                    for (int i = 0; i < children.length; i++) {
                        traverseDirectory(new File(dir, children[i]));
                    }
                }

            } else {
                // It's a File
                fileCount++; //// Increment the count by 1
                fileSize += dir.length(); // Accumulate the file size (bytes)
            }
        }
        //457 MB = 47,95,62,693 bytes
        //479562693 bytes -> 457 MB
        // ?
        return (fileSize * 457) / 479562693;
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            new GetDirSize(args[0]);
        } else {
            // If no argument is specified, use the current directory
            new GetDirSize(".");
        }
    }
}
```
 
Here we use a method called traverseDirectory() that traverses the entire directory to get the directory size, no. of files & directories.
We increment the directory count by 1 every time we find a directory, else we increment the file count by 1. We get the size of a File using
the method length(). We keep accumulating it until we traverse the directory.
And finally display the size of the directory. Also display the no. of files & directories.

Q) Write a program to display the contents of a directory using a pattern (wildcard) using the Java NIO class SimpleFileVisitor?

Find.java


```
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import static java.nio.file.FileVisitResult.*;
import static java.nio.file.FileVisitOption.*;
import java.util.*;

/**
 * Sample code that finds files that
 * match the specified glob pattern.
 * For more information on what
 * constitutes a glob pattern, see
 * *docs.oracle.com/javase/javatutorials/tutorial/essential/io/fileOps.html#glob
 *
 * The file or directories that match
 * the pattern are printed to
 * standard out.  The number of
 * matches is also printed.
 *
 * When executing this application,
 * you must put the glob pattern
 * in quotes, so the shell will not
 * expand any wild cards:
 *     java Find . -name "*.java"
 */

public class Find {

    /**
     * A {@code FileVisitor} that finds
     * all files that match the
     * specified pattern.
     */
    public static class Finder
        extends SimpleFileVisitor<Path> {

        private final PathMatcher matcher;
        private int numMatches = 0;

        Finder(String pattern) {
            matcher = FileSystems.getDefault()
                    .getPathMatcher("glob:" + pattern);
        }

        // Compares the glob pattern against
        // the file or directory name.
        void find(Path file) {
            Path name = file.getFileName();
            if (name != null && matcher.matches(name)) {
                numMatches++;
                System.out.println(file);
            }
        }

        // Prints the total number of
        // matches to standard out.
        void done() {
            System.out.println("Matched: "
                + numMatches);
        }

        // Invoke the pattern matching
        // method on each file.
        @Override
        public FileVisitResult visitFile(Path file,
                BasicFileAttributes attrs) {
            find(file);
            return CONTINUE;
        }

        // Invoke the pattern matching
        // method on each directory.
        @Override
        public FileVisitResult preVisitDirectory(Path dir,
                BasicFileAttributes attrs) {
            find(dir);
            return CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file,
                IOException exc) {
            System.err.println(exc);
            return CONTINUE;
        }
    }

    static void usage() {
        System.err.println("java Find <path>" +
            " -name \"<glob_pattern>\"");
        System.exit(-1);
    }

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

        if (args.length < 3 || !args[1].equals("-name"))
            usage();

        Path startingDir = Paths.get(args[0]);
        String pattern = args[2];

        Finder finder = new Finder(pattern);
        Files.walkFileTree(startingDir, finder);
        finder.done();
    }
}
```

Execute the command 

*java Find . -name "*.java"* from the cmd-line.

The '.' refers to the current directory.

java Find "D:/" -name "*.java"

For eg., if you use the wildcard "*.java", it displays the only .java files in the current directory.
You can also use other patterns like "*.html", "*.mp3", "*.jpg" etc.,
We use a inner class Finder that extends SimpleFileVisitor class that do this job.
We have created a method called find() that takes a Path argument & matches a specific pattern.
We have introduce a variable called numMatches, increment it if we find a pattern.
And finally we call the done() method to print the number of matches found.

Q) Write a program to find the Factorial of given number without using recursion?

Hint : Use a for loop

Ans) You do this as an Exercise!!

Q) Write a program to count count the number of Words & characters in a String?


```
// A program to count the words & characters in a String
public class CountWordsChars {

    String str = "Java is a great programming language";
    int charCount = 0; // To count the number of characters
    int wordCount = 0; // To count the number of words

    public CountWordsChars() {
        System.out.println("Word Count = " + count(str) + ", Charaters = " + charCount);
    }

    // Return the number of words found
    public int count(String string) {

        if (string != null) {
            //Convert the String to char array
            char[] charArray = string.toCharArray();
            char c;
            for (int i = 0; i < charArray.length; i++) {
                //Fetch every character (char)
                c = charArray[i];
                if (Character.isLetter(c)) {
                    //If the character is a alphabet
                    charCount++;
                }
                if (Character.isWhitespace(c)) {
                    // If it's a whitespace (' ')
                    wordCount++; // Increment the word count by 1
                }
            }
            // At last we increment the wrodCount by 1
            return ++wordCount;
        }
        return 0;
    }

    public static void main(String[] args) {
        new CountWordsChars();
    }
}
```

Here in this program we declare a method called count() that take a String as argument and finds the number of words in a String, as well the characters in a String.

Q) Write a Program to display the Anagram of the given word? 


```
// creates anagrams
// to run this program: java AnagramApp camel
////////////////////////////////////////////////////////////////

public class AnagramApp {

    int size;
    int count;
    char[] arrChar = new char[100];

    public AnagramApp(String word) {
        String input = word;
        size = input.length(); // find its size
        count = 0;
        for (int j = 0; j < size; j++) // put it in array
        {
            arrChar[j] = input.charAt(j);
        }
        doAnagram(size);                       // anagram it
    }

    // rotate left all chars from position to end
    public void rotate(int newSize) {
        int j;
        int position = size - newSize;
        char temp = arrChar[position];       // save first letter
        for (j = position + 1; j < size; j++) // shift others left
        {
            arrChar[j - 1] = arrChar[j];
        }
        arrChar[j - 1] = temp;                 // put first on right
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            new AnagramApp(args[0]);
        } else {
            System.out.println("java AnagramApp <word>");
        }
    }

    public void doAnagram(int newSize) {
        if (newSize == 1) // if too small,
        {
            return;                           // go no further
        }
        for (int j = 0; j < newSize; j++) // for each position,
        {
            doAnagram(newSize - 1);             // anagram remaining
            if (newSize == 2) // if innermost,
            {
                displayWord();                 // display it
            }
            rotate(newSize);                  // rotate word
        }
    }

    // Display the output on the screen
    public void displayWord() {
        if (count < 99) {
            System.out.print(" ");
        }
        if (count < 9) {
            System.out.print(" ");
        }
        System.out.print(++count + " ");
        for (int j = 0; j < size; j++) {
            System.out.print(arrChar[j]);
        }
        System.out.print("   ");
        System.out.flush();
        if (count % 6 == 0) {
            System.out.println("");
        }
    }
}  // end class AnagramApp
```

*s29.postimg.org/49n0s7q9f/Anagram_App.jpg

This program accepts a word as cmd-line argument & displays the anagram for the word.
The rotate() method rotates left all chars. The displayWord() method displays the output on
the screen. The method doAnagram() does the actual job here, It uses recursion to find the 
anagram for the given word.

Q) Write a program to find the biggest word in a array of Strings ?

  For eg., String []str = {"Java" , "is", "a", "cool", "Programming", "language"};

  Write a method called compare() that takes Strings as argument and returns the bigger String.

  for eg., boolean Compare(String str1, String atr2) 

Ans) You do this as an Exercise!!

Q)Write a Java program to check armstrong number ?
Ans)
This java program checks if a number is Armstrong or not. Armstrong number is a number which is equal to sum of digits raise to the power total number of digits in the number. Some Armstrong numbers are: 0, 1, 4, 5, 9, 153, 371, 407, 8208 etc.

```
import java.util.Scanner;
 
class ArmstrongNumber
{
   public static void main(String args[])
   {
      int n, sum = 0, temp, remainder, digits = 0;
 
      Scanner in = new Scanner(System.in);
      System.out.println("Input a number to check if it is an Armstrong number");      
      n = in.nextInt();
 
      temp = n;
 
      // Count number of digits
 
      while (temp != 0) {
         digits++;
         temp = temp/10;
      }
 
      temp = n;
 
      while (temp != 0) {
         remainder = temp%10;
         sum = sum + power(remainder, digits);
         temp = temp/10;
      }
 
      if (n == sum)
         System.out.println(n + " is an Armstrong number.");
      else
         System.out.println(n + " is not an Armstrong number.");         
   }
 
   static int power(int n, int r) {
      int c, p = 1;
 
      for (c = 1; c <= r; c++) 
         p = p*n;
 
      return p;   
   }
}
```
Q) Write a Java program to reverse number?
Ans) This program prints reverse of a number i.e. if the input is 951 then output will be 159.

```
import java.util.Scanner;
 
class ReverseNumber
{
   public static void main(String args[])
   {
      int n, reverse = 0;
 
      System.out.println("Enter the number to reverse");
      Scanner in = new Scanner(System.in);
      n = in.nextInt();
 
      while( n != 0 )
      {
          reverse = reverse * 10;
          reverse = reverse + n%10;
          n = n/10;
      }
 
      System.out.println("Reverse of entered number is "+reverse);
   }
}
```
Q) Write a Java program to add two matrices?
Ans)

```
import java.util.Scanner;
 
class AddTwoMatrix
{
   public static void main(String args[])
   {
      int m, n, c, d;
      Scanner in = new Scanner(System.in);
 
      System.out.println("Enter the number of rows and columns of matrix");
      m = in.nextInt();
      n  = in.nextInt();
 
      int first[][] = new int[m][n];
      int second[][] = new int[m][n];
      int sum[][] = new int[m][n];
 
      System.out.println("Enter the elements of first matrix");
 
      for (  c = 0 ; c < m ; c++ )
         for ( d = 0 ; d < n ; d++ )
            first[c][d] = in.nextInt();
 
      System.out.println("Enter the elements of second matrix");
 
      for ( c = 0 ; c < m ; c++ )
         for ( d = 0 ; d < n ; d++ )
            second[c][d] = in.nextInt();
 
      for ( c = 0 ; c < m ; c++ )
         for ( d = 0 ; d < n ; d++ )
             sum[c][d] = first[c][d] + second[c][d];  //replace '+' with '-' to subtract matrices
 
      System.out.println("Sum of entered matrices:-");
 
      for ( c = 0 ; c < m ; c++ )
      {
         for ( d = 0 ; d < n ; d++ )
            System.out.print(sum[c][d]+"\t");
 
         System.out.println();
      }
   }
}
```
Q) Java program to multiply two matrices ?
Ans) This java program multiply two matrices. Before multiplication matrices are checked whether they can be multiplied or not.

```
import java.util.Scanner;
 
class MatrixMultiplication
{
   public static void main(String args[])
   {
      int m, n, p, q, sum = 0, c, d, k;
 
      Scanner in = new Scanner(System.in);
      System.out.println("Enter the number of rows and columns of first matrix");
      m = in.nextInt();
      n = in.nextInt();
 
      int first[][] = new int[m][n];
 
      System.out.println("Enter the elements of first matrix");
 
      for ( c = 0 ; c < m ; c++ )
         for ( d = 0 ; d < n ; d++ )
            first[c][d] = in.nextInt();
 
      System.out.println("Enter the number of rows and columns of second matrix");
      p = in.nextInt();
      q = in.nextInt();
 
      if ( n != p )
         System.out.println("Matrices with entered orders can't be multiplied with each other.");
      else
      {
         int second[][] = new int[p][q];
         int multiply[][] = new int[m][q];
 
         System.out.println("Enter the elements of second matrix");
 
         for ( c = 0 ; c < p ; c++ )
            for ( d = 0 ; d < q ; d++ )
               second[c][d] = in.nextInt();
 
         for ( c = 0 ; c < m ; c++ )
         {
            for ( d = 0 ; d < q ; d++ )
            {   
               for ( k = 0 ; k < p ; k++ )
               {
                  sum = sum + first[c][k]*second[k][d];
               }
 
               multiply[c][d] = sum;
               sum = 0;
            }
         }
 
         System.out.println("Product of entered matrices:-");
 
         for ( c = 0 ; c < m ; c++ )
         {
            for ( d = 0 ; d < q ; d++ )
               System.out.print(multiply[c][d]+"\t");
 
            System.out.print("\n");
         }
      }
   }
}
```

Q) Java Program to Find Inverse of a Matrix ?
Ans)
This is the java program to find the inverse of square invertible matrix. The matrix is invertible if its determinant is non zero.
Here is the source code of the Java Program to Find Inverse of a Matrix. The Java program is successfully compiled and run on a Windows system. The program output is also shown below.

```
//This is sample program to find the inverse of a matrix
 
import java.util.Scanner;
 
public class Inverse 
{
    public static void main(String argv[]) 
    {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter the dimension of square matrix: ");
        int n = input.nextInt();
        double a[][]= new double[n][n];
        System.out.println("Enter the elements of matrix: ");
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                a[i][j] = input.nextDouble();
 
        double d[][] = invert(a);
 
        System.out.println("The inverse is: ");
        for (int i=0; i<n; ++i) 
        {
            for (int j=0; j<n; ++j)
            {
                System.out.print(d[i][j]+"  ");
            }
            System.out.println();
        }
        input.close();
    }	
 
    public static double[][] invert(double a[][]) 
    {
        int n = a.length;
        double x[][] = new double[n][n];
        double b[][] = new double[n][n];
        int index[] = new int[n];
        for (int i=0; i<n; ++i) 
            b[i][i] = 1;
 
 // Transform the matrix into an upper triangle
        gaussian(a, index);
 
 // Update the matrix b[i][j] with the ratios stored
        for (int i=0; i<n-1; ++i)
            for (int j=i+1; j<n; ++j)
                for (int k=0; k<n; ++k)
                    b[index[j]][k]
                    	    -= a[index[j]][i]*b[index[i]][k];
 
 // Perform backward substitutions
        for (int i=0; i<n; ++i) 
        {
            x[n-1][i] = b[index[n-1]][i]/a[index[n-1]][n-1];
            for (int j=n-2; j>=0; --j) 
            {
                x[j][i] = b[index[j]][i];
                for (int k=j+1; k<n; ++k) 
                {
                    x[j][i] -= a[index[j]][k]*x[k][i];
                }
                x[j][i] /= a[index[j]][j];
            }
        }
        return x;
    }
 
// Method to carry out the partial-pivoting Gaussian
// elimination.  Here index[] stores pivoting order.
 
    public static void gaussian(double a[][], int index[]) 
    {
        int n = index.length;
        double c[] = new double[n];
 
 // Initialize the index
        for (int i=0; i<n; ++i) 
            index[i] = i;
 
 // Find the rescaling factors, one from each row
        for (int i=0; i<n; ++i) 
        {
            double c1 = 0;
            for (int j=0; j<n; ++j) 
            {
                double c0 = Math.abs(a[i][j]);
                if (c0 > c1) c1 = c0;
            }
            c[i] = c1;
        }
 
 // Search the pivoting element from each column
        int k = 0;
        for (int j=0; j<n-1; ++j) 
        {
            double pi1 = 0;
            for (int i=j; i<n; ++i) 
            {
                double pi0 = Math.abs(a[index[i]][j]);
                pi0 /= c[index[i]];
                if (pi0 > pi1) 
                {
                    pi1 = pi0;
                    k = i;
                }
            }
 
   // Interchange rows according to the pivoting order
            int itmp = index[j];
            index[j] = index[k];
            index[k] = itmp;
            for (int i=j+1; i<n; ++i) 	
            {
                double pj = a[index[i]][j]/a[index[j]][j];
 
 // Record pivoting ratios below the diagonal
                a[index[i]][j] = pj;
 
 // Modify other elements accordingly
                for (int l=j+1; l<n; ++l)
                    a[index[i]][l] -= pj*a[index[j]][l];
            }
        }
    }
}
```
Output:
$ javac Inverse.java
$ java Inverse
Enter the dimension of square matrix: 
2
Enter the elements of matrix: 
1 2 
3 4 
The Inverse is: 
-1.9999999999999998  1.0  
1.4999999999999998  -0.49999999999999994
Q) Write a Java Program to Implement Radix Sort ?
Ans)
This is a Java Program to implement Radix Sort Algorithm. This program is to sort a list of numbers.
Here is the source code of the Java program to implement Radix Sort Algorithm. The Java program is successfully compiled and run on a Windows system. The program output is also shown below.

```
/**
 ** Java Program to Implement Radix Sort
 **/
 
import java.util.Scanner;
 
/** Class RadixSort **/
public class RadixSort 
{
    /** Radix Sort function **/
    public static void sort( int[] a)
    {
        int i, m = a[0], exp = 1, n = a.length;
        int[] b = new int[10];
        for (i = 1; i < n; i++)
            if (a[i] > m)
                m = a[i];
        while (m / exp > 0)
        {
            int[] bucket = new int[10];
 
            for (i = 0; i < n; i++)
                bucket[(a[i] / exp) % 10]++;
            for (i = 1; i < 10; i++)
                bucket[i] += bucket[i - 1];
            for (i = n - 1; i >= 0; i--)
                b[--bucket[(a[i] / exp) % 10]] = a[i];
            for (i = 0; i < n; i++)
                a[i] = b[i];
            exp *= 10;        
        }
    }    
    /** Main method **/
    public static void main(String[] args) 
    {
        Scanner scan = new Scanner( System.in );        
        System.out.println("Radix Sort Test\n");
        int n, i;
        /** Accept number of elements **/
        System.out.println("Enter number of integer elements");
        n = scan.nextInt();
        /** Create integer array on n elements **/
        int arr[] = new int[ n ];
        /** Accept elements **/
        System.out.println("\nEnter "+ n +" integer elements");
        for (i = 0; i < n; i++)
            arr[i] = scan.nextInt();
        /** Call method sort **/
        sort(arr);
        /** Print sorted Array **/
        System.out.println("\nElements after sorting ");        
        for (i = 0; i < n; i++)
            System.out.print(arr[i]+" ");            
        System.out.println();                     
    }    
}
```
Radix Sort Test

Enter number of integer elements
10

Enter 10 integer elements
877 567 3456 876 467 26 934 9876 1 4567
 Elements after sorting
1 26 467 567 876 877 934 3456 4567 9876
Q) Java Program to Find Minimum Element in an Array using Linear Search?
Ans) This is a java program to find the minimum element of the sequence using the technique of linear search. First we assign min equal to the first element of the sequence, then we go on exploring each element of the sequence and compare it with the min element, if less we update min.

```
//This is a java program to find the minimum element using the technique of Sequential Search
import java.util.Random;
import java.util.Scanner;
 
public class Minimum_Using_Sequential 
{
    static int N = 20;
    static int []sequence = new int[N];
 
    public static int minSequential()
    {
        int min = sequence[0];
        for(int i=0; i<N; i++)
            if(min > sequence[i])
                min = sequence[i];
 
        return min;
    }
    public static void main(String args[])
    {
        Random random = new Random();
 
        for(int i=0; i<N; i++)
            sequence[i] = Math.abs(random.nextInt(100));
        System.out.println("The sequence is :");
        for(int i=0; i<N; i++)
            System.out.print(sequence[i] + " ");     
 
        Scanner sc = new Scanner(System.in);
        System.out.println("\nThe minimum element in the sequence is : " + minSequential());
        sc.close();
    }
}
```
Output:

$ javac Minimum_Using_Sequential.java
$ java Minimum_Using_Sequential

The sequence is :
33 43 61 93 97 31 53 62 58 87 68 61 16 52 12 29 27 63 68 22 
The minimum element in the sequence is : 12
Q) Java Program to Find Maximum Element in an Array using Binary Search?
Ans) This is a java program to find the maximum element using binary search technique. Binary search requires sequence to be sorted. We return the last element of the sequence, which is maximum.


```
//This is a java program to find maximum element using Binary Search
import java.util.Random;
 
public class Maximum_Using_Binary 
{
    static int N = 20;
    static int []sequence = new int[N];
 
    public static void sort()
    {
       int i, j, temp;
        for (i = 1; i< N; i++) 
        {
            j = i;
            temp = sequence[i];    
            while (j > 0 && temp < sequence[j-1])
            {
                sequence[j] = sequence[j-1];
                j = j-1;
            }
            sequence[j] = temp;            
        }        
    }
 
    public static void main(String args[])
    {
        Random random = new Random();
 
        for(int i=0; i<N; i++)
            sequence[i] = Math.abs(random.nextInt(100));
        System.out.println("The sequence is :");
        for(int i=0; i<N; i++)
            System.out.print(sequence[i] + " ");     
 
        sort();
 
        System.out.println("\nThe maximum element in the sequence is : " + sequence[N-1]);
    }
}
```

Q) Java Program to find the number of occurrences of a given number using Binary Search approach?
Ans) This is a Java Program to find number of occurences of a given number using binary search approach. The time complexity of the following program is O (log n).

```
/*
 *    Java Program to Find the Number of occurrences of a given Number using Binary Search approach
 */
 
import java.util.Scanner;
 
public class NumberOfOccurences
{
    public static void main(String[] args) 
    {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter number of elements in sorted array");
        int N = scan.nextInt();
        int[] arr = new int[ N ];
        /* Accept N elements */
        System.out.println("Enter "+ N +" sorted elements");
        for (int i = 0; i < N; i++)
            arr[i] = scan.nextInt();
        System.out.println("Enter number to find occurences");
        int num = scan.nextInt();
 
        int f = occur(arr, num);
        if (f == -1)
            System.out.println("No occurence");
        else 
            System.out.println("Occurences = "+ f);
    }    
    public static int occur(int[] arr, int num)
    {
        /* find first index */
        int l1 = first(arr, num);
        /* find last index */
        int l2 = last(arr, num);
        if (l1 == -1 || l2 == -1)
            return -1;
        return l2 - l1 + 1;
    }
    public static int first(int[] arr, int num)
    {
        if (arr[0] == num)
            return 0;
        int start = 0, end = arr.length - 1;
        int mid = (start + end) / 2;
        int flag = 0;
        while (!(arr[mid] == num && arr[mid - 1] < arr[mid]))
        {
            if (start == end)
            {
                flag = 1;
                break;
            }
            if (arr[mid] >= num)
                end = mid - 1;
            if (arr[mid] < num)
                start = mid + 1;
            mid = (start + end) / 2;
        }
        if (flag == 0)
            return mid;
        return -1;        
    }
    public static int last(int[] arr, int num)
    {
        if (arr[arr.length - 1] == num)
            return arr.length - 1;
        int start = 0, end = arr.length - 1;
        int mid = (start + end) / 2;
        int flag = 0;
        while (!(arr[mid] == num && arr[mid + 1] > arr[mid]))
        {
            if (start == end)
            {
                flag = 1;
                break;
            }
            if (arr[mid] > num)
                end = mid - 1;
            if (arr[mid] <= num)
                start = mid + 1;
            mid = (start + end) / 2;
        }
        if (flag == 0)
            return mid;
        return -1;        
    }
}
```
Q) Java Program to Implement Ternary Search Algorithm?
Ans) This is a Java Program to Implement Ternary Search Algorithm. A ternary search algorithm is a technique in computer science for finding the minimum or maximum of an increasing or decreasing function. A ternary search determines either that the minimum or maximum cannot be in the first third of the domain or that it cannot be in the last third of the domain, then repeats on the remaining two-thirds. A ternary search is an example of a divide and conquer algorithm.

```
/**
 ** Java Program to Implement Ternary Search Algorithm
 **/
 
import java.util.Scanner;
 
/** Class TernarySearch **/
public class TernarySearch
{
    /** call function **/
    public static int ternarySearch (int[] A, int value)
    {
        return ternarySearch(A, value, 0, A.length - 1);
    }
    /** TernarySearch function **/
    public static int ternarySearch (int[] A, int value, int start, int end)
    {
        if (start > end) 
            return -1;       
 
        /** First boundary: add 1/3 of length to start **/
        int mid1 = start + (end-start) / 3;        
        /** Second boundary: add 2/3 of length to start **/
        int mid2 = start + 2*(end-start) / 3;
 
        if (A[mid1] == value) 
            return mid1;
 
        else if (A[mid2] == value) 
            return mid2;
        /** Search 1st third **/
        else if (value < A[mid1]) 
            return ternarySearch (A, value, start, mid1-1);
        /** Search 3rd third **/
        else if (value > A[mid2]) 
            return ternarySearch (A, value, mid2+1, end);
        /** Search middle third **/
        else 
            return ternarySearch (A, value, mid1,mid2);        
    }
    /** Main method **/
    public static void main(String[] args) 
    {
        Scanner scan = new Scanner( System.in );        
        System.out.println("Ternary Search Test\n");
        int n, i;
        /** Accept number of elements **/
        System.out.println("Enter number of integer elements");
        n = scan.nextInt();
        /** Create integer array on n elements **/
        int arr[] = new int[ n ];
        /** Accept elements **/
        System.out.println("\nEnter "+ n +" sorted integer elements");
        for (i = 0; i < n; i++)
            arr[i] = scan.nextInt();
        System.out.println("\nEnter element to search for : ");
        int key = scan.nextInt();
 
        int result = ternarySearch(arr, key);
 
        if (result == -1)
            System.out.println("\n"+ key +" element not found");
        else
            System.out.println("\n"+ key +" element found at position "+ result);
 
    }    
}
```
Q) Java Program to Implement the String Search Algorithm for Short Text Sizes?
Ans) This is a java program to search string using simple algorithm BoyerMoore.

```
import java.util.Scanner;
 
class BoyerMoore
{
    private final int BASE;
    private int[]     occurrence;
    private String    pattern;
 
    public BoyerMoore(String pattern)
    {
        this.BASE = 256;
        this.pattern = pattern;
        occurrence = new int[BASE];
        for (int c = 0; c < BASE; c++)
            occurrence[c] = -1;
        for (int j = 0; j < pattern.length(); j++)
            occurrence[pattern.charAt(j)] = j;
    }
 
    public int search(String text)
    {
        int n = text.length();
        int m = pattern.length();
        int skip;
        for (int i = 0; i <= n - m; i += skip)
        {
            skip = 0;
            for (int j = m - 1; j >= 0; j--)
            {
                if (pattern.charAt(j) != text.charAt(i + j))
                {
                    skip = Math.max(1, j - occurrence[text.charAt(i + j)]);
                    break;
                }
            }
            if (skip == 0)
                return i;
        }
        return n;
    }
}
 
public class StringSearch
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter the main string: ");
        String text = sc.nextLine();
        System.out.print("Enter the string to be searched: ");
        String pattern = sc.nextLine();
        BoyerMoore bm = new BoyerMoore(pattern);
        int first_occur_position = bm.search(text);
        System.out.println("The text '" + pattern
                + "' is first found after the " + first_occur_position
                + " position.");
        sc.close();
    }
}
```
Q) Java Program to Implement Sorted Array?
Ans) This Java program is to Implement Sorted array. A sorted array is an array data structure in which each element is sorted in numerical, alphabetical, or some other order, and placed at equally spaced addresses in computer memory.

```
import java.util.Arrays;
 
public class SortedArray<T>
{
    private T[] array;
 
    public SortedArray(T[] array)
    {
        this.array = array;
    }
 
    public void sort()
    {
        Arrays.sort(array);
    }
 
    public T[] getArray()
    {
        return array;
    }
 
    public static void main(String...arg)
    {
        Integer[] inums = {10,9,8,7,6};
        Float[] fnums = {23.9f,5.5f,10.8f,2.5f,82.0f};
        Double[] dnums = {12.5,244.92,1.9,98.3,35.2};
        String[] strings = {"banana","pineapple","apple","mango","jackfruit"};
 
        System.out.println("The Values Before sorting");
        System.out.println();
 
        System.out.println("Integer Values");
        for (int i = 0; i < inums.length; i++)
            System.out.print(inums[i] + "\t");
 
        System.out.println();
        System.out.println("Floating Values");
        for (int i = 0; i < fnums.length; i++)
            System.out.print(fnums[i] + "\t");
 
        System.out.println();
        System.out.println("Double Values");
 
        for (int i = 0; i < dnums.length; i++)
            System.out.print(dnums[i] + "\t");
 
        System.out.println();
        System.out.println("String Values");
 
        for (int i = 0; i < strings.length; i++)
            System.out.print(strings[i] + "\t");
 
        SortedArray<Integer> integer = new SortedArray<Integer>(inums);
        SortedArray<Float> floating = new SortedArray<Float>(fnums);
        SortedArray<Double> doubles = new SortedArray<Double>(dnums);
        SortedArray<String> string = new SortedArray<String>(strings);
 
        integer.sort();
        floating.sort();
        doubles.sort();
        string.sort();
 
        inums = integer.getArray();
        fnums = floating.getArray();
        dnums = doubles.getArray();
        strings = string.getArray();
 
        System.out.println();
        System.out.println("The Values After sorting");
        System.out.println();
        System.out.println("Integer Values");
        for (int i = 0; i < inums.length; i++)
            System.out.print(inums[i] + "\t");
 
        System.out.println();
        System.out.println("Floating Values");
        for (int i = 0; i < fnums.length; i++)
            System.out.print(fnums[i] + "\t");
 
        System.out.println();
        System.out.println("Double Values");
        for (int i = 0; i < dnums.length; i++)
            System.out.print(dnums[i] + "\t");
 
        System.out.println();
        System.out.println("String Values");
        for (int i = 0; i < strings.length; i++)
            System.out.print(strings[i] + "\t");
    }	
}
```
Q) Java Program to Implement Doubly Linked List?
Ans) This is a Java Program to implement a Doubly Linked List. A linked list is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of a data and a reference (in other words, a link) to the next node in the sequence. This structure allows for efficient insertion or removal of elements from any position in the sequence. In a doubly linked list each node has two links one pointing to the next node in the list and one pointing to the previous node in the list .

```
/*
 *  Java Program to Implement Doubly Linked List
 */
 
import java.util.Scanner;
 
/*  Class Node  */
class Node
{
    protected int data;
    protected Node next, prev;
 
    /* Constructor */
    public Node()
    {
        next = null;
        prev = null;
        data = 0;
    }
    /* Constructor */
    public Node(int d, Node n, Node p)
    {
        data = d;
        next = n;
        prev = p;
    }
    /* Function to set link to next node */
    public void setLinkNext(Node n)
    {
        next = n;
    }
    /* Function to set link to previous node */
    public void setLinkPrev(Node p)
    {
        prev = p;
    }    
    /* Funtion to get link to next node */
    public Node getLinkNext()
    {
        return next;
    }
    /* Function to get link to previous node */
    public Node getLinkPrev()
    {
        return prev;
    }
    /* Function to set data to node */
    public void setData(int d)
    {
        data = d;
    }
    /* Function to get data from node */
    public int getData()
    {
        return data;
    }
}
 
/* Class linkedList */
class linkedList
{
    protected Node start;
    protected Node end ;
    public int size;
 
    /* Constructor */
    public linkedList()
    {
        start = null;
        end = null;
        size = 0;
    }
    /* Function to check if list is empty */
    public boolean isEmpty()
    {
        return start == null;
    }
    /* Function to get size of list */
    public int getSize()
    {
        return size;
    }
    /* Function to insert element at begining */
    public void insertAtStart(int val)
    {
        Node nptr = new Node(val, null, null);        
        if(start == null)
        {
            start = nptr;
            end = start;
        }
        else
        {
            start.setLinkPrev(nptr);
            nptr.setLinkNext(start);
            start = nptr;
        }
        size++;
    }
    /* Function to insert element at end */
    public void insertAtEnd(int val)
    {
        Node nptr = new Node(val, null, null);        
        if(start == null)
        {
            start = nptr;
            end = start;
        }
        else
        {
            nptr.setLinkPrev(end);
            end.setLinkNext(nptr);
            end = nptr;
        }
        size++;
    }
    /* Function to insert element at position */
    public void insertAtPos(int val , int pos)
    {
        Node nptr = new Node(val, null, null);    
        if (pos == 1)
        {
            insertAtStart(val);
            return;
        }            
        Node ptr = start;
        for (int i = 2; i <= size; i++)
        {
            if (i == pos)
            {
                Node tmp = ptr.getLinkNext();
                ptr.setLinkNext(nptr);
                nptr.setLinkPrev(ptr);
                nptr.setLinkNext(tmp);
                tmp.setLinkPrev(nptr);
            }
            ptr = ptr.getLinkNext();            
        }
        size++ ;
    }
    /* Function to delete node at position */
    public void deleteAtPos(int pos)
    {        
        if (pos == 1) 
        {
            if (size == 1)
            {
                start = null;
                end = null;
                size = 0;
                return; 
            }
            start = start.getLinkNext();
            start.setLinkPrev(null);
            size--; 
            return ;
        }
        if (pos == size)
        {
            end = end.getLinkPrev();
            end.setLinkNext(null);
            size-- ;
        }
        Node ptr = start.getLinkNext();
        for (int i = 2; i <= size; i++)
        {
            if (i == pos)
            {
                Node p = ptr.getLinkPrev();
                Node n = ptr.getLinkNext();
 
                p.setLinkNext(n);
                n.setLinkPrev(p);
                size-- ;
                return;
            }
            ptr = ptr.getLinkNext();
        }        
    }    
    /* Function to display status of list */
    public void display()
    {
        System.out.print("\nDoubly Linked List = ");
        if (size == 0) 
        {
            System.out.print("empty\n");
            return;
        }
        if (start.getLinkNext() == null) 
        {
            System.out.println(start.getData() );
            return;
        }
        Node ptr = start;
        System.out.print(start.getData()+ " <-> ");
        ptr = start.getLinkNext();
        while (ptr.getLinkNext() != null)
        {
            System.out.print(ptr.getData()+ " <-> ");
            ptr = ptr.getLinkNext();
        }
        System.out.print(ptr.getData()+ "\n");
    }
}
 
/* Class DoublyLinkedList */
public class DoublyLinkedList
{    
    public static void main(String[] args)
    {            
        Scanner scan = new Scanner(System.in);
        /* Creating object of linkedList */
        linkedList list = new linkedList(); 
        System.out.println("Doubly Linked List Test\n");          
        char ch;
        /*  Perform list operations  */
        do
        {
            System.out.println("\nDoubly Linked List Operations\n");
            System.out.println("1. insert at begining");
            System.out.println("2. insert at end");
            System.out.println("3. insert at position");
            System.out.println("4. delete at position");
            System.out.println("5. check empty");
            System.out.println("6. get size");
 
            int choice = scan.nextInt();            
            switch (choice)
            {
            case 1 : 
                System.out.println("Enter integer element to insert");
                list.insertAtStart( scan.nextInt() );                     
                break;                          
            case 2 : 
                System.out.println("Enter integer element to insert");
                list.insertAtEnd( scan.nextInt() );                     
                break;                         
            case 3 : 
                System.out.println("Enter integer element to insert");
                int num = scan.nextInt() ;
                System.out.println("Enter position");
                int pos = scan.nextInt() ;
                if (pos < 1 || pos > list.getSize() )
                    System.out.println("Invalid position\n");
                else
                    list.insertAtPos(num, pos);
                break;                                          
            case 4 : 
                System.out.println("Enter position");
                int p = scan.nextInt() ;
                if (p < 1 || p > list.getSize() )
                    System.out.println("Invalid position\n");
                else
                    list.deleteAtPos(p);
                break;     
            case 5 : 
                System.out.println("Empty status = "+ list.isEmpty());
                break;            
            case 6 : 
                System.out.println("Size = "+ list.getSize() +" \n");
                break;                         
            default : 
                System.out.println("Wrong Entry \n ");
                break;   
            }    
            /*  Display List  */ 
            list.display();
            System.out.println("\nDo you want to continue (Type y or n) \n");
            ch = scan.next().charAt(0);    
 
        } while (ch == 'Y'|| ch == 'y');               
    }
}
```

Doubly Linked List Test


Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
1
Enter integer element to insert
5

Doubly Linked List = 5

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
1
Enter integer element to insert
2

Doubly Linked List = 2 <-> 5

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
2
Enter integer element to insert
6

Doubly Linked List = 2 <-> 5 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
1
Enter integer element to insert
7

Doubly Linked List = 7 <-> 2 <-> 5 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
3
Enter integer element to insert
3
Enter position
3

Doubly Linked List = 7 <-> 2 <-> 3 <-> 5 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
2

Doubly Linked List = 7 <-> 3 <-> 5 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
3
Enter integer element to insert
4
Enter position
4

Doubly Linked List = 7 <-> 3 <-> 5 <-> 4 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
6
Size = 5


Doubly Linked List = 7 <-> 3 <-> 5 <-> 4 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
1

Doubly Linked List = 3 <-> 5 <-> 4 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
2

Doubly Linked List = 3 <-> 4 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
2

Doubly Linked List = 3 <-> 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
1

Doubly Linked List = 6

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
4
Enter position
1

Doubly Linked List = empty

Do you want to continue (Type y or n)

y

Doubly Linked List Operations

1. insert at begining
2. insert at end
3. insert at position
4. delete at position
5. check empty
6. get size
5
Empty status = true

Doubly Linked List = empty

Do you want to continue (Type y or n)
 n
Q) Java Program to implement Dynamic Array?
Ans) This is a Java Program to implement Dynamic Array. A dynamic array, growable array, resizable array, dynamic table, mutable array, or array list is a random access, variable-size list data structure that allows elements to be added or removed.

```
/**
 ** Java Program to implement Dynamic Array
 **/
 
import java.util.Scanner;
import java.util.ArrayList;
 
/** class DynamicArray */
class DynamicArray
{
    private ArrayList<String> al;
 
    /** constructor **/
    public DynamicArray()
    {
        al = new ArrayList<String>();        
    }    
    /** function to clear **/
    public void clear()
    {
        al.clear();
    }
    /** function to get size **/
    public int size()
    {
        return al.size();
    }   
    /** function to insert element **/
    public void insert(String key)
    {
        al.add(key);
    }    
    /** function to get element at index **/
    public String get(int index)
    {
        if (index >= al.size())
            return "";
        return al.get(index);
    }
    /** function to remove element at index **/
    public void remove(int index)
    {
        if (index >= al.size())
            return ;
        al.remove(index);
    }   
    /** function to remove element **/
    public void remove(String key)
    {
        al.remove(key);
    } 
    /** function to display array **/
    public void display()
    {
        System.out.println("\nDynamic Array : "+ al);
        System.out.println();
    }              
}
 
/** Class DynamicArrayTest **/
public class DynamicArrayTest
{
    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        System.out.println("Dynamic Array Test\n");   
 
        DynamicArray da = new DynamicArray();
 
        char ch;
        /*  Perform Dynamic Array operations */
        do    
        {
            System.out.println("\nDynamic Array\n");
            System.out.println("1. insert ");
            System.out.println("2. remove by index");
            System.out.println("3. remove by val");
            System.out.println("4. clear");
            System.out.println("5. size");
 
            int choice = scan.nextInt();            
            switch (choice) 
            {
            case 1 : 
                System.out.println("Enter value to insert");
                da.insert(scan.next() );                     
                break;                          
            case 2 : 
                System.out.println("Enter index");
                da.remove(scan.nextInt() );
                break;        
            case 3 : 
                System.out.println("Enter value");
                da.remove(scan.next() );
                break;                                   
            case 4 : 
                System.out.println("\nDynamic Array Cleared");
                da.clear();
                break;    
            case 5 : 
                System.out.println("\nSize = "+ da.size() );
                break;         
            default : 
                System.out.println("Wrong Entry \n ");
                break;   
            }    
            da.display();    
 
            System.out.println("\nDo you want to continue (Type y or n) \n");
            ch = scan.next().charAt(0);                        
        } while (ch == 'Y'|| ch == 'y');               
    }
}
```

Dynamic Array Test


Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
1
Enter value to insert
apple

Dynamic Array : [apple]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
1
Enter value to insert
mango

Dynamic Array : [apple, mango]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
1
Enter value to insert
banana

Dynamic Array : [apple, mango, banana]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
1
Enter value to insert
strawberry

Dynamic Array : [apple, mango, banana, strawberry]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
5

Size = 4

Dynamic Array : [apple, mango, banana, strawberry]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
2
Enter index
2

Dynamic Array : [apple, mango, strawberry]


Do you want to continue (Type y or n)

y

Dynamic Array

1. insert
2. remove by index
3. remove by val
4. clear
5. size
3
Enter value
strawberry

Dynamic Array : [apple, mango]



*Level - II*


Q) Write a program to display a BarChart of the given values ?

BarChartDemo.java


```
import java.awt.*;
 import javax.swing.*;
 
 public class BarChartDemo extends JPanel {
 
     //Array of Strings
     private String[] string = {"Microsoft", "Oracle", "Google", "IBM", "RedHat", "Intel", "Fujitsu", "Accenture"};
     //Array of Colors
     private Color[] color = {Color.red, Color.blue, Color.pink, Color.green, Color.cyan, Color.orange, Color.yellow, Color.gray};
     //Array of Values
     private int[] value = {1500, 850, 550, 500, 450, 420, 320, 280};
     private int barHeight = 50;
 
     public BarChartDemo() {
         Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
         setBackground(Color.white);
         setPreferredSize(new Dimension(scrDim.width / 2 + 650, scrDim.height / 2 + 200));
     }
 
     @Override
     public void paintComponent(Graphics g) {
         super.paintComponent(g);
         Graphics2D g2d = (Graphics2D) g;
         // Set RenderingHints properties
         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
         g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
         g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         g2d.setStroke(new BasicStroke(3f));
         g2d.setFont(new Font("Serif", Font.BOLD, 20));
 
         int X = 50, Y = 50;
         for (int i = 0; i < string.length; i++) {
             g2d.setColor(color[i]);
             g2d.fillRect(X, Y, value[i], barHeight);
             g2d.setColor(Color.black);
             g2d.drawRect(X, Y, value[i], barHeight);
             g2d.drawString(string[i], X + 80, Y + 25);
             // Increment barHeight
             Y += barHeight + 15;
         }
     }
 
     public static void main(String[] args) {
         SwingUtilities.invokeLater(new Runnable() {
 
             @Override
             public void run() {
                 JFrame f = new JFrame("BarChartDemo");
                 f.add(new BarChartDemo());
                 f.pack();
                 f.setVisible(true);
                 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             }
         });
     }
 }
```

*s13.postimg.org/yorx37k2b/Bar_Chart_Demo.jpg

Here we display a BarChart using the given data of strings, colors, values.
We use a for loop to loop through the array values. We use fillRect() method to draw a filled Rectangle of
a specific dimension. The drawRect() draws the Rectangle of specific dimension. Finally we plot the graph
of the given values using X & Y coordinates. We increment Y to render the Rectangle one below the other.
How simple it is to draw a BarChart!!

Q) Write a Program to draw a PieChart of the given values?

Ans)  Here is the code that accomplishes it!!

PieChartDemo.java


```
//Drawing a Pie Chart
//This example implements a method for drawing a pie chart.
import java.awt.*;
import javax.swing.*;

// Class to hold a value for a slice
class PieChart {

    private double value;
    private Color color;
    private Font textFont = new Font("Serif", Font.BOLD, 16);
    private Color textColor = Color.black;
    private int originX, originY;
    private int radius;
    private double d2r = Math.PI / 180.0; // degrees to radians.

    public PieChart(double value, Color color) {
        this.value = value;
        this.color = color;
    }

    // slices is an array of values that represent the size of each slice.
    public void drawPie(Graphics2D g, Rectangle area, PieChart[] slices, String[] labels) {
        originX = area.width / 2;
        originY = area.height / 2;
        int diameter = (originX < originY ? area.width - 40
                : area.height - 40);
        radius = (diameter / 2) + 1;
        // Get total value of all slices
        double total = 0.0D;
        for (int i = 0; i < slices.length; i++) {
            total += slices[i].value;
        }

        // Draw each pie slice
        double curValue = 0.0D;
        int startAngle = 0;
        for (int i = 0; i < slices.length; i++) {
            // Compute the start and stop angles
            startAngle = (int) (curValue * 360 / total);
            int arcAngle = (int) (slices[i].value * 360 / total);

            // Ensure that rounding errors do not leave a gap between the first and last slice
            if (i == slices.length - 1) {
                arcAngle = 360 - startAngle;
            }

            // Set the color and draw a filled arc
            g.setColor(slices[i].color);
            g.fillArc(area.x, area.y, area.width, area.height, startAngle, arcAngle);

            curValue += slices[i].value;
            // Draw the Labels
            drawLabel(g, labels[i] + " - " + (int) slices[i].value + "%", startAngle + (arcAngle / 2));
        }
    }

    //Draw the labels
    public void drawLabel(Graphics g, String text, double angle) {
        g.setFont(textFont);
        g.setColor(textColor);
        double radians = angle * d2r;
        int x = (int) ((radius + 5) * Math.cos(radians));
        int y = (int) ((radius + 5) * Math.sin(radians));
        if (x < 0) {
            x -= SwingUtilities.computeStringWidth(g.getFontMetrics(), text);
        }
        if (y < 0) {
            y -= g.getFontMetrics().getHeight();
        }
        g.drawString(text, x + originX, originY - y);
    }

}

public class PieChartDemo extends JPanel {

    //Array of slices
    private PieChart[] slices = new PieChart[4];
    private Rectangle area;
    private int width, height;
    //Array of values
    private final int percent[] = {25, 33, 20, 15};
    //Array of names
    private final String[] language = {"C++", "Java", "C#", "Visual Basic"};
    //Array of Colors
    private final Color color[] = {Color.red, Color.green, Color.pink, Color.blue};

    PieChartDemo() {
        // Set the size of the Component
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setPreferredSize(new Dimension(scrDim.height / 2 + 250, scrDim.height / 2 + 150));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        width = getWidth();
        height = getHeight();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2.setStroke(new BasicStroke(1.5f));

        area = new Rectangle(20, 20, width - 40, height - 40);
        for (int i = 0; i < slices.length; i++) {
            slices[i] = new PieChart(percent[i], color[i]);
        }
        slices[0].drawPie(g2, area, slices, language);
    }

    public static void main(String[] arg) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("PieChart Demo");
                f.add(new PieChartDemo());
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}
```

*s18.postimg.org/betqqgrrp/Pie_Chart_Demo.jpg

 We declare a class called PieChartDemo with specific values (arrays) the method paintComponent() 
 does all the painting job.
 We declare a utility class called PieChart to to render the PieChart on the screen.
 The constructor PieChart(double value, Color color) takes a double & Color as argument.
 The method drawPie() draws the PieChart on the screen.
 We use the fillArc() method of the Graphics class to draw a filled Arc.
 The drawLabel() method draws the String (Label) on the screen.
 Very easy & simple to draw a PieChart!!

 Q) Write a program to display the Mouse dragging operation in a Frame ?

 Ans) Here is a code that does it!!

MouseDragDemo.java


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MouseDragDemo extends JPanel {

    private int mouseX, mouseY, width, height;
    // mouseX - starting point X coordinate
    // mouseY - starting point Y coordinate
    // width - width of the Rectangle
    // height - height of the Rectangle
    private int x, y;
    private Dimension scrDim;

    public MouseDragDemo() {
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();

        // Set the background
        setBackground(Color.white);
        // Add a Mouse listener
        addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent me) {
                // Starting point of X & Y coordinate
                mouseX = me.getX();
                mouseY = me.getY();
            }
        });
        // Add a Mouse motion listener
        addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseDragged(MouseEvent me) {
                // Calculate the Rectangle coordinates (x, y, width, height)
                x = Math.min(mouseX, me.getX());
                y = Math.min(mouseY, me.getY());
                width = Math.abs(mouseX - me.getX());
                height = Math.abs(mouseY - me.getY());
                repaint();
            }
        });
        setPreferredSize(scrDim);
    }

    /**
     * Overridden to return true which means that children may not overlap.
     * <p>
     * This is a little bit obscure.
     *
     * @return
     */
    @Override
    public boolean isOptimizedDrawingEnabled() {
        return true;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        // Set Rendering hints properties render for Speed
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        // Set the thickness of the Rectangle
        g2.setStroke(new BasicStroke(3f));

        // Translucent green color
        g2.setColor(Color.red);
        // Draw the Rectangle
        // Fill the Rectangle region with translucent color
        g2.fillRect(x, y, width, height);
        g2.setColor(Color.black);
        // Draw a rectangle outline
        g2.drawRect(x, y, width, height);
        // Disposes of this graphics context and releases any system resources
        g2.dispose();
    }

    public static void main(String[] s) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("MouseDragDemo");
                frame.add(new MouseDragDemo());
                //Set the Frame's properties
                frame.pack();
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}
```

*s14.postimg.org/skp9fgbd9/Mouse_Drag_Demo.jpg

 The class MouseDragDemo displays the Mouse drag operation by drawing a Rectangle in Red color
 in the specified region on the screen.
 mouseX - starting point X coordinate
 mouseY - starting point Y coordinate
 width - width of the Rectangle
 height - height of the Rectangle

 we use the addMouseListener() to track the Mouse drag operation.
 We capture that Mouse positions X & Y in the variables mouseX, mouseY.
 We add addMouseMotionListener() method to capture the Mouse drag

 The mouseDragged() method captures the Mouse drag. The values of x, y, width, height
 are calculated & rendered using the paint() method .The  width = Math.abs(mouseX - me.getX())
 height = Math.abs(mouseY - me.getY())
 After calculating width & height we draw the Rectangle using the coordinates x, y, width, height.

 Q) Write a program to draw the zoomed Image using a ComboBox containing the given String?

    String array values are {"10%", "25%", "50%", "75%", "100%", "150%", "200%", "400%", "600%", "800%"}

 Ans) Here is the code!!


```
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: JGuru
 * Date: 7/20/14
 * Time: 1:20 PM
 * To change this template use File | Settings | File Templates.
 */
public class ImageZoomCombo extends JFrame {

    private final String []zFactor = new String[] {"10%", "25%", "50%", "75%", "100%", "125%", "150%", "200%", "250%", "300%", "450%", "500%", "600%", "700%", "800%"};
    private final JComboBox <String> comboBox = new JComboBox<>(zFactor);
    private Image image;
    private final JLabel label = new JLabel();
    private int imgWidth, imgHeight;

    public ImageZoomCombo() {
        //Set System look'n feel
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look 'n feel!!");
        }
        comboBox.updateUI();
        // Alignment for the Label
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        comboBox.setPreferredSize(new Dimension(150, 30));
        comboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // Catch the OutOfMemoryError error, in case it happens!!
                        try
                        {
                            String zoomFactor = comboBox.getSelectedItem().toString();
                            //Remove the percent (%) sign from the String
                            zoomFactor = zoomFactor.substring(0, zoomFactor.lastIndexOf("%"));
                            int zoomValue = 100;
                            try
                            {
                                zoomValue = Integer.parseInt(zoomFactor);
                            }  catch (NumberFormatException nfe) {
                                zoomValue = 100;
                            }
                            setCursor(new Cursor(Cursor.WAIT_CURSOR));
                            label.setIcon(new ImageIcon(image.getScaledInstance(imgWidth * zoomValue/100, imgHeight * zoomValue/100, Image.SCALE_SMOOTH)));
                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                        }  catch (OutOfMemoryError ome) {
                            JOptionPane.showMessageDialog(null, "Oops, The JVM is running out of Memory (Heap)!! \n Start the JVM with -Xms128m -Xmx256m argument", "Error", JOptionPane.ERROR_MESSAGE);
                            System.exit(-1);
                        }
                    }
                }).start();
            }
        });

        //Get the Image
        //Create a directory called 'Images' and copy or rename a File called Aishwarya Rai2.jpg in that directory
        image = getImage("Images/Aishwarya Rai2.jpg");
        if(image != null) {
            imgWidth = image.getWidth(this);
            imgHeight = image.getHeight(this);
            label.setIcon(new ImageIcon(image));
        }
        add(new JScrollPane(label));
        JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
        top.add(new JLabel("Image Zoom"));
        top.add(comboBox);
        add(top, BorderLayout.NORTH);
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2 + 120, scrDim.height);
        setTitle("ImageZoom");
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName + "!!");
            System.exit(-1);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ImageZoomCombo();
            }
        });
    }
}
```

*s14.postimg.org/6b6qv5qj1/Image_Zoom_Combo.jpg

To run the program 
java ImageZoomCombo

 If you have a directory called Images (in the current directory) & it contains a Image called "Aishwarya.jpg"

Let's examine the code a wee bit. The program accepts a String as cmd-line argument.
It displays the Image on the Frame. We fetch the Image dimension in the variables imgWidth &
imgHeight. We add a ItemListener to the ComboBox to process it. When the user selects a
particular String the Image is zoomed to the corresponding size & it's displayed.
We calculate the new width & height of the Image & display it.
Simple program to show Image zoom!!

Q) Write a program using Java Swing to display the directory contents ?
   Use a separate Thread to process it & display it.

Ans) Here is the code!!

DirectoryLister.java


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.*;

public class DirectoryLister extends JFrame {

    private JButton browse = new JButton("Browse");
    private JButton quit = new JButton("Quit");
    private JButton stop = new JButton("Stop");
    private JTextArea textArea = new JTextArea();
    private JFileChooser fileChooser = new JFileChooser();
    private File file;
    private boolean isCancelled = false;

    public void updateUI() {
        browse.updateUI();
        quit.updateUI();
        textArea.updateUI();
        fileChooser.updateUI();
        stop.updateUI();
    }

    public DirectoryLister() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        //Update the UI
        updateUI();
        fileChooser.setPreferredSize(new Dimension(650, 400));
        JPanel top = new JPanel();
        top.add(browse);
        top.add(stop);
        top.add(quit);
        add(top, BorderLayout.NORTH);
        stop.setEnabled(false);
        add(new JScrollPane(textArea), BorderLayout.CENTER);

        textArea.setFont(new Font("Serif", Font.BOLD, 14));
        textArea.setBackground(Color.black);
        textArea.setForeground(Color.green);

        browse.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // Browse
                fileChooser.setDialogTitle("Browse");
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int result = fileChooser.showOpenDialog(null);
                if (result != 0) {
                    return;
                }
                file = fileChooser.getSelectedFile();
                if (file == null) {
                    JOptionPane.showMessageDialog(null, "You didn't select a directory", "Message", JOptionPane.WARNING_MESSAGE);
                } else {
                    //Reset the flag
                    isCancelled = false;
                    //The user did select a directory
                    // Clear the previous output
                    textArea.setText("");
                    // Start the Thread from within the Event-dispatch Thread since Swing is not Thread safe!!
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            start();
                        }
                    });
                }
            }
        });
        stop.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                isCancelled = true;
            }
        });
        quit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2, scrDim.height);
        setTitle("DirectoryLister");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Process the directory contents
    public void traverseDirectory(File dir) {
        // If the user has not pressed the Stop button
        if (!isCancelled) {
            if (dir != null) {
                //If it'a a directory
                if (dir.isDirectory()) {
                    textArea.append(" < DIR > " + dir + "\n");
                    // Get the files & directories of the directory
                    String[] children = dir.list();
                    File dirFile;
                    if (children != null) {
                        for (int i = 0; i < children.length; i++) {
                            dirFile = new File(dir, children[i]);
                            // Possible Null Pointer Exception here!!
                            if (dirFile != null) {
                                traverseDirectory(dirFile);
                            }
                        }
                    }
                } else {
                    textArea.append("  " + dir + "\n");
                }
                // Scroll down to the bottom
                textArea.setCaretPosition(textArea.getDocument().getLength());
            }
        }
    }

    public void start() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                // I'm busy procesing
                textArea.setCursor(new Cursor(Cursor.WAIT_CURSOR));
                // Only when we are processing we can stop it!!
                stop.setEnabled(true);
                browse.setEnabled(false);
                traverseDirectory(file);
                browse.setEnabled(true);
                // I have finished processing!!
                stop.setEnabled(false);
                textArea.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        }).start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new DirectoryLister();
            }
        });
    }
}
```

*s2.postimg.org/l0qzhxad1/Directory_Lister.jpg

 The class DirectoryLister has a browse button (To choose a directory), stop button to stop the operation.
 The real processing is done in the method travserseDirectory() . We use a Thread start() method to display
 the directory entries recursively.
 Click the browse button & select a particular directory. Click on the OK button of the FileChooser dialog.
 The TextArea displays the contents of the directory, it automatically scrolls to the end of the Component.
 While the Thread is processing the data, you can click on the Stop button if you want to stop the operation.

 Q) Write a program to do a little Image processing likeblur, emboss, sharpen, threshold, grayScale etc.,?

 Ans) Here is the code!!
 ProcessImage.java


```
/**
  *
  * @author Sowndar
  */
 // ProcessImage - Do some effects like Blur, Sharpen, Contrast, Negative etc.,
 import java.awt.*;
 import java.awt.color.ColorSpace;
 import java.awt.event.*;
 import java.awt.image.*;
 import java.io.*;
 import java.util.*;
 import javax.swing.border.*;
 import java.beans.*;
 import javax.imageio.ImageIO;
 import javax.swing.*;
 import javax.swing.filechooser.FileFilter;
 
 class ProcessImage extends JFrame implements ActionListener {
 
     private JLabel label = new JLabel("", JLabel.CENTER);
     private JFileChooser fc = new JFileChooser(".");
     private JLabel message = new JLabel("Ready", JLabel.LEFT);
     private BufferedImage buffImg;
     // MenuItems ...
     private JMenuItem open = new JMenuItem("Open...");
     private JMenuItem revert = new JMenuItem("Revert");
     private JMenuItem blur = new JMenuItem("Blur");
     private JMenuItem edgeDetect = new JMenuItem("Edge Detect");
     private JMenuItem emboss = new JMenuItem("Emboss");
     private JMenuItem posterize = new JMenuItem("Posterize");
     private JMenuItem sharpen = new JMenuItem("Sharpen");
     private JMenuItem negative = new JMenuItem("Negative");
     private JMenuItem threshold = new JMenuItem("Threshold");
     private JMenuItem grayScale = new JMenuItem("GrayScale");
     private JMenuItem exit = new JMenuItem("Exit");
     private Image image = null;
     private int imgWidth = -1;
     private int imgHeight = -1;
     private Dimension scrDim;
 
     // Get supported Image formats (remove duplicate entries)
     public String[] getReaderFormats() {
         String[] rFormat = ImageIO.getReaderFormatNames();
         Set<String> set = new HashSet<String>();
         String imgformat = "";
         // Remove duplicate entries
         for (int i = 0; i < rFormat.length; i++) {
             imgformat = rFormat[i];
             imgformat = imgformat.toLowerCase();
             set.add(imgformat);
         }
         String[] frmt = new String[set.size()];
         return set.toArray(frmt);
     }
 
     public void updateUI() {
         open.updateUI();
         revert.updateUI();
         blur.updateUI();
         edgeDetect.updateUI();
         emboss.updateUI();
         posterize.updateUI();
         sharpen.updateUI();
         negative.updateUI();
         threshold.updateUI();
         grayScale.updateUI();
         exit.updateUI();
         fc.updateUI();
     }
 
     // Enable or disable menuitems
     @Override
     public void setEnabled(boolean condition) {
         revert.setEnabled(condition);
         blur.setEnabled(condition);
         edgeDetect.setEnabled(condition);
         emboss.setEnabled(condition);
         posterize.setEnabled(condition);
         sharpen.setEnabled(condition);
         negative.setEnabled(condition);
         threshold.setEnabled(condition);
         grayScale.setEnabled(condition);
     }
 
     ProcessImage(String title) {
         super(title);
         try {
             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
             System.err.println("Error loading look'n feel!!");
         }
         updateUI();
         scrDim = Toolkit.getDefaultToolkit().getScreenSize();
         open.addActionListener(this);
         revert.addActionListener(this);
         blur.addActionListener(this);
         edgeDetect.addActionListener(this);
         emboss.addActionListener(this);
         posterize.addActionListener(this);
         sharpen.addActionListener(this);
         negative.addActionListener(this);
         threshold.addActionListener(this);
         grayScale.addActionListener(this);
         exit.addActionListener(this);
         JMenuBar mBar = new JMenuBar();
 
         JMenu menu = new JMenu("File");
         menu.addActionListener(this);
 
         //Disable menuitems other than 'Open' & 'Exit"!
         // Since there is no Image to process!!
         revert.setEnabled(false);
         blur.setEnabled(false);
         edgeDetect.setEnabled(false);
         emboss.setEnabled(false);
         posterize.setEnabled(false);
         sharpen.setEnabled(false);
         negative.setEnabled(false);
         threshold.setEnabled(false);
         grayScale.setEnabled(false);
         menu.add(open);
         menu.addSeparator();
         menu.add(revert);
         menu.addSeparator();
         menu.add(exit);
 
         mBar.add(menu);
 
         menu = new JMenu("Effects");
         menu.addActionListener(this);
 
         menu.add(blur);
         menu.add(edgeDetect);
         menu.add(emboss);
         menu.add(negative);
         menu.add(posterize);
         menu.add(sharpen);
         menu.add(threshold);
         menu.add(grayScale);
         mBar.add(menu);
         setJMenuBar(mBar);
 
         JScrollPane scroller = new JScrollPane(label);
         add(scroller, BorderLayout.CENTER);
         add(message, BorderLayout.SOUTH);
         setSize(scrDim.width / 2, scrDim.height / 2);
         setVisible(true);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
     }
     // Blur the Image
 
     public BufferedImage blur() {
         float ninth = 1.0f / 9.0f;
 
         float[] blurKernel = {
             ninth, ninth, ninth,
             ninth, ninth, ninth,
             ninth, ninth, ninth
         };
 
         BufferedImageOp blurOp = new ConvolveOp(new Kernel(3, 3, blurKernel));
         return blurOp.filter(buffImg, null);
     }
     // Sharpen the Image
 
     public BufferedImage sharpen() {
         float[] sharpenKernel = {
             0.0f, -1.0f, 0.0f,
             -1.0f, 5.0f, -1.0f,
             0.0f, -1.0f, -0.0f
         };
 
         BufferedImageOp sharpenOp = new ConvolveOp(new Kernel(3, 3, sharpenKernel));
         return sharpenOp.filter(buffImg, null);
     }
     // Edge detect the Image
 
     public BufferedImage edgeDetect() {
         float[] edgeKernel = {
             0.0f, -1.0f, 0.0f,
             -1.0f, 4.0f, -1.0f,
             0.0f, -1.0f, 0.0f
         };
 
         BufferedImageOp edgeOp = new ConvolveOp(new Kernel(3, 3, edgeKernel));
         return edgeOp.filter(buffImg, null);
     }
     //Convert a Color Image to Gray
 
     public BufferedImage grayScale() {
         //Converting a Color Image to Gray
         //Darker Gray
         ColorSpace cs = ColorSpace.getInstance(
                 ColorSpace.CS_GRAY);
         ColorConvertOp op = new ColorConvertOp(cs, null);
         return op.filter(buffImg, null);
     }
     // Emboss the Image
 
     public BufferedImage emboss(BufferedImage buff) {
         int width = buff.getWidth();
         int height = buff.getHeight();
 
         BufferedImage dst;
         dst = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         // Start changing pixel-by-pixel
         for (int i = 0; i < height; i++) {
             for (int j = 0; j < width; j++) {
                 int upperLeft = 0;
                 int lowerRight = 0;
 
                 if (i > 0 && j > 0) {
                     upperLeft = buff.getRGB(j - 1, i - 1);
                 }
 
                 if (i < height - 1 && j < width - 1) {
                     lowerRight = buff.getRGB(j + 1, i + 1);
                 }
 
                 int redDiff = ((lowerRight >> 16) & 255)
                         - ((upperLeft >> 16) & 255);
 
                 int greenDiff = ((lowerRight >> 8) & 255)
                         - ((upperLeft >> 8) & 255);
 
                 int blueDiff = (lowerRight & 255)
                         - (upperLeft & 255);
 
                 int diff = redDiff;
                 if (Math.abs(greenDiff) > Math.abs(diff)) {
                     diff = greenDiff;
                 }
                 if (Math.abs(blueDiff) > Math.abs(diff)) {
                     diff = blueDiff;
                 }
 
                 int grayColor = 128 + diff;
 
                 if (grayColor > 255) {
                     grayColor = 255;
                 } else if (grayColor < 0) {
                     grayColor = 0;
                 }
 
                 int newColor = (grayColor << 16) + (grayColor << 8)
                         + grayColor;
 
                 dst.setRGB(j, i, newColor);
             }
         }
         return dst;
     }
     // Posterize the Image
 
     public BufferedImage posterize() {
         short[] posterize = new short[256];
 
         for (int i = 0; i < posterize.length; i++) {
             posterize[i] = (short) (i - i % 32);
         }
 
         BufferedImageOp posterizeOp
                 = new LookupOp(new ShortLookupTable(0, posterize), null);
 
         return posterizeOp.filter(buffImg, null);
     }
     // Create Image negative
 
     public BufferedImage negative() {
         short[] invert = new short[256];
 
         for (int i = 0; i < invert.length; i++) {
             invert[i] = (short) (255 - i);
         }
 
         BufferedImageOp invertOp
                 = new LookupOp(new ShortLookupTable(0, invert), null);
 
         return invertOp.filter(buffImg, null);
     }
     // Create Image Threshold
 
     public BufferedImage threshold() {
         short[] threshold = new short[256];
 
         for (int i = 0; i < threshold.length; i++) {
             threshold[i] = (i < 128) ? (short) 0 : (short) 255;
         }
 
         BufferedImageOp thresholdOp = new LookupOp(new ShortLookupTable(0, threshold), null);
 
         return thresholdOp.filter(buffImg, null);
     }
     // Convert Image to BufferedImage
 
     public BufferedImage toBufferedImage(Image image) {
         if (image != null) {
             int width = image.getWidth(null);
             int height = image.getHeight(null);
             BufferedImage buff = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
             Graphics g2 = buff.getGraphics();
             g2.drawImage(image, 0, 0, null);
             g2.dispose();
             return buff;
         }
         return null;
     }
 
     @Override
     public void actionPerformed(ActionEvent ae) {
         Object source = ae.getSource();
         if (source == exit) {
             System.exit(0);
         } else if (source == revert) {
             label.setIcon(new ImageIcon(buffImg));
             message.setText("Image Reverted");
         } else if (source == open) {
             fc.setAccessory(new ImagePreview(fc));
             fc.setPreferredSize(new Dimension(scrDim.width / 2, scrDim.height / 3));
             fc.setAcceptAllFileFilterUsed(false);
             fc.setCurrentDirectory(new File("Samples"));
             final String[] format = getReaderFormats();
             fc.addChoosableFileFilter(new FileFilter() {
 
                 @Override
                 public boolean accept(File file) {
                     String fileName = file.getName();
                     for (int i = 0; i < format.length; i++) {
                         // Show directory & images files only
                         if (fileName.endsWith(format[i]) || file.isDirectory()) {
                             return true;
                         }
                     }
                     return false;
                 }
 
                 // Show something like "*.jpg,*.jpeg,*.bmp,*.tiff,*.gif,*.jpeg2000" etc.,
                 @Override
                 public String getDescription() {
                     String str = "";
                     for (int i = 0; i < format.length; i++) {
                         str += "*." + format[i] + ",";
                     }
                     return str;
                 }
             });
             int result = fc.showOpenDialog(this);
 
             if (result != 0) {
                 return;
             }
 
             File file = fc.getSelectedFile();
             String fileName = file.toString();
             if (file == null) {
                 return;
             } else {
                 //Fetch the Image for processing
                 try {
                     image = ImageIO.read(new File(fileName));
 
                     imgWidth = image.getWidth(null);
                     imgHeight = image.getHeight(null);
 
                 } catch (IOException ioe) {
                     System.err.println("Error loading the Image!!");
                     JOptionPane.showMessageDialog(null, "Not a valid Image!!!", "Error", JOptionPane.ERROR_MESSAGE);
                     //Disable menuitems other than 'Open' & 'Exit"!
                     // Since there is no Image to process!!
                     setEnabled(false);
                 }
                 //Enable the MenuItems now!
                 setEnabled(true);
                 // Convert Image to BufferedIage
                 buffImg = toBufferedImage(image);
                 // Update the label
                 label.setIcon(new ImageIcon(buffImg));
                 message.setText("Ready");
                 pack();
             }
         } else if (source == blur) {
             label.setIcon(new ImageIcon(blur()));
             message.setText("Image Blurred");
 
         } else if (source == edgeDetect) {
             label.setIcon(new ImageIcon(edgeDetect()));
             message.setText("Image EdgeDetected");
 
         } else if (source == sharpen) {
             label.setIcon(new ImageIcon(sharpen()));
             message.setText("Image Sharpened");
 
         } else if (source == negative) {
             label.setIcon(new ImageIcon(negative()));
             message.setText("Image Negative");
 
         } else if (source == threshold) {
             label.setIcon(new ImageIcon(threshold()));
             message.setText("Image Threshold");
 
         } else if (source == emboss) {
             label.setIcon(new ImageIcon(emboss(buffImg)));
             message.setText("Image Embossed");
 
         } else if (source == posterize) {
             label.setIcon(new ImageIcon(posterize()));
             message.setText("Image Posterized");
 
         } else {   // GrayScale
             label.setIcon(new ImageIcon(grayScale()));
             message.setText("Image GrayScaled");
         }
     }
 
     public static void main(String[] args) {
         SwingUtilities.invokeLater(new Runnable() {
 
             @Override
             public void run() {
                 new ProcessImage("Process Image");
             }
         });
     }
 }
 
 // Utility class to show ImagePreview 
 
 class ImagePreview extends JComponent implements PropertyChangeListener {
 
     ImageIcon thumbnail = null;
     int width = 180;
 
     public ImagePreview(JFileChooser fc) {
         setPreferredSize(new Dimension(width, 50));
         fc.addPropertyChangeListener(this);
         setBorder(new BevelBorder(BevelBorder.LOWERED));
     }
 
     public void loadImage(File f) {
         if (f == null) {
             thumbnail = null;
         } else {
             ImageIcon tmpIcon = new ImageIcon(getImage(f.getPath()));
             if (tmpIcon.getIconWidth() > width) {
                 thumbnail = new ImageIcon(
                         tmpIcon.getImage().getScaledInstance(width, -1, Image.SCALE_SMOOTH));
             } else {
                 thumbnail = tmpIcon;
             }
         }
     }
 
     public BufferedImage getImage(String fileName) {
         try {
             return ImageIO.read(new File(fileName));
         } catch (IOException ioe) {
             System.err.println("Error loading Image!!");
         }
         return null;
     }
 
     @Override
     public void propertyChange(PropertyChangeEvent e) {
         String prop = e.getPropertyName();
         if (prop == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY) {
             if (isShowing()) {
                 loadImage((File) e.getNewValue());
                 repaint();
             }
         }
     }
 
     @Override
     public void paintComponent(Graphics g) {
         super.paintComponent(g);
         if (thumbnail != null) {
             int x = getWidth() / 2 - thumbnail.getIconWidth() / 2;
             int y = getHeight() / 2 - thumbnail.getIconHeight() / 2;
             if (y < 0) {
                 y = 0;
             }
 
             if (x < 5) {
                 x = 5;
             }
             thumbnail.paintIcon(this, g, x, y);
         }
     }
 }
```

*s2.postimg.org/jqasjwn1x/Process_Image.jpg

We define various methods like blur(), sharpen(), edgeDetect(), grayScale(), emboss(),
posterize(), threshold() etc.,
We use a Label to display the Image.
Click on the menuitem Open & select a Image. You can apply the various Image filters.
If you want to revert to the original Image, select Revert from the File menu.
There are books available that discusses Image processing in detail.
You can search through amazon.in for various books on Image processing.

*Level -III*


Q) Write a program to implement a PaintBrush (similar to Windows's PaintBrush) using Java?

Ans) The code is right below!!


```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

public class Airbrush extends JFrame implements ActionListener {

    private Image brushes[];
    private int brushIndex;
    private JButton clearBtn;
    private Image offsrceen;
    private Graphics gOffscreen;

    private final int BRUSH_SIZE = 100;
    private final int BRUSH_AREA = BRUSH_SIZE * BRUSH_SIZE;
    private final int RED = 0;
    private final int GREEN = 1;
    private final int BLUE = 2;
    private final int YELLOW = 3;
    private final int MAGENTA = 4;
    private final int CYAN = 5;
    private final int BLACK = 6;
    private final int GRAY = 7;
    private final int WHITE = 8;
    private Color[] color = {Color.red, Color.green, Color.blue, Color.yellow, Color.magenta, Color.cyan, Color.black, Color.gray, Color.white};
    private String[] colorName = {"Red", "Green", "Blue", "Yellow", "Magenta", "Cyan", "Black", "Gray", "White"};
    private Dimension scrDim;
    private JButton[] button = new JButton[9];
    private int bIndex = 0;

    Airbrush() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
        }
        int index, i, j;
        int alpha;
        MemoryImageSource mis;

        // Handle our own mouse events.
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                mouseDragged(e);
            }
        });
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                int x = e.getX() - BRUSH_SIZE / 2;
                int y = e.getY() - BRUSH_SIZE / 2;
                Image brush = brushes[bIndex];
                gOffscreen.drawImage(brush, x, y, null);
                repaint();
            }
        });

        Panel top = new Panel();
        top.setBackground(Color.white);
        top.setLayout(new FlowLayout());
        for (int k = 0; k < button.length; k++) {
            button[k] = new ColorButton(color[k]);
            button[k].setToolTipText(colorName[k]);
            button[k].addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    Object source = e.getSource();
                    for (int l = 0; l < button.length; l++) {
                        if (source == button[l]) {
                            bIndex = l;
                        }
                    }
                }
            });
            top.add(button[k]);
        }
        clearBtn = new JButton("Clear");
        clearBtn.addActionListener(this);
        top.add(clearBtn);
        add(top, BorderLayout.NORTH);

        // Populate arrays of ints.
        index = 0;
        int[][] sources = new int[9][BRUSH_AREA];
        for (j = 0; j < BRUSH_SIZE; j++) {
            for (i = 0; i < BRUSH_SIZE; i++) {
                alpha = getAlpha(i, j);
                alpha <<= 24;
                sources[RED][index] = 0x00ff0000 + alpha;
                sources[GREEN][index] = 0x0000ff00 + alpha;
                sources[BLUE][index] = 0x000000ff + alpha;
                sources[YELLOW][index] = 0x00ffff00 + alpha;
                sources[MAGENTA][index] = 0x00ff00ff + alpha;
                sources[CYAN][index] = 0x0000ffff + alpha;
                sources[BLACK][index] = 0x00000000 + alpha;
                sources[GRAY][index] = 0x00b8b8b8 + alpha;
                sources[WHITE][index] = 0x00ffffff + alpha;
                index++;
            }
        }

        // Construct images from the memory sources.
        brushes = new Image[9];
        for (i = 0; i < 9; i++) {
            mis = new MemoryImageSource(BRUSH_SIZE, BRUSH_SIZE,
                    sources[i], 0, BRUSH_SIZE);
            brushes[i] = createImage(mis);
        }

        setTitle("Airbrush Effects");
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2 + 150, scrDim.height);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Override addNotify to create a Peer (for an application)
    @Override
    public void addNotify() {
        super.addNotify();
        // Build offscreen image for caching picture.
        int width = scrDim.width;
        int height = scrDim.height;
        offsrceen = createImage(width, height);
        gOffscreen = offsrceen.getGraphics();
        gOffscreen.setColor(Color.white);
        gOffscreen.fillRect(0, 0, width, height);
    }

    int getAlpha(int x, int y) {
        double deltaX = (double) (x - BRUSH_SIZE / 2);
        double deltaY = (double) (y - BRUSH_SIZE / 2);
        double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        double fracDistance = distance / (BRUSH_SIZE / 2);
        if (fracDistance > 1.0) {
            fracDistance = 1.0;
        }
        fracDistance = 1.0 - fracDistance;
        fracDistance = Math.pow(fracDistance, 6);
        return (int) (255 * fracDistance);
    }

    // Reduce flickering
    // Override update()
    @Override
    public void update(Graphics g) {
        paint(g);
    }

    @Override
    public void paint(Graphics g) {
        if (offsrceen != null) {
            g.drawImage(offsrceen, 0, 0, this);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == clearBtn) {
            gOffscreen.setColor(Color.white);
            gOffscreen.fillRect(0, 0, getSize().width, getSize().height);
            repaint();
        }
    }

    public static void main(String[] arg) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Airbrush();
            }
        });
    }
    
    // ColorButton to display Color buttons 
    class ColorButton extends JButton {

        Color color;
        final int width = 40, height = 20;

        ColorButton(Color myColor) {
            color = myColor;
            setPreferredSize(new Dimension(width, height));
            setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
            setDoubleBuffered(true);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillRect(0, 0, width, height);
        }
    }
}
```

*s1.postimg.org/z5etfjk3v/Air_Brush.jpg

We examine the code in detail.
First we override addNotify() to create a peer for the application.
We create a BufferedImage using the createImage() method.
We implement the methods to do when the Mouse is dragged.
We use the MemoryImageSource class to draw various brushes.
We use the hexadecimal values to represent various colors.

Click on a color button & drag the cursor on the Screen to draw a
AirBrush pattern. You can go on clicking on a Color button & dragging
the Cursor to produce a AirBrush effect.
Finally click the clear button, if you want to clear the Canvas.

Q) Write a Program to display the Sizes (in MB) of various directories in a particular directory.
  Show them in a PieChart . Showing a maximum of 9 entries.

Ans) You do this as an excercise!!


Q) Write a program to draw a Mandelbrot pattern using MemoryImageSource ?

Ans) The code is here!!


```
/*
 * This example demonstrates how to convert a byte array of pixel values that are indices to a color table into an Image.
 In particular, the example generates the Mandelbrot set in a byte buffer and uses the MemoryImageSource image producer to
 create an image from the pixel data in the byte buffer. A 16-color index color model is used to represent the pixel colors.
 *
 */
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

// Instantiate this class and then use the draw() method to draw the
// generated on the graphics context.
public class Mandelbrot {
    // Holds the generated image

    private Image image;
    private MemoryImageSource mis;
    // 16-color model
    private final ColorModel colorModel = generateColorModel();

    public Mandelbrot(int width, int height) {
        // Initialize with default location
        this(width, height, new Rectangle2D.Float(-2.0f, -1.2f, 3.2f, 2.4f));
    }

    public Mandelbrot(int width, int height, Rectangle2D.Float loc) {
        mis = new MemoryImageSource(width, height, colorModel, generatePixels(width, height, loc), 0, width);
        image = Toolkit.getDefaultToolkit().createImage(mis);
    }

    public void draw(Graphics g, int x, int y) {
        g.drawImage(image, x, y, null);
    }

    private byte[] generatePixels(int width, int height, Rectangle2D.Float loc) {
        float xmin = loc.x;
        float ymin = loc.y;
        float xmax = loc.x + loc.width;
        float ymax = loc.y + loc.height;

        byte[] pixels = new byte[width * height];
        int pIx = 0;
        float[] p = new float[width];
        float q = ymin;
        float dp = (xmax - xmin) / width;
        float dq = (ymax - ymin) / height;

        p[0] = xmin;
        for (int i = 1; i < width; i++) {
            p[i] = p[i - 1] + dp;
        }

        for (int r = 0; r < height; r++) {
            for (int c = 0; c < width; c++) {
                int color = 1;
                float x = 0.0f;
                float y = 0.0f;
                float xsqr = 0.0f;
                float ysqr = 0.0f;
                do {
                    xsqr = x * x;
                    ysqr = y * y;
                    y = 2 * x * y + q;
                    x = xsqr - ysqr + p[c];
                    color++;
                } while (color < 512 && xsqr + ysqr < 4);
                pixels[pIx++] = (byte) (color % 16);
            }
            q += dq;
        }
        return pixels;
    }

    private static ColorModel generateColorModel() {
        // Generate 16-color model
        byte[] r = new byte[16];
        byte[] g = new byte[16];
        byte[] b = new byte[16];
        // Assign values to r, g, b
        r[0] = 0;
        g[0] = 0;
        b[0] = 0;
        r[1] = 0;
        g[1] = 0;
        b[1] = (byte) 192;
        r[2] = 0;
        g[2] = 0;
        b[2] = (byte) 255;
        r[3] = 0;
        g[3] = (byte) 192;
        b[3] = 0;
        r[4] = 0;
        g[4] = (byte) 255;
        b[4] = 0;
        r[5] = 0;
        g[5] = (byte) 192;
        b[5] = (byte) 192;
        r[6] = 0;
        g[6] = (byte) 255;
        b[6] = (byte) 255;
        r[7] = (byte) 192;
        g[7] = 0;
        b[7] = 0;
        r[8] = (byte) 255;
        g[8] = 0;
        b[8] = 0;
        r[9] = (byte) 192;
        g[9] = 0;
        b[9] = (byte) 192;
        r[10] = (byte) 255;
        g[10] = 0;
        b[10] = (byte) 255;
        r[11] = (byte) 192;
        g[11] = (byte) 192;
        b[11] = 0;
        r[12] = (byte) 255;
        g[12] = (byte) 255;
        b[12] = 0;
        r[13] = (byte) 80;
        g[13] = (byte) 80;
        b[13] = (byte) 80;
        r[14] = (byte) 192;
        g[14] = (byte) 192;
        b[14] = (byte) 192;
        r[15] = (byte) 255;
        g[15] = (byte) 255;
        b[15] = (byte) 255;
        return new IndexColorModel(4, 16, r, g, b);
    }

    // Drawing Canvas
    static class Canvas extends JPanel {

        Mandelbrot mandelbrot;

        Canvas() {
            // Add a listener for resize events
            addComponentListener(new ComponentAdapter() {
                // This method is called when the component's size changes

                @Override
                public void componentResized(final ComponentEvent evt) {

                    Component comp = (Component) evt.getSource();
                    // Get new size
                    Dimension newSize = comp.getSize();
                    // Regenerate the image
                    mandelbrot = new Mandelbrot(newSize.width, newSize.height);
                    comp.repaint();
                }
            });
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            if (mandelbrot != null) {   // Draw it
                mandelbrot.draw(g2d, 0, 0);
            } else {   // Show a message status
                g2d.setColor(Color.blue.darker().darker());
                g2d.fillRect(0, 0, getWidth(), getHeight());
                Font font = g.getFont();
                String fontName = font.getName();
                int size = font.getSize();
                font = new Font(fontName, Font.BOLD, size + 5);
                g2d.setColor(Color.yellow.darker());
                g2d.setFont(font);
                // Center the message
                g2d.drawString("Calculating, Please wait...", getWidth() / 2 - 50, getHeight() / 2);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Mandelbrot");
                frame.add(new Canvas());
                Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
                //Reduce the app size by half
                frame.setSize(dim.width / 2 + 150, dim.height / 2 + 150);
                // Center the frame
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}
```

[img=*s28.postimg.org/6d8ikai6h/Mandelbrot.jpg]

We create a class called Mandelbrot to implement the Mandelbrot pattern.
The method generateColorModel() creates a 16-color model ColorModel.
The method generatePixels() generates pixels of a array of bytes.
The draw() method draws the MemoryImageSource on the screen.
We create a class called Canvas to draw the Mandelbrot pattern.

Q) Write a program to list the directory contents in the List form (JList).
  Include a ComboBox showing various wild card patterns. Also include a
  Search button to search for a particular file pattern?

Ans) Do it yourself as an exercise!!

Q) Write a draw an Arc( fill Arc, draw Arc) to the specified degress (0 to 360)
   Use Java Swing to draw a Red color Arc. ?

Ans) Here is the code!!


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * An interactive test of the Graphics.drawArc and Graphics.fillArc routines.
 * Can be run either as a standalone application by typing "java ArcDemo" or as
 * an applet in the AppletViewer.
 */
public class ArcDemo extends JFrame {

    ArcControls controls;   // The controls for marking and filling arcs
    ArcCanvas canvas;       // The drawing area to display arcs

    public ArcDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        canvas = new ArcCanvas();
        add("Center", canvas);
        add("South", controls = new ArcControls(canvas));
        setSize(scrDim.height / 2 + 100, scrDim.height / 2 + 100);
        setTitle("ArcDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ArcDemo();
            }
        });
    }
}

class ArcCanvas extends JPanel {

    int startAngle = 0;
    int extent = 45;
    boolean filled = false;
    Font font = new Font("Serif", Font.PLAIN, 12);

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Get the Graphics
        Graphics2D g2d = (Graphics2D) g;
        // Best appearance at the cost of performance
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        Rectangle r = getBounds();
        int hlines = r.height / 10;
        int vlines = r.width / 10;

        g2d.setColor(Color.pink);
        for (int i = 1; i <= hlines; i++) {
            g2d.drawLine(0, i * 10, r.width, i * 10);
        }
        for (int i = 1; i <= vlines; i++) {
            g2d.drawLine(i * 10, 0, i * 10, r.height);
        }

        g2d.setColor(Color.red);
        if (filled) {
            g2d.fillArc(0, 0, r.width - 1, r.height - 1, startAngle, extent);
        } else {
            g2d.drawArc(0, 0, r.width - 1, r.height - 1, startAngle, extent);
        }

        g2d.setColor(Color.black);
        g2d.setFont(font);
        g2d.drawLine(0, r.height / 2, r.width, r.height / 2);
        g2d.drawLine(r.width / 2, 0, r.width / 2, r.height);
        g2d.drawLine(0, 0, r.width, r.height);
        g2d.drawLine(r.width, 0, 0, r.height);
        int sx = 10;
        int sy = r.height - 28;
        g2d.drawString("Start = " + startAngle, sx, sy);
        g2d.drawString("Extent = " + extent, sx, sy + 14);
    }

    public void redraw(boolean filled, int start, int extent) {
        this.filled = filled;
        this.startAngle = start;
        this.extent = extent;
        repaint();
    }
}

class ArcControls extends JPanel implements ActionListener {

    JTextField startTF;
    JTextField extentTF;
    ArcCanvas canvas;

    public ArcControls(ArcCanvas canvas) {
        JButton b = null;

        this.canvas = canvas;
        add(startTF = new IntegerTextField("0", 4));
        add(extentTF = new IntegerTextField("45", 4));
        b = new JButton("Fill");
        b.addActionListener(this);
        add(b);
        b = new JButton("Draw");
        b.addActionListener(this);
        add(b);
    }

    @Override
    public void actionPerformed(ActionEvent ev) {
        String label = ev.getActionCommand();

        int start, extent;
        try {
            start = Integer.parseInt(startTF.getText().trim());
        } catch (NumberFormatException ignored) {
            start = 0;
        }
        try {
            extent = Integer.parseInt(extentTF.getText().trim());
        } catch (NumberFormatException ignored) {
            extent = 0;
        }

        canvas.redraw(label.equals("Fill"), start, extent);
    }
}

class IntegerTextField extends JTextField {

    String oldText = null;

    public IntegerTextField(String text, int columns) {
        super(text, columns);
        enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.TEXT_EVENT_MASK);
        oldText = getText();
    }

    // Consume non-digit KeyTyped events
    // Note that processTextEvent kind of eliminates the need for this
    // function, but this is neater, since ideally, it would prevent
    // the text from appearing at all.  Sigh.  See bugid 4100317/4114565.
    //
    @Override
    protected void processEvent(AWTEvent evt) {
        int id = evt.getID();
        if (id != KeyEvent.KEY_TYPED) {
            super.processEvent(evt);
            return;
        }

        KeyEvent kevt = (KeyEvent) evt;
        char c = kevt.getKeyChar();

        // Digits, backspace, and delete are okay
        // Note that the minus sign is allowed, but not the decimal
        if (Character.isDigit(c) || (c == '\b') || (c == '\u007f') || (c
                == '\u002d')) {
            super.processEvent(evt);
            return;
        }

        Toolkit.getDefaultToolkit().beep();
        kevt.consume();
    }

    // Should consume TextEvents for non-integer Strings
    // Store away the text in the tf for every TextEvent
    // so we can revert to it on a TextEvent (paste, or
    // legal key in the wrong location) with bad text
    //
    protected void processTextEvent(TextEvent te) {
        // The empty string is okay, too
        String newText = getText();
        if (newText.equals("") || textIsInteger(newText)) {
            oldText = newText;
            //super.processTextEvent(te);
            return;
        }

        Toolkit.getDefaultToolkit().beep();
        setText(oldText);
    }

    // Returns true for Integers (zero and negative
    // values are allowed).
    // Note that the empty string is not allowed.
    //
    private boolean textIsInteger(String textToCheck) {

        try {
            Integer.parseInt(textToCheck, 10);
            return true;
        } catch (NumberFormatException ignored) {
            return false;
        }
    }
}
```

*s8.postimg.org/ncxxdznld/Arc_Demo.jpg

The main class is the ArcCanvas that renders the Arc on the screen.
The two TextFields represent the starting angle & the extent angle
Suppose you specify the starting angle as 0 & the extent as 180.
Click on the Fill button . The program renders an filled Arc in Red color.
If you click on the Draw button, the program draws the Arc in Red color.
The class IntegerTextField is a Custom TextField to validate the user input!!

Q) Write a program to browse the Images in a directory ?
   The program should have various buttons browse, first, previous, next, last, exit.

   browse - To select a particular directory

   first - Displays the 1st Image

   previous - Displays the previous Image

   next - Displays the next Image

   last - Displays the last Image

   exit - Exits the application

Ans) Here is the code !!

ImageBrowser.java


```
// Image Browser
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageBrowser extends JFrame implements ActionListener {

    private JButton browse, first, previous, next, last, close;
    private JLabel label;
    private JFileChooser fChooser;
    private File file;
    private String directory;
    private String[] imgName;
    private BufferedImage image;
    private int index = 0;
    private JScrollPane scrollPane;
    private Image[] images = new Image[10];
    private ImageStrip imageStrip = new ImageStrip();

    @Override
    public void setEnabled(boolean condition) {
        first.setEnabled(condition);
        previous.setEnabled(condition);
        next.setEnabled(condition);
        last.setEnabled(condition);
    }

    public ImageBrowser() {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }

        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        label = new JLabel();
        label.setVerticalAlignment(SwingConstants.CENTER);
        label.setHorizontalAlignment(SwingConstants.CENTER);
        fChooser = new JFileChooser(".");
        fChooser.setPreferredSize(new Dimension(600, 450));
        //create the Buttons
        browse = new JButton("Browse");
        browse.setToolTipText("Browse");
        first = new JButton("First");
        first.setToolTipText("First");
        previous = new JButton("Previous");
        previous.setToolTipText("Previous");
        next = new JButton("Next");
        next.setToolTipText("Next");
        last = new JButton("Last");
        last.setToolTipText("Last");
        close = new JButton("Quit");
        close.setToolTipText("Quit");
        setEnabled(false);
        // Add listener to the Buttons
        browse.addActionListener(this);
        first.addActionListener(this);
        previous.addActionListener(this);
        next.addActionListener(this);
        last.addActionListener(this);
        close.addActionListener(this);

        // Add the buttons to the Panel
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        
        panel.add(browse);
        panel.add(first);
        panel.add(previous);
        panel.add(next);
        panel.add(last);
        panel.add(close);

        scrollPane = new JScrollPane(label);
        imageStrip.setPreferredSize(new Dimension(scrDim.width / 2, 80));
        add(imageStrip, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
        add(panel, BorderLayout.SOUTH);
        setTitle("Image Browser");
        setSize(scrDim.width / 2 + 230, scrDim.height);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    //Load Images faster
    public BufferedImage getImage(String fileName) {
        if (fileName.endsWith("jpg") || fileName.endsWith("png") || fileName.endsWith("gif")) {
            label.setText("");
            setTitle("ImageBrowser/ " + fileName.substring(fileName.lastIndexOf("/") + 1));
            return toBufferedImage(new ImageIcon(fileName).getImage());
        }
        try {
            label.setText("");
            setTitle("ImageBrowser/ " + fileName.substring(fileName.lastIndexOf("/") + 1));
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            label.setText("Error loading Image!!");
        }
        return null;
    }

    public BufferedImage toBufferedImage(Image image) {
        if (image != null) {
            BufferedImage buff = new BufferedImage(image.getWidth(this), image.getHeight(this), BufferedImage.TYPE_INT_RGB);
            Graphics gr = buff.getGraphics();
            gr.drawImage(image, 0, 0, null);
            gr.dispose();
            return buff;
        }
        return null;
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();
        if (source == browse) {
            // Browse
            fChooser.setDialogTitle("Browse");
            fChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int result = fChooser.showOpenDialog(null);
            if (result != 0) {
                return;
            }
            file = fChooser.getSelectedFile();
            if (file == null) {
                return;
            } else {
                directory = file.toString();
                // Filter out only Images
                imgName = new File(directory).list(new FilenameFilter() {

                    String[] readFormat = ImageIO.getReaderFormatNames();

                    @Override
                    public boolean accept(File dir, String name) {
                        for (int i = 0; i < readFormat.length; i++) {
                            if (name.endsWith(readFormat[i])) {
                                return true;
                            }
                        }
                        return false;
                    }
                });
                if (imgName.length > 0) {
                    setEnabled(true);
                    previous.setEnabled(false);
                    next.setEnabled(true);
                    first.setEnabled(true);
                    last.setEnabled(true);
                    directory = directory.replace('\\', '/');
                    directory = directory + "/";
                    image = getImage(directory + imgName[0]);
                    // Display the Image
                    if (image != null) {
                        label.setIcon(new ImageIcon(image));
                    }

                    //Get the Images for the Image strip
                    for (int i = 0; i < 10; i++) {
                        images[i] = getImage(directory + imgName[i]);
                        images[i] = images[i].getScaledInstance(100, 70, Image.SCALE_SMOOTH);
                    }
                    imageStrip.setStrip(images);
                    //Set the first Images's title
                    setTitle("ImageBrowser/" + imgName[0]);

                } else {
                    JOptionPane.showMessageDialog(null, "Oops, No Image found!!!");
                    label.setIcon(null);
                    previous.setEnabled(false);
                    next.setEnabled(false);
                    first.setEnabled(false);
                    last.setEnabled(false);
                    setTitle("ImageBrowser");
                    setEnabled(false);
                }
            }

        } else if (source == first) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    index = 0;
                    image = getImage(directory + imgName[index]);
                    if (image != null) {
                        label.setIcon(new ImageIcon(image));
                    }
                    next.setEnabled(true);
                    previous.setEnabled(false);
                }
            }).start();

        }
        else if (source == previous) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        next.setEnabled(true);
                        if (index == 1) {
                            previous.setEnabled(false);
                        } else if (index > 0) {
                            previous.setEnabled(true);
                        }

                        image = getImage(directory + imgName[--index]);
                        if (image != null) {
                            label.setIcon(new ImageIcon(image));
                        }
                    } catch (Exception e) {
                        index = 0;
                    }
                }
            }).start();

        } else if (source == next) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        previous.setEnabled(true);
                        if (index == imgName.length - 2) {
                            next.setEnabled(false);
                        } else if (index < imgName.length - 1) {
                            next.setEnabled(true);
                        }
                        image = getImage(directory + imgName[++index]);
                        if (image != null) {
                            label.setIcon(new ImageIcon(image));
                        }

                    } catch (Exception e) {
                        index = imgName.length - 1;
                    }
                }
            }).start();

        }
        else if (source == last) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    index = imgName.length - 1;
                    image = getImage(directory + imgName[index]);
                    if (image != null) {
                        label.setIcon(new ImageIcon(image));
                    }
                    next.setEnabled(false);
                    previous.setEnabled(true);
                }
            }).start();

        } else {
            dispose();
            System.gc();
            System.exit(0);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ImageBrowser();
            }
        });
    }

    // ImageStrip Panel
    class ImageStrip extends JPanel {

        Image[] imgStrip = new Image[10];

        void setStrip(Image[] images) {
            imgStrip = new Image[images.length];
            for (int i = 0; i < images.length; i++) {
                imgStrip[i] = images[i];
            }
            repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            // Set RenderingHints properties
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            int x = 5, y = 5;
            for (int i = 0; i < imgStrip.length; i++) {
                if (imgStrip[i] != null) {
                    g2d.drawImage(imgStrip[i], x, y, this);
                }
                x += 100;
            }
        }
    }
}
```

*s22.postimg.org/k0b4x803h/Image_Browser.jpg

The getImage() method fetches the Image from the disk.
We filter out the Images using the FilenameFilter after the user selects a particular directory.
We display the ImagesStrip on the Top.
The first button displays the first Image in the directory, last button displays the last.
The previous button displays the previous Image. The next button displays the next Image.
Simple program to browse the Images in a directory!!

Q) Write a program to get a particular number (say 1000, 5525) display the output in Roman number?

If the input is 1000, display One Thousand only, If the input is 5525, display Five Thousand Five Hundred and Twenty Five.

Ans) You do this as an Exercise!!

Q) Write a program to perform Image zoom operation using Mouse wheel listener?

Ans.


```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.NumberFormat;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MouseWheelDemo extends JFrame {

    private BufferedImage bi;
    private int zoom = 0;
    private String path = "Images5/";
    private File directory = new File(path);
    private final String filename;
    private NumberFormat perc = NumberFormat.getPercentInstance();
    private double factor;
    private static final double ZOOM_AMOUNT = 1.1;
    private JLabel label = new JLabel();
    private int imgWidth, imgHeight;
    private BufferedImage buff;
    private Graphics2D g2d;

    private void sizeToZoom() {
        factor = Math.pow(ZOOM_AMOUNT, zoom);
        setTitle("MouseWheelListener - Image Zoom" + " (" + perc.format(factor) + ")");
        // Possible NullPointerException needs to be caught!!
        try {
            label.setIcon(new ImageIcon(zoomIcon()));
        } catch (Exception e) {
            // Do nothing
        }
    }

    public BufferedImage zoomIcon() {
        // New width & height as per Mouse wheel position
        int newWidth = 0;
        int newHeight = 0;
        newWidth = (int) (imgWidth * factor);
        newHeight = (int) (imgHeight * factor);
        // If the Image's width or height is '0', throws IllegalArgumentException!!
        if (newWidth > 0 && newHeight > 0) {
            buff = new BufferedImage(newWidth, newHeight, BufferedImage.TRANSLUCENT);
            g2d = buff.createGraphics();
            // Draw the Scaled Image
            g2d.drawImage(bi, 0, 0, newWidth, newHeight, this);
            return buff;
        }
        return null;
    }

    public MouseWheelDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
        }
        String[] name = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        int rand = (int) (name.length * Math.random());
        filename = name[rand];
        try {
            bi = ImageIO.read(new File(path + filename));
            if (bi != null) {
                imgWidth = bi.getWidth();
                imgHeight = bi.getHeight();
            }
        } catch (IOException e) {
        }
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        label.setIcon(new ImageIcon(bi));
        JScrollPane scroller = new JScrollPane(label);
        scroller.getViewport().setBackground(Color.pink);
        add(scroller);
        sizeToZoom();

        label.addMouseWheelListener(new MouseWheelListener() {

            @Override
            public void mouseWheelMoved(final MouseWheelEvent mwe) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        int steps = mwe.getWheelRotation();
                        zoom += steps;
                        sizeToZoom();
                    }
                }).start();
            }
        });
        setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    public static void main(final String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MouseWheelDemo();
            }
        });
    }
}
```

*s30.postimg.org/jz06vv2x9/Mouse_Wheel_Demo.jpg

Here we add a Mouse wheel listener to the JLabel , we get the wheel rotation using getWheelRotation() method.
The method sizeToZoom() calculates the zoom factor , & finally the method zoomIcon() zooms the Image to the zoom factor,
update the JLabel.

Q) Write a program to display the table contents (RDBMS) in a table format?

Ans. Here is a code (split into several files for readability) that does just that.

JDBCAdapter.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

/**
 * An adaptor, transforming the JDBC interface to the TableModel interface.
 *
 * @author Philip Milne
 */
   [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public class JDBCAdapter extends AbstractTableModel {

    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;
    private String[] columnNames = {};
    private List<List<Object>> rows = new ArrayList<>();
    private ResultSetMetaData metaData;

    public JDBCAdapter(String url, String driverName,
            String user, String passwd) {
        try {
            Class.forName(driverName);
            System.out.println("Opening db connection");

            connection = DriverManager.getConnection(url, user, passwd);
            statement = connection.createStatement();
        } catch (ClassNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Cannot find the database driver classes.", "Error", JOptionPane.WARNING_MESSAGE);

        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Cannot connect to this database!!", "Error", JOptionPane.WARNING_MESSAGE);
        }
    }

    public void executeQuery(String query) {
        if (connection == null || statement == null) {
            JOptionPane.showMessageDialog(null, "There is no database to execute the query!!", "Error", JOptionPane.WARNING_MESSAGE);
            return;
        }
        try {
            resultSet = statement.executeQuery(query);
            metaData = resultSet.getMetaData();

            int numberOfColumns = metaData.getColumnCount();
            columnNames = new String[numberOfColumns];
            // Get the column names and cache them.
            // Then we can close the connection.
            for (int column = 0; column < numberOfColumns; column++) {
                columnNames[column] = metaData.getColumnLabel(column + 1);
            }

            // Get all rows.
            rows = new ArrayList<>();
            while (resultSet.next()) {
                List<Object> newRow = new ArrayList<>();
                for (int i = 1; i <= getColumnCount(); i++) {
                    newRow.add(resultSet.getObject(i));
                }
                rows.add(newRow);
            }
            //  close(); Need to copy the metaData, bug in jdbc:odbc driver.

            // Tell the listeners a new table has arrived.
            fireTableChanged(null);
        } catch (SQLException ex) {
            System.err.println(ex);
        }
    }

    public void close() throws SQLException {
        System.out.println("Closing db connection");
        resultSet.close();
        statement.close();
        connection.close();
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    //////////////////////////////////////////////////////////////////////////
    //
    //             Implementation of the TableModel Interface
    //
    //////////////////////////////////////////////////////////////////////////
    // MetaData
    @Override
    public String getColumnName(int column) {
        if (columnNames[column] != null) {
            return columnNames[column];
        } else {
            return "";
        }
    }

    @Override
    public Class<?> getColumnClass(int column) {
        int type;
        try {
            type = metaData.getColumnType(column + 1);
        } catch (SQLException e) {
            return super.getColumnClass(column);
        }

        switch (type) {
            case Types.CHAR:
            case Types.VARCHAR:
            case Types.LONGVARCHAR:
                return String.class;

            case Types.BIT:
                return Boolean.class;

            case Types.TINYINT:
            case Types.SMALLINT:
            case Types.INTEGER:
                return Integer.class;

            case Types.BIGINT:
                return Long.class;

            case Types.FLOAT:
            case Types.DOUBLE:
                return Double.class;

            case Types.DATE:
                return java.sql.Date.class;

            default:
                return Object.class;
        }
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        try {
            return metaData.isWritable(column + 1);
        } catch (SQLException e) {
            return false;
        }
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    // Data methods
    @Override
    public int getRowCount() {
        return rows.size();
    }

    @Override
    public Object getValueAt(int aRow, int aColumn) {
        List<Object> row = rows.get(aRow);
        return row.get(aColumn);
    }

    public String dbRepresentation(int column, Object value) {
        int type;

        if (value == null) {
            return "null";
        }

        try {
            type = metaData.getColumnType(column + 1);
        } catch (SQLException e) {
            return value.toString();
        }

        switch (type) {
            case Types.INTEGER:
            case Types.DOUBLE:
            case Types.FLOAT:
                return value.toString();
            case Types.BIT:
                return ((Boolean) value).booleanValue() ? "1" : "0";
            case Types.DATE:
                return value.toString(); // This will need some conversion.
            default:
                return "\"" + value.toString() + "\"";
        }

    }

    @Override
    public void setValueAt(Object value, int row, int column) {
        try {
            String tableName = metaData.getTableName(column + 1);
            // Some of the drivers seem buggy, tableName should not be null.
            if (tableName == null) {
                System.out.println("Table name returned null.");
            }
            String columnName = getColumnName(column);
            String query
                    = "update " + tableName + " set " + columnName + " = "
                    + dbRepresentation(column, value) + " where ";
            // We don't have a model of the schema so we don't know the
            // primary keys or which columns to lock on. To demonstrate
            // that editing is possible, we'll just lock on everything.
            for (int col = 0; col < getColumnCount(); col++) {
                String colName = getColumnName(col);
                if (colName.equals("")) {
                    continue;
                }
                if (col != 0) {
                    query = query + " and ";
                }
                query = query + colName + " = " + dbRepresentation(col,
                        getValueAt(row, col));
            }
            System.out.println(query);
            System.out.println("Not sending update to database");
            // statement.executeQuery(query);
        } catch (SQLException e) {
            System.err.println("Update failed");
        }
        List<Object> dataRow = rows.get(row);
        dataRow.set(column, value);

    }
}
```

TableExample.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
/**
 * A a UI around the JDBCAdaptor, allowing database data to be interactively
 * fetched, sorted and displayed using Swing.
 *
 * NOTE: This example uses a modal dialog via the static convenience methods in
 * the JOptionPane. Use of modal dialogs requires JDK 1.1.4 or greater.
 *
 * @author Philip Milne
 */
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.BevelBorder;

public final class TableExample implements LayoutManager {

    private static String[] ConnectOptionNames = {"Connect"};
    private static String ConnectTitle = "Connection Information";
    private Dimension origin = new Dimension(0, 0);
    private JButton fetchButton;
    private JButton showConnectionInfoButton;
    private JPanel connectionPanel;
    private JFrame frame; // The query/results window.
    private JLabel userNameLabel;
    private JTextField userNameField;
    private JLabel passwordLabel;
    private JTextField passwordField;
    private JTextArea queryTextArea;
    private JComponent queryAggregate;
    private JLabel serverLabel;
    private JTextField serverField;
    private JLabel driverLabel;
    private JTextField driverField;
    private JPanel mainPanel;
    private TableSorter sorter;
    private JDBCAdapter dataBase;
    private JScrollPane tableAggregate;

    /**
     * Brigs up a JDialog using JOptionPane containing the connectionPanel. If
     * the user clicks on the 'Connect' button the connection is reset.
     */
    void activateConnectionDialog() {
        if (JOptionPane.showOptionDialog(tableAggregate, connectionPanel,
                ConnectTitle,
                JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
                null, ConnectOptionNames, ConnectOptionNames[0]) == 0) {
            connect();
            frame.setVisible(true);
        } else if (!frame.isVisible()) {
            System.exit(0);
        }
    }

    /**
     * Creates the connectionPanel, which will contain all the fields for the
     * connection information.
     */
    public void createConnectionDialog() {
        // Create the labels and text fields.
        userNameLabel = new JLabel("User name: ", JLabel.RIGHT);
        userNameField = new JTextField("app");

        passwordLabel = new JLabel("Password: ", JLabel.RIGHT);
        passwordField = new JTextField("app");

        serverLabel = new JLabel("Database URL: ", JLabel.RIGHT);
        serverField = new JTextField("jdbc:derby://localhost:1527/sample");

        driverLabel = new JLabel("Driver: ", JLabel.RIGHT);
        driverField = new JTextField("org.apache.derby.jdbc.ClientDriver");

        connectionPanel = new JPanel(false);
        connectionPanel.setLayout(new BoxLayout(connectionPanel,
                BoxLayout.X_AXIS));

        JPanel namePanel = new JPanel(false);
        namePanel.setLayout(new GridLayout(0, 1));
        namePanel.add(userNameLabel);
        namePanel.add(passwordLabel);
        namePanel.add(serverLabel);
        namePanel.add(driverLabel);

        JPanel fieldPanel = new JPanel(false);
        fieldPanel.setLayout(new GridLayout(0, 1));
        fieldPanel.add(userNameField);
        fieldPanel.add(passwordField);
        fieldPanel.add(serverField);
        fieldPanel.add(driverField);

        connectionPanel.add(namePanel);
        connectionPanel.add(fieldPanel);
    }

    public TableExample() {
        mainPanel = new JPanel();

        // Create the panel for the connection information
        createConnectionDialog();

        // Create the buttons.
        showConnectionInfoButton = new JButton("Configuration");
        showConnectionInfoButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                activateConnectionDialog();
            }
        });

        fetchButton = new JButton("Fetch");
        fetchButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fetch();
            }
        });

        // Create the query text area and label.
        queryTextArea = new JTextArea("SELECT * FROM APP.CUSTOMER", 25, 25);
        queryAggregate = new JScrollPane(queryTextArea);
        queryAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));

        // Create the table.
        tableAggregate = createTable();
        tableAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));

        // Add all the components to the main panel.
        mainPanel.add(fetchButton);
        mainPanel.add(showConnectionInfoButton);
        mainPanel.add(queryAggregate);
        mainPanel.add(tableAggregate);
        mainPanel.setLayout(this);

        // Create a Frame and put the main panel in it.
        frame = new JFrame("TableExample");
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setBackground(Color.lightGray);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(false);
        frame.setBounds(200, 200, 640, 480);

        activateConnectionDialog();
    }

    public void connect() {
        dataBase = new JDBCAdapter(
                serverField.getText(),
                driverField.getText(),
                userNameField.getText(),
                passwordField.getText());
        sorter.setModel(dataBase);
    }

    public void fetch() {
        dataBase.executeQuery(queryTextArea.getText());
    }

    public JScrollPane createTable() {
        sorter = new TableSorter();

        //connect();
        //fetch();
        // Create the table
        JTable table = new JTable(sorter);
        // Use a scrollbar, in case there are many columns.
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Install a mouse listener in the TableHeader as the sorter UI.
        sorter.addMouseListenerToHeaderInTable(table);

        JScrollPane scrollpane = new JScrollPane(table);

        return scrollpane;
    }

    public static void main(String s[]) {
        // Trying to set Nimbus look and feel
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(TableExample.class.getName()).log(Level.SEVERE,
                    "Failed to apply Nimbus look and feel", ex);
        }

        new TableExample();
    }

    @Override
    public Dimension preferredLayoutSize(Container c) {
        return origin;
    }

    @Override
    public Dimension minimumLayoutSize(Container c) {
        return origin;
    }

    @Override
    public void addLayoutComponent(String s, Component c) {
    }

    @Override
    public void removeLayoutComponent(Component c) {
    }

    @Override
    public void layoutContainer(Container c) {
        Rectangle b = c.getBounds();
        int topHeight = 90;
        int inset = 4;
        showConnectionInfoButton.setBounds(b.width - 2 * inset - 120, inset, 120,
                25);
        fetchButton.setBounds(b.width - 2 * inset - 120, 60, 120, 25);
        // queryLabel.setBounds(10, 10, 100, 25);
        queryAggregate.setBounds(inset, inset, b.width - 2 * inset - 150, 80);
        tableAggregate.setBounds(new Rectangle(inset,
                inset + topHeight,
                b.width - 2 * inset,
                b.height - 2 * inset - topHeight));
    }
}
```

TableMap.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
/**
 * In a chain of data manipulators some behaviour is common. TableMap provides
 * most of this behavour and can be subclassed by filters that only need to
 * override a handful of specific methods. TableMap implements TableModel by
 * routing all requests to its model, and TableModelListener by routing all
 * events to its listeners. Inserting a TableMap which has not been subclassed
 * into a chain of table filters should have no effect.
 *
 * @author Philip Milne
 */
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

   [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public class TableMap extends AbstractTableModel implements TableModelListener {

    protected TableModel model;

    public TableModel getModel() {
        return model;
    }

    public void setModel(TableModel model) {
        this.model = model;
        model.addTableModelListener(this);
    }

    // By default, Implement TableModel by forwarding all messages
    // to the model.
    @Override
    public Object getValueAt(int aRow, int aColumn) {
        return model.getValueAt(aRow, aColumn);
    }

    @Override
    public void setValueAt(Object aValue, int aRow, int aColumn) {
        model.setValueAt(aValue, aRow, aColumn);
    }

    @Override
    public int getRowCount() {
        return (model == null) ? 0 : model.getRowCount();
    }

    @Override
    public int getColumnCount() {
        return (model == null) ? 0 : model.getColumnCount();
    }

    @Override
    public String getColumnName(int aColumn) {
        return model.getColumnName(aColumn);
    }

    @Override
    public Class<?> getColumnClass(int aColumn) {
        return model.getColumnClass(aColumn);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return model.isCellEditable(row, column);
    }
// Implementation of the TableModelListener interface,
// By default forward all events to all the listeners.

    @Override
    public void tableChanged(TableModelEvent e) {
        fireTableChanged(e);
    }
}
```

TableSorter.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * A sorter for TableModels. The sorter has a model (conforming to TableModel)
 * and itself implements TableModel. TableSorter does not store or copy the data
 * in the TableModel, instead it maintains an array of integers which it keeps
 * the same size as the number of rows in its model. When the model changes it
 * notifies the sorter that something has changed eg. "rowsAdded" so that its
 * internal array of integers can be reallocated. As requests are made of the
 * sorter (like getValueAt(row, col) it redirects them to its model via the
 * mapping array. That way the TableSorter appears to hold another copy of the
 * table with the rows in a different order. The sorting algorthm used is stable
 * which means that it does not move around rows when its comparison function
 * returns 0 to denote that they are equivalent.
 *
 * @author Philip Milne
 */
   [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public final class TableSorter extends TableMap {

    int indexes[];
    List<Integer> sortingColumns = new ArrayList<>();
    boolean ascending = true;
    int compares;

    public TableSorter() {
        indexes = new int[0]; // For consistency.
    }

    public TableSorter(TableModel model) {
        setModel(model);
    }

    @Override
    public void setModel(TableModel model) {
        super.setModel(model);
        reallocateIndexes();
    }

    public int compareRowsByColumn(int row1, int row2, int column) {
        Class<?> type = model.getColumnClass(column);
        TableModel data = model;

        // Check for nulls
        Object o1 = data.getValueAt(row1, column);
        Object o2 = data.getValueAt(row2, column);

        // If both values are null return 0
        if (o1 == null && o2 == null) {
            return 0;
        } else if (o1 == null) { // Define null less than everything.
            return -1;
        } else if (o2 == null) {
            return 1;
        }

        /* We copy all returned values from the getValue call in case
         an optimised model is reusing one object to return many values.
         The Number subclasses in the JDK are immutable and so will not be used
         in this way but other subclasses of Number might want to do this to save
         space and avoid unnecessary heap allocation.
         */
        if (type.getSuperclass() == java.lang.Number.class) {
            Number n1 = (Number) data.getValueAt(row1, column);
            double d1 = n1.doubleValue();
            Number n2 = (Number) data.getValueAt(row2, column);
            double d2 = n2.doubleValue();

            if (d1 < d2) {
                return -1;
            } else if (d1 > d2) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == java.util.Date.class) {
            Date d1 = (Date) data.getValueAt(row1, column);
            long n1 = d1.getTime();
            Date d2 = (Date) data.getValueAt(row2, column);
            long n2 = d2.getTime();

            if (n1 < n2) {
                return -1;
            } else if (n1 > n2) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == String.class) {
            String s1 = (String) data.getValueAt(row1, column);
            String s2 = (String) data.getValueAt(row2, column);
            int result = s1.compareTo(s2);

            if (result < 0) {
                return -1;
            } else if (result > 0) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == Boolean.class) {
            Boolean bool1 = (Boolean) data.getValueAt(row1, column);
            boolean b1 = bool1.booleanValue();
            Boolean bool2 = (Boolean) data.getValueAt(row2, column);
            boolean b2 = bool2.booleanValue();

            if (b1 == b2) {
                return 0;
            } else if (b1) // Define false < true
            {
                return 1;
            } else {
                return -1;
            }
        } else {
            Object v1 = data.getValueAt(row1, column);
            String s1 = v1.toString();
            Object v2 = data.getValueAt(row2, column);
            String s2 = v2.toString();
            int result = s1.compareTo(s2);

            if (result < 0) {
                return -1;
            } else if (result > 0) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    public int compare(int row1, int row2) {
        compares++;
        for (int level = 0; level < sortingColumns.size(); level++) {
            Integer column = sortingColumns.get(level);
            int result = compareRowsByColumn(row1, row2, column.intValue());
            if (result != 0) {
                return ascending ? result : -result;
            }
        }
        return 0;
    }

    public void reallocateIndexes() {
        int rowCount = model.getRowCount();

        // Set up a new array of indexes with the right number of elements
        // for the new data model.
        indexes = new int[rowCount];

        // Initialise with the identity mapping.
        for (int row = 0; row < rowCount; row++) {
            indexes[row] = row;
        }
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        System.out.println("Sorter: tableChanged");
        reallocateIndexes();

        super.tableChanged(e);
    }

    public void checkModel() {
        if (indexes.length != model.getRowCount()) {
            System.err.println("Sorter not informed of a change in model.");
        }
    }

    public void sort(Object sender) {
        checkModel();

        compares = 0;
        // n2sort();
        // qsort(0, indexes.length-1);
        shuttlesort(indexes.clone(), indexes, 0, indexes.length);
        System.out.println("Compares: " + compares);
    }

    public void n2sort() {
        for (int i = 0; i < getRowCount(); i++) {
            for (int j = i + 1; j < getRowCount(); j++) {
                if (compare(indexes[i], indexes[j]) == -1) {
                    swap(i, j);
                }
            }
        }
    }

    // This is a home-grown implementation which we have not had time
    // to research - it may perform poorly in some circumstances. It
    // requires twice the space of an in-place algorithm and makes
    // NlogN assigments shuttling the values between the two
    // arrays. The number of compares appears to vary between N-1 and
    // NlogN depending on the initial order but the main reason for
    // using it here is that, unlike qsort, it is stable.
    public void shuttlesort(int from[], int to[], int low, int high) {
        if (high - low < 2) {
            return;
        }
        int middle = (low + high) / 2;
        shuttlesort(to, from, low, middle);
        shuttlesort(to, from, middle, high);

        int p = low;
        int q = middle;

        /* This is an optional short-cut; at each recursive call,
         check to see if the elements in this subset are already
         ordered.  If so, no further comparisons are needed; the
         sub-array can just be copied.  The array must be copied rather
         than assigned otherwise sister calls in the recursion might
         get out of sinc.  When the number of elements is three they
         are partitioned so that the first set, [low, mid), has one
         element and and the second, [mid, high), has two. We skip the
         optimisation when the number of elements is three or less as
         the first compare in the normal merge will produce the same
         sequence of steps. This optimisation seems to be worthwhile
         for partially ordered lists but some analysis is needed to
         find out how the performance drops to Nlog(N) as the initial
         order diminishes - it may drop very quickly.  */
        if (high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
            System.arraycopy(from, low, to, low, high - low);
            return;
        }

        // A normal merge.
        for (int i = low; i < high; i++) {
            if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
                to[i] = from[p++];
            } else {
                to[i] = from[q++];
            }
        }
    }

    public void swap(int i, int j) {
        int tmp = indexes[i];
        indexes[i] = indexes[j];
        indexes[j] = tmp;
    }

    // The mapping only affects the contents of the data rows.
    // Pass all requests to these rows through the mapping array: "indexes".
    @Override
    public Object getValueAt(int aRow, int aColumn) {
        checkModel();
        return model.getValueAt(indexes[aRow], aColumn);
    }

    @Override
    public void setValueAt(Object aValue, int aRow, int aColumn) {
        checkModel();
        model.setValueAt(aValue, indexes[aRow], aColumn);
    }

    public void sortByColumn(int column) {
        sortByColumn(column, true);
    }

    public void sortByColumn(int column, boolean ascending) {
        this.ascending = ascending;
        sortingColumns.clear();
        sortingColumns.add(column);
        sort(this);
        super.tableChanged(new TableModelEvent(this));
    }

    // There is no-where else to put this.
    // Add a mouse listener to the Table to trigger a table sort
    // when a column heading is clicked in the JTable.
    public void addMouseListenerToHeaderInTable(JTable table) {
        final TableSorter sorter = this;
        final JTable tableView = table;
        tableView.setColumnSelectionAllowed(false);
        MouseAdapter listMouseListener = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                TableColumnModel columnModel = tableView.getColumnModel();
                int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                int column = tableView.convertColumnIndexToModel(viewColumn);
                if (e.getClickCount() == 1 && column != -1) {
                    System.out.println("Sorting ...");
                    int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
                    boolean ascending = (shiftPressed == 0);
                    sorter.sortByColumn(column, ascending);
                }
            }
        };
        JTableHeader th = tableView.getTableHeader();
        th.addMouseListener(listMouseListener);
    }
}
```

*s30.postimg.org/w63xdf8ul/Table_Example.jpg

Place all the files in the same directory. If you use an IDE like NetBeans or IDEA or Eclipse, place them under the same
package.

To run the program , type

java TableExample

Q) Write a program to download a resource from the Web, also display it's progress (using JProgressBar) as it's fetched from the Net?

Ans. 


```
import java.awt.*;
import java.io.*;
import java.net.*;
import javax.swing.*;

public class Downloader extends JPanel {

  protected URL downloadURL;
  protected InputStream inputStream;
  protected OutputStream outputStream;
  protected byte[] buffer;
  protected Thread thisThread;

  protected int fileSize;
  protected int bytesRead;

  protected JLabel urlLabel;
  protected JLabel sizeLabel;
  protected JLabel completeLabel;
  protected JProgressBar progressBar;

  public final static int BUFFER_SIZE = 1000;
  public final static int SLEEP_TIME = 5 * 1000; // 5 seconds
  protected boolean stopped;
  protected boolean sleepScheduled;
  protected boolean suspended;


  public static void main(String[] args) throws Exception {
    Downloader dl = null;
    if (args.length < 2) {
      System.out.println("You must specify the URL of the file to download and " +
          "the name of the local file to which its contents will be written.");
      System.out.println("java Downloader <URL> <filepath>");
      System.exit(0);
    }
    URL url = new URL(args[0]);
    FileOutputStream fos = new FileOutputStream(args[1]);
    try {
      dl = new Downloader(url, fos);
    } catch (FileNotFoundException fnfe) {
      System.out.println("File '" + args[0] + "' does not exist");
      System.exit(0);
    }
    JFrame f = new JFrame();
    f.getContentPane().add(dl);
    f.setSize(600, 400);
    f.setVisible(true);
    dl.performDownload();
  }

  public Downloader(URL url, OutputStream os) throws IOException {
    downloadURL = url;
    outputStream = os;
    bytesRead = 0;
    URLConnection urlConnection = downloadURL.openConnection();
    fileSize = urlConnection.getContentLength();
    if (fileSize == -1) {
      throw new FileNotFoundException(url.toString());
    }
    inputStream = new BufferedInputStream(
        urlConnection.getInputStream());
    buffer = new byte[BUFFER_SIZE];
    buildLayout();

    stopped = false;
  }

protected void buildLayout() {
    JLabel label;
    setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets = new Insets(5, 10, 5, 10);

    gbc.gridx = 0;
    label = new JLabel("URL:", JLabel.LEFT);
    add(label, gbc);

    label = new JLabel("Complete:", JLabel.LEFT);
    add(label, gbc);

    label = new JLabel("Downloaded:", JLabel.LEFT);
    add(label, gbc);

    gbc.gridx = 1;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.weightx = 1;
    urlLabel = new JLabel(downloadURL.toString());
    add(urlLabel, gbc);

    progressBar = new JProgressBar(0, fileSize);
    progressBar.setStringPainted(true);
    add(progressBar, gbc);

    gbc.gridwidth = 1;
    completeLabel = new JLabel(Integer.toString(bytesRead));
    add(completeLabel, gbc);

    gbc.gridx = 2;
    gbc.weightx = 0;
    gbc.anchor = GridBagConstraints.EAST;
    label = new JLabel("Size:", JLabel.LEFT);
    add(label, gbc);

    gbc.gridx = 3;
    gbc.weightx = 1;
    sizeLabel = new JLabel(Integer.toString(fileSize));
    add(sizeLabel, gbc);
  }

  public synchronized void setSuspended(boolean suspend) {
    suspended = suspend;
  }

  public synchronized boolean isSuspended() {
    return suspended;
  }
  public synchronized void setStopped(boolean stop) {
    stopped = stop;
  }

  public synchronized boolean isStopped() {
    return stopped;
  }

  public synchronized void setSleepScheduled(boolean doSleep) {
    sleepScheduled = doSleep;
  }

  public synchronized boolean isSleepScheduled() {
    return sleepScheduled;
  }


  public void run() {
    performDownload();
  }

  public void stopDownload() {
    thisThread.interrupt();
  }

  public void performDownload() {
    int byteCount;
    Runnable progressUpdate = new Runnable() {
      public void run() {
        progressBar.setValue(bytesRead);
        completeLabel.setText(
            Integer.toString(
            bytesRead));
      }
    };
    while ((bytesRead < fileSize) && (!isStopped())) {
      try {
        if (isSleepScheduled()) {
          try {
            Thread.sleep(SLEEP_TIME);
            setSleepScheduled(false);
          }
          catch (InterruptedException ie) {
            setStopped(true);
            break;
          }
        }
        byteCount = inputStream.read(buffer);
        if (byteCount == -1) {
          setStopped(true);
          break;
        }
        else {
          outputStream.write(buffer, 0,
              byteCount);
          bytesRead += byteCount;
          SwingUtilities.invokeLater(
              progressUpdate);
        }
      } catch (IOException ioe) {
        setStopped(true);
        JOptionPane.showMessageDialog(this,
            ioe.getMessage(),
            "I/O Error",
            JOptionPane.ERROR_MESSAGE);
        break;
      }
      synchronized (this) {
        if (isSuspended()) {
          try {
            this.wait();
            setSuspended(false);
          }
          catch (InterruptedException ie) {
            setStopped(true);
            break;
          }
        }
      }
      if (Thread.interrupted()) {
        setStopped(true);
        break;
      }
    }
    try {
      outputStream.close();
      inputStream.close();
    } catch (IOException ioe) {};
  }
}
```

java Downloader <URL> <filepath>

Where URL is the URL of the resource that needs to be downloaded.
filepath is the path where this resource needs to be saved.

The above program fetches the resource from the Web byte-by-byte (using a while loop)and displays the progress in a JProgressBar.

Q) Write a program to display the WAV form of a audio file (WAV)?

Ans.



```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 10/1/14
 * Time: 2:34 PM
 * To change this template use File | Settings | File Templates.
 */
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

public class AudioWavformDemo {

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {

                    JFrame frame = new JFrame("Audio Waveform Display");
                    frame.setBounds(200, 200, 500, 350);

                    if (args.length != 1) {
                        System.err.println("Usage: java AudioWavformDemo <wav file>");
                        System.exit(-1);
                    }
                    File file = new File(args[0]);
                    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);

                    WaveformPanelContainer container = new WaveformPanelContainer();
                    container.setAudioToDisplay(audioInputStream);

                    frame.setLayout(new BorderLayout());
                    frame.add(container, BorderLayout.CENTER);

                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setResizable(false);
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);

                } catch (HeadlessException | UnsupportedAudioFileException | IOException e) {
                }
            }
        });

    }
}

class AudioInfo {
    private static final int NUM_BITS_PER_BYTE = 8;

    private final AudioInputStream audioInputStream;
    private int[][] samplesContainer;

    //cached values
    protected int sampleMax = 0;
    protected int sampleMin = 0;
    protected double biggestSample;

    public AudioInfo(AudioInputStream aiStream) {
        this.audioInputStream = aiStream;
        createSampleArrayCollection();
    }

    public int getNumberOfChannels(){
        int numBytesPerSample = audioInputStream.getFormat().getSampleSizeInBits() / NUM_BITS_PER_BYTE;
        return audioInputStream.getFormat().getFrameSize() / numBytesPerSample;
    }

    private void createSampleArrayCollection() {
        try {
            audioInputStream.mark(Integer.MAX_VALUE);
            //audioInputStream.reset();
            byte[] bytes = new byte[(int) (audioInputStream.getFrameLength()) * audioInputStream.getFormat().getFrameSize()];
            int result = 0;
            try {
                result = audioInputStream.read(bytes);
            } catch (IOException e) {
            }

            //convert sample bytes to channel separated 16 bit samples
            samplesContainer = getSampleArray(bytes);

            //find biggest sample. used for interpolating the yScaleFactor
            if (sampleMax > sampleMin) {
                biggestSample = sampleMax;
            } else {
                biggestSample = Math.abs(((double) sampleMin));
            }
        } catch (Exception e) {
        }
    }

    protected int[][] getSampleArray(byte[] eightBitByteArray) {
        int[][] toReturn = new int[getNumberOfChannels()][eightBitByteArray.length / (2 * getNumberOfChannels())];
        int index = 0;

        //loop through the byte[]
        for (int t = 0; t < eightBitByteArray.length;) {
            //for each iteration, loop through the channels
            for (int a = 0; a < getNumberOfChannels(); a++) {
                //do the byte to sample conversion
                //see AmplitudeEditor for more info
                int low = (int) eightBitByteArray[t];
                t++;
                int high = (int) eightBitByteArray[t];
                t++;
                int sample = (high << 8) + (low & 0x00ff);

                if (sample < sampleMin) {
                    sampleMin = sample;
                } else if (sample > sampleMax) {
                    sampleMax = sample;
                }
                //set the value.
                toReturn[a][index] = sample;
            }
            index++;
        }

        return toReturn;
    }

    public double getXScaleFactor(int panelWidth){
        return (panelWidth / ((double) samplesContainer[0].length));
    }

    public double getYScaleFactor(int panelHeight){
        return (panelHeight / (biggestSample * 2 * 1.2));
    }

    public int[] getAudio(int channel){
        return samplesContainer[channel];
    }

    protected int getIncrement(double xScale) {
        try {
            int increment = (int) (samplesContainer[0].length / (samplesContainer[0].length * xScale));
            return increment;
        } catch (Exception e) {
        }
        return -1;
    }
}


class SingleWaveformPanel extends JPanel {
    protected static final Color BACKGROUND_COLOR = Color.white;
    protected static final Color REFERENCE_LINE_COLOR = Color.black;
    protected static final Color WAVEFORM_COLOR = Color.red;
    private static final long serialVersionUID = 1L;


    private final AudioInfo helper;
    private final int channelIndex;

    public SingleWaveformPanel(AudioInfo helper, int channelIndex) {
        this.helper = helper;
        this.channelIndex = channelIndex;
        setBackground(BACKGROUND_COLOR);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        // Set the rendering hints
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

        g2d.setStroke(new BasicStroke(1.3f));
        int lineHeight = getHeight() / 2;
        g2d.setColor(REFERENCE_LINE_COLOR);
        g2d.drawLine(0, lineHeight, getWidth(), lineHeight);

        drawWaveform(g2d, helper.getAudio(channelIndex));
    }

    protected void drawWaveform(Graphics2D g, int[] samples) {
        if (samples == null) {
            return;
        }

        int oldX = 0;
        int oldY = getHeight() / 2;
        int xIndex = 0;

        int increment = helper.getIncrement(helper.getXScaleFactor(getWidth()));
        g.setColor(WAVEFORM_COLOR);

        int t = 0;

        for (t = 0; t < increment; t += increment) {
            g.drawLine(oldX, oldY, xIndex, oldY);
            xIndex++;
            oldX = xIndex;
        }

        for (; t < samples.length; t += increment) {
            double scaleFactor = helper.getYScaleFactor(getHeight());
            double scaledSample = samples[t] * scaleFactor;
            int y = (int) ((getHeight() / 2) - (scaledSample));
            g.drawLine(oldX, oldY, xIndex, y);

            xIndex++;
            oldX = xIndex;
            oldY = y;
        }
    }
}

class WaveformPanelContainer extends JPanel {
    private static final long serialVersionUID = 1L;

    private ArrayList singleChannelWaveformPanels = new ArrayList();
    private AudioInfo audioInfo = null;

    public WaveformPanelContainer() {
        setLayout(new GridLayout(0,1));
    }

      [MENTION=139512]Sup[/MENTION]pressWarnings("unchecked")
    public void setAudioToDisplay(AudioInputStream audioInputStream){
        singleChannelWaveformPanels = new ArrayList();
        audioInfo = new AudioInfo(audioInputStream);
        for (int t=0; t<audioInfo.getNumberOfChannels(); t++){
            SingleWaveformPanel waveformPanel
                    = new SingleWaveformPanel(audioInfo, t);
            singleChannelWaveformPanels.add(waveformPanel);
            add(createChannelDisplay(waveformPanel, t));
        }
    }

    private JComponent createChannelDisplay(SingleWaveformPanel waveformPanel, int index) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(waveformPanel, BorderLayout.CENTER);

        JLabel label = new JLabel("Channel " + ++index);
        panel.add(label, BorderLayout.NORTH);

        return panel;
    }
}
```

*s8.postimg.org/laxy6nj1t/Audio_Wavform_Demo.jpg

The class SingleWaveformPanel draws the wav form of the given audio file. The class AudioInfo is the helper class that gets the information
of the given audio file. Finally the class AudioWavformDemo loads & displays the WAV form of the audio file.

Q) Write a program to show Image loading progress (using JProgressBar) & Image writing progress ?

Ans.


```
/**
 *
 * @author Sowndar
 */
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.imageio.event.*;
import javax.imageio.stream.*;
import javax.swing.*;

// ProgressBar can be seen only for a bigger Image file
public class ImageReadWriteProgress extends JFrame {

    private BufferedImage image;
    private JComboBox<String> input;
    private JLabel label = new JLabel();
    private String fileName;
    private File file;
    private String extension;
    private JProgressBar pBar;
    private int count = 0;
    private String[] readFormat = ImageIO.getReaderFormatNames();
    private JButton write;
    private String path = "Images/";
    private String[] imgName;

    public ImageReadWriteProgress() {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        pBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
        write = new JButton("Write");
        pBar.setPreferredSize(new Dimension(350, 30));
        imgName = new File(path).list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        input = new JComboBox<>(imgName);
        write.setEnabled(false);
        label.setHorizontalAlignment(JLabel.CENTER);
        input.setFont(new Font("Courier", Font.BOLD, 13));
        input.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        process();
                    }
                });
            }
        });
        JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
        top.add(new JLabel("Select Image : "));
        top.add(input);
        top.add(write);
        write.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        write.setEnabled(false);
                        writeImage();
                    }
                }).start();
            }
        });
        add(top, BorderLayout.NORTH);
        add(new JScrollPane(label));
        setSize(scrDim.width / 2 + 350, scrDim.height - 50);
        setTitle("ImageReadWrite Progress");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public boolean isImage(File file) {
        String name = file.getName();
        for (int i = 0; i < readFormat.length; i++) {
            if (name.endsWith(readFormat[i])) {
                return true;
            }
        }
        return false;
    }

    public void process() {
        fileName = path + input.getSelectedItem();
        file = new File(fileName);
        if (file != null) {
            if (file.exists()) {
                // Whether the file is a valid Image, and Java supports that readFormat
                if (isImage(file)) {
                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            // If the Image is successfully loaded , then write button is enabled
                            try {
                                if (getImage(fileName)) {
                                    write.setEnabled(true);
                                }
                            } catch (Exception e) {
                            }

                        }
                    }).start();
                }
            } else {
                label.setIcon(null);
            }
        } else {
            label.setIcon(null);
        }
    }

    public boolean getImage(String fileName) {
        // Find a Image reader
        ImageReader reader = null;
        int dotindex = fileName.lastIndexOf(".");
        extension = fileName.substring(dotindex + 1);
        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(extension);
        reader = readers.next();
        file = new File(fileName);
        // Prepare input file
        try {
            ImageInputStream iis = ImageIO.createImageInputStream(file);
            ImageReadParam irparam = reader.getDefaultReadParam();
            // Read the Image

            reader.addIIOReadProgressListener(new IIOReadProgressListener() {

                @Override
                public void sequenceStarted(ImageReader source, int minIndex) {
                }

                @Override
                public void sequenceComplete(ImageReader source) {
                }

                @Override
                public void imageStarted(ImageReader source, int imageIndex) {
                }

                @Override
                public void imageProgress(ImageReader source, float percentageDone) {
                    add(pBar, BorderLayout.SOUTH);
                    validate();
                    count = (int) percentageDone + 4;
                    pBar.setValue(count);
                    if (count > 95) {
                        remove(pBar);
                        repaint();
                    }
                }

                @Override
                public void imageComplete(ImageReader source) {
                }

                @Override
                public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) {
                }

                @Override
                public void thumbnailProgress(ImageReader source, float percentageDone) {
                }

                @Override
                public void thumbnailComplete(ImageReader source) {
                }

                @Override
                public void readAborted(ImageReader source) {
                }
            });
            synchronized (reader) {
                reader.setInput(iis, true);
                image = reader.read(0, irparam);
            }

        } catch (IllegalStateException ise) {
            print("Illegal state Exception!!");
        } catch (IndexOutOfBoundsException ibe) {
            print("IndexOutOfBounds Exception!!");
        } catch (IllegalArgumentException iae) {
            print("IllegalArgument Exception!!");
        } catch (IOException ioe) {
            print("Error loading Image : " + fileName);

        }
        if (image != null) {
            // Update the label
            label.setIcon(new ImageIcon(image));
            return true;
        } else {
            write.setEnabled(false);
            label.setIcon(null);
            image = null;
            return false;
        }
    }

    public void print(String msg) {
        System.out.println(msg);
    }

    public void writeImage() {
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(extension);
        ImageWriter writer = writers.next();
        String lastName = file.getName();
        file = new File(lastName);
        try {
            ImageOutputStream ios = ImageIO.createImageOutputStream(file);
            writer.setOutput(ios);
            writer.addIIOWriteProgressListener(new IIOWriteProgressListener() {

                @Override
                public void imageStarted(ImageWriter source, int imageIndex) {
                }

                @Override
                public void imageProgress(ImageWriter source, float percentageDone) {
                    add(pBar, BorderLayout.SOUTH);
                    validate();
                    count = (int) percentageDone + 4;
                    pBar.setValue(count);
                    if (count > 95) {
                        remove(pBar);
                        repaint();
                    }
                }

                @Override
                public void imageComplete(ImageWriter source) {
                }

                @Override
                public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
                }

                @Override
                public void thumbnailProgress(ImageWriter source, float percentageDone) {
                }

                @Override
                public void thumbnailComplete(ImageWriter source) {
                }

                @Override
                public void writeAborted(ImageWriter source) {
                }
            });
            synchronized (writer) {
                writer.write(image);
            }

        } catch (IOException ioe) {
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new ImageReadWriteProgress();
                } catch (Exception e) {
                }
            }
        });
    }
}
```

*s15.postimg.org/uvas23q8n/Image_Read_Write_Progress.jpg

First we get all the supported Image formats & create a ComboBox (of all the images in the 'Images' directory)
Selecting a particular Image from the ComboBox, starts loading that Image & shows the Image loading progress.
The method getImage() fetches the Image from the disk. The IIOReadProgressListener shows the image read progress.
The writeImage() method actually writes the Image to the disk (Write button). This is done using the IIOWriteProgressListener.

Q) Write a program to display the animation (of Images) in an application ?

Ans.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 9/22/14
 * Time: 8:26 PM
 * To change this template use File | Settings | File Templates.
 */
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class AnimationApp extends JFrame {

    private String path = "resources/";
    // Initial Frame no.
    private int frameNumber = 1;
    private JLabel label = new JLabel();
    // Size of the Image displayed
    private Dimension dim;
    private Image image = null;
    // Total no of frames
    private int totalFrames = 0;
    // 32 for BMP, 22 for PNG format
    private int sleepTime = 29;
    private File file = new File(path);
    private String[] readFormat = ImageIO.getReaderFormatNames();
    private String prefix = "J"; // We need Images in the sequence J0.png, J1.png, J2.png etc.,
    private String[] name;
    private String extension = "png";
    
    /*
      You put a VCD into your DVD Drive & select a song (dance sequence), extract the Images , pick every 25th Image & copy it to a separate directory.
       Rename them as SM0.png, SM1.png etc., We need 60 Images for a good animation. 
      
        Here is the procedure to extract the Images from a VCD using VirtualDubMod (*sourceforge.net/projects/virtualdubmod/)
        Select the song from the VCD. Wait for it load completely. From the menu select File -> Save Image sequence..., A dialog pops out. Select the output format as "PNG".
        Enter the file prefix name as  SM 
        Select a directory to hold these Images. Now click on the OK button. It will take a few minutes time. So wait until the Images are extracted!!!
      
        You can also extract the audio (WAV format) using VirtualDub. Play the animation with audio & Image. Synchronize both to create an excellent animation!!!!
       I will leave that to you!!! 
    
    */

    public String[] getImages(String path) {
        name = new File(path).list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        totalFrames = name.length - 1;
        return name;
    }

    public AnimationApp() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look 'n feel!!");
        }

        if (!file.exists()) {
            System.out.println("The specified path : " + path + " doesn't exist!!!");
            System.exit(1);
        }

        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        getImages(path);
        add(label, BorderLayout.CENTER);

        image = getImage(path + name[0]);
        dim = new Dimension(image.getWidth(this) * 3, image.getHeight(this) * 3);

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) // put it in infinite loop
                {
                    if (frameNumber == totalFrames) {
                            // We have reached the end, start from the beginning again
                            frameNumber = 0;
                        }
                        frameNumber++;
                        // totalFrames - > 100
                        // currentFrame -> (currentFrame*100)/totalFrames

                        String str = path + prefix + frameNumber + "." + extension;
                        image = getImage(str);
                        if (image != null) {
                            image.setAccelerationPriority(0.9f);
                            label.setIcon(new ImageIcon(image.getScaledInstance(dim.width, dim.height, Image.SCALE_DEFAULT)));
                            sleep(sleepTime);
                        }

                }
            }
        }).start();
        //Frame's properties
        setTitle("Animation Demo");
        setSize(dim.width + 40, dim.height + 40);
        setLocationRelativeTo(this);
        setResizable(false);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
        }
        return null;
    }

    public void print(String msg) {
        System.out.println(msg);
    }

    public void sleep(long ms) {   //     millis - the length of time to sleep in milliseconds.
        //nanos - 0-999999 additional nanoseconds to sleep.
        // sleep(millis, nanos)
        // This synchronizes the Audio with the Video
        try {
            Thread.sleep(ms, 700);
        } catch (InterruptedException ie) {
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new AnimationApp();
            }
        });
    }
}
```

*s29.postimg.org/693mjmkkz/Animation_App.jpg

Q) Write a program to cascade & tile a group of Internal frames?

Ans.


```
/**
 *
 * @author JGuru
 */
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;

// NOTE :  A directory by the name "Images" must exist in the current directory & it it must contain atleast 4 or 5 Images in it.
public class DesktopPaneDemo extends JFrame implements ActionListener {

    private JDesktopPane desktop = new JDesktopPane();
    // The gap between internal frames when cascading effect is applied
    private int FRAME_OFFSET = 20;
    private Image image;
    private ImageIcon icon;
    private String path = "Images/";
    private String[] name;
    private int MAX;
    private boolean resizable = true;
    private boolean closable = true;
    private boolean maximizable = true;
    private boolean iconifiable = true;
    private JInternalFrame[] jif;
    private String fileName = "";
    private String title;
    private int X = 25, Y = 30;
    private JMenu file = new JMenu("File");
    private JMenuItem vTile = new JMenuItem("Tile Vertically");
    private JMenuItem hTile = new JMenuItem("Tile Horizontally");
    private JMenuItem cascade = new JMenuItem("Cascade");
    private JMenuItem close = new JMenuItem("Close");
    private int sleepTime = 450;
    private JMenuBar mBar = new JMenuBar();
    private File directory = new File(path);
    private String[] format = ImageIO.getReaderFormatNames();
    private String iState = "";

    private void sleep() {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException ie) {
        }
    }

    public void updateUI() {
        desktop.updateUI();
        file.updateUI();
        vTile.updateUI();
        hTile.updateUI();
        cascade.updateUI();
        close.updateUI();
        mBar.updateUI();
    }

    public DesktopPaneDemo() {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        updateUI();
        // Filter only the Images
        name = directory.list(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                for (int i = 0; i < format.length; i++) {
                    if (name.endsWith(format[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = name.length;
        if (MAX == 0) {
            System.err.println("Oops, No Images found!!");
            System.exit(1);
        }
        // Restrict to a maximum of 5 Images
        if (MAX > 5) {
            MAX = 5;
        }
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        file.add(cascade);
        file.add(vTile);
        file.add(hTile);
        file.add(close);
        cascade.addActionListener(this);
        vTile.addActionListener(this);
        hTile.addActionListener(this);
        close.addActionListener(this);
        // Set Accelerators
        vTile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK));
        hTile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, KeyEvent.CTRL_DOWN_MASK));
        cascade.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
        close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK));

        mBar.add(file);
        setJMenuBar(mBar);
        // Allocate that many internal frames
        jif = new JInternalFrame[MAX];
        // Show 5 JInternalFrames
        for (int i = 0; i < MAX; i++) {
            fileName = path + name[i];
            image = getImage(fileName);
            // Show only the fileName, sans the file extension
            title = name[i].substring(0, name[i].lastIndexOf("."));
            icon = new ImageIcon(image);
            jif[i] = new JInternalFrame(title, resizable, closable, maximizable, iconifiable);
            jif[i].setFrameIcon(createIcon(image));
            jif[i].add(new JScrollPane(new JLabel(icon)));
            jif[i].setSize(650, 600);
            //Cascade effect
            jif[i].setLocation(X, 10);
            // Icrement X
            X += 85;
            jif[i].setVisible(true);
            desktop.add(jif[i]);
        }
        // When the Component is resized , do the appropriate action
        addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent ce) {
                new Thread(new Runnable() {

                    public void run() {
                        if (iState.equals("Tile Vertical")) {
                            tileVertical();
                        } else if (iState.equals("Tile Horizontal")) {
                            tileHorizontal();
                        } else if (iState.equals("Cascade")) {
                            cascadeFrames();
                        }
                    }
                }).start();
            }
        });
        setContentPane(desktop);
        desktop.setVisible(true);
        setTitle("DesktopPane Demo");
        setSize(scrDim.width / 2 + 250, scrDim.height - 20);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    /* Create an icon for the internal frame */
    public ImageIcon createIcon(Image image) {
        if (image != null) {
            int imgWidth = image.getWidth(null);
            int imgHeight = image.getHeight(null);
            double aspect = ((double) imgWidth) / ((double) imgHeight);
            int maxWidth, maxHeight;
            // If aspect ratio exceeds 1.3333
            if (aspect > 1.3333) {
                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = 28;
                maxHeight = (int) (((double) maxWidth) / aspect);
            } else {
                // Fix the height as iconHeight, calculate the maxWidth for this
                maxHeight = 28;
                maxWidth = (int) (((double) maxHeight) * aspect);
            }
            return new ImageIcon(image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH));
        }
        return null;
    }

    public void actionPerformed(ActionEvent ae) {
        final Object source = ae.getSource();
        new Thread(new Runnable() {

            public void run() {
                if (source == vTile) {
                    iState = "Tile Vertical";
                    tileVertical();

                } else if (source == hTile) {
                    iState = "Tile Horizontal";
                    tileHorizontal();

                } else if (source == cascade) {
                    iState = "Cascade";
                    cascadeFrames();

                } else {
                    System.exit(0);
                }
            }
        }).start();
    }
    /* Cascade the internal frames */

    public void cascadeFrames() {
        int x = 0;
        int y = 0;
        JInternalFrame allFrames[] = desktop.getAllFrames();
        int frameHeight = (desktop.getBounds().height - 5) - allFrames.length * FRAME_OFFSET;
        int frameWidth = (desktop.getBounds().width - 5) - allFrames.length * FRAME_OFFSET;
        for (int i = allFrames.length - 1; i >= 0; i--) {
            allFrames[i].setSize(frameWidth, frameHeight);
            allFrames[i].setLocation(x, y);
            x = x + FRAME_OFFSET;
            y = y + FRAME_OFFSET;
            sleep();
        }
    }

    /**
     * Tile all internal frames horizontally
     */
    public void tileHorizontal() {
        JInternalFrame allFrames[] = desktop.getAllFrames();
        int frameHeight = desktop.getBounds().height / allFrames.length;
        int frameWidth = desktop.getBounds().width / allFrames.length;
        int wholeHeight = desktop.getBounds().height;
        int x = 0, y = 0;
        for (int i = 0; i < allFrames.length; i++) {
            allFrames[i].setSize(frameWidth, wholeHeight);
            allFrames[i].setLocation(x, 0);
            x = x + frameWidth;
            y = y + frameHeight;
            sleep();
        }
    }

    /**
     * Tile all internal frames vertically
     */
    public void tileVertical() {
        JInternalFrame[] frames = desktop.getAllFrames();
        if (frames.length == 0) {
            return;
        }
        int cols = (int) Math.sqrt(frames.length);
        int rows = (int) (Math.ceil(((double) frames.length) / cols));
        int lastRow = frames.length - cols * (rows - 1);
        Rectangle dBounds = desktop.getBounds();
        int height = 0, width = 0;
        if (lastRow == 0) {
            rows--;
            height = dBounds.height / rows;
        } else {
            height = dBounds.height / rows;
            if (lastRow < cols) {
                rows--;
                width = dBounds.width / lastRow;
                for (int i = 0; i < lastRow; i++) {
                    frames[cols * rows + i].setBounds(i * width, rows * height,
                            width, height);
                }
            }
        }
        width = dBounds.width / cols;
        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < cols; i++) {
                frames[i + j * cols].setBounds(i * width, j * height,
                        width, height);
            }
            sleep();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new DesktopPaneDemo();
            }
        });
    }
}
```



*s29.postimg.org/79cefkudv/Desktop_Pane_Demo.jpg


The above program loads the Images (maximum 5 ) in the 'Images' directory. 
From the menu choose File - > Cascade to cascade all the internal frames. You can also tile the internal frames vertically & horizaontally.

1) Write a program to show a simple text editor in action (open, save, saveAs etc.,)?

Ans) 


```
// SimpleEditor.java

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.*;
import java.util.Hashtable;
import javax.swing.*;
import javax.swing.text.*;

// An example showing several DefaultEditorKit features. This class is designed
// to be easily extended to add additional functionality.
public class SimpleEditor extends JFrame implements DropTargetListener {

    DropTarget dt;

    // Create an editor
    public SimpleEditor() {
        super("Simple Editor");
        textComp = createTextComponent();
        textComp.setDragEnabled(true); // enable drag and drop
        //Add Drag & Drop
        dt = new DropTarget(textComp, this);

        hashDefaultActions();
        makeActionsPretty();
        updateKeymap();
        Container content = getContentPane();
        JScrollPane scroll = new JScrollPane(textComp);
        content.add(scroll, BorderLayout.CENTER);
        content.add(createToolBar(), BorderLayout.NORTH);

        setJMenuBar(createMenuBar());

        setSize(800, 600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    // Create the JTextComponent subclass.
    protected JTextComponent createTextComponent() {
        JTextArea ta = new JTextArea("", 15, 35);
        ta.setLineWrap(false); // no line wrapping.
        return ta;
    }

    // Get all of the actions defined for our text component. Hash each one by name
    // so we can look for it later.
    protected void hashDefaultActions() {
        Action[] actions = textComp.getActions();
        for (int i = 0; i < actions.length; i++) {
            String name = (String) actions[i].getValue(Action.NAME);
            actionHash.put(name, actions[i]);
        }
    }

    // Get an action by name
    protected Action getHashedAction(String name) {
        return (Action) actionHash.get(name);
    }

    // Add icons and friendly names to actions we care about
    protected void makeActionsPretty() {
        Action a;
        a = getHashedAction(DefaultEditorKit.cutAction);
        a.putValue(Action.SMALL_ICON, new ImageIcon("icons/cut.gif"));
        a.putValue(Action.NAME, "Cut");

        a = getHashedAction(DefaultEditorKit.copyAction);
        a.putValue(Action.SMALL_ICON, new ImageIcon("icons/copy.gif"));
        a.putValue(Action.NAME, "Copy");

        a = getHashedAction(DefaultEditorKit.pasteAction);
        a.putValue(Action.SMALL_ICON, new ImageIcon("icons/paste.gif"));
        a.putValue(Action.NAME, "Paste");

        a = getHashedAction(DefaultEditorKit.selectAllAction);
        a.putValue(Action.NAME, "Select All");

    }

    // Add some key->Action mappings
    protected void updateKeymap() {

        // Create a new child Keymap
        Keymap map = JTextComponent.addKeymap("NextPrevMap",
                textComp.getKeymap());

        // Define the keystrokes to be added
        KeyStroke next = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
                InputEvent.CTRL_MASK, false);
        KeyStroke prev = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
                InputEvent.CTRL_MASK, false);
        KeyStroke selNext = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
                InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
        KeyStroke selPrev = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
                InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);

        // Add the new mappings used DefaultEditorKit actions
        map.addActionForKeyStroke(next, getHashedAction(
                DefaultEditorKit.nextWordAction));
        map.addActionForKeyStroke(prev, getHashedAction(
                DefaultEditorKit.previousWordAction));
        map.addActionForKeyStroke(selNext, getHashedAction(
                DefaultEditorKit.selectionNextWordAction));
        map.addActionForKeyStroke(selPrev, getHashedAction(
                DefaultEditorKit.selectionPreviousWordAction));

        // Set the Keymap for the text component
        textComp.setKeymap(map);
    }

    // Create a simple JToolBar with some buttons
    protected JToolBar createToolBar() {
        JToolBar bar = new JToolBar();

        // Add simple actions for opening & saving
        bar.add(getOpenAction()).setText("");
        bar.add(getSaveAction()).setText("");
        bar.addSeparator();

        // Add cut/copy/paste buttons
        bar.add(getHashedAction(DefaultEditorKit.cutAction)).setText("");
        bar.add(getHashedAction(DefaultEditorKit.copyAction)).setText("");
        bar.add(getHashedAction(DefaultEditorKit.pasteAction)).setText("");
        return bar;
    }

    // Create a JMenuBar with file & edit menus
    protected JMenuBar createMenuBar() {
        JMenuBar menubar = new JMenuBar();
        JMenu file = new JMenu("File");
        JMenu edit = new JMenu("Edit");
        menubar.add(file);
        menubar.add(edit);

        file.add(getOpenAction());
        file.add(getSaveAction());
        file.add(new ExitAction());
        edit.add(getHashedAction(DefaultEditorKit.cutAction));
        edit.add(getHashedAction(DefaultEditorKit.copyAction));
        edit.add(getHashedAction(DefaultEditorKit.pasteAction));
        edit.add(getHashedAction(DefaultEditorKit.selectAllAction));
        return menubar;
    }

    //Enable Drag & Drop facility!
    public void dragEnter(DropTargetDragEvent dtde) {
        System.out.println("Drag Enter");
    }

    public void dragExit(DropTargetEvent dte) {
        System.out.println("Drag Exit");
    }

    public void dragOver(DropTargetDragEvent dtde) {
        System.out.println("Drag Over");
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
        System.out.println("Drop Action Changed");
    }

    public void drop(DropTargetDropEvent dtde) {
        try {
            // Ok, get the dropped object and try to figure out what it is
            Transferable tr = dtde.getTransferable();
            DataFlavor[] flavors = tr.getTransferDataFlavors();
            for (int i = 0; i < flavors.length; i++) {
                System.out.println("Possible flavor: " + flavors[i].getMimeType());
                // Check for file lists specifically
                if (flavors[i].isFlavorJavaFileListType()) {
                    // Great!  Accept copy drops...
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                    System.out.println("Successful file list drop.\n\n");

                    // And add the list of file names to our text area
                    java.util.List list = (java.util.List) tr.getTransferData(flavors[i]);
                    for (int j = 0; j < list.size(); j++) {
                        String filename = "" + list.get(j);
                        //Monitor the progress of the file-loading progress!
                        new MonitorInput(filename);
                        FileReader reader = null;
                        try {
                            reader = new FileReader(filename);
                            textComp.read(reader, null);

                        } catch (IOException ex) {
                            System.out.println("Failed File-reading operation!!");
                        }
                    }

                    // If we made it this far, everything worked.
                    dtde.dropComplete(true);
                    return;
                }// Ok, is it another Java object?
                else if (flavors[i].isFlavorSerializedObjectType()) {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);

                    Object o = tr.getTransferData(flavors[i]);

                    dtde.dropComplete(true);
                    return;
                }// How about an input stream?
                else if (flavors[i].isRepresentationClassInputStream()) {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                    dtde.dropComplete(true);
                    return;
                }
            }
            // Hmm, the user must not have dropped a file list
            System.out.println("Drop failed: " + dtde);
            dtde.rejectDrop();
        } catch (Exception e) {
            e.printStackTrace();
            dtde.rejectDrop();
        }
    }

    //End Drag & Drop facility methods
    // Subclass can override to use a different open action
    protected Action getOpenAction() {
        return openAction;
    }

    // Subclass can override to use a different save action
    protected Action getSaveAction() {
        return saveAction;
    }

    protected JTextComponent getTextComponent() {
        return textComp;
    }

    private Action openAction = new OpenAction();
    private Action saveAction = new SaveAction();

    private JTextComponent textComp;

    private Hashtable actionHash = new Hashtable();

    // ********** ACTION INNER CLASSES ********** //
    // A very simple "exit" action
    public class ExitAction extends AbstractAction {

        public ExitAction() {
            super("Exit");
        }

        public void actionPerformed(ActionEvent ev) {
            System.exit(0);
        }
    }

    // An action that opens an existing file
    class OpenAction extends AbstractAction {

        public OpenAction() {
            super("Open", new ImageIcon("icons/open.gif"));
        }

        // Query user for a filename and attempt to open and read the file into the
        // text component
        public void actionPerformed(ActionEvent ev) {
            String filename = JOptionPane.showInputDialog(
                    SimpleEditor.this, "Enter Filename");
            if (filename == null) {
                return;
            }

            FileReader reader = null;

            try {
                reader = new FileReader(filename);
                textComp.read(reader, null);

            } catch (IOException ex) {
                JOptionPane.showMessageDialog(SimpleEditor.this,
                        "File Not Found", "ERROR", JOptionPane.ERROR_MESSAGE);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException x) {
                    }
                }
            }
        }
    }

    // An action that saves the document to a file
    class SaveAction extends AbstractAction {

        public SaveAction() {
            super("Save", new ImageIcon("icons/save.gif"));
        }

        // Query user for a filename and attempt to open and write the text
        // component's content to the file
        public void actionPerformed(ActionEvent ev) {
            String filename = JOptionPane.showInputDialog(
                    SimpleEditor.this, "Enter Filename");
            if (filename == null) {
                return;
            }

            FileWriter writer = null;
            try {
                writer = new FileWriter(filename);
                textComp.write(writer);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(SimpleEditor.this,
                        "File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException x) {
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new SimpleEditor();
            }
        });
    }
}
```

4) Write a program to show a download manager in action?

Ans)


```
import java.io.*;
import java.net.*;
import java.util.*;

// This class downloads a file from a URL.
class Download extends Observable implements Runnable {
  // Max size of download buffer.
  private static final int MAX_BUFFER_SIZE = 1024;

  // These are the status names.
  public static final String STATUSES[] = {"Downloading",
    "Paused", "Complete", "Cancelled", "Error"};

  // These are the status codes.
  public static final int DOWNLOADING = 0;
  public static final int PAUSED = 1;
  public static final int COMPLETE = 2;
  public static final int CANCELLED = 3;
  public static final int ERROR = 4;

  private URL url; // download URL
  private int size; // size of download in bytes
  private int downloaded; // number of bytes downloaded
  private int status; // current status of download

  // Constructor for Download.
  public Download(URL url) {
    this.url = url;
    size = -1;
    downloaded = 0;
    status = DOWNLOADING;

    // Begin the download.
    download();
  }

  // Get this download's URL.
  public String getUrl() {
    return url.toString();
  }

  // Get this download's size.
  public int getSize() {
    return size;
  }

  // Get this download's progress.
  public float getProgress() {
    return ((float) downloaded / size) * 100;
  }

  // Get this download's status.
  public int getStatus() {
    return status;
  }

  // Pause this download.
  public void pause() {
    status = PAUSED;
    stateChanged();
  }

  // Resume this download.
  public void resume() {
    status = DOWNLOADING;
    stateChanged();
    download();
  }

  // Cancel this download.
  public void cancel() {
    status = CANCELLED;
    stateChanged();
  }

  // Mark this download as having an error.
  private void error() {
    status = ERROR;
    stateChanged();
  }

  // Start or resume downloading.
  private void download() {
    Thread thread = new Thread(this);
    thread.start();
  }

  // Get file name portion of URL.
  private String getFileName(URL url) {
    String fileName = url.getFile();
    return fileName.substring(fileName.lastIndexOf('/') + 1);
  }

  // Download file.
  public void run() {
    RandomAccessFile file = null;
    InputStream stream = null;

    try {
      // Open connection to URL.
      HttpURLConnection connection =
        (HttpURLConnection) url.openConnection();

      // Specify what portion of file to download.
      connection.setRequestProperty("Range",
        "bytes=" + downloaded + "-");

      // Connect to server.
      connection.connect();

      // Make sure response code is in the 200 range.
      if (connection.getResponseCode() / 100 != 2) {
        error();
      }

      // Check for valid content length.
      int contentLength = connection.getContentLength();
      if (contentLength < 1) {
        error();
      }

      /* Set the size for this download if it
         hasn't been already set. */
      if (size == -1) {
        size = contentLength;
        stateChanged();
      }

      // Open file and seek to the end of it.
      file = new RandomAccessFile(getFileName(url), "rw");
      file.seek(downloaded);

      stream = connection.getInputStream();
      while (status == DOWNLOADING) {
        /* Size buffer according to how much of the
           file is left to download. */
        byte buffer[];
        if (size - downloaded > MAX_BUFFER_SIZE) {
          buffer = new byte[MAX_BUFFER_SIZE];
        } else {
          buffer = new byte[size - downloaded];
        }

        // Read from server into buffer.
        int read = stream.read(buffer);
        if (read == -1)
          break;

        // Write buffer to file.
        file.write(buffer, 0, read);
        downloaded += read;
        stateChanged();
      }

      /* Change status to complete if this point was
         reached because downloading has finished. */
      if (status == DOWNLOADING) {
        status = COMPLETE;
        stateChanged();
      }
    } catch (Exception e) {
      error();
    } finally {
      // Close file.
      if (file != null) {
        try {
          file.close();
        } catch (Exception e) {}
      }

      // Close connection to server.
      if (stream != null) {
        try {
          stream.close();
        } catch (Exception e) {}
      }
    }
  }

  // Notify observers that this download's status has changed.
  private void stateChanged() {
    setChanged();
    notifyObservers();
  }
}


import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

// The Download Manager.
public class DownloadManager extends JFrame
  implements Observer
{
  // Add download text field.
  private JTextField addTextField;

  // Download table's data model.
  private DownloadsTableModel tableModel;
  
  // Table showing downloads.
  private JTable table;

  // These are the buttons for managing the selected download.
  private JButton pauseButton, resumeButton;
  private JButton cancelButton, clearButton;

  // Currently selected download.
  private Download selectedDownload;

  // Flag for whether or not table selection is being cleared.
  private boolean clearing;

  // Constructor for Download Manager.
  public DownloadManager()
  {
    // Set application title.
    setTitle("Download Manager");

    // Set window size.
    setSize(640, 480);

    // Handle window closing events.
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        actionExit();
      }
    });

    // Set up file menu.
    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    fileMenu.setMnemonic(KeyEvent.VK_F);
    JMenuItem fileExitMenuItem = new JMenuItem("Exit",
      KeyEvent.VK_X);
    fileExitMenuItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionExit();
      }
    });
    fileMenu.add(fileExitMenuItem);
    menuBar.add(fileMenu);
    setJMenuBar(menuBar);

    // Set up add panel.
    JPanel addPanel = new JPanel();
    addTextField = new JTextField(30);
    addPanel.add(addTextField);
    JButton addButton = new JButton("Add Download");
    addButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionAdd();
      }
    });
    addPanel.add(addButton);

    // Set up Downloads table.
    tableModel = new DownloadsTableModel();
    table = new JTable(tableModel);
    table.getSelectionModel().addListSelectionListener(new
      ListSelectionListener() {
      public void valueChanged(ListSelectionEvent e) {
        tableSelectionChanged();
      }
    });
    // Allow only one row at a time to be selected.
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  
    // Set up ProgressBar as renderer for progress column.
    ProgressRenderer renderer = new ProgressRenderer(0, 100);
    renderer.setStringPainted(true); // show progress text
    table.setDefaultRenderer(JProgressBar.class, renderer);

    // Set table's row height large enough to fit JProgressBar.
    table.setRowHeight(
      (int) renderer.getPreferredSize().getHeight());

    // Set up downloads panel.
    JPanel downloadsPanel = new JPanel();
    downloadsPanel.setBorder(
      BorderFactory.createTitledBorder("Downloads"));
    downloadsPanel.setLayout(new BorderLayout());
    downloadsPanel.add(new JScrollPane(table),
      BorderLayout.CENTER);

    // Set up buttons panel.
    JPanel buttonsPanel = new JPanel();
    pauseButton = new JButton("Pause");
    pauseButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionPause();
      }
    });
    pauseButton.setEnabled(false);
    buttonsPanel.add(pauseButton);
    resumeButton = new JButton("Resume");
    resumeButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionResume();
      }
    });
    resumeButton.setEnabled(false);
    buttonsPanel.add(resumeButton);
    cancelButton = new JButton("Cancel");
    cancelButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionCancel();
      }
    });
    cancelButton.setEnabled(false);
    buttonsPanel.add(cancelButton);
    clearButton = new JButton("Clear");
    clearButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        actionClear();
      }
    });
    clearButton.setEnabled(false);
    buttonsPanel.add(clearButton);

    // Add panels to display.
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(addPanel, BorderLayout.NORTH);
    getContentPane().add(downloadsPanel, BorderLayout.CENTER);
    getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
  }

  // Exit this program.
  private void actionExit() {
    System.exit(0);
  }

  // Add a new download.
  private void actionAdd() {
    URL verifiedUrl = verifyUrl(addTextField.getText());
    if (verifiedUrl != null) {
      tableModel.addDownload(new Download(verifiedUrl));
      addTextField.setText(""); // reset add text field
    } else {
      JOptionPane.showMessageDialog(this,
        "Invalid Download URL", "Error",
        JOptionPane.ERROR_MESSAGE);
    }
  }

  // Verify download URL.
  private URL verifyUrl(String url) {
    // Only allow HTTP URLs.
    if (!url.toLowerCase().startsWith("*"))
      return null;

    // Verify format of URL.
    URL verifiedUrl = null;
    try {
      verifiedUrl = new URL(url);
    } catch (Exception e) {
      return null;
    }

    // Make sure URL specifies a file.
    if (verifiedUrl.getFile().length() < 2)
      return null;

    return verifiedUrl;
  }

  // Called when table row selection changes.
  private void tableSelectionChanged() {
    /* Unregister from receiving notifications
       from the last selected download. */
    if (selectedDownload != null)
      selectedDownload.deleteObserver(DownloadManager.this);

    /* If not in the middle of clearing a download,
       set the selected download and register to
       receive notifications from it. */
    if (!clearing && table.getSelectedRow() > -1) {
      selectedDownload =
        tableModel.getDownload(table.getSelectedRow());
      selectedDownload.addObserver(DownloadManager.this);
      updateButtons();
    }
  }

  // Pause the selected download.
  private void actionPause() {
    selectedDownload.pause();
    updateButtons();
  }

  // Resume the selected download.
  private void actionResume() {
    selectedDownload.resume();
    updateButtons();
  }

  // Cancel the selected download.
  private void actionCancel() {
    selectedDownload.cancel();
    updateButtons();
  }

  // Clear the selected download.
  private void actionClear() {
    clearing = true;
    tableModel.clearDownload(table.getSelectedRow());
    clearing = false;
    selectedDownload = null;
    updateButtons();
  }

  /* Update each button's state based off of the
     currently selected download's status. */
  private void updateButtons() {
    if (selectedDownload != null) {
      int status = selectedDownload.getStatus();
      switch (status) {
        case Download.DOWNLOADING:
          pauseButton.setEnabled(true);
          resumeButton.setEnabled(false);
          cancelButton.setEnabled(true);
          clearButton.setEnabled(false);
          break;
        case Download.PAUSED:
          pauseButton.setEnabled(false);
          resumeButton.setEnabled(true);
          cancelButton.setEnabled(true);
          clearButton.setEnabled(false);
          break;
        case Download.ERROR:
          pauseButton.setEnabled(false);
          resumeButton.setEnabled(true);
          cancelButton.setEnabled(false);
          clearButton.setEnabled(true);
          break;
        default: // COMPLETE or CANCELLED
          pauseButton.setEnabled(false);
          resumeButton.setEnabled(false);
          cancelButton.setEnabled(false);
          clearButton.setEnabled(true);
      }
    } else {
      // No download is selected in table.
      pauseButton.setEnabled(false);
      resumeButton.setEnabled(false);
      cancelButton.setEnabled(false);
      clearButton.setEnabled(false);
    }
  }

  /* Update is called when a Download notifies its
     observers of any changes. */
  public void update(Observable o, Object arg) {
    // Update buttons if the selected download has changed.
    if (selectedDownload != null && selectedDownload.equals(o))
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          updateButtons();
        }
      });
  }

  // Run the Download Manager.
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        DownloadManager manager = new DownloadManager();
        manager.setVisible(true);
      }
    });
  }
}


import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

// This class manages the download table's data.
class DownloadsTableModel extends AbstractTableModel
  implements Observer
{
  // These are the names for the table's columns.
  private static final String[] columnNames = {"URL", "Size",
    "Progress", "Status"};

  // These are the classes for each column's values.
  private static final Class[] columnClasses = {String.class,
    String.class, JProgressBar.class, String.class};

  // The table's list of downloads.
  private ArrayList<Download> downloadList =
             new ArrayList<Download>();

  // Add a new download to the table.
  public void addDownload(Download download) {
    // Register to be notified when the download changes.
    download.addObserver(this);

    downloadList.add(download);

    // Fire table row insertion notification to table.
    fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
  }

  // Get a download for the specified row.
  public Download getDownload(int row) {
    return (Download) downloadList.get(row);
  }

  // Remove a download from the list.
  public void clearDownload(int row) {
    downloadList.remove(row);

    // Fire table row deletion notification to table.
    fireTableRowsDeleted(row, row);
  }

  // Get table's column count.
  public int getColumnCount() {
    return columnNames.length;
  }

  // Get a column's name.
  public String getColumnName(int col) {
     return columnNames[col];
  }

  // Get a column's class.
  public Class<?> getColumnClass(int col) {
    return columnClasses[col];
  }

  // Get table's row count.
  public int getRowCount() {
    return downloadList.size();
  }

  // Get value for a specific row and column combination.
  public Object getValueAt(int row, int col) {
    Download download = downloadList.get(row);
    switch (col) {
      case 0: // URL
        return download.getUrl();
      case 1: // Size
        int size = download.getSize();
        return (size == -1) ? "" : Integer.toString(size);
      case 2: // Progress
        return new Float(download.getProgress());
      case 3: // Status
        return Download.STATUSES[download.getStatus()];
    }
    return "";
  }

  /* Update is called when a Download notifies its
     observers of any changes */
  public void update(Observable o, Object arg) {
    int index = downloadList.indexOf(o);
    // Fire table row update notification to table.
    fireTableRowsUpdated(index, index);
  }
}


import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

// This class renders a JProgressBar in a table cell.
class ProgressRenderer extends JProgressBar
  implements TableCellRenderer
{
  // Constructor for ProgressRenderer.
  public ProgressRenderer(int min, int max) {
    super(min, max);
  }

  /* Returns this JProgressBar as the renderer
     for the given table cell. */
  public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected,
    boolean hasFocus, int row, int column)
  {
    // Set JProgressBar's percent complete value.
    setValue((int) ((Float) value).floatValue());
    return this;
  }
}
```

5) Write a program to display the contents of a RDBMS table in a tabular format ?

Ans. Here is a code (split into several files for readability) that does just that.
When you write software you need to split the code into several files, so that it's easy to read & follow!!

JDBCAdapter.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

/**
 * An adaptor, transforming the JDBC interface to the TableModel interface.
 *
 * @author Philip Milne
 */
 [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public class JDBCAdapter extends AbstractTableModel {

    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;
    private String[] columnNames = {};
    private List<List<Object>> rows = new ArrayList<>();
    private ResultSetMetaData metaData;

    public JDBCAdapter(String url, String driverName,
            String user, String passwd) {
        try {
            Class.forName(driverName);
            System.out.println("Opening db connection");

            connection = DriverManager.getConnection(url, user, passwd);
            statement = connection.createStatement();
        } catch (ClassNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Cannot find the database driver classes.", "Error", JOptionPane.WARNING_MESSAGE);

        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Cannot connect to this database!!", "Error", JOptionPane.WARNING_MESSAGE);
        }
    }

    public void executeQuery(String query) {
        if (connection == null || statement == null) {
            JOptionPane.showMessageDialog(null, "There is no database to execute the query!!", "Error", JOptionPane.WARNING_MESSAGE);
            return;
        }
        try {
            resultSet = statement.executeQuery(query);
            metaData = resultSet.getMetaData();

            int numberOfColumns = metaData.getColumnCount();
            columnNames = new String[numberOfColumns];
            // Get the column names and cache them.
            // Then we can close the connection.
            for (int column = 0; column < numberOfColumns; column++) {
                columnNames[column] = metaData.getColumnLabel(column + 1);
            }

            // Get all rows.
            rows = new ArrayList<>();
            while (resultSet.next()) {
                List<Object> newRow = new ArrayList<>();
                for (int i = 1; i <= getColumnCount(); i++) {
                    newRow.add(resultSet.getObject(i));
                }
                rows.add(newRow);
            }
            //  close(); Need to copy the metaData, bug in jdbc:odbc driver.

            // Tell the listeners a new table has arrived.
            fireTableChanged(null);
        } catch (SQLException ex) {
            System.err.println(ex);
        }
    }

    public void close() throws SQLException {
        System.out.println("Closing db connection");
        resultSet.close();
        statement.close();
        connection.close();
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    //////////////////////////////////////////////////////////////////////////
    //
    //             Implementation of the TableModel Interface
    //
    //////////////////////////////////////////////////////////////////////////
    // MetaData
    @Override
    public String getColumnName(int column) {
        if (columnNames[column] != null) {
            return columnNames[column];
        } else {
            return "";
        }
    }

    @Override
    public Class<?> getColumnClass(int column) {
        int type;
        try {
            type = metaData.getColumnType(column + 1);
        } catch (SQLException e) {
            return super.getColumnClass(column);
        }

        switch (type) {
            case Types.CHAR:
            case Types.VARCHAR:
            case Types.LONGVARCHAR:
                return String.class;

            case Types.BIT:
                return Boolean.class;

            case Types.TINYINT:
            case Types.SMALLINT:
            case Types.INTEGER:
                return Integer.class;

            case Types.BIGINT:
                return Long.class;

            case Types.FLOAT:
            case Types.DOUBLE:
                return Double.class;

            case Types.DATE:
                return java.sql.Date.class;

            default:
                return Object.class;
        }
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        try {
            return metaData.isWritable(column + 1);
        } catch (SQLException e) {
            return false;
        }
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    // Data methods
    @Override
    public int getRowCount() {
        return rows.size();
    }

    @Override
    public Object getValueAt(int aRow, int aColumn) {
        List<Object> row = rows.get(aRow);
        return row.get(aColumn);
    }

    public String dbRepresentation(int column, Object value) {
        int type;

        if (value == null) {
            return "null";
        }

        try {
            type = metaData.getColumnType(column + 1);
        } catch (SQLException e) {
            return value.toString();
        }

        switch (type) {
            case Types.INTEGER:
            case Types.DOUBLE:
            case Types.FLOAT:
                return value.toString();
            case Types.BIT:
                return ((Boolean) value).booleanValue() ? "1" : "0";
            case Types.DATE:
                return value.toString(); // This will need some conversion.
            default:
                return "\"" + value.toString() + "\"";
        }

    }

    @Override
    public void setValueAt(Object value, int row, int column) {
        try {
            String tableName = metaData.getTableName(column + 1);
            // Some of the drivers seem buggy, tableName should not be null.
            if (tableName == null) {
                System.out.println("Table name returned null.");
            }
            String columnName = getColumnName(column);
            String query
                    = "update " + tableName + " set " + columnName + " = "
                    + dbRepresentation(column, value) + " where ";
            // We don't have a model of the schema so we don't know the
            // primary keys or which columns to lock on. To demonstrate
            // that editing is possible, we'll just lock on everything.
            for (int col = 0; col < getColumnCount(); col++) {
                String colName = getColumnName(col);
                if (colName.equals("")) {
                    continue;
                }
                if (col != 0) {
                    query = query + " and ";
                }
                query = query + colName + " = " + dbRepresentation(col,
                        getValueAt(row, col));
            }
            System.out.println(query);
            System.out.println("Not sending update to database");
            // statement.executeQuery(query);
        } catch (SQLException e) {
            System.err.println("Update failed");
        }
        List<Object> dataRow = rows.get(row);
        dataRow.set(column, value);

    }
}
```

TableExample.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
/**
 * A a UI around the JDBCAdaptor, allowing database data to be interactively
 * fetched, sorted and displayed using Swing.
 *
 * NOTE: This example uses a modal dialog via the static convenience methods in
 * the JOptionPane. Use of modal dialogs requires JDK 1.1.4 or greater.
 *
 * @author Philip Milne
 */
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.BevelBorder;

public final class TableExample implements LayoutManager {

    private static String[] ConnectOptionNames = {"Connect"};
    private static String ConnectTitle = "Connection Information";
    private Dimension origin = new Dimension(0, 0);
    private JButton fetchButton;
    private JButton showConnectionInfoButton;
    private JPanel connectionPanel;
    private JFrame frame; // The query/results window.
    private JLabel userNameLabel;
    private JTextField userNameField;
    private JLabel passwordLabel;
    private JTextField passwordField;
    private JTextArea queryTextArea;
    private JComponent queryAggregate;
    private JLabel serverLabel;
    private JTextField serverField;
    private JLabel driverLabel;
    private JTextField driverField;
    private JPanel mainPanel;
    private TableSorter sorter;
    private JDBCAdapter dataBase;
    private JScrollPane tableAggregate;

    /**
     * Brigs up a JDialog using JOptionPane containing the connectionPanel. If
     * the user clicks on the 'Connect' button the connection is reset.
     */
    void activateConnectionDialog() {
        if (JOptionPane.showOptionDialog(tableAggregate, connectionPanel,
                ConnectTitle,
                JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
                null, ConnectOptionNames, ConnectOptionNames[0]) == 0) {
            connect();
            frame.setVisible(true);
        } else if (!frame.isVisible()) {
            System.exit(0);
        }
    }

    /**
     * Creates the connectionPanel, which will contain all the fields for the
     * connection information.
     */
    public void createConnectionDialog() {
        // Create the labels and text fields.
        userNameLabel = new JLabel("User name: ", JLabel.RIGHT);
        userNameField = new JTextField("app");

        passwordLabel = new JLabel("Password: ", JLabel.RIGHT);
        passwordField = new JTextField("app");

        serverLabel = new JLabel("Database URL: ", JLabel.RIGHT);
        serverField = new JTextField("jdbc:derby://localhost:1527/sample");

        driverLabel = new JLabel("Driver: ", JLabel.RIGHT);
        driverField = new JTextField("org.apache.derby.jdbc.ClientDriver");

        connectionPanel = new JPanel(false);
        connectionPanel.setLayout(new BoxLayout(connectionPanel,
                BoxLayout.X_AXIS));

        JPanel namePanel = new JPanel(false);
        namePanel.setLayout(new GridLayout(0, 1));
        namePanel.add(userNameLabel);
        namePanel.add(passwordLabel);
        namePanel.add(serverLabel);
        namePanel.add(driverLabel);

        JPanel fieldPanel = new JPanel(false);
        fieldPanel.setLayout(new GridLayout(0, 1));
        fieldPanel.add(userNameField);
        fieldPanel.add(passwordField);
        fieldPanel.add(serverField);
        fieldPanel.add(driverField);

        connectionPanel.add(namePanel);
        connectionPanel.add(fieldPanel);
    }

    public TableExample() {
        mainPanel = new JPanel();

        // Create the panel for the connection information
        createConnectionDialog();

        // Create the buttons.
        showConnectionInfoButton = new JButton("Configuration");
        showConnectionInfoButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                activateConnectionDialog();
            }
        });

        fetchButton = new JButton("Fetch");
        fetchButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fetch();
            }
        });

        // Create the query text area and label.
        queryTextArea = new JTextArea("SELECT * FROM APP.CUSTOMER", 25, 25);
        queryAggregate = new JScrollPane(queryTextArea);
        queryAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));

        // Create the table.
        tableAggregate = createTable();
        tableAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));

        // Add all the components to the main panel.
        mainPanel.add(fetchButton);
        mainPanel.add(showConnectionInfoButton);
        mainPanel.add(queryAggregate);
        mainPanel.add(tableAggregate);
        mainPanel.setLayout(this);

        // Create a Frame and put the main panel in it.
        frame = new JFrame("TableExample");
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setBackground(Color.lightGray);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(false);
        frame.setBounds(200, 200, 640, 480);

        activateConnectionDialog();
    }

    public void connect() {
        dataBase = new JDBCAdapter(
                serverField.getText(),
                driverField.getText(),
                userNameField.getText(),
                passwordField.getText());
        sorter.setModel(dataBase);
    }

    public void fetch() {
        dataBase.executeQuery(queryTextArea.getText());
    }

    public JScrollPane createTable() {
        sorter = new TableSorter();

        //connect();
        //fetch();
        // Create the table
        JTable table = new JTable(sorter);
        // Use a scrollbar, in case there are many columns.
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Install a mouse listener in the TableHeader as the sorter UI.
        sorter.addMouseListenerToHeaderInTable(table);

        JScrollPane scrollpane = new JScrollPane(table);

        return scrollpane;
    }

    public static void main(String s[]) {
        // Trying to set Nimbus look and feel
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(TableExample.class.getName()).log(Level.SEVERE,
                    "Failed to apply Nimbus look and feel", ex);
        }

        new TableExample();
    }

    @Override
    public Dimension preferredLayoutSize(Container c) {
        return origin;
    }

    @Override
    public Dimension minimumLayoutSize(Container c) {
        return origin;
    }

    @Override
    public void addLayoutComponent(String s, Component c) {
    }

    @Override
    public void removeLayoutComponent(Component c) {
    }

    @Override
    public void layoutContainer(Container c) {
        Rectangle b = c.getBounds();
        int topHeight = 90;
        int inset = 4;
        showConnectionInfoButton.setBounds(b.width - 2 * inset - 120, inset, 120,
                25);
        fetchButton.setBounds(b.width - 2 * inset - 120, 60, 120, 25);
        // queryLabel.setBounds(10, 10, 100, 25);
        queryAggregate.setBounds(inset, inset, b.width - 2 * inset - 150, 80);
        tableAggregate.setBounds(new Rectangle(inset,
                inset + topHeight,
                b.width - 2 * inset,
                b.height - 2 * inset - topHeight));
    }
}
```

TableMap.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
/**
 * In a chain of data manipulators some behaviour is common. TableMap provides
 * most of this behavour and can be subclassed by filters that only need to
 * override a handful of specific methods. TableMap implements TableModel by
 * routing all requests to its model, and TableModelListener by routing all
 * events to its listeners. Inserting a TableMap which has not been subclassed
 * into a chain of table filters should have no effect.
 *
 * @author Philip Milne
 */
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

 [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public class TableMap extends AbstractTableModel implements TableModelListener {

    protected TableModel model;

    public TableModel getModel() {
        return model;
    }

    public void setModel(TableModel model) {
        this.model = model;
        model.addTableModelListener(this);
    }

    // By default, Implement TableModel by forwarding all messages
    // to the model.
    @Override
    public Object getValueAt(int aRow, int aColumn) {
        return model.getValueAt(aRow, aColumn);
    }

    @Override
    public void setValueAt(Object aValue, int aRow, int aColumn) {
        model.setValueAt(aValue, aRow, aColumn);
    }

    @Override
    public int getRowCount() {
        return (model == null) ? 0 : model.getRowCount();
    }

    @Override
    public int getColumnCount() {
        return (model == null) ? 0 : model.getColumnCount();
    }

    @Override
    public String getColumnName(int aColumn) {
        return model.getColumnName(aColumn);
    }

    @Override
    public Class<?> getColumnClass(int aColumn) {
        return model.getColumnClass(aColumn);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return model.isCellEditable(row, column);
    }
// Implementation of the TableModelListener interface,
// By default forward all events to all the listeners.

    @Override
    public void tableChanged(TableModelEvent e) {
        fireTableChanged(e);
    }
}
```

TableSorter.java


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * A sorter for TableModels. The sorter has a model (conforming to TableModel)
 * and itself implements TableModel. TableSorter does not store or copy the data
 * in the TableModel, instead it maintains an array of integers which it keeps
 * the same size as the number of rows in its model. When the model changes it
 * notifies the sorter that something has changed eg. "rowsAdded" so that its
 * internal array of integers can be reallocated. As requests are made of the
 * sorter (like getValueAt(row, col) it redirects them to its model via the
 * mapping array. That way the TableSorter appears to hold another copy of the
 * table with the rows in a different order. The sorting algorthm used is stable
 * which means that it does not move around rows when its comparison function
 * returns 0 to denote that they are equivalent.
 *
 * @author Philip Milne
 */
 [MENTION=139512]Sup[/MENTION]pressWarnings("serial")
public final class TableSorter extends TableMap {

    int indexes[];
    List<Integer> sortingColumns = new ArrayList<>();
    boolean ascending = true;
    int compares;

    public TableSorter() {
        indexes = new int[0]; // For consistency.
    }

    public TableSorter(TableModel model) {
        setModel(model);
    }

    @Override
    public void setModel(TableModel model) {
        super.setModel(model);
        reallocateIndexes();
    }

    public int compareRowsByColumn(int row1, int row2, int column) {
        Class<?> type = model.getColumnClass(column);
        TableModel data = model;

        // Check for nulls
        Object o1 = data.getValueAt(row1, column);
        Object o2 = data.getValueAt(row2, column);

        // If both values are null return 0
        if (o1 == null && o2 == null) {
            return 0;
        } else if (o1 == null) { // Define null less than everything.
            return -1;
        } else if (o2 == null) {
            return 1;
        }

        /* We copy all returned values from the getValue call in case
         an optimised model is reusing one object to return many values.
         The Number subclasses in the JDK are immutable and so will not be used
         in this way but other subclasses of Number might want to do this to save
         space and avoid unnecessary heap allocation.
         */
        if (type.getSuperclass() == java.lang.Number.class) {
            Number n1 = (Number) data.getValueAt(row1, column);
            double d1 = n1.doubleValue();
            Number n2 = (Number) data.getValueAt(row2, column);
            double d2 = n2.doubleValue();

            if (d1 < d2) {
                return -1;
            } else if (d1 > d2) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == java.util.Date.class) {
            Date d1 = (Date) data.getValueAt(row1, column);
            long n1 = d1.getTime();
            Date d2 = (Date) data.getValueAt(row2, column);
            long n2 = d2.getTime();

            if (n1 < n2) {
                return -1;
            } else if (n1 > n2) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == String.class) {
            String s1 = (String) data.getValueAt(row1, column);
            String s2 = (String) data.getValueAt(row2, column);
            int result = s1.compareTo(s2);

            if (result < 0) {
                return -1;
            } else if (result > 0) {
                return 1;
            } else {
                return 0;
            }
        } else if (type == Boolean.class) {
            Boolean bool1 = (Boolean) data.getValueAt(row1, column);
            boolean b1 = bool1.booleanValue();
            Boolean bool2 = (Boolean) data.getValueAt(row2, column);
            boolean b2 = bool2.booleanValue();

            if (b1 == b2) {
                return 0;
            } else if (b1) // Define false < true
            {
                return 1;
            } else {
                return -1;
            }
        } else {
            Object v1 = data.getValueAt(row1, column);
            String s1 = v1.toString();
            Object v2 = data.getValueAt(row2, column);
            String s2 = v2.toString();
            int result = s1.compareTo(s2);

            if (result < 0) {
                return -1;
            } else if (result > 0) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    public int compare(int row1, int row2) {
        compares++;
        for (int level = 0; level < sortingColumns.size(); level++) {
            Integer column = sortingColumns.get(level);
            int result = compareRowsByColumn(row1, row2, column.intValue());
            if (result != 0) {
                return ascending ? result : -result;
            }
        }
        return 0;
    }

    public void reallocateIndexes() {
        int rowCount = model.getRowCount();

        // Set up a new array of indexes with the right number of elements
        // for the new data model.
        indexes = new int[rowCount];

        // Initialise with the identity mapping.
        for (int row = 0; row < rowCount; row++) {
            indexes[row] = row;
        }
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        System.out.println("Sorter: tableChanged");
        reallocateIndexes();

        super.tableChanged(e);
    }

    public void checkModel() {
        if (indexes.length != model.getRowCount()) {
            System.err.println("Sorter not informed of a change in model.");
        }
    }

    public void sort(Object sender) {
        checkModel();

        compares = 0;
        // n2sort();
        // qsort(0, indexes.length-1);
        shuttlesort(indexes.clone(), indexes, 0, indexes.length);
        System.out.println("Compares: " + compares);
    }

    public void n2sort() {
        for (int i = 0; i < getRowCount(); i++) {
            for (int j = i + 1; j < getRowCount(); j++) {
                if (compare(indexes[i], indexes[j]) == -1) {
                    swap(i, j);
                }
            }
        }
    }

    // This is a home-grown implementation which we have not had time
    // to research - it may perform poorly in some circumstances. It
    // requires twice the space of an in-place algorithm and makes
    // NlogN assigments shuttling the values between the two
    // arrays. The number of compares appears to vary between N-1 and
    // NlogN depending on the initial order but the main reason for
    // using it here is that, unlike qsort, it is stable.
    public void shuttlesort(int from[], int to[], int low, int high) {
        if (high - low < 2) {
            return;
        }
        int middle = (low + high) / 2;
        shuttlesort(to, from, low, middle);
        shuttlesort(to, from, middle, high);

        int p = low;
        int q = middle;

        /* This is an optional short-cut; at each recursive call,
         check to see if the elements in this subset are already
         ordered.  If so, no further comparisons are needed; the
         sub-array can just be copied.  The array must be copied rather
         than assigned otherwise sister calls in the recursion might
         get out of sinc.  When the number of elements is three they
         are partitioned so that the first set, [low, mid), has one
         element and and the second, [mid, high), has two. We skip the
         optimisation when the number of elements is three or less as
         the first compare in the normal merge will produce the same
         sequence of steps. This optimisation seems to be worthwhile
         for partially ordered lists but some analysis is needed to
         find out how the performance drops to Nlog(N) as the initial
         order diminishes - it may drop very quickly.  */
        if (high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
            System.arraycopy(from, low, to, low, high - low);
            return;
        }

        // A normal merge.
        for (int i = low; i < high; i++) {
            if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
                to[i] = from[p++];
            } else {
                to[i] = from[q++];
            }
        }
    }

    public void swap(int i, int j) {
        int tmp = indexes[i];
        indexes[i] = indexes[j];
        indexes[j] = tmp;
    }

    // The mapping only affects the contents of the data rows.
    // Pass all requests to these rows through the mapping array: "indexes".
    @Override
    public Object getValueAt(int aRow, int aColumn) {
        checkModel();
        return model.getValueAt(indexes[aRow], aColumn);
    }

    @Override
    public void setValueAt(Object aValue, int aRow, int aColumn) {
        checkModel();
        model.setValueAt(aValue, indexes[aRow], aColumn);
    }

    public void sortByColumn(int column) {
        sortByColumn(column, true);
    }

    public void sortByColumn(int column, boolean ascending) {
        this.ascending = ascending;
        sortingColumns.clear();
        sortingColumns.add(column);
        sort(this);
        super.tableChanged(new TableModelEvent(this));
    }

    // There is no-where else to put this.
    // Add a mouse listener to the Table to trigger a table sort
    // when a column heading is clicked in the JTable.
    public void addMouseListenerToHeaderInTable(JTable table) {
        final TableSorter sorter = this;
        final JTable tableView = table;
        tableView.setColumnSelectionAllowed(false);
        MouseAdapter listMouseListener = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                TableColumnModel columnModel = tableView.getColumnModel();
                int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                int column = tableView.convertColumnIndexToModel(viewColumn);
                if (e.getClickCount() == 1 && column != -1) {
                    System.out.println("Sorting ...");
                    int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
                    boolean ascending = (shiftPressed == 0);
                    sorter.sortByColumn(column, ascending);
                }
            }
        };
        JTableHeader th = tableView.getTableHeader();
        th.addMouseListener(listMouseListener);
    }
}
```

Place all the files in the same directory. If you use an IDE like NetBeans or IDEA or Eclipse, place them under the same package.

To run the program , type

java TableExample

NOTE : You need to connect to Apache Derby Database table called 'sample' first.
Use a Java IDE like NetBeans -> Under the 'Services' tab under 'Drivers' , select jdbc:derby , right-click , select 'connect' (from the PopupMenu)

You can connect it to any RDBMS like Oracle, SQL Server, DB2, MySQL SyBase etc.,


This wraps up this tutorial on how to program using Java language!!
Java is not only fun to use, easy to program compared C/C++. You should use the necessary Java API with the correct logic. The solution is available for a given problem in a few minutes!!
If you take the initial step , start writing programs, you can become a Java expert in a few years time!!
If you are a graduate who has finished a course in Programming from Aptech/NIIT, CSC etc., (1 year course) Then you need to learn how to program
by yourself by studying these books. You need to understand programming & master them. ie., go beyond the basics!!
Then you can apply yourself to write bigger monster programs (say a Image processor, Download Manager, CRM etc.,).

Q) Which are the best institutes that teach Computer programming in India ?

Ans. There are institutes like Aptech, NIIT, CSC etc., that teach the basics in C/C++/C#/Java/Oracle.
     There is RCS, Bangalore which teaches Java (Very good). NIIT/Aptech/CSC teaching is very basic!!
     So NIIT/Aptech/CSC don't make the cut. Most of the NIIT & Aptech guys don't know a wee bit about
     programming, that's the bitter truth!! I'm an Aptech student myself!! So I know the inside view of things.
     I have learnt programming by myself by studying the best books on programming & writing more programs by myself.

     On a serious note there isn't any great institute that teaches Computer programming!!
     If you want to learn Networking, Security ( CCIE, CCNP, CCNA, CCSE, CISSP, CCNA, CWNA etc.,) go for
     Top Gun Technologies, Bangalore (www.topguntechnologies.com). They are best out there in Security & Networking.

     You can also study in the top colleges in India like VIT (Vellore Institute of Technology), NIT (National Institute of Technology),
     SRM University, IIIT (Indian Institute of Information Technology), BITS (Birla Institute of Technology & Science), Amity University etc.,

     Most of the top colleges have campus recruitment. The companies like TCS, Infosys, Cognizant, Oracle, Google, Honeywell, etc., recruit from the top colleges.

Q) What are the projects I can do in Java?

  Ans. You can write a GUI (Swing) application, applet or a e-commerce application (Servlet/JSP) or a JavaME (Java Micro Edition).
       Here are some projects that you can do.

*Swing (GUI)*

   1) Banking System

   2) Customer Relationship Software (CRM)

   3) Text Editor (TextPad)

   4) Integrated Development Environment (IDE like NetBeans, Eclipse, JDeveloper) (NOTE :  IDE Development is only for Java experts !!, not for novice programmers!!!)

   5) Media Player (WinAmp, iTunes)

   6) Web Browser (FireFox, Chrome, Opera)

   7) Image Processing (PhotoShop, GIMP)

   8) Peer to Peer (P2P like LimeWire)

   9) DataBase Explorer

   10) Download Manager (FlashGet, DAP)

   11) RDBMS (Oracle, DB2, SQL Server)

   12) Supply Chain Management (SCM)

   13) Text to Speech Converter 

   14) Accounting (Tally, Busy)

   15) 3D Modelling program (using Java3D - like Blender, ZBrush, Sculptris)

   16) Geographical Information System (GIS)

   17) Enterpise Resource Planning (ERP like SAP, Oracle Financials)

   18) Compiler design in Java ( Compiler design is for Java experts , it needs professional expertise!!! It's not for novice programmers!!!)

   19) Stock Market monitoring Applet or application

   20) XML Editor

   21) Zip archiver like WinZip, WinRAR

   22) UML Editor (Unified Modeling Language)

   23) FTP Client

   24) Web Server

   25) Voice Chat & Video Conferencing (using JMF)

   26) Word processor (like MS Word )

*E-Commerce* (JSP/Servlets)

   1) Banking System

   2) HRM (Human Resource Management)

   3) Airline Reservation System

   4) Job Portal System (naukri.com, monster.com)

   5) Inventory Management System

   6) Hotel Management System

   7) Energy Billing System

   8) Travel Billing System

   9) Online ecommerce Portal (eBay, amazon.com)

   10) Telecom management System

   11) Voice chat & Video conferencing (using JMF)

*Mobile Development* (JavaME)

   1) M-commerce

   2) Game Development

   3) Media Player

   4) Web Crawler

   5) Download Manager

   6) Web Browser 


   Q) What are the books I need to study, to write a Project in Java ?

   Ans.

*Must read Books for writing Java Projects:*

   1) Core Java - Vol -I & II by Horstmann C S

   2) Beginning Java Objects (Wrox)/ Object-Oriented Programming in Java by Balagurusamy

   3) Java Tutorial 5th Edition

   4) Graphic Java 2 ,Volume 2 Swing: Mastering the JFC by David M Geary

   5) Data Structures & Algorithms in Java by Robert Lafore (Techmedia) / Algorithms in Java 4th Edition by Robert SedgeWick

   6) The Java Developers Almanac 1.4, Volume I & II by Patrick Chan

   7) Java Swing 5th Edition by Eckstein (Oreilly)

   8) Thinking in Java 

   9) Object-Oriented Design in Java by Stephen Gilbert and Bill McCarty

   10) Oracle Database JDBC Developer's Guide & Reference

   11) Beginning Java Databases / Java Database Programming Bible by John O' Donahue 

   12) Professional Java Programming (Wrox)

   13) Beginning Java Networking (Wrox)/ An Itroduction to Network Programming with Java : Java 7 Compatible by Jan Graba

   14) JSP 2.0 : The Complete Reference by Phil Hanna (Tata McGraw Hill)

   15) Struts : The Complete Reference (Tata McGraw Hill)

   16) Mastering HTML 5 (Sybex/ BPB)

   17) Professional Java Networking (Wrox)

   18) Oracle 12c: The Complete Reference (Tata McGraw Hill)

   19) Java Threads (Oreilly)

   20) Java How To Program by H M Deitel & P J Deitel 

   21) Software Engineering in Java 

   23) Desktop Java Live (Discusses various Layout Managers , GUI Builders, Swing Threading, Data Binding , Validation, Packaging & Deployment )

   24) Java Servlet Programming by Jason Hunter, William Crawford (Oreilly)

   Also if you are new to software development(Project). Then download a Open Source project (sourceforge.net) & study it. See
   how things are implemented. Study the Source code in detail. This will help you understand what a Software project is!!
   Apply yourself to develop something very similar to what you have seen.
   You need to work day & night , 12 hours a day for a year to become a very good programmer!!

Happy Coding!! 

*Books on Programming*

1) Core Java (2 volumes) / Beginning Java 7 (Wrox)

2) Algorithms in Java (4th Edition) by Robert Sedgewick and Kevin Wayne

3) Algorithms in C++ by Robert Sedgewick (Addison Wesley)

4) Thinking in Java 

5) Thinking in C++

6) Data Structures & Algorithms in Java by Robert Lafore 

7) Java How To Program by H M Deitel & P J Deitel 

8) C++ How To Program by H M Deitel & P J Deitel 

9) C# How To Program by H M Deitel & P J Deitel 

10) Effective Java by Joshua Bloch 

11) Effective C# by Joshua Bloch

12) Effective C++ by Joshua Bloch

13) Programming Pearls by Jon Bentely (Addison Wesley 1986)

14) Writing Solid Code by Steve Maguire (Microsoft Press 1993)

15) The Art of Computer Programming by Donald E. Knuth (3 Volumes ,Addison Wesley 1997)

16) The Mythical Man-Month by Frederick P Brooks Jr (Addison Wesley 1975)


----------



## Desmond (Sep 25, 2014)

This article does warrant as an introduction tutorial. The examples you have provided are too complicated and advanced for an introduction. It would be better if you could explain from the basics of OOP and so forth.


----------



## JGuru (Nov 4, 2014)

David, the examples provided are in the beginner to intermediate level. Also if you want to become a good programmer then you should
work atleast 10 to 12 hours a day, study atleast 15 best books on Java and write more programs!!!
There are no shortcuts!! Practise, practise, practise is the mantra!!


----------

