Friday, December 9, 2016

Internal resources in Eclipse

Files can be opened from storage devices, but they need a specific path and drive letter, sometimes.  If you are planning to create a runnable jar file created from your project, it is better to access the resources internally from an internal resource path and include them in the runnable jar file.

This simple example demonstrates the process.

1. Create two images with 600x400 dimensions and name them one.jpg and two.jpg.  Store them on your C drive's temp directory for now.
2. Follow the image below to create a new resource folder (1-8) in your project.
3. Import (9) the two image files into the newly created res resource folder.



import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


@SuppressWarnings("serial")
public class FirstGuiApp extends JPanel{
BufferedImage img;

//First try - load images from your hard drive
//String img1 = "c:\\temp\\one.jpg";
//String img2 = "c:\\temp\\two.jpg";

//Second try - load images from internal resource, comment out first step

/*Add project folder res ( add res path to project properties->Build Path->Source)
 * Then, import two jpg images 600x400 named one.jpg and two.jpg
 * */

String img1 = "one.jpg";
String img2 = "two.jpg";
boolean evenClick = false;

public FirstGuiApp(){
setSize(600,400);
setVisible(true);
loadImage(img1);

this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent me){
if(evenClick){
    loadImage(img1);
    evenClick=false;
    }
else{
    loadImage(img2);
    evenClick=true;
    }
updateUI();
}

});
}//end of FirstGuiApp

private void loadImage(String str){
try{
       //img=ImageIO.read(FirstGuiApp.class.getResource(str)); //one way to load internal resoure
       img=ImageIO.read(getClass().getResource(str)); //preferred way of loading internal resource
       //img=ImageIO.read(new File(str)); //use this with first step to load image from hard drive
     }
catch(IOException e){   e.printStackTrace();  }
}//end of loadImage method

protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(img, 0, 0, 600, 400, this);

}//end of paintComponent

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
              public void run(){
                         JFrame frm = new JFrame();
                         frm.setSize(620,465);
                         frm.setVisible(true);
                         frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                         frm.add(new FirstGuiApp());
                         frm.setTitle("My GUI Application");
                         }//end of run
              }//end of runnable
          );
     }//end of main
}//end of class

Run the program.  The program window should show your image one.jpg and when you click on the image the image two.jpg is loaded alternating between the images. If it does not work, uncomment

//String img1 = "c:\\temp\\one.jpg";
//String img2 = "c:\\temp\\two.jpg";


and 

//img=ImageIO.read(new File(str)); //use this with first step to load image from hard drive

and comment out the following lines to load the images from your hard drive directly for trouble shooting.

String img1 = "one.jpg";
String img2 = "two.jpg";

img=ImageIO.read(getClass().getResource(str)); //preferred way of loading internal resource
 
After you have tested your application, you can then create the runnable jar file.


Speed Test Array Processing By - Column vs. Row

At small array elements, processing arrays by row vs. by column might not suggest any difference in speed, but as elements increase, the difference will show its face.

Most people see arrays like this:

... but arrays are stored as a linear structure of consecutive cells.  Arrays look like this in memory and visualizing them might help better understand their performance difference.

What values do the consistent difference show up?  Try it, test it, document it, share your results!!!



public class TestArrays{
  
public static void main(String[] args){

int[][] array2D=new int[Dim.R.val][Dim.C.val];
long milis = System.currentTimeMillis();
processByRow(array2D);
System.out.println("2D Array processed by row takes "+(System.currentTimeMillis() - milis)+" ms");

milis = System.currentTimeMillis();
processByColumn(array2D);
System.out.println("2D Array processed by column takes "+(System.currentTimeMillis() - milis)+" ms");

}

private static void processByRow(int[][] array2D){
    for(int row=0;row<Dim.R.val;row++){
        for(int column=0;column<Dim.C.val;column++){
            array2D[row][column]=5;
        }
    } 
}

private static void processByColumn(int[][] array2D){
    for(int column=0;column<Dim.C.val;column++){  
        for(int row=0;row<Dim.R.val;row++){
           array2D[row][column]=5;
        }
    }
}
private enum Dim{R(10),C(10);
        public final int val;
        Dim(int val){this.val=val;}
        public int getValue() { return val; }
}
}

Run msinfo32 on your system to gather basic info about your basic configuration.

OS Name    Microsoft Windows 8.1 Pro
System Type:x64-based PC
Processor:Intel(R) Core(TM) i7-4702HQ CPU @ 2.20GHz, 2201 Mhz, 4 Core(s), 8 Logical Processor(s)
Installed Physical Memory (RAM):16.0 GB
Total Physical Memory:15.9 GB
Available Physical Memory:6.78 GB
Total Virtual Memory:18.3 GB
Available Virtual Memory:8.72 GB
Page File Space:2.38 GB
10x10 Array Processed
2D Array processed by row takes 0 ms
2D Array processed by column takes 0 ms
100x100 Array Processed
2D Array processed by row takes 1 ms
2D Array processed by column takes 0 ms
1000x1000 Array Processed
2D Array processed by row takes 2 ms
2D Array processed by column takes 6 ms

