Monday, December 22, 2014

Generating XPATH from a Selenium WebDriver WebElement

Call the method below with 

generateXPATH(element, "");


The output will be something like:

/html[1]/body[1]/div[5]/div[1]/div[2]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/form[1]/div[2]/div[1]/input[2]

METHOD
private String generateXPATH(WebElement childElement, String current) {
    String childTag = childElement.getTagName();
    if(childTag.equals("html")) {
        return "/html[1]"+current;
    }
    WebElement parentElement = childElement.findElement(By.xpath("..")); 
    List<WebElement> childrenElements = parentElement.findElements(By.xpath("*"));
    int count = 0;
    for(int i=0;i<childrenElements.size(); i++) {
        WebElement childrenElement = childrenElements.get(i);
        String childrenElementTag = childrenElement.getTagName();
        if(childTag.equals(childrenElementTag)) {
            count++;
        }
        if(childElement.equals(childrenElement)) {
            return generateXPATH(parentElement, "/" + childTag + "[" + count + "]"+current);
        }
    }
    return null;
}

Monday, December 15, 2014

An Introduction to JNI using a Bottom Up Approach: Prologue

The goal of this article is to allow Java developers to include C++ code in their programs. Related Pages: This tutorial is written such that:
  1. Each individual step represents a technology layer:
    • Step 1: C++ Low Level Function
    • Step 2: C++ Main Function
    • Step 3: C Main Function
    • Step 4: Java Main Function
  2. Each individual step is skippable:
    • This means you can start from any step and work your way forward, with some slight modifications.
    • Developers can decide to follow the steps backwards and use a top down approach (by commenting out access to the lower technology layer).
    • When developing new code, developers can decide not to include bottom technology layers (for instance, starting with Step 3 will mean you have no C++ code and are just using Java to run a C Program).
  3. Each individual step is testable:
    • New developers have less variables involved when stuff doesn't work.
    • Developers get immediate feedback regarding whether they are on the right track.
    • Developers can check a technology layer along with lower technology layers (by uncommmenting the main function are recompiling).
    • When debugging code, developers can decide not to include top technology layers (for instance, running the C main function will mean you are not running the Java code and are just checking the functionality of the C and C++ code).