1000x10000 Array Processed
2D Array processed by row takes 17 ms
2D Array processed by column takes 265 ms
10000x1000 Array Processed
2D Array processed by row takes 16 ms
2D Array processed by column takes 136 ms

 

Wednesday, November 30, 2016

Error Handling Challenge

In this exercise, you will learn how to handle exceptions and how to validate inputs.

The base code is:
/**
 * Class MyCopy does just that, it copies a file into another.
 * @author Zoltan Szabo
 * @version 1.0.0
 */
public class MyCopy{
    /**
     * Entry point to application.
     * If output file exists or input file does not exists, it sets errorlevel.
     * @param args[0] source file name
     * @param args[1] destination file name
     */
    public static void main(String args[]){
            File inFile=new File(args[0]);  //source file name
            File outFile=new File(args[1]); //destination file name

            Scanner input = new Scanner(inFile);
            PrintWriter output = new PrintWriter(outFile);
            while(input.hasNext()){                    //read input file until it reaches the end of file
                    output.println(input.nextLine());
                }
            output.close();
            input.close();
    }
}

Now let's try to compile it with BlueJ ( any other IDE will do that does not give you too much help. Try to find the problems logically using the Java API )

1. We get an error message - "cannot find symbol - class File"  This suggest the missing class, so we should think about importing the class.
Solution:
Go to Java API and search for File class
Copy the path
Add the import java.io.File; to your code
2. We get an error message - "cannot find symbol - class Scanner"  This suggest the missing class, so we should think about importing the class.
Solution:
Go to Java API and search for Scanner class
Copy the path
Add the import java.util.Scanner; to your code
3. We get an error message - "cannot find symbol - class PrintWriter"  This suggest the missing class, so we should think about importing the class.
Solution:
Go to Java API and search for PrintWriter class
Copy the path
Add the import java.io.PrintWriter; to your code
4. At this point, we seem like have all the classes imported, but we get another type of error:
"unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown"
Let's look at the Scanner class constructor to see why we get this error message.
We see that
public Scanner(File source)
        throws FileNotFoundException
and FileNotFoundException is thrown - if source is not found

So, you can add public static void main(String args[])throws java.io.FileNotFoundException to your main method header or just public static void main(String args[])throws FileNotFoundException and then also import java.io.FileNotFoundException; to have the class available.
You should also add the docstring tag @throws since you need to explain why you are throwing the exception.

@throws java.io.FileNotFoundException if source is not found

5. Now, if we run the application without entering a filename argument, we'll get an error:
"java.lang.ArrayIndexOutOfBoundsException:0" This error was not handled yet, so we need to see how we can handle it.  This time, we'll actually will catch the exception and handle it locally instead of throwing it to the JVM to handle.
So, add the try block embracing all statements in the main method and the catch block to the code:

catch(ArrayIndexOutOfBoundsException e){
  System.out.println("You need to type the input and output files for this utility to work properly. \"MyCopy [[drive:\\]path]input.txt [[drive:\\]path]output.txt\"");
   System.exit(2017);
        }

ArrayIndexOutOfBoundsException class is in java.lang so you will not have to import it, but as a learning process, you should add the import anyway and you should also lookup the class in Java API documentation.

6. Now, you should also look at the other classes in your program to see if more exception might be thrown by any one of those classes.
public PrintWriter(File file)
            throws FileNotFoundException
You can see that PrintWriter class also throws an exception, so you can also handle that locally by surrounding the PrintWriter related statements in a try block and catching the exception.

 catch(FileNotFoundException e){
    System.out.println("The destination file " + outFile + " might not have the appropriate rights.");
    System.exit(2016);
    }

If you look further into the methods like nextLine method in the Scanner class also throws exceptions, but instead of handling every exception individually,

public String nextLine()
    NoSuchElementException - if no line was found
    IllegalStateException - if this scanner is closed


you can see in the Java API the hierarchy that it might make sense to throw the Exception object at a method level to handle all other than FileNotFoundException will be thrown and handled by the common class and due to polymorphism, the exception will be handled.

7. You can still have another exception thrown if you do not give the proper input arguments to the application at run time due to the args[0] and args[1] usage.  It can throw and ArrayIndexOutOfBoundsException and that exception should not let the program continue to run.  Thus, add another try/catch block to handle that case as well.

        catch(ArrayIndexOutOfBoundsException e){
            System.out.println("Type the input and output files. \"MyCopy [[drive:\\]path]input.txt [[drive:\\]path]output.txt\"");
            System.exit(2017);
        }

8. Now, you just have to add the input and output validation where we can terminate the application and return an exit code to the OS to show status of program exit.

So, the final program should look like this:

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
//you don't really need it since it is in java.lang, but nice to have it to remind you 
import java.lang.ArrayIndexOutOfBoundsException;
/**
 * Class MyCopy does just that, it copies a file into another.
 * @author Zoltan Szabo
 * @version 1.0.0
 */
public class MyCopy
{
    /**
     * Entry point to application.
     * If output file exists or input file does not exists, it sets errorlevel.
     * @param args[0] source file name
     * @param args[1] destination file name

     * @throws Exception to handle all exceptions not specifically handled locally
     */
    public static void main(String args[])throws Exception {
        try{
            File inFile=new File(args[0]);  //source file name
            File outFile=new File(args[1]); //destination file name

            if (!inFile.exists()){           //Checks if the file name exists
                System.out.println("Source file " + inFile + " does not exists.");
                System.exit(2014);            // Exit the program.
            }

            Scanner input = new Scanner(inFile);

            if (outFile.exists()){           //Checks if the file name already exists
                System.out.println("The destination file " + outFile + " already exists.");
                System.exit(2015);            // Exit the program.
            }

            try{
                PrintWriter output = new PrintWriter(outFile);
                while(input.hasNext()){                    //read input file until it reaches the end of file
                    //System.out.println(input.nextLine());
                    output.println(input.nextLine());
                }
                output.close();
            }
            catch(FileNotFoundException e){
                System.out.println("The destination file " + outFile + " might not have the appropriate rights.");
                System.exit(2016);
            }

            input.close();
        }
        catch(ArrayIndexOutOfBoundsException e){
            System.out.println("Type the input and output files. \"MyCopy [[drive:\\]path]input.txt [[drive:\\]path]output.txt\"");
            System.exit(2017);
        }

    }
}

Exception handling simple example with custom exception

Simple example to practice throwing, catching, and creating custom exceptions.  Look at the API documentation for each class and familiarize yourself with the exceptions the class or method can throw in order to pan for exception handling.  In this example, look up FileReader(String ) constructor and take not of the exception and BufferedReader's readLine() method. 

In order to understand exception handling, you need to understand polymorphic object references. In this case, the relevant inheritance tree is as follows:
java.lang.Object

     java.lang.Throwable
         java.lang.Exception
              java.io.IOException
                   java.io.FileNotFoundException 

The program UML is as follows:

Source code that you should copy/paste and experiment with

import java.io.IOException; // For File class and FileNotFoundException
import java.io.File;
import java.util.Scanner; // For the Scanner class 

/**
 * This program demonstrates how a FileNotFoundException, IOException, and custom exception 
 * exception can be handled.
 */
public class OpenFile {
   public static void main(String[] args)   {
     FilePrinter my=new FilePrinter();
     try{
           my.displayFile("c:\\temp\\input.txt");
    }
    catch(IOException e){
            System.out.println("Got you - can't read anymore");   //change source file security rights to deny read.
           }
   }
}

import java.io.*;   
   
public class FilePrinter{   
     private FileReader reader;   
     private BufferedReader inputFile;   
     private String input;   
   
     public void displayFile(String name)throws IOException{   
       //  try{
                 callMe(name);   
       // }
      //  catch(FileNotFoundException e){
      //      System.out.println("File not found");   
      //  }
     }   
         /**
          * This is just a test
          * @param name as a string of the file name including path to the file if any
          * @throws IOException if file was not found
          * @throws FileNotFoundException if file was not able to open
          */

     public void callMe(String name)throws IOException,FileNotFoundException{   
         try{
          callMeAgain(name);   
        }
        catch(MyError e){
            System.out.println(e.toString());
            System.out.println(e.getMessage());
        }
         catch(FileNotFoundException e){
            System.out.println("File name does not exists.");
           // e.printStackTrace();
           }

         }   
          /**
          * This is just a test
          * @param name as a string of the file name including path to the file if any
          * @throws IOException if file was not found
          * @throws FileNotFoundException if file was not able to open
          * @throws MyError if a particular file name was attempted to open
          */

    public void callMeAgain(String name)throws IOException,FileNotFoundException,MyError{   
          if(name.equals("c:\\temp\\two.jpg"))
              throw new MyError();
          if(name.equals("c:\\temp\\two2.jpg"))
              throw new MyError("This is just a custom message!!!");
          try{
                reader = new FileReader(name);                //throws FileNotFoundException
                inputFile = new BufferedReader(reader);       

                input = inputFile.readLine();                    //throws IOException
                while (input != null) {   
                        System.out.println(input);   
                        input = inputFile.readLine();   
                       }   
                inputFile.close();   
               }
        catch(IOException e){
               System.out.println("read not allowed");   
               }
     }   
}   


public class MyError extends Exception
{
public MyError(){
    super("My error - zoltan");
}
public MyError(String msg){
    super(msg);
}
}