Prerequisites:
  • You need a Java compiler for Windows (ie, see Getting Started with Java's Hello World: Part I).
  • You need a C++ compiler for Windows (ie, download TDM-GCC at tdm-gcc.tdragon.net).
  • Choose a working directory for the C++/C code (ie, preferrably in your project's resources folder, "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls").
Continued at An Introduction to JNI using a Bottom Up Approach: Step 1.

This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-introduction/, originally written on August 21st, 2013.

An Introduction to JNI using a Bottom Up Approach: Step 1

Continued from An Introduction to JNI using a Bottom Up Approach: Prologue.

Step 1: C++ Low Level Function

  1. In your working directory, add an empty file, named "PrintOpenWindows.h". This will make the functions available other C/C++ files.
    #ifndef _PRINT_OPEN_WINDOWS_H
    #define _PRINT_OPEN_WINDOWS_H

    #ifdef __cplusplus
            extern "C" {
    #endif
            void printOpenWindowsEntryPoint ();
    #ifdef __cplusplus
            }
    #endif

    #endif
  2. In your working directory, add the following code, in a file named "PrintOpenWindows.cpp":
    #include "PrintOpenWindows.h"
    #include <stdlib.h>
    #include <string.h>
    #include <tchar.h>
    #include <windows.h>
    #include <iostream>

    using namespace std;

    BOOL CALLBACK FindWindowBySubstr(HWND hwnd, LPARAM substring)
    {
        const DWORD TITLE_SIZE = 1024;
        TCHAR windowTitle[TITLE_SIZE];

        if (GetWindowText(hwnd, windowTitle, TITLE_SIZE))
        {
            _tprintf(TEXT("%s\n"), windowTitle);
            // Uncomment to print all windows being enumerated
            if (_tcsstr(windowTitle, LPCTSTR(substring)) != NULL)
            {
                // We found the window! Stop enumerating.
                return false;
            }
        }
        return true// Need to continue enumerating windows
    }

    void printOpenWindowsEntryPoint()
    {
        cout << "PRINT_OPEN_WINDOWS ENTRY START" << endl;
        const TCHAR substring[] = TEXT("Substring");
        EnumWindows(FindWindowBySubstr, (LPARAM)substring);
        cout << "PRINT_OPEN_WINDOWS ENTRY FINISH" << endl;
    }

    int main()
    {
        cout << "PRINT_OPEN_WINDOWS MAIN START" << endl;
        printOpenWindowsEntryPoint();
        cout << "PRINT_OPEN_WINDOWS MAIN FINISH" << endl;
    }
  3. Compile the code and run "PrintOpenWindows.exe", using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"

    "C:\MinGW64\bin\g++.exe" -o PrintOpenWindows.exe PrintOpenWindows.cpp

    PrintOpenWindows.exe
Continued at An Introduction to JNI using a Bottom Up Approach: Step 2.

This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-step-1/, originally written on August 21st, 2013.

An Introduction to JNI using a Bottom Up Approach: Step 2

Continued from An Introduction to JNI using a Bottom Up Approach: Step 1. Note: These steps may be followed without the first step below, if you remove the two references to PrintOpenWindows in the C++ code and remove "PrintOpenWindows.cpp" from the commands to compile and run "CPPHelper.exe".

Step 2: C++ Main Function

  1. Comment out the main function in "PrintOpenWindows.cpp".
    /*  Uncomment to compile and run PrintOpenWindows.exe 
    int main()
    {
        cout << "PRINT_OPEN_WINDOWS ENTRY START" << endl;
        printOpenWindowsEntryPoint();
        cout << "PRINT_OPEN_WINDOWS ENTRY FINISH" << endl;
    }
    */
  2. In your working directory, add an empty file, named "CPPHelper.h"
    #ifndef _CPP_HELPER_H
    #define _CPP_HELPER_H

    #ifdef __cplusplus
            extern "C" {
    #endif
            void cppHelperEntryPoint();
    #ifdef __cplusplus
            }
    #endif

    #endif
  3. In your working directory, add the following code, in a file named "CPPHelper.cpp":
    #include "CPPHelper.h"
    #include "PrintOpenWindows.h" // Comment to ignore PrintOpenWindows
    #include  <iostream>

    using namespace std;

    void cppHelperExitPoint()
    {
        cout << "CPP_HELPER EXIT START" << endl;
        printOpenWindowsEntryPoint(); // Comment to ignore PrintOpenWindows
        cout << "CPP_HELPER EXIT FINISH" << endl;
    }

    int main()
    {
        cout << "CPP_HELPER MAIN START" << endl;
        cppHelperExitPoint();
        cout << "CPP_HELPER MAIN FINISH" << endl;
    }

    void cppHelperEntryPoint()
    {
        cout << "CPP_HELPER ENTRY START" << endl;
        cppHelperExitPoint(); // Comment to ignore PrintOpenWindows
        cout << "CPP_HELPER ENTRY FINISH" << endl;
    }
  4. Compile the code and run "CPPHelper.exe", using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"

    "C:\MinGW64\bin\g++.exe" -o CPPHelper.exe CPPHelper.cpp PrintOpenWindows.cpp

    CPPHelper.exe
Continued at An Introduction to JNI using a Bottom Up Approach: Step 3.

This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-step-2/, originally written on August 21st, 2013.

An Introduction to JNI using a Bottom Up Approach: Step 3

Continued from An Introduction to JNI using a Bottom Up Approach: Step 2. Note: These steps may be followed without the first step below, if you remove the two references to CPPHelper in the C code and remove "CPPHelper.cpp" from the commands to compile and run "CToCPPHelper.exe".

Step 3: C Main Function

  1. Comment out the main function in "CPPHelper.cpp".
    /*  Uncomment to compile and run CPPHelper.exe  
    int main()
    {
     cout << "CPP_HELPER MAIN START" << endl;
     cppHelperEntryPoint();
     cout << "CPP_HELPER MAIN FINISH" << endl;
    }
    */
  2. In your working directory, add an empty file, named "CToCPPHelper.h"
  3. In your working directory, add the following code, in a file named "CToCPPHelper.cpp":
    #include "CToCPPHelper.h"
    #include "CPPHelper.h" // Comment to ignore CPPHelper
    #include <jni.h>
    #include <stdio.h>

    void cToCPPHelperExitPoint() {
        printf("C_TO_CPP_HELPER EXIT START\n");
        cppHelperEntryPoint(); // Comment to ignore CPPHelper
        printf("C_TO_CPP_HELPER EXIT FINISH\n");
    }

    int main()
    {
        printf("C_TO_CPP_HELPER MAIN START\n");
        cToCPPHelperExitPoint();
        printf("C_TO_CPP_HELPER MAIN FINISH\n");
    }

    JNIEXPORT void JNICALL Java_com_mycompany_myapp_JavaToCHelper_cToCPPHelperEntryPoint(JNIEnv *env, jobject thisObj)
    {
        printf("C_TO_CPP_HELPER ENTRY START\n");
        cToCPPHelperExitPoint(); // Comment to ignore CPPEntryPoint
        printf("C_TO_CPP_HELPER ENTRY FINISH\n");
    }
  4. Compile the code and run "CToCPPHelper.exe", using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"

    "C:\MinGW64\bin\g++.exe" -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.exe CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp

    CToCPPHelper.exe
Continued at An Introduction to JNI using a Bottom Up Approach: Step 4.

This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-step-3/, originally written on August 21st, 2013.

An Introduction to JNI using a Bottom Up Approach: Step 4

Continued from An Introduction to JNI using a Bottom Up Approach: Step 3.

Step 4: Java Main Function

Run Java without the CToCPPHelper Entry Point

  1. Create the following Java Class:
    package com.mycompany.myapp;

    public class JavaToCHelper {
        public native void cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper

        static // static initializer code
        {
    //        System.load(JavaToCHelper.class.getResource("/dlls/CToCPPHelper.dll").getPath()); // Comment to ignore CToCPPHelper
        }

        public void jToCHelperExitPoint() {
            System.out.println("JAVA_TO_C_HELPER EXIT START");
    //        cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper
            System.out.println("JAVA_TO_C_HELPER EXIT FINISH");
        }

        public static void main(String[] args) {
            System.out.println("JAVA_TO_C_HELPER MAIN START");
            JavaToCHelper jToCHelper = new JavaToCHelper();
            jToCHelper.jToCHelperExitPoint();
            System.out.println("JAVA_TO_C_HELPER MAIN FINISH");
        }

        public void jToCHelperEntryPoint() {
            System.out.println("JAVA_TO_C_HELPER ENTRY START");
            jToCHelperExitPoint();
            System.out.println("JAVA_TO_C_HELPER ENTRY FINISH");
        }
    }
  2. Compile and run JavaToCHelper, using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"

    "C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java

    "C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath "." com.mycompany.myapp.JavaToCHelper

Run CToCPPHelper.exe with a Generated Header File

  1. Generate CToCPPHelper.h from JavaToCHelper.class, using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"
    "C:\Program Files\Java\jdk1.6.0_26\bin\javah.exe" -classpath "." com.mycompany.myapp.JavaToCHelper
    mv com_mycompany_myapp_JavaToCHelper.h "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls\CToCPPHelper.h"
  2. Verify the CToCPPHelper.h was generated in the same folder as CToCPPHelper.c:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_mycompany_myapp_JavaToCHelper */

    #ifndef _Included_com_mycompany_myapp_JavaToCHelper
    #define _Included_com_mycompany_myapp_JavaToCHelper
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_mycompany_myapp_JavaToCHelper
     * Method:    cToCPPHelperEntryPoint
     * Signature: ()V
     */

    JNIEXPORT void JNICALL Java_com_mycompany_myapp_JavaToCHelper_cToCPPHelperEntryPoint
      (JNIEnv *, jobject);

    #ifdef __cplusplus
    }
    #endif
    #endif
  3. Compile the code and run "CToCPPHelper.exe" (see An Introduction to JNI using a Bottom Up Approach: Step 3).

Run JavaToCHelper with the New DLL

  1. Uncomment two lines of code:
     System.load(JavaToCHelper.class.getResource("/dlls/CToCPPHelper.dll").getPath()); // Comment to ignore CToCPPHelper
        cToCPPHelperEntryPoint(); // Comment to ignore CToCPPHelper
  2. Generate a 64 bit dll file (for 32 bit Java, remove "-m64") using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"

    "C:\MinGW64\bin\g++.exe" -m64 -Wl,--add-stdcall-alias -shared -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.dll CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp
  3. Compile and run JavaToCHelper (adding the new dll to the class path), using the following commands:
    cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"

    "C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java

    "C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath ".;../resources" com.mycompany.myapp.JavaToCHelper

Summary of commands

Anytime you change the JavaToCHelper.java, CToCPPHelper.c, CPPHelper.cpp or PrintOpenWindows.cpp, you can regenerate the appropriate files via:
REM Generate the New C Header File

cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"

"C:\Program Files\Java\jdk1.6.0_26\bin\javac.exe" -classpath "." com\mycompany\myapp\JavaToCHelper.java

"C:\Program Files\Java\jdk1.6.0_26\bin\javah.exe" -classpath "." com.mycompany.myapp.JavaToCHelper

mv com_mycompany_myapp_JavaToCHelper.h "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls\CToCPPHelper.h"


REM Generate the New DLL

cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\resources\dlls"

"C:\MinGW64\bin\g++.exe" -m64 -Wl,--add-stdcall-alias -shared -I"C:\Program Files\Java\jdk1.6.0_26\include" -I"C:\Program Files\Java\jdk1.6.0_26\include\win32" -o CToCPPHelper.dll CToCPPHelper.c CPPHelper.cpp PrintOpenWindows.cpp


REM Run Java

cd /D "C:\Users\Scott\workspace\myrepo\my-app\src\main\java"

"C:\Program Files\Java\jdk1.6.0_26\bin\java.exe" -classpath ".;../resources" com.mycompany.myapp.JavaToCHelper

A warning! If you followed these instructions and you received the error "Can't load this .dll (machine code=0xbd) on a AMD 64-bit platform", it may be because your project is a "Maven Project". You can "Disable Maven Nature" and try recompiling from the command line with the following command:

mvn eclipse:clean eclipse:eclipse clean compile test-compile

Also, you can run the JavaToCHelper by right clicking and "Run As Java Application" or executing this command.

mvn exec:java -Dexec.mainClass="com.mycompany.myapp.JavaToCHelper"

This assumes your src/main/resources folder will be copied to the target folder during the build phase.
    <build>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
            </plugin>
        </plugins>
    </build>

This post was reposted from http://scottizu.wordpress.com/2013/08/21/an-introduction-to-jni-using-a-bottom-up-approach-step-4/, originally written on August 21st, 2013.

Your First C++ to List All Open Windows: Part I

To get a C++ compiler for Windows, see TDM-GCC at tdm-gcc.tdragon.net.

I googled "Get the Window Handle of an Externally Running Window" and went to stackoverflow.com to find the following piece of code:

#include "HelloWindows.h"
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <windows.h>
#include <iostream>
 
using namespace std;

BOOL CALLBACK FindWindowBySubstr(HWND hwnd, LPARAM substring)
{
    const DWORD TITLE_SIZE = 1024;
    TCHAR windowTitle[TITLE_SIZE];

    if (GetWindowText(hwnd, windowTitle, TITLE_SIZE))
    {
        _tprintf(TEXT("%s\n"), windowTitle);
        // Uncomment to print all windows being enumerated
        if (_tcsstr(windowTitle, LPCTSTR(substring)) != NULL)
        {
            // We found the window! Stop enumerating.
            return false;
        }
    }
    return true// Need to continue enumerating windows
}

int main()
{
 cout << "START" << endl;
    const TCHAR substring[] = TEXT("Substring");
    EnumWindows(FindWindowBySubstr, (LPARAM)substring);
}


I named the file HelloWindows.cpp and placed it at "C:\Users\Scott\CPrograms\HelloWindows.cpp".

I also created an empty file called HelloWindows.h in the same directory.

Then, I ran:



cd "C:\Users\Scott\CPrograms\"
"C:\MinGW64\bin\g++.exe" HelloWindows.cpp -o HelloWindows.exe"
HelloWindows.exe

This post was reposted from http://scottizu.wordpress.com/2013/08/20/your-first-c-to-list-all-open-windows-part-i/, originally written on August 20th, 2013.

Your first C++ program to List All Open Windows: Part II

This article shows how to have one C++ call another and then compile.
Change the code from Your first C++ program to List All Open Windows: Part I to (change "int main" to "void listWindows":
void listWindows()
{
    cout << "START" << endl;
    const TCHAR substring[] = TEXT("Substring");
    EnumWindows(FindWindowBySubstr, (LPARAM)substring);
}

Add one line to HelloWindows.h:
void listWindows()

Create a file called HelloWorldCPP.cpp which contains the following code:
#include "HelloWindows.h"
#include <iostream>

using namespace std;
 
void sayHelloCPP () {
    cout << "Hello World! CPP" << endl;
    return;


int main() 
{
    sayHelloCPP();
    listWindows();
}

Add the file HelloWorldCPP.h

Lastly, run:

cd "C:\Users\Scott\CPrograms\"
"C:\MinGW64\bin\g++.exe" HelloWindows.cpp -o HelloWindows.exe"
HelloWindows.exe
Note: You have to make sure the main function from HelloWindows.cpp is gone since the main function is defined in HelloWorldCPP.cpp.

Note: The header file defines the functions which can be used by other .cpp files.

This post was reposted from http://scottizu.wordpress.com/2013/08/20/your-first-c-program-to-list-all-open-windows/, originally written on August 20th, 2013.

Thursday, December 11, 2014

How to Fake Adding Piccolo's PCanvas to a JPanel

One issue with Piccolo is that typically the PCanvas, which is the main canvas used to draw items on the screen must be attached to the top level JFrame. This might be problematic if you want to have your top level JFrame include several Panels. For instance, you might want a JPanel on the left to be a control panel and the PCanvas to be to the right of that. This is like the popular Paint program in Windows.

Here's how to fake it:
  1. Add the PCanvas to the top level JFrame.
  2. Set the Bounds of the PCanvas to shadow that of a JPanel.
private MainFrame() {    
        JButton myButton = new JButton("My Button");
        JPanel panel2 = new JPanel();
        this.add(myButton);
        this.add(panel2);
        this.add(canvas);
        
        this.setLayout(new BorderLayout());
        this.add(myButton, BorderLayout.NORTH);
        this.add(panel2, BorderLayout.CENTER);

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

        canvas.setBounds(panel2.getX(), panel2.getY(), panel2.getWidth(), panel2.getHeight());
    }


This post was reposted from http://scottizu.wordpress.com/2013/08/20/how-to-fake-adding-piccolos-pcanvas-to-a-jpanel/, originally written on August 20th, 2010.

An Introduction to Piccolo

I googled "download piccolo.jar", selected Piccolo Home Page, www.piccolo2d.org, clicked Download, Compiled Source (2.9MB).

See www.piccolo2d.org for more information.

    <dependency>
      <groupId>org.piccolo2d</groupId>
      <artifactId>piccolo2d-core</artifactId>
      <version>1.3.1</version>
    </dependency>


mvn install:install-file -Dfile="C:\Users\Scott\Desktop\piccolo2d-1.3.1-bin\piccolo2d-core-1.3.1.jar" -Dpackaging=jar -DgroupId=org.piccolo2d -DartifactId=piccolo2d-core -Dversion=1.3.1


package com.mycompany.gui;

import javax.swing.JFrame;

import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.nodes.*;

public class MainFrame extends JFrame {
    private MainFrame() {
        final PCanvas canvas = new PCanvas();
        final PText text = new PText("Hello World");
        canvas.getLayer().addChild(text);
        add(canvas);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 400);
        setVisible(true);
    }
    
    public static void main(String[] args) {
            new MainFrame();
    }

}


This post was reposted from http://scottizu.wordpress.com/2013/08/20/an-introduction-to-piccolo/, originally written on August 20th, 2010.

Install Notepad++ to Quickly View Files

I googled "Install Notepad++", clicked Download - Notepad++, clicked v6.4.5 - Current Version, clicked Notepad++ Installer.

Then, I installed Notepad++. After this, whenever I right click on files, I can Open With Notepad++.

This application is also open source, meaning you can download the source code via Notepad++ source code.

See Working with Compressed Files on Windows for how to deal with 7 Zip compressed files.

This post was reposted from http://scottizu.wordpress.com/2013/08/20/install-notepad-to-quickly-view-files/, originally written on August 8th, 2013.

Friday, December 5, 2014

Reading and Writing Files in Java

Here is code to read and write from a file in Java. You will have to change the output path and package appropriately.

package com.mycompany.app.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class FileHelper {
    
    public static void main(String[] args) {
        try {
            System.out.println("START");
            String outputPath = "/Users/Scott/workspace/myrepo/my-app/output/text.txt";
            FileHelper fileHelper = new FileHelper();
            fileHelper.write(new File(outputPath), "Hello World!
My First HTML Page!");
            String string = fileHelper.read(new File(outputPath));
            System.out.println("From FILE:"+string);
            System.out.println("FINISH");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public String read(File inputFile) throws Exception {
        // Initialization
        String string = "";
        String line;
        
        // Read from file
        FileReader fr = new FileReader(inputFile);
        BufferedReader br = new BufferedReader(fr);
        while ((line = br.readLine()) != null) {
            string = string + line;
        }
        br.close();
        fr.close();
        
        return string;
    }

    public void write(File outputFile, String string) throws Exception {
        // Initialization
        if (!outputFile.exists()) {
            outputFile.createNewFile();
        }

        // Write to file
        FileWriter fw = new FileWriter(outputFile);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(string);
        bw.close();
        fw.close();

    }
}


This post was reposted from http://scottizu.wordpress.com/2013/08/19/reading-and-writing-files-in-java/, originally written on August 19th, 2013.

Reading and Writing MusicXml Files with Java

Download JFugue with Music Xml Support from JFugue Downloads. Click on jfugue-4.0.3-with-musicxml.jar. Change your pom.xml file and run "mvn install" as described in Adding an external Jar to a Maven Project (JFugue). Then add the following code (and include the code found in Reading and Writing Files in Java):

package com.mycompany.app.util;

import java.io.File;
import org.jfugue.MusicStringParser;
import org.jfugue.MusicStringRenderer;
import org.jfugue.MusicXmlParser;
import org.jfugue.MusicXmlRenderer;
import org.jfugue.Pattern;
import org.jfugue.Player;

public class MusicXMLFileHelper {
    
    public static void main(String[] args) { 
        try {
            System.out.println("START");
            String outputFile = "/Users/Scott/workspace/myrepo/my-app/output/mxmlfhout.xml";
            Pattern pattern = new Pattern("KEmaj V0 E4i+B4i B3i E4i+B4i B3i E4i+B4i B3i E4i+B4i B3i V1 E1h E1i F#1i G#1i B1i");
        
            MusicXMLFileHelper fileHelper = new MusicXMLFileHelper(); 
            fileHelper.write(new File(outputFile), pattern);
            
            Player player = new Player();
            player.play(pattern);
            System.out.println("FINISH");
        } catch (Exception ex) {
            
        }
    }
    
    public void write(File outputFile, Pattern musicPattern) throws Exception {
        MusicXmlRenderer renderer = new MusicXmlRenderer();
        
        MusicStringParser parser = new MusicStringParser();
        parser.addParserListener(renderer);
        parser.parse(musicPattern);
        
        FileHelper fileHelper = new FileHelper();
        fileHelper.write(outputFile, renderer.getMusicXMLString());
    }
    
    public Pattern read(File inputFile) throws Exception{
        MusicStringRenderer renderer = new MusicStringRenderer();

        MusicXmlParser parser = new MusicXmlParser();
            
        parser.addParserListener(renderer);
        parser.parse(inputFile);
        
        return renderer.getPattern();
    }
}


This post was reposted from http://scottizu.wordpress.com/2013/08/19/reading-and-writing-musicxml-files-with-java/, originally written on August 19, 2013.

Monday, December 1, 2014

Packaging All JARS with Maven Plugin

A description of the build lifecycle of Maven can be found at maven.apache.org.

When executing a command such as

call mvn -e deploy -DskipTests=true

You may want to include all the dependencies into the jar itself.

You may add this plugin to your pom.xml file in the <project><build><plugins> section (copied from stackoverflow.com).

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

If you do this, the maven-assemply-plugin will execute the jar-with-dependencies during the package phase. You should then see two jars in your Maven repository. One will have a suffix like '-jar-with-dependencies.jar'.

Wednesday, November 26, 2014

Adding Keyboard Shortcuts in Eclipse

Adding keyboard shortcuts can help develop code much faster. For instance, when refactoring it is common practice to move multiple lines of code up, down , right, left. In Eclipse->Window->Preferences->General->Keys, change the following:
Bind "Shift Left" to Shift+Alt+Left
Bind "Shift Right" to Shift+Alt+Right
Also, you may want to show line numbers: In Eclipse->Window->Editors->Text Editors->Show line numbers

This post was reposted from http://scottizu.wordpress.com/2013/08/19/adding-keyboard-shortcuts-in-eclipse/, originally written on August 19th, 2013.

Working with Compressed Files on Windows

Files such as ".tar" are typically created on a Unix machine and represent Tarballs, created using the Tar archiving system, which is similar to the Zip archiving system on Windows.

To Extract Files from a Tar archive, you may go to 7 Zip, click Download for the 32 Bit 7 Zip 9.20.

Files such as ".7z" are actually created by 7 Zip, so need to be extracted using 7 Zip.

There are various compression schemes used with the Tar archiving system. For example, a ".tar.bz2" extension represents Tar archive and Bzip2 compression. If you know the appropriate command, you may be able to decompress the file directly from the Git command prompt:

tar -jxvf "/c/Users/Scott/Desktop/mscore-1.3.tar.bz2"


This post was reposted from http://scottizu.wordpress.com/2013/08/18/working-with-compressed-files-on-windows/, originally written on August 18th, 2013.

Monday, November 24, 2014

Executing Javascript on Various Web Pages

Option 1: Execute via Drag and Drop

  • Open a webpage in Google Chrome
  • Highlight the code below and drag it onto the Tab just opened:
    javascript:alert('Hello World');
Note: This method works well for a one click execution of your code. This allows demos directly from a tutorial or documentation page.
Note: This may not work in Firefox but depends on the browser configuration for javascript.
Note: This link may also be dragged into the Firefox Bookmarks Menu or the Google Chrome Bookmarks Toolbar.
Note: Instead of dragging the whole javascript code, you may also drag a hyperlink like this: Hello World Bookmark. This was created from the following html:
<a href="javascript:alert('Hello World');">Hello World Bookmark</a>

Option 2: Execute via Address Bar

  • Open a webpage in Google Chrome
  • Type the following into the address bar:
    javascript:alert('Hello World');
  • Press Enter
Note: This may not work in Firefox but depends on the browser configuration for javascript.
Note: When copying this code, make sure that the prefix "javascript:" is copied. In some cases, this will have to be manually typed.

Option 3: Execute via Console

  • Open a webpage in Google Chrome or Firefox
  • Right click the page, Inspect Element
  • Switch to the Console Tab
  • Type the following code:
    javascript:alert('Hello World');
  • Press Enter
Note: Accessing the console will vary depending on the browser and plugins. However, in most cases you need the previx "javascript:".

Option 4: Execute via Bookmark

  • Open a webpage in Google Chrome or Firefox
  • Go to the Bookmark Menu and select the Bookmark
Note: Option 1 above shows how to create a new bookmark via drag and drop. However, below are instructions on how to manually create a Bookmark which will execute javascript code.

Manually Creating a Bookmark

  • Open a webpage in Firefox
  • From the Bookmark Menu, Bookmark This Page
  • From the Bookmark Menu, Right Click the new Bookmark, Properties
  • Change the Name to "Hello World Bookmark"
  • Change the Location to "javascript:alert('Hello World');"
  • Save the bookmark
Note: Similar directions will work in Google Chrome.

Hosting Your Javascript Code

For more complicated javascript, I suggest hosting the main javascript code on a server. This requires a few pieces:
  • Executing the following javascript code through one of the options previously mentioned on this page:
    javascript:addScript=function(){s=document.getElementById("bmScript");if(s){document.body.removeChild(s);}s=document.createElement("script");s.id="bmScript";s.src="http://localhost:8080/HelloWorld.js";document.body.appendChild(s);};void(addScript());
  • Placing the javascript code on the server (for example, if using Tomcat as a server, the above javascript code assumes a file HelloWorld.js is placed in the ROOT Tomcat directory)
  • Running a server somewhere (for example, if using Tomcat as a server, the above javascript code assumes a Tomcat server is running on the same machine which is executing the code so that localhost:8080 is available)
Note: The javascript here, which will be executed on the page adds a script element to the page. When the script element is added, it will also be loaded. At this point, the src found on the server will be executed as well.

Sunday, November 23, 2014

An Introduction to Java Project Management

At this point, our project has the following, in order of importance:

Programming Language: Java

There are many other programming languages such as JavaScript, C, C++, C#, Perl, Python. After you write a computer program, you will need a compiler (or interpreter) to run that program. In order to compile C/C++ code, for example, you might use gcc.exe/g++.exe, respectively.

Build Manager: Maven

Another common build manager is Ant. In order to facilitate creating a single executable program that people can actually install and use, you will need a build manager. Build managers also help to import libraries and manage other resources (files, images, etc). In order to build C/C++ code, for example, you might use cmake (Makefile).

Integrated Development Environment (IDE): Eclipse

Common IDEs include Netbeans and IntelliJ. A good IDE will help you to build programs quickly and have lots of shortcuts to perform common tasks like starting with a template for new classes or importing other classes. In order to develop C/C++ code, for example, you might use Visual Studio C++.

Automated Testing: JUnit

For Java, JUnit really is the standard for automated testing. Agile methodologies such as SCRUM and Extreme Programming took down 6 month development cycles to 1 month. This meant getting your services out to customers quicker.

Version Control: Git

Other version control programs include WinCVS, SubVersion and Perforce. After you have been developing for a while, you will want to release different versions of your program. It can be helpful to explore a source code repository to compare, for instance, your source code from version 1.0 to your source code from version 2.0. And here are some additional things to incorporate into your project:

Bug and Feature Tracking: JIRA

There are also tools like BugZilla. A good rule of thumb is to have a few Wow! features and then deliver 20 percent of the desired features. Tools like JIRA allow you to prioritize all the great things you want to deliver while allowing the capability to deliver a solid product by really focusing on what you need to deliver.

Collaboration Tool: Wiki

JIRA also comes with Confluence. A Wiki page gives people a voice! Wiki pages, like blogs are very easy to use to share ideas and keep the communication and creative juices flowing. They can document resources and tutorials. Any new programmer should be able to join a new team and be up and running in a day. This includes being able to configure their personal development environment and then download and verify code.

Continuous Integration Tool: Bamboo

There is also Jenkins. A Continuous integration tool allows multiple developers to work in parallel. Typically, when a new developer commits code to the code base, you want a new build to be created, deployed and tested. Then, you want immediate feedback to know if the new commit broke previously working features. A continuous integration tool helps you to do this and provides the capability to send e-mails in the case things aren't working correctly, all automated, of course.

Database: MySQL

Once you have a lot of data that you need to store, you will want to add Database support. This allows you to hold customer names, addresses, etc or any other data your program uses.

Application Server: Geronimo

Apache has a Web Server for web pages and also has Tomcat. If your program has a lot of services that are needed by a lot of clients, you will want to look into using an application server.

This post was reposted from http://scottizu.wordpress.com/2013/08/18/an-introduction-to-java-project-management/, originally written on August 18th, 2013.

Adding an external Jar to a Maven Project (JFugue)

In this article, we show how to manually download an external jar file and install it in your local Maven repository. It is possible to automatically download from a third party central Maven repository or from your own central Maven repository. We will use JFugue 4 to demonstrate. I googled "java program to play a middle c", clicked JFugue - Java Music Programming API, clicked www.jfugue.org, clicked Download, clicked jfugue-4.0.3.jar. I googled "JFugue 4.0.3 Maven Dependency" to find the following information about JFugue:
<dependency>
   <groupId>org</groupId>
   <artifactId>jfugue</artifactId>
   <version>4.0.3</version>
</dependency>
  1. Download JFugue 4.0.3 to your Desktop.
  2. Install the jar into your local Maven repository from the Windows Command Prompt (see maven.apache.org):
    "C:\apache-maven-3.1.0\bin\mvn" install:install-file -Dfile="C:\Users\Scott\Desktop\jfugue-4.0.3.jar" -Dpackaging=jar -DgroupId=org -DartifactId=jfugue -Dversion=4.0.3
  3. Add the dependency xml above to your project's pom.xml file (ie "C:\Users\Scott\workspace\myrepo\my-app\pom.xml"):
    ...
    <dependencies>
       <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
       </dependency>
       <dependency>
          <groupId>org</groupId>
          <artifactId>jfugue</artifactId>
          <version>4.0.3</version>
       </dependency>
    </dependencies>
    ...
  4. Recompile the new pom.xml file:
    cd "C:\Users\Scott\workspace\myrepo\my-app"
    mvn clean compile eclipse:eclipse
  5. In Eclipse, Project Explorer, right click on my-app->Refresh (F5).
  6. Add new code to your main function:
     public static void main( String[] args )
        {
            System.out.println( "Hello World!" );
            Player player = new Player();
            Pattern pattern = new Pattern("C D E F G A B");
            player.play(pattern);
            System.exit(0);
        }
  7. Run As-Java Application.
You can now add several different types of jars and reuse lots of existing code!

This post was reposted from http://scottizu.wordpress.com/2013/08/18/adding-an-external-jar-to-a-maven-project-jfugue/, originally written on August 18th, 2013.

An Introduction to Java Sound

This article talks about how to include sound into your project. We will assume you have a .wav file to input into your program. Sound files can be created and edited with Audacity. I googled Audacity, selected Audacity: Free Audio Editor and Recorder (Source Forge), Download, Audacity for Windows®, Audacity 2.0.3 installer. We will be adding to the project created in the previous posts. I have the following directory structure:
  • "C:\Users\Scott\workspace\myrepo" is a clone of the myrepo.git central repository.
  • "C:\Users\Scott\workspace\myrepo\my-app" is the project folder for my Maven/Java Project.
  1. Configure your input and output directories for your project.
    • In the my-app folder (project folder) add two new directories, input and output.
    • In the output folder create a .gitignore with the following two lines:
    • Note: To create the .gitignore file with Notepad, you can create a new Text Document, edit in Notepad, then File->Save As, and Enter File name: ".gitignore" (include the double quotes here) and Save as type: "All Files".
    • Note: Git doesn't track folders, just files. We want other developers to get the output folder when they clone the central repository but we don't want them to get all the files in the output folder. This setup ensures that they get only the output folder and the .gitignore file.
  2. Create input.wav using Audacity.
    • Install Audacity.
    • Launch Audacity.
    • Create a .wav file that is about ten seconds of continuous sound.
    • Name the .wav file input.wav and save the file to your input folder (ie "C:\Users\Scott\workspace\myrepo\my-app\input\input.wav").
    • Note: In Audacity, you can either open a file or record sound.
    • Note: In Audacity, you can use the Selection Tool and Trim Audio to extract a few seconds.
    • Note: In Audacity, you can File->Export and Enter Save as type: "WAV (Microsoft) signed 16 bit PCM.
  3. Create the WavFileHelper Class.
    • In Eclipse, Package Explorer, right click on src/main/java->New->Package, Enter "com.mycompany.app.util".
    • In Eclipse, Package Explorer, right click on the com.mycompany.app.util package->New->Class, Enter "WavFileHelper.
    • Add the following code:
      package com.mycompany.app.util;

      import java.io.*;
      import java.nio.ByteBuffer;
      import java.nio.ByteOrder;
      import java.util.LinkedHashMap;

      import javax.sound.sampled.*;

      /**
       * This class reads a .wav file and converts it to a bunch of byte arrays.
       * 
       * The info represented by these byte arrays is then printed out.
       * 
       * An example of playing these byte arrays with the speakers is used.
       * 
       * It also converts the byte arrays to a .wav file.
       * 
       * An extension of this concept can record from a microphone. In this case, some
       * values like sampling rate would need to be assumed.
       * 
       * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ for .wav file
       * spec
       * 
       * @author sizu
       */

      public class WavFileHelper {

          public static void main(String[] args) {
              final String NEWLINE = "\n";
              int recordingSampleRate = 22050;
              short recordingBitsPerSample = 16;
              short recordingNumChannels = 2;
              String inputPath = "/Users/Scott/workspace/myrepo/my-app/input/input.wav"// Place the wav file in the top level
                                                  // directory, ie S:/input.wav
              String outputPath = "/Users/Scott/workspace/myrepo/my-app/output/output.wav";
              String recordedPath = "/Users/Scott/workspace/myrepo/my-app/output/capture.wav";

              System.out.println("START");
              try {
                  if (!new File(inputPath).exists()) {
                      System.err.println("Error loading file:"
                              + new File(inputPath).getAbsolutePath());
                  }

                  WavFileHelper wavFileHelper = new WavFileHelper();

                  WavData wavRecordData = new WavData();
                  wavRecordData.put(WaveSection.SAMPLE_RATE, recordingSampleRate);
                  wavRecordData.put(WaveSection.BITS_PER_SAMPLE,
                          recordingBitsPerSample);
                  wavRecordData.put(WaveSection.NUM_CHANNELS, recordingNumChannels);

                  System.out.println(NEWLINE + "CONVERT WAV FILE TO BYTE ARRAY");
                  WavData wavInputData = wavFileHelper.read(new File(inputPath));

                  System.out.println(NEWLINE + "CONVERT BYTE ARRAY TO WAV FILE");
                  wavFileHelper.write(new File(outputPath), wavInputData);

                  System.out.println(NEWLINE
                          + "DISPLAY BYTE ARRAY INFORMATION FOR INPUT FILE");
                  wavInputData.printByteInfo();

                  System.out
                          .println(NEWLINE
                                  + "START RECORDING - You can connect the microphone to the speakers");
                  WavAudioRecorder recorder = new WavFileHelper.WavAudioRecorder(
                          wavRecordData);
                  recorder.startRecording();

                  System.out.println(NEWLINE
                          + "PLAY BYTE ARRAY (THIS WILL BE RECORDED)");
                  WavAudioPlayer player = new WavFileHelper.WavAudioPlayer(
                          wavInputData);
                  player.playAudio();

                  System.out.println(NEWLINE + "STOP RECORDING FOR RECORDING");
                  recorder.stopRecording();

                  System.out.println(NEWLINE + "DISPLAY BYTE ARRAY INFORMATION");
                  wavRecordData.printByteInfo();

                  System.out.println(NEWLINE + "SAVE RECORDING IN WAV FILE");
                  wavFileHelper.write(new File(recordedPath), wavRecordData);

              } catch (Exception ex) {
                  ex.printStackTrace();
              }
              System.out.println("FINISH");
          }

          public WavData read(File inputFile) throws Exception {
              WavData returnVal = new WavData();

              // Analyze redundant info
              int dataSize = (int) inputFile.length() - WavData.HEADER_SIZE;
              WaveSection.DATA.numBytes = dataSize; // Can't have two threads
                                                      // using this at the same
                                                      // time

              // Read from File
              DataInputStream inFile = new DataInputStream(new FileInputStream(
                      inputFile));

              for (WaveSection waveSection : WaveSection.values()) {
                  byte[] readBytes = new byte[waveSection.numBytes];
                  for (int i = 0; i < waveSection.numBytes; i++) {
                      readBytes[i] = inFile.readByte();
                  }
                  returnVal.put(waveSection, readBytes);
              }

              inFile.close();

              return returnVal;
          }

          public void write(File outputFile, WavData waveData) throws Exception {
              // Analyze redundant info
              int dataSize = waveData.get(WaveSection.DATA).length;
              waveData.put(WaveSection.CHUNK_SIZE, dataSize + 36);
              waveData.put(WaveSection.SUBCHUNK2_SIZE, dataSize);

              int byteRate = waveData.getInt(WaveSection.SAMPLE_RATE)
                      * waveData.getShort(WaveSection.BLOCK_ALIGN);
              waveData.put(WaveSection.BYTE_RATE, byteRate);

              // Write to File
              DataOutputStream dataOutputStream = new DataOutputStream(
                      new FileOutputStream(outputFile));

              for (WaveSection waveSection : WaveSection.values()) {
                  dataOutputStream.write(waveData.getBytes(waveSection));
              }

              dataOutputStream.close();
          }

          public static enum WaveSection {
              // 12 Bytes
              CHUNK_ID(4, ByteOrder.BIG_ENDIAN), CHUNK_SIZE(4,
                      ByteOrder.LITTLE_ENDIAN), FORMAT(4, ByteOrder.BIG_ENDIAN),

              // 24 Bytes
              SUBCHUNK1_ID(4, ByteOrder.BIG_ENDIAN), SUBCHUNK1_SIZE(4,
                      ByteOrder.LITTLE_ENDIAN), AUDIO_FORMAT(2,
                      ByteOrder.LITTLE_ENDIAN), NUM_CHANNELS(2,
                      ByteOrder.LITTLE_ENDIAN), SAMPLE_RATE(4,
                      ByteOrder.LITTLE_ENDIAN), BYTE_RATE(4, ByteOrder.LITTLE_ENDIAN), BLOCK_ALIGN(
                      2, ByteOrder.LITTLE_ENDIAN), BITS_PER_SAMPLE(2,
                      ByteOrder.LITTLE_ENDIAN),

              // 8 Bytes
              SUBCHUNK2_ID(4, ByteOrder.BIG_ENDIAN), SUBCHUNK2_SIZE(4,
                      ByteOrder.LITTLE_ENDIAN), DATA(0, ByteOrder.LITTLE_ENDIAN), ;

              private Integer numBytes;
              private ByteOrder endian;

              WaveSection(Integer numBytes, ByteOrder endian) {
                  this.numBytes = numBytes;
                  this.endian = endian;
              }
          }

          public static class WavData extends LinkedHashMap {
              static final long serialVersionUID = 1;
              static int HEADER_SIZE = 44; // There are 44 bits before the data
                                              // section
              static int DEFAULT_SUBCHUNK1_SIZE = 16;
              static short DEFAULT_AUDIO_FORMAT = 1;
              static short DEFAULT_BLOCK_ALIGN = 4;
              static String DEFAULT_CHUNK_ID = "RIFF";
              static String DEFAULT_FORMAT = "WAVE";
              static String DEFAULT_SUBCHUNK1_ID = "fmt ";
              static String DEFAULT_SUBCHUNK2_ID = "data";

              public WavData() {
                  this.put(WaveSection.CHUNK_ID, DEFAULT_CHUNK_ID);
                  this.put(WaveSection.FORMAT, DEFAULT_FORMAT);
                  this.put(WaveSection.SUBCHUNK1_ID, DEFAULT_SUBCHUNK1_ID);
                  this.put(WaveSection.SUBCHUNK1_SIZE, DEFAULT_SUBCHUNK1_SIZE);
                  this.put(WaveSection.AUDIO_FORMAT, DEFAULT_AUDIO_FORMAT);
                  this.put(WaveSection.BLOCK_ALIGN, DEFAULT_BLOCK_ALIGN);
                  this.put(WaveSection.SUBCHUNK2_ID, DEFAULT_SUBCHUNK2_ID);

                  this.put(WaveSection.CHUNK_SIZE, 0);
                  this.put(WaveSection.SUBCHUNK2_SIZE, 0);
                  this.put(WaveSection.BYTE_RATE, 0);
              }

              public void put(WaveSection waveSection, String value) {
                  byte[] bytes = value.getBytes();
                  this.put(waveSection, bytes);
              }

              public void put(WaveSection waveSection, int value) {
                  byte[] bytes = ByteBuffer.allocate(4)
                          .order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
                  this.put(waveSection, bytes);
              }

              public void put(WaveSection waveSection, short value) {
                  byte[] bytes = ByteBuffer.allocate(2)
                          .order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
                  this.put(waveSection, bytes);
              }

              public byte[] getBytes(WaveSection waveSection) {
                  return this.get(waveSection);
              }

              public String getString(WaveSection waveSection) {
                  byte[] bytes = this.get(waveSection);
                  return new String(bytes);
              }

              public int getInt(WaveSection waveSection) {
                  byte[] bytes = this.get(waveSection);
                  return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN)
                          .getInt();
              }

              public short getShort(WaveSection waveSection) {
                  byte[] bytes = this.get(waveSection);
                  return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN)
                          .getShort();
              }

              public void printByteInfo() {
                  for (WaveSection waveSection : WaveSection.values()) {
                      if (waveSection.numBytes == 4
                              && waveSection.endian == ByteOrder.BIG_ENDIAN) {
                          System.out.println("SECTION:" + waveSection + ":STRING:"
                                  + this.getString(waveSection));
                      } else if (waveSection.numBytes == 4
                              && waveSection.endian == ByteOrder.LITTLE_ENDIAN) {
                          System.out.println("SECTION:" + waveSection + ":INTEGER:"
                                  + this.getInt(waveSection));
                      } else if (waveSection.numBytes == 2
                              && waveSection.endian == ByteOrder.LITTLE_ENDIAN) {
                          System.out.println("SECTION:" + waveSection + ":SHORT:"
                                  + this.getShort(waveSection));
                      } else {
                          // Data Section
                      }
                  }
              }

              public AudioFormat createAudioFormat() {
                  boolean audioSignedSamples = true// Samples are signed
                  boolean audioBigEndian = false;
                  float sampleRate = (floatthis.getInt(WaveSection.SAMPLE_RATE);
                  int bitsPerSample = (intthis
                          .getShort(WaveSection.BITS_PER_SAMPLE);
                  int numChannels = (intthis.getShort(WaveSection.NUM_CHANNELS);
                  return new AudioFormat(sampleRate, bitsPerSample, numChannels,
                          audioSignedSamples, audioBigEndian);
              }
          }

          public static class WavAudioPlayer {
              WavData waveData = new WavData();

              public WavAudioPlayer(WavData waveData) {
                  this.waveData = waveData;
              }

              public void playAudio() throws Exception {
                  byte[] data = waveData.getBytes(WaveSection.DATA);

                  // Create an audio input stream from byte array
                  AudioFormat audioFormat = waveData.createAudioFormat();
                  InputStream byteArrayInputStream = new ByteArrayInputStream(data);
                  AudioInputStream audioInputStream = new AudioInputStream(
                          byteArrayInputStream, audioFormat, data.length
                                  / audioFormat.getFrameSize());

                  // Write audio input stream to speaker source data line
                  DataLine.Info dataLineInfo = new DataLine.Info(
                          SourceDataLine.class, audioFormat);
                  SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem
                          .getLine(dataLineInfo);
                  sourceDataLine.open(audioFormat);
                  sourceDataLine.start();

                  // Loop through input stream to write to source data line
                  byte[] tempBuffer = new byte[10000];
                  int cnt;
                  while ((cnt = audioInputStream.read(tempBuffer, 0,
                          tempBuffer.length)) != -1) {
                      sourceDataLine.write(tempBuffer, 0, cnt);
                  }

                  // Cleanup
                  sourceDataLine.drain();
                  sourceDataLine.close();
                  byteArrayInputStream.close();
              }
          }

          public static class WavAudioRecorder implements Runnable {
              WavData waveData = new WavData();
              boolean recording = true;
              Thread runningThread;
              ByteArrayOutputStream byteArrayOutputStream;

              public WavAudioRecorder(WavData waveData) {
                  this.waveData = waveData;
              }

              public void startRecording() {
                  this.recording = true;
                  this.runningThread = new Thread(this);
                  runningThread.start();
              }

              @SuppressWarnings("deprecation")
              public WavData stopRecording() throws Exception {
                  this.recording = false;
                  runningThread.stop();

                  waveData.put(WaveSection.DATA, byteArrayOutputStream.toByteArray());

                  return waveData;
              }

              public void run() {
                  try {
                      // Create an audio output stream for byte array
                      byteArrayOutputStream = new ByteArrayOutputStream();

                      // Write audio input stream to speaker source data line
                      AudioFormat audioFormat = waveData.createAudioFormat();
                      DataLine.Info info = new DataLine.Info(TargetDataLine.class,
                              audioFormat);
                      TargetDataLine targetDataLine = (TargetDataLine) AudioSystem
                              .getLine(info);
                      targetDataLine.open(audioFormat);
                      targetDataLine.start();

                      // Loop through target data line to write to output stream
                      int numBytesRead;
                      byte[] data = new byte[targetDataLine.getBufferSize() / 5];
                      while (recording) {
                          numBytesRead = targetDataLine.read(data, 0, data.length);
                          byteArrayOutputStream.write(data, 0, numBytesRead);
                      }

                      // Cleanup
                      targetDataLine.stop();
                      targetDataLine.close();
                      byteArrayOutputStream.close();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  }
              }
          }
      }
  4. Right click within WavFileHelper->Run As->Java Application.
    • You may also use the short cut: Alt+Shift+X, J.
    • Or from the Windows command prompt:
      "C:\Program Files\Java\jdk1.7.0_25\bin\javac.exe" "C:\Users\Scott\workspace\myrepo\my-app\src\main\java\com\mycompany\app\util\WavFileHelper.java"
      "C:\Program Files\Java\jdk1.7.0_25\bin\java.exe" -classpath "C:\Users\Scott\workspace\myrepo\my-app\src\main\java" com.mycompany.app.util.WavFileHelper
The recorded file may have either no sound or softer sound depending on your speakers and microphone setup. Also, if you have git setup, you should push these changes to your central repository as demonstrated in Step 7 of Adding Git Version Control to Your Project: Part I.

This post was reposted from http://scottizu.wordpress.com/2013/08/18/an-introduction-to-java-sound/, originally written on August 18th, 2013.