% latex generated by the script '/home/project-web/bumble/cgi-bin/text2latex.cgi' % with help from the sed script 'text2latex.sed' % query string: 'books/java/win-dev/java-book' % sFileName= 'java-book' % sDirName = 'books/java/win-dev' % sName = '' --> % latex by http://bumble.sourceforge.net/scripts/text2latex.sed % this script is a work in progress \documentclass[11pt]{article} \usepackage[hmargin=2cm, vmargin=2cm]{geometry} \usepackage{url} \usepackage{hyperref} \begin{document} \\&\\& The Java Programming Language --------------------------------: quote: "A world in itself" (anon) Stroustrup: "bloated and inefficient" This booklet attempts to provide 'recipes' for how to carry out common tasks with the java language. The idea of this and other booklets at bumble.sf.net is to provide the most succint but complete code snippets which will get the job done. But the java language doesnt really lend itself to this type of succintness. Complete examples are given where possible.. @@ \url{http://www.exampledepot.com/egs/} short examples @@ \url{http://www.kodejava.org/examples/28.html} @@ \url{http://www.java2s.com/} a lot of examples @@ \url{http://leepoint.net/notes-java/} good notes @@ \url{http://www.java-tips.org} good tips HISTORY Bill Joy was an influential figure in the elaboration of the Berkeley Standard Distribution (BSD) of the Unix operating system at the University of California, Berkeley in the late 1960s / 1970s. He was also involved in writing one of the first implementations of the tcp/ip protocol while still a student as well as creating the 'vi' text editor which is one of the most popular terminal unix text editors (especially in its modern 'vim' version). He then went on to co-found Sun Microsystems, where he sponsored the development of the Java language. James Gosling, who had previously worked on the development of the emacs text editor worked on Java. INSTALLING JAVA There are several versions of the java 'run-time engine', librarys and 'java development kit', but the most complete still seems to be the version from Sun Microsystems, the inventors of Java ON MICROSOFT WINDOWS .... On Microsoft windows computers one needs to set the 'path' environment variable manually after the installer has completed ON UNIX .... The process is basically: download a .tar.gz file, unpack and uncompress it with tar xvzf ...., copy the files to somewhere, maybe \texttt{/opt/} set permissions, and more. All this is necessary because Sun/Oracle do not provide a .deb or .rpm package file which would make the process much simpler. Download the 32bit or 64bit Linux "compressed binary file" - it has a ".tar.gz" file extension and uncompress it * unpack the .tar.gz file >> tar -xvf jre-7-linux-i586.tar.gz a folder such as ./jre1.7.0 is created * move this new folder into the \texttt{/usr/lib/jvm/} folder >> sudo mv ./jre1.7.0* \texttt{/usr/lib/jvm/jre1.7.0} * choose the sun version of the jre >> sudo update-alternatives --config java and more stuff .... BASIC JAVA @@ \url{http://www.java2s.com/Code/Java/Language-Basics/CatalogLanguage-Basics.htm} examples of language basics * possibly the simplest java program ------------------------------------ public class Test \{ public static void main(String[] args) \{ System.out.println("hello"); \} \} ,,, The parameter to the main method is necessary. CLASSES * a simple class with a constructor ----------------------------------- public class Name \{ public String first; public String last; public Name(String f, String l) \{ this.first = f; this.last = l; \} \} ,,, * another simple class with a constructor ----------------------------------- public class Name \{ private String first; private String last; public Name(String f, String l) \{ this.first = f; this.last = l; \} public void print() \{ System.out.println(this.first + " " + this.last); \} public static void main(String[] args) \{ Name t = new Name("Bill", "King"); t.print(); \} \} ,,, INHERITING FROM CLASSES .... The process of inheriting from a class is also known as 'extending' a class. * create a class 'Circle' which inherits from the 'Shape' class >> public class Circle extends Shape \{\} OBJECTS An object is an instance of a class which has been created (that is: allocated memory, and initialized). Objects in java are created with the 'new' keyword and one of the classes constructors. * check if an object is an instance of a class ------------------------------------------------------------- BufferedImage bufImg = null; if (origImage instanceof BufferedImage) \{ bufImg = (BufferedImage) origImage; \} else \{ bugImg = new BufferedImage(...); \} ,,, DECLARATIONS * declare 2 variables as type integer >> int x, y; METHODS * a simple method declaration and body -------------------------------------- public string getAge(String name) \{ return this.age; \} ,,, REFLECTION Reflection allows a program to find out information about java classes. This is also known as 'introspection' and allows a program at run-time to find out what methods a particular class or object has. @@ \url{http://java.sun.com/developer/technicalArticles/ALT/Reflection/} a good article about using reflection with java DISPLAY METHODS .... We can use reflection to find out and display all the methods, whether public or private which belong to a particular class. * display the public methods for the 'String' class including inherited -------------------------------------------------------------------- import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.String"); Method m[] = c.getMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i]); \} \} ,,, * display public and private methods declared in the 'String' class ------------------------------------------------------------------- import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.String"); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i]); \} \} ,,, This technique, however, doesnt display the methods which are inherited from super-classes, which in some cases is a serious deficiency. * display the public methods for the 'String' class in a list box ----------------------------------------------------------- import java.lang.reflect.*; import javax.swing.*; public class PublicMethodsTest \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.String"); Method mm[] = c.getMethods(); Object r = JOptionPane.showInputDialog( null, "Choose a method:", "Methods", JOptionPane.PLAIN\\_MESSAGE, null, mm, mm[0]); System.out.println( "value selected: " + r ); \} \} ,,, * public methods in a listbox with a scroll pane -------------------------------------------------- import javax.swing.*; import java.awt.Font; import java.lang.reflect.*; public class MethodList extends JFrame \{ public MethodList() \{ super("A method Box"); try \{ Class c = Class.forName("java.lang.String"); Method mm[] = c.getMethods(); JList list = new JList(mm); //list.setFont(new Font("Georgia", Font.PLAIN, 20)); JPanel p = new JPanel(); p.add(new JScrollPane(list)); this.getContentPane().add(p); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.pack(); this.setLocationRelativeTo(null); this.setVisible(true); \} catch (ClassNotFoundException e) \{ System.out.println(e); \} \} public static void main(String[] args) \{ MethodList t = new MethodList(); \} \} ,,, * display all the public methods for the current class ----------------------------------------------- import java.lang.reflect.*; import javax.swing.*; public class Test \{ public static void main(String args[]) throws Exception \{ Test t = new Test(); Class c = t.getClass(); Method mm[] = c.getMethods(); Object r = JOptionPane.showInputDialog( null, "Choose method:", "Methods", JOptionPane.PLAIN\\_MESSAGE, null, mm, mm[0]); System.out.println( "Method selected was: " + r ); \} \} ,,, * display all the methods for the 'Integer' class ------------------------------------------------ import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Integer.TYPE; Method m[] = c.getMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString()); \} \} ,,, This does not display any results for me. * display the public method names and return type for the 'Method' class ------------------------------------------------------------------ import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.reflect.Method"); Method m[] = c.getMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].getReturnType() + " " + m[i].getName()); \} \} ,,, * display a list of methods with checkboxes for the 'URL' class -------------------------------------------------------------- import java.lang.reflect.*; import javax.swing.*; import java.awt.GridLayout; public class Test \{ public static void main(String[] args) throws Exception \{ JFrame f = new JFrame("Methods with checkboxes for 'URL'"); JPanel p = new JPanel(new GridLayout(0,1)); Class c = Class.forName("java.net.URL"); Method mm[] = c.getDeclaredMethods(); for (int ii = 0; ii < mm.length; ii++) \{ p.add(new JCheckBox(mm[ii].toString())); \} f.getContentPane().add(new JScrollPane(p)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents useful methods of the Method class .. m.getParameterTypes() - the types of all the method parameters .. m.getDeclaringClass() - the class which declared the method .. m.getReturnType() - the method return type .. * display the constructors for the 'String' class ------------------------------------------------- import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.String"); Constructor co[] = c.getDeclaredConstructors(); for (int i = 0; i < co.length; i++) System.out.println(co[i].toString()); \} \} ,,, * display all the field variables for the 'String' class -------------------------------------------------------- import java.lang.reflect.*; public class Test \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.String"); Field f[] = c.getDeclaredFields(); for (int i = 0; i < f.length; i++) System.out.println(f[i].toString()); \} \} ,,, COMPILING JAVA PROGRAMS * compile and run a java program >> javac Test.java >> java Test RUNTIME COMPILING OF JAVA CODE .... \url{http://www.javabeat.net/2007/04/the-java-6-0-compiler-api/} a very good article about doing this \url{http://juixe.com/techknow/index.php/2006/12/13/java-se-6-compiler-api/} another article about this * compiling java code using the compiler api ------------- JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null); File javaFile = new File(¿c:/src/com/juixe/Entity.java¿); // by default is compiled to c:/src // getJavaFileObjects¿ param is a vararg, a variable number of arguments Iterable fileObjects = sjfm.getJavaFileObjects(javaFile); String[] options = new String[] \{¿-d¿, ¿c: /bin¿\}; jc.getTask(null, sjfm, null, Arrays.asList(options), null, fileObjects).call(); // Add more compilation tasks sjfm.close(); ,,, * load a class at runtime ---------------------- File outputDir = new File(¿c:/bin¿); URL[] urls = new URL[]\{outputDir.toURL()\}; URLClassLoader ucl = new URLClassLoader(urls, cl); Class clazz = ucl.loadClass(¿com.juixe.Entity¿); ,,, * another better example of compiling at runtime ------------------------- MyClass.java: the class that will be compiled package test; public class MyClass \{ public void myMethod()\{ System.out.println("My Method Called"); \} \} SimpleCompileTest.java: the class which compiles the other at runtime package test; import javax.tools.*; public class SimpleCompileTest \{ public static void main(String[] args) \{ String fileToCompile = "test" + java.io.File.separator +"MyClass.java"; JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int compilationResult = compiler.run(null, null, null, fileToCompile); if(compilationResult == 0)\{ System.out.println("Compilation is successful"); \}else\{ System.out.println("Compilation Failed"); \} \} \} ,,, But the jdk is required for the above to work because it accesses the tools.jar file in the jdk lib/tools folder * before java 6 compile java code at runtime -------------------------- //put tools.jar from the jdk in your classpath, com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main(); String[] options = new String[] \{ ¿-classpath¿, classpath, ¿-d¿, outputDir, filename \}; javac.compile(options); ,,, BUILDING PROJECTS .... For large projects with many source files a build tool is often used to ensure that all files are properly built. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents tools .. Ant - .. make - .. maven - finds and solves class dependencies .. The Maven Central repository maybe the closest things Java has to the Perl cpan repository. IF CONDITIONALS The 'if' statement is used to branch pogram flow depending on a particular condition. TERNARY OPERATOR The ternary operator is a compact form of the if / else statement * find the minimum value >> minVal = a < b ? a : b; >> minVal = (a < b) ? a : b; * a print statement using a the ternary operator >> System.out.println("will last " + icecreamLife + >> " month" + (icecreamLife==1?"":"s") +" and " + icecreamFate); * use the ternary operator >> int i = 1; String s = (i==0?"zero":"non-zero"); SWITCH STATEMENT * a simple switch statement --------------------------- int result = 0; switch (result) \{ case 0: break; case 1: break; default: break; \} ,,, LOOPS Java does not have a 'map' function, which transforms each element of a collection using a function and without looping. FOR LOOPS .... * since java 1.5 the extended for loop or foreach loop ------------------------------------------------------------- for (type var : arr) \{ body-of-loop \} ,,, * loop over any type of collection (implements iterable) ------------------------------------------------------------- for (Iterator iter = coll.iterator(); iter.hasNext(); ) \{ type var = iter.next(); body-of-loop \} ,,, * the same as above, but only since java 1.5 ------------------------------------------------------------- for (type var : coll) \{ body-of-loop \} ,,, * a simple counting loop ------------------------ for (int ii = 0; ii < 7; ii++) \{ System.out.println("ii=" + ii + " "); \} ,,, * a loop which runs until the user enters 'q' --------------------------------------------- import java.util.Scanner; public class Test \{ public static void main(String[] args) \{ Scanner scan = new Scanner(System.in); for (String s = ""; !s.equals("q"); s = scan.nextLine()) \{ System.out.println("You entered: " + s); System.out.println("Type q to quit"); \} \} \} ,,, WHILE LOOPS .... * a while loop -------------- String s = ""; Scanner scan = new Scanner(System.in); while (!s.equals("q")) \{ System.out.print("type q to quit> "); s = scan.nextLine(); \} ,,, ARRAYS Arrays can be passed to methods or functions, but changes made to the elements are permanent (no copy of the array is made when it is passed to the method). * declare a method 'do' which takes an integ >> public void do(int [] array); DECLARING ARRAYS .... * create an array of 4 integers, with the values initialized >> int[] ii = \{100, 200, 300, 400\}; * declare an array of 30 integers >> int[30] a; * declare an array with space for 25 strings >> String[] ss = new String[25]; \\#\\#(???) * declare an array of characters >> char[] c = \{'a', 'b', 'c'\}; * declare an array of strings >> String[] ss = \{"oak", "alder", "amber"\}; DISPLAYING ARRAYS .... * print an array with Arrays.toString (since 1.5) ------------------------------------------------- import java.util.Arrays; public class ArrayTest \{ public static void main(String[] args) \{ String[] ss = \{"gold", "green", "red"\}; System.out.println(Arrays.toString(ss)); \} \} ,,, * display an array with a JOptionPane list-box ------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ String[] ss = \{"gold", "green", "red"\}; Object r = JOptionPane.showInputDialog( null, "Choose one element:", "Displaying arrays", JOptionPane.PLAIN\\_MESSAGE, null, ss, ss[0]); System.out.println("element selected: " + r); \} \} ,,, LOOPING THROUGH ARRAYS .... Java does have a way to apply a function to all elements of an array at once (although apparently scala does), so you have to loop through the array one element at a time. * Add all elements of the array nn ---------------------------------- int sum = 0; for (int v : nn) \{ sum += v; \} ,,, The above loop cannot be used to set the values of the array * assign random numbers to the elements of an array ------------------------------------------------------------- int[] a = new int[1000]; for (int i = 0; i < a.length(); i++) \{ // Random number 0-99999 a[i] = (int)(Math.random() * 100000); \} ,,, COMPARING ARRAYS .... * check if 2 arrays are equal (contain the same objects) ------------------------------------------------- import java.util.Arrays; public class Test \{ public static void main(String[] args) \{ String[] ss = \{"gold", "green", "red"\}; String[] tt = \{"gold", "green", "red"\}; System.out.println("equal? " + Arrays.equals(ss, tt)); \} \} ,,, * sort an array of integers into ascending order ------------------------------------------------- import java.util.Arrays; public class Test \{ public static void main(String[] args) \{ int[] ii = \{5, 3, 8, 1\}; System.out.println("array: " + Arrays.toString(ii)); Arrays.sort(ii); System.out.println("sorted: " + Arrays.toString(ii)); \} \} ,,, * concatenate 2 arrays of strings --------------------------------- String[] concat(String[] aa, String[] bb) \{ String[] C= new String[A.length+B.length]; System.arraycopy(aa, 0, cc, 0, aa.length); System.arraycopy(B, 0, C, A.length, B.length); return C; \} ,,,, * create an array of 10 integers >> anArray = new int[10]; * copy one array to another --------------------------- public class Test \{ public static void main(String[] args) \{ char[] copyFrom = \{ 'd', 'e', 'c', 'a', 'f', 'f', 'e'\}; char[] copyTo = new char[7]; System.arraycopy(copyFrom, 2, copyTo, 0, 3); System.out.println(new String(copyTo)); \} \} ,,, SEARCHING ARRAYS .... * determine if an array contains a certain element >> String ss = \{"a","b","c"\}; Arrays.asList(ss).contains("b"); MORE ARRAYS .... CAN create and return an array from a method arrays passed in are changed by methods. * different ways to initialize arrays >> int[] ii = \{100, 200, 300, 400\}; >> int[30] a; >> char[] c = \{'a', 'b', 'c'\}; >> double[] d = new double[5]; >> String[] ss = new String[25]; >> int[] aa = \{1, 2, 3\}; ob.doo(aa); All c is initialised to (int)0 char[] c = new char[20]; for (int i=0; i < c.length; i++) System.out.println("c1=" + (int)c[i]); COLLECTIONS Collections are used for arrays of objects where the number or type of objects which need to be stored is not known by the program writer. In modern Java, use is made of 'generics' which allow an easier use of objects within collections. * use ArrayList for resizable arrays * create and add a mutable string to an array list. --------------------------------------------------- List l = new ArrayList(); l.add(new StringBuffer()); ,,, * loop through each element of an array list by index number ------------------------------------------------------------ import java.util.ArrayList; import java.util.List; public class Test \{ public static void main(String[] args) \{ List list = new ArrayList(); for (int jj = 0; jj < list.size(); jj++) \{ System.out.println("[" + jj + "] - " + list.get(jj)); \} \} \} ,,, * get the first element (an integer) from the array list >> Integer one = (Integer) arrayList.get(0) * Vector is older (synchronised for multi threads?) ARRAYLISTS .... @@ \url{http://www.java2s.com/Code/Java/Collections-Data-Structure/ArrayList.htm} arraylist examples NUMBERS RANDOM NUMBERS .... * generate a random integer ------------------------- Random rand = new Random(); selected = rand.nextInt(100); ,,, * generate a random number from 0 to 100 >> int r = (int)(Math.random() * 100) CHARACTERS * get information about a character ----------------------------------- import java.text.*; char cc = 'a'; if (Character.isLowerCase(cc)) \{ //true \} ,,, UNICODE One of the great strength of java is that it was designed with the unicode character set in mind. The font Droid Sans Fallback seems to have the largest number of glyphs and therefore is the font to use for displaying weird and wonderful characters * displays some unicode characters in a grid, with descriptions -------------------------------------------------- import javax.swing.*; import java.awt.*; public class Glyphs \{ public static void main(String[] args) \{ JFrame t = new JFrame(); Font font; JLabel label; String name = new String(); JPanel p = new JPanel(new GridLayout(0, 10)); font = new Font("Georgia", Font.PLAIN, 30); for (int i = 0; i < 10000 \\&\\& font.hasGlyph(i); i++) \{ label = new JLabel("" + (char)i); label.setFont(font); label.setToolTipText("decimal:" + i + " " + Character.getName(i)); p.add(label); \} t.getContentPane().add(new JScrollPane(p)); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setExtendedState(Frame.MAXIMIZED\\_BOTH); t.pack(); t.setVisible(true); \} \} ,,, The code above takes a long time to display, several seconds on a netbook computer. INTERESTING UNICODE CHARACTERS \url{http://unicode.org/Public/UNIDATA/NamesList.txt} the official list of unicode character names. Helpful for finding something U+2620 skull and cross bones U+2603 snow man U+2368 APL FUNCTIONAL SYMBOL TILDE DIAERESIS, looks like a sad face U+0E5B a spirally curly symbol, thai character khomut \url{http://coolunicodecharacters.blogspot.com/} some interesting fancy letter unicode characters \url{http://fsymbols.com/} graphical unicode characters, such as an aeroplane etc organised by type. Have to look at the source code for the numbers The miscelaneous technical page has some clock symbols \\#592 to \\#780 linguistic phonetic symbols note: jdk7 will have a String getName(int codepoint) function (READ: a ¿static method¿ in class java.lang.Character) that will turn a codepoint into its official Unicode name. STRINGS * determine of a string contains a character >> if ("abcd".indexOf('e') == -1) System.out.println("not in the string"); * check if a string is an integer >> boolean isInteger = Pattern.matches("\\^\\$\\backslash\\$\\$\\backslash\\$d*\\$", "1245"); CONVERTING STRINGS .... * convert a String to a double >> double d = Double.valueOf("2.333").doubleValue(); * convert a double to a String >> String s = String.valueOf(2.333); * convert a string to an integer (throws NumberFormatException) >> int i = Integer.parseInt("124") * parse a string with whitespace into an integer >> int test= Integer.parseInt(s.trim()); SUBSTITUTING IN STRINGS .... * substitute in strings ----------------------- String t = new String("Content: one" String s = t.replace("Content:", "").replace("o", "O"); ,,, STRING BUFFERS .... * create and append something to a string buffer ------------------------------------------------ StringBuffer s = new StringBuffer(""); s.append("hi"); ,,, * concatenate 2 strings >> "A" + "B" * concatenate a string and an integer >> "A" + 2 FILES AND DIRECTORIES * get the absolute file name from a relative name. -------------------------------------------------- file = new File("dir" + File.separatorChar + "filename.txt"); file = file.getAbsoluteFile(); // c:\\$\\backslash\\$temp\\$\\backslash\\$dir\\$\\backslash\\$filename.txt ,,, * print a list of files in the current directory ---------------------------------------------- import java.io.File; import java.util.Arrays; public class Test \{ public static void main(String[] args) \{ File[] ff = (new File(".")).listFiles(); System.out.println(Arrays.toString(ff)); \} \} ,,, * print a list of files and their sizes in the current directory ---------------------------------------------------------------- import java.io.File; import java.util.Arrays; public class Test \{ public static void main(String[] args) \{ File[] ff = (new File(".")).listFiles(); for (int ii = 0; ii < ff.length; ii++) \{ System.out.println(ff[ii] + " " + ff[ii].length()); \} \} \} ,,, \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents useful methods of the File class .. File[] listFiles() - returns all the files in the folder .. long length() - returns the size of the file in bytes .. boolean isDirectory() - if the file is a folder .. boolean isFile() - if the file is not a folder .. boolean renameTo(File) - rename the file object .. * open a file within a jar file or in the local file system. >> URL url = this.getClass().getClassLoader().getResource("gameover.wav"); READING FILES .... * read and display text file line by line, using default encoding ---- import java.io.*; public class FileReadTest \{ public static void main(String[] args) throws Exception \{ String line; File f = new File("FileReadTest.java"); BufferedReader in = new BufferedReader(new FileReader(f)); while ((line = in.readLine()) != null) System.out.println(line); in.close(); \} \} ,,, * read a text file into a string buffer line by line ------------------------------------------------------------- import java.io.*; public class FileReadTest \{ public static void main(String[] args) throws Exception \{ String line; File f = new File("FileReadTest.java"); BufferedReader in = new BufferedReader(new FileReader(f)); StringBuffer result = new StringBuffer(); while ((line = in.readLine()) != null) result.append(line + "\\$\\backslash\\$n"); in.close(); System.out.println(result); \} \} ,,, ---- BufferedReader br = new BufferedReader(fr); String buffer; StringBuffer result = new StringBuffer(); while ((buffer = br.readLine()) != null) \{ result.append(buffer); \} ,,, It would probably be faster to read into a larger buffer (8k ?) rather than just one line. STANDARD INPUT STREAM URLS * connect through a proxy host to the net >> java -Dhttp.proxyHost=proxyhost [-Dhttp.proxyPort=portNumber] URLReader * read a url ---- import java.net.*; import java.io.*; public class Test \{ public static void main(String[] args) throws Exception \{ URL url = new URL("http://bumble.sf.net/notes/index.txt"); BufferedReader in = new BufferedReader( new InputStreamReader(url.openStream())); String line; while ((line = in.readLine()) != null) System.out.println(line); in.close(); \} \} ,,, * check if a url host is valid and the file exists -------------------------------------------------- import java.net.*; import java.io.*; public class Test \{ public static void main(String[] args) throws Exception \{ URL url = new URL("http://bumble.sf.net/ntes/index.txt"); try \{ url.openStream(); System.out.println("ok"); \} catch (UnknownHostException e) \{ System.out.println("unknown host"); \} catch (FileNotFoundException e) \{ System.out.println("file not found"); \} \} \} ,,, INPUT AND OUTPUT * get one line of input from the user ------------------------------------- BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); ,,, * use the Scanner class to get and parse user input ---------------- import java.util.Scanner; public class Test \{ public static void main(String[] args) \{ String s = ""; Scanner input = new Scanner(System.in); System.out.println("enter something, 'q' to end"); while (!s.equals("q")) \{ s = input.next(); System.out.println("entered: " + s); \} \} \} ,,, * read all numbers from a string, ignoring anything else ----- import java.util.Scanner; public class Test \{ public static void main(String args[]) \{ String s = "10 99.88 scanning 44.1 is easy."; Scanner scan = new Scanner(s); while (scan.hasNext()) \{ if (scan.hasNextDouble()) System.out.println(scan.nextDouble()); else scan.next(); \} \} \} ,,, TEXT FILES * read long integers from a text file ------------------------------------- // since 1.6 Scanner scanner = new Scanner(new File("numbers.txt")); while (scanner.hasNextLong()) \{ long aLong = scanner.nextLong(); \} ,,, * read a textfile line by line ------------------------------ try \{ BufferedReader in = new BufferedReader (new FileReader ("infilename")); String s; while ((s = in.readLine()) != null) \{ System.out.println(s); \} in.close (); \} catch (IOException e) \{ \} ,,, * read either a file or a Url (file://c:/.. or \url{http://)} ------------------------------------------------------- URL url = new URI(http://www.google.com).toURL(); URLConnection conn = url.openConnection (); Reader rd = new InputStreamReader (conn.getInputStream ()); ,,, * reading a utf-8 file in a non utf-8 locale -------------------------------------------- FileInputStream fis = new FileInputStream("test.txt"); InputStreamReader in = new InputStreamReader(fis, "UTF-8"); ,,, WORKING WITH HTML .... \url{http://www.exampledepot.com/egs/javax.swing.text.html/pkg.html} an example of getting the links in an html document FONTS The default fonts for Java are not very pleasant. They dont seem to be well antialiases or smoothed and this does alot to put people of developing in Java even before they get started Fonts bundled with the Java development kit are stored in >> J:\\$\\backslash\\$Program Files\\$\\backslash\\$java\\$\\backslash\\$jdk1.7.0\\_04 \\$\\backslash\\$jre\\$\\backslash\\$lib\\$\\backslash\\$fonts\\$\\backslash\\$. They are only available to java applications unless they are explicitly installed in the Windows or Unix font repositories * create a new monospace courier font, size 20 points >> Font font = new Font("Courier", Font.PLAIN, 20); * make a bold serifed font, 10 points in size >> Font font = new Font("Serif", Font.BOLD, 10); * create a 24 point italic font >> Font f = new Font("Times New Roman", Font.ITALIC, 24); * get all available font family names ------------------------------------- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fontNames[] = ge.getAvailableFontFamilyNames(); ,,, * show a list of all available font families and select one ------------------------------------------------------------------ import javax.swing.*; import java.awt.*; public class FontList \{ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fontNames[] = ge.getAvailableFontFamilyNames(); Object r = JOptionPane.showInputDialog( null, "Choose a font:", "Available Fonts", JOptionPane.PLAIN\\_MESSAGE, null, fontNames, fontNames[0]); System.out.println("font selected: " + r); \} \}); \} \} ,,, * displays fonts in a listbox and uses the font for the item ------------------------------------------------------------- import java.awt.*; import javax.swing.*; public class ShowFonts \{ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ GraphicsEnvironment ge = GraphicsEnvironment. getLocalGraphicsEnvironment(); String[] fonts = ge.getAvailableFontFamilyNames(); JList fontChooser = new JList(fonts); fontChooser.setCellRenderer(new FontCellRenderer()); JOptionPane.showMessageDialog(null, fontChooser); \} \}); \} \} class FontCellRenderer extends DefaultListCellRenderer \{ public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ JLabel label = (JLabel)super.getListCellRendererComponent( list,value,index,isSelected,cellHasFocus); Font font = new Font((String)value, Font.PLAIN, 20); label.setFont(font); return label; \} \} ,,, * displays fonts in a combobox and uses the font for the item ------------------------------------------------------------- import java.awt.*; import javax.swing.*; public class ShowFonts \{ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ GraphicsEnvironment ge = GraphicsEnvironment. getLocalGraphicsEnvironment(); String[] fonts = ge.getAvailableFontFamilyNames(); JComboBox fontChooser = new JComboBox(fonts); fontChooser.setRenderer(new FontCellRenderer()); JOptionPane.showMessageDialog(null, fontChooser); \} \}); \} \} class FontCellRenderer extends DefaultListCellRenderer \{ public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ JLabel label = (JLabel)super.getListCellRendererComponent( list,value,index,isSelected,cellHasFocus); Font font = new Font((String)value, Font.PLAIN, 20); label.setFont(font); return label; \} \} ,,, * displays a list of fonts available in a list box -------------------------------------------------- import javax.swing.*; import java.awt.*; public class FontList \{ public static void main(String[] args) \{ JFrame t = new JFrame(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fontNames[] = ge.getAvailableFontFamilyNames(); JList lb = new JList(fontNames); JPanel p = new JPanel(); p.add(new JScrollPane(lb)); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * displays all fonts in labels -------------------------------------------------- import javax.swing.*; import java.awt.*; public class FontList \{ public static void main(String[] args) \{ JFrame t = new JFrame(); Font font; JLabel label; String name = new String(); Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); JPanel p = new JPanel(new GridLayout(0, 1)); for (int i = 0; i < fonts.length; i++) \{ name = fonts[i].getFamily(); font = new Font(name, Font.PLAIN, 20); label = new JLabel(name + " glyphs:" + font.getNumGlyphs()); label.setFont(font); p.add(label); \} t.getContentPane().add(new JScrollPane(p)); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setExtendedState(Frame.MAXIMIZED\\_BOTH); t.pack(); t.setVisible(true); \} \} ,,, * create a JLabel with a large Georgia font in grey colour -------------------------------------------------- import javax.swing.*; import java.awt.*; public class LabelFont \{ public static void main(String[] args) \{ JFrame t = new JFrame(); Font font = new Font("Georgia", Font.PLAIN, 40); JLabel l = new JLabel("This is the Georgia Font size 40"); l.setFont(font); l.setForeground(Color.gray); JPanel p = new JPanel(); p.add(l); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setVisible(true); \} \} ,,, By using grey instead of black the java fonts dont look quite as bad as normal. * print something like "mono bold" etc >> fonts.getName (); * print all font family names to standard output ----------------------------------------------------- import java.awt.Font; import java.awt.GraphicsEnvironment; public class FontTest \{ public static void main(String[] args) \{ Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); for (int i = 0; i < fonts.length; i++) \{ String familyName = fonts[i].getFamily(); System.out.println(i + ": " + familyName); \} \} \} ,,, DRAWING WITH FONTS .... * create shapes from character glyphs and then use those shapes to draw ------------------------- Font font = new Font("Serif", Font.BOLD, 10); // a basic font // a scaled up version Font bigfont = font.deriveFont(AffineTransform.getScaleInstance(30.0, 30.0)); GlyphVector gv = bigfont.createGlyphVector(g.getFontRenderContext(), "JAV"); Shape jshape = gv.getGlyphOutline(0); // Shape of letter J Shape ashape = gv.getGlyphOutline(1); // Shape of letter A Shape vshape = gv.getGlyphOutline(2); // Shape of letter V g.fill(jshape); ,,, \url{http://www.javadocexamples.com/java\\_source/\\_\\_/tt/TTFontDemo.java.html} an example of loading a true type font from an input stream \url{http://www.javadocexamples.com/java/awt/Font/deriveFont(int\\%20style,float\\%20size).html} some interesting java examples LOADING FONTS .... * how to load a font from a file -------------------- // First, see if we can load the font file. InputStream is = this.getClass().getResourceAsStream(fontFileName); if (is == null) \{ throw new IOException("Cannot open " + fontFileName); \} // createFont makes a 1-point font, bit hard to read :-) Font ttfBase = Font.createFont(Font.TRUETYPE\\_FONT, is); // So scale it to 24 pt. Font ttfReal = ttfBase.deriveFont(Font.PLAIN, 24); ,,, * check whether a font has a glyph to display a specified character >> font.canDisplay(char c) there are a number of other canDisplay methods * create a font from a file or stream bundled with an application >> font.createFont(int fontFormat, InputStream fontStream) TRANSFORMING FONTS .... * we apply rotates/scales/shears to fonts >> deriveFont(AffineTransform trans) * create a backward slanting font with a shear transform -------------- Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); Font font = new Font("Serif", Font.PLAIN, 24); float x = 20, y = 20; AffineTransform at = new AffineTransform(); at.shear(.2, 0); Font fontShear = font.deriveFont(at); g2.setFont(fontShear); g2.drawString("font.deriveFont(at)", x, y += 30); ,,, DERIVED FONTS .... * increase the size of a font by 2 points >> font = font.deriveFont(font.getSize2D() + 2.0f); getSize2D returns a float value * make a bold italic version of the current font >> font = font.deriveFont(Font.ITALIC + Font.BOLD); * create a derived font with a map of text attributes -------------- Font font = new Font("Serif", Font.PLAIN, 24); float x = 20, y = 20; Hashtable attributes = new Hashtable(); attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT\\_BOLD); Font fontBold = font.deriveFont(attributes); g2.setFont(fontBold); g2.drawString("font.deriveFont(attributes)", x, y += 30); ,,, FONT METRICS .... * create a new image and determine its font metrics ---------------------------------------------------- BufferedImage image = new BufferedImage(800, 600, BufferedImage.TYPE\\_INT\\_RGB); Graphics2D g = (Graphics2D)image.getGraphics(); FontMetrics fm = g.getFontMetrics(); int w = fm.stringWidth("Hello"); int h = fm.getHeight() + fm.getMaxDescent(); ,,, FONT INFORMATION .... * get the number of glyphs contained in a font >> font.getNumGlyphs() COLOURS In Java colours are colors. And grey is gray. In general when creating rgb (red, green, blue) colours, the higher the numbers the lighter the colour, and the lower the numbers the darker the colours. * create a new rgb colour >> Color c = new Color(int red, int green, int blue) * create a light turqoisy colour >> Color c = new Color(0, 230, 230); * set the background for a component using a hex string for the colour >> this.setBackground(new Color(Integer.decode("\\#eeff99"))); * set the foreground and background colours of a jtextarea ---------------------------------------------------------- final JTextArea ta = new JTextArea(); ta.setForeground(Color.green); ta.setBackground(Color.black); ,,, * colours in rgb format >> red is (255, 0, 0) >> green is (0, 255, 0) >> white is (255, 255, 255) >> black is (0,0,0) \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents some java colour names Color.black Color.lightGray Color.blue Color.magenta Color.cyan Color.orange Color.darkGray Color.pink Color.gray Color.red Color.green Color.white Color.yellow * mix colors using the HSB color model when creating a new colour >> Color c = Color.getHSBColor(hue, saturation, brightness) The hue parameter is a decimal number between 0.0 and 1.0 which indicates the hue of the color. You'll have to experiment with the hue number to find out what color it represents. The saturation is a decimal number between 0.0 and 1.0 which indicates how deep the color should be. Supplying a "1" will make the color as deep as possible, and to the other extreme, supplying a "0," will take all the color out of the mixture and make it a shade of gray. The brightness is also a decimal number between 0.0 and 1.0 which obviously indicates how bright the color should be. A 1 will make the color as light as possible and a 0 will make it very dark. * A swing textarea with a foreground and background colour -------------------------------------------------- import javax.swing.*; import java.awt.*; public class ColourArea \{ public static void main(String[] args) \{ JFrame t = new JFrame(); Font font = new Font("Georgia", Font.PLAIN, 30); JTextArea ta = new JTextArea("Botany and Trees"); ta.setForeground(Color.gray); ta.setBackground(Color.white); ta.setFont(font); JPanel p = new JPanel(); p.add(ta); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setVisible(true); \} \} ,,, INTERNATIONALIZATION LOCALIZING MESSAGES .... * an example of using a properties file for messages in other languages ----------------------------------------------------------------------- file 'MyResources\\_en.properties': hello = Hello bye = Goodbye ... file 'MyResources\\_fr.properties': hello = Bonjour bye = Au Revoir ... try \{ // Get the resource bundle for the default locale ResourceBundle rb = ResourceBundle.getBundle ("MyResources"); String key = "hello"; String s = rb.getString (key); key = "bye"; s = rb.getString(key); rb = ResourceBundle.getBundle ("MyResources, Locale.FRENCH); key = "hello"; s = rb.getString (key); // Bonjour key = "bye"; s = rb.getString (key); // Au Revoir \} catch (MissingResourceException e) \{ // The resource bundle or no key \} ,,, PACKAGES * how to create a package \begin{enumerate} \item put 'package namea.nameb;' at the top of the .java file \item place the .java file in the folder namea/nameb \item compile from 'nameb' with javac class.java \item run with java namea.nameb.class \end{enumerate} GUI APPLICATIONS The term 'gui' application refers to an application which uses 'windows' in order to display various graphical components to interact with the user, such as 'text boxes', 'buttons', 'labels' and various other elements. @@ \url{http://www.rgagnon.com/topics/java-swing.html} good practical examples of using swing * create a windowed application ------------------------------- import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ApplicationPanel extends JPanel \{ public ApplicationPanel() \{ super(); JLabel label = new JLabel("Hello World"); this.add(label); \} public static void main(String[] args) \{ SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ JFrame frame = new JFrame("LabelDemo"); frame.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); frame.getContentPane().add(new ApplicationPanel()); frame.pack(); frame.setVisible(true); \} \}); \} \} ,,, * another way to start a swing gui (correct) ----------------------- public static void main(String[] args) \{ Runnable r = new Runnable() \{ public void run() \{ final JFrame frame = new JFrame("..."); ... \} \}; SwingUtilities.invokeLater(r); \} ,,, * possibly the simplest java gui application -------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JOptionPane.showMessageDialog(null, "Hello!"); \} \} ,,, * a very simple gui application, just a window ---------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a application which extends JFrame ------------------------------------ import javax.swing.*; public class Test extends JFrame \{ public Test () \{ super(); JLabel label = new JLabel("extending a jframe"); this.getContentPane().add(label); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.setLocationRelativeTo(null); this.pack(); this.setVisible(true); \} public static void main(String[] args) \{ Test f = new Test(); \} \} ,,, * make an application exit when the window is closed >> frame.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); JFRAME WINDOWS .... @@ \url{http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html} Application windows are created using the JFrame class. These are also known as top level windows because they are not contained by any other element (window, container component ...). In order to create a new window, which will in turn contain panels, buttons, textboxes and all the other bricabrac, there are 2 choices: Create a JFrame within a main method (or other suitable method) >> JFrame f = new JFrame(); and then add stuff to it, or else subclass the JFrame, for example >> public class NewFrame extends JFrame \{ ... and add the bricabrac within the constructor method of the of the NewFrame class * create a 300x300 Window which is centered in the screen --------------------------------- import javax.swing.*; public class NewFrame \{ public static void main(String[] args) \{ JFrame f = new JFrame(); f.setSize(new java.awt.Dimension(300, 300)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, It is necessary to call the "pack" method before the "setLocationRelativeTo" because java uses the pack method to work out how big the window will need to be in order to contain all its elements, so it wont be able to centre the window on the screen before that. * set the size of a window. Its better to call .pack() >> jframe.setSize(220, 90); If you call setSize, its difficult to know if the window will be big enough to display all the stuff it contains. * set the image icon in a window >> jframe.setIconImage(new ImageIcon(imgURL).getImage()); * set the absolute location of the window >> f.setLocation(200,300); * make a JFrame open in the centre of the screen >> jframe.setLocationRelativeTo(null); * make the jframe open big enough to contain its components >> jframe.pack(); * make the application exit when the window is closed >> f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); * set the size of a jframe window --------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame(); f.setSize(new java.awt.Dimension(300, 300)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, FULL SCREEN WINDOWS .... * make the application window as big as the screen (but not maximized) ------------------------------------------------------------- import javax.swing.JFrame; import java.awt.Toolkit; public class Test \{ JFrame frame; public Test() \{ frame = new JFrame("Test"); Toolkit tk = Toolkit.getDefaultToolkit(); int xSize = ((int) tk.getScreenSize().getWidth()); int ySize = ((int) tk.getScreenSize().getHeight()); frame.setSize(xSize,ySize); frame.show(); \} public static void main(String[] args) \{ Test app = new Test(); \} \} ,,, * make the application window maximized ------------------------------------------------------------- import java.awt.Frame; import javax.swing.*; public class MaxFrame \{ JFrame frame; public MaxFrame() \{ frame = new JFrame("Test"); frame.setExtendedState(Frame.MAXIMIZED\\_BOTH); frame.show(); \} public static void main(String[] args) \{ MaxFrame app = new MaxFrame(); \} \} ,,, The frame.show method is probably not very good anymore * make the application window maximized and no window decorations ------------------------------------------------------------- import java.awt.Frame; import javax.swing.*; public class MaxFrame \{ JFrame frame; public MaxFrame() \{ frame = new JFrame("Test"); frame.setExtendedState(Frame.MAXIMIZED\\_BOTH); frame.setUndecorated(true); frame.show(); \} public static void main(String[] args) \{ MaxFrame app = new MaxFrame(); \} \} ,,, For complete full screen applications (to change the screen resolution etc) search for the sun tutorial on fullscreen applications DIALOG BOXES A dialog box or window is a window which displays some message and refuses to go away until you click one of its buttons. They are intensely annoying and should be avoided like botulism. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents Alternative tools .. tk - a script based dialog tool .. perl-tk - the perl version of the 'tk' tool .. zenity - a linux command line dialog tool .. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents JOptionPane dialog boxes .. JOptionPane.showMessageDialog() .. JOptionPane.showInputDialog() .. JOptionPane.showConfirmDialog() .. JOptionPane.showOptionDialog() .. * A simple use of a joptionpane dialog box -------------------------------------------- import javax.swing.*; public class MessageDialog \{ public static void main(String[] args) \{ JOptionPane.showMessageDialog(null, "Hello!"); \} \} ,,, According to Oracle, there are some thread problems with directly executing the showMessageDialog() method. The following technique is supposed to solve these problems. * display a message dialog using a 'thread-safe' technique -------------------------------------------- import javax.swing.*; public class MessageDialog \{ public static void main(String[] args) \{ SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ JOptionPane.showMessageDialog(null, "A thread safe dialog"); \} \}); \} \} ,,, * a dialog box with no icon and a window title -------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JOptionPane.showMessageDialog( null, "Hello!", "Testing Dialogs", JOptionPane.PLAIN\\_MESSAGE); \} \} ,,, * a dialog box with a custom icon image --------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ int messageType = JOptionPane.PLAIN\\_MESSAGE; String s = "/usr/share/icons/gnome/24x24/apps/config-users.png"; ImageIcon icon = new ImageIcon(s, "blob"); JOptionPane.showMessageDialog( null, "New User", "User System", messageType, icon); \} \} ,,, \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents Option Pane button configuration .. JOptionPane.DEFAULT\\_OPTION - OK button .. JOptionPane.YES\\_NO\\_OPTION - YES and NO buttons .. JOptionPane.YES\\_NO\\_CANCEL\\_OPTION - YES, NO, and CANCEL buttons .. JOptionPane.OK\\_CANCEL\\_OPTION - OK and CANCEL buttons .. INPUT DIALOGS .... * an inputbox which returns the text ------------------------------------- import javax.swing.*; public class InputBox \{ public static void main(String[] args) \{ String r = JOptionPane.showInputDialog( "Enter address:", ""); System.out.println("text entered: " + r); \} \} ,,, COMBOBOX DIALOG .... In Java a combobox is a small box with one line of text in it, and a down-arrow which allows the user to select a different value to place in the combobox. In html these are called "select boxes". * a combobox dialog with an array of values which return the selected value -------------------------------------------------------------------- import javax.swing.*; public class ListBoxDialog \{ public static void main(String[] args) \{ Object[] values = \{ "Almond", "Oak", "Cork Oak" \}; Object result = JOptionPane.showInputDialog( null, "Choose a tree to plant:", "Testing the Combobox Dialog", JOptionPane.PLAIN\\_MESSAGE, null, values, values[0]); System.out.println("value selected: " + result); \} \} ,,, * a list box with an array of values with a custom icon image ------------------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ Object[] selValues = \{ "abc", "def", "ghi" \}; ImageIcon icon = new ImageIcon("blob.gif", "blob"); Object res = JOptionPane.showInputDialog( null, "Enter value:", "Message Title", JOptionPane.PLAIN\\_MESSAGE, icon, selValues, selValues[0]); System.out.println( "value selected: " + res ); \} \} ,,, OPTION DIALOGS .... * a dialog box with a series of buttons to choose from ------------------------------------------------------ import javax.swing.*; public class Test \{ public static void main(String[] args) \{ Object[] vv = \{ "a", "b", "c" \}; int r = JOptionPane.showOptionDialog( null, "Which letter do you choose?", "Select One", JOptionPane.DEFAULT\\_OPTION, JOptionPane.PLAIN\\_MESSAGE, null, vv, vv[0]); System.out.println("you selected: " + r); \} \} ,,, * a dialog with a series of option buttons and a custom image ------------------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ int optionType = JOptionPane.DEFAULT\\_OPTION; int messageType = JOptionPane.PLAIN\\_MESSAGE; // no standard icon ImageIcon icon = new ImageIcon("blob.gif", "blob"); Object[] vv = \{ "abc", "def", "ghi" \}; int res = JOptionPane.showOptionDialog( null, "Hello!", "Message Title", JOptionPane.DEFAULT\\_OPTION, JOptionPane.PLAIN\\_MESSAGE, icon, vv, vv[0]); \} \} ,,, COLORCHOOSER * create a swing colorchooser component >> colorChooser = new JColorChooser(); COLORCHOOSER DIALOG .... FILECHOOSER The JFileChooser and JColorChooser components can be used either as components added to a container, such as a panel, or else as dialog boxes, that is, contained within a new window. FILECHOOSER DIALOG .... * show a file chooser dialog and determine the result ----------------------------------------------------- import javax.swing.*; public class ChooseFile \{ public static void main(String[] args) \{ JFrame f = new JFrame("test file chooser"); JFileChooser chooser = new JFileChooser(); int result = chooser.showOpenDialog(f); java.io.File file = chooser.getSelectedFile(); switch (result) \{ case JFileChooser.APPROVE\\_OPTION: break; case JFileChooser.CANCEL\\_OPTION: break; \} \} \} ,,, Using setFont to set the font for a builtin dialog box doesnt work. The Another technique is to set the FileChooser font in the UIManager defaults. * display only directories in a file chooser box ------------------------------------------------ import javax.swing.*; public class ChooseFile \{ public static void main(String[] args) \{ JFrame f = new JFrame("test file chooser"); JFileChooser c = new JFileChooser(); c.setFileSelectionMode(JFileChooser.DIRECTORIES\\_ONLY); int result = c.showOpenDialog(f); java.io.File file = c.getSelectedFile(); switch (result) \{ case JFileChooser.APPROVE\\_OPTION: break; case JFileChooser.CANCEL\\_OPTION: System.exit(-1); break; \} \} \} ,,, * display a file chooser with the native look and feel ------------------------------------------------ import javax.swing.*; public class NiceFileDialog \{ public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame f = new JFrame("Trying to make the FileChooser look nicer"); JFileChooser c = new JFileChooser(); if (c.showOpenDialog(f) == JFileChooser.CANCEL\\_OPTION) System.exit(-1); \} \} ,,, JCOMBOBOX .... * displays fonts in a combobox and uses the font for the item ------------------------------------------------------------- import java.awt.*; import javax.swing.*; public class ShowFonts \{ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ GraphicsEnvironment ge = GraphicsEnvironment. getLocalGraphicsEnvironment(); String[] fonts = ge.getAvailableFontFamilyNames(); JComboBox fontChooser = new JComboBox(fonts); fontChooser.setRenderer(new FontCellRenderer()); JOptionPane.showMessageDialog(null, fontChooser); \} \}); \} \} class FontCellRenderer extends DefaultListCellRenderer \{ public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ JLabel label = (JLabel)super.getListCellRendererComponent( list,value,index,isSelected,cellHasFocus); Font font = new Font((String)value, Font.PLAIN, 20); label.setFont(font); return label; \} \} ,,, JLIST LIST BOXES Swing list boxes can use a model, view, controller pattern or else they can be initialized with a simple array. In order to use a 'model' to populate the swing listbox, it is necessary to implement the AbstractListModel, which involves implementing two functions. Otherwise you can use the DefaultListModel, which is the easiest or the ListModel which is the hardest. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents important methods for the swing listbox .. getSelectedIndex - get the index number of the selected item .. getSelectedValue - get the value (usually text) associated with selected item .. .. * set some parameters for a listbox ------------------------------------------------------------- list = new JList(data); //data has type Object[] list.setSelectionMode(ListSelectionModel.SINGLE\\_INTERVAL\\_SELECTION); list.setLayoutOrientation(JList.HORIZONTAL\\_WRAP); list.setVisibleRowCount(-1); ,,, * set the selectmode, but is all this necessary? >> list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE\\_INTERVAL\\_SELECTION); * get the value of an element in a list at in 4 >> s = (String)list.getModel().getElementAt(4); * a simple example of using a swing listbox -------------------------------------------------- import javax.swing.*; import java.io.*; public class Box \{ public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame t = new JFrame(); String[] ss = \{"Eucalypt", "Oak", "Apple", "Walnut"\}; JList trees = new JList(ss); JPanel pl = new JPanel(); pl.add(new JScrollPane(trees)); t.getContentPane().add(pl); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * a listbox with a different font and colour -------------------------------------------------- import javax.swing.*; import java.awt.Font; public class Box \{ public static void main(String[] args) \{ JFrame t = new JFrame(); String[] ss = \{"Eucalypt", "Cork Oak", "Apple", "Walnut"\}; JList trees = new JList(ss); trees.setFont(new Font("Georgia", Font.PLAIN, 30)); JPanel p = new JPanel(); p.add(trees); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setLocationRelativeTo(null); t.pack(); t.setVisible(true); \} \} ,,, If we explicitly use the DefaultListModel as the 'data model' for the swing listbox, then we can add and remove elements from the listbox after it has been created. * create a list box to which elements can be added or removed -------------------------------------------------- import javax.swing.*; import java.awt.Font; public class Box \{ public static void main(String[] args) \{ JFrame t = new JFrame(); DefaultListModel listModel = new DefaultListModel(); listModel.addElement("Tibouchina"); listModel.addElement("Siete Cueros"); listModel.addElement("Hevea Brasiliensis"); JList trees = new JList(listModel); trees.setFont(new Font("Georgia", Font.PLAIN, 30)); JPanel p = new JPanel(); p.add(trees); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setLocationRelativeTo(null); t.pack(); t.setVisible(true); \} \} ,,, * displays a file list in the center of the screen -------------------------------------------------- import javax.swing.*; import java.io.*; import java.awt.Font; public class Test \{ public static void main(String[] args) \{ JFrame t = new JFrame(); JList fileList = new JList((new File(".")).listFiles()); fileList.setFont(new Font("Georgia", Font.PLAIN, 50)); JPanel pl = new JPanel(); pl.add(new JScrollPane(fileList)); t.getContentPane().add(pl); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * jlist box with lots of numbers using a list model --------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ ListModel bigData = new AbstractListModel() \{ public int getSize() \{ return Short.MAX\\_VALUE; \} public Object getElementAt(int index) \{ return "Index " + index; \} \}; JList dataList = new JList(bigData); // the following makes rendering quicker dataList.setPrototypeCellValue("Index 1234567890"); JFrame f = new JFrame(); f.getContentPane().add(new JScrollPane(dataList)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a list box with a model and unicode characters ------------------------------------------------ import javax.swing.*; public class UnicodeBox \{ public static void main(String[] args) \{ ListModel bigData = new AbstractListModel() \{ public int getSize() \{ return Short.MAX\\_VALUE; \} public Object getElementAt(int index) \{ return "unicode " + index + 1000 + ":" + (char)(index + 1000); \} \}; JList unicodeList = new JList(bigData); unicodeList.setPrototypeCellValue("Index 1234567890"); JPanel p = new JPanel(); p.add(new JScrollPane(unicodeList)); JFrame f = new JFrame(); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, LISTBOX ELEMENTS .... It is possible to customize the way that each list element in a swing list box is rendered by implementing the ListCellRenderer interface. This involves writing a body for the getListCellRendererComponent method * An example of a ListCellRenderer implementation ------------------------------------------------------------- import javax.swing.*; class ColourCell extends JLabel implements ListCellRenderer \{ public ColourCell() \{ setOpaque(true); \} public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ this.setText(value.toString()); // Is the listbox item currently selected? if (isSelected) \{ this.setBackground(Color.RED); this.setForeground(Color.WHITE); \} else \{ this.setBackground(Color.WHITE); this.setForeground(Color.GRAY); \} return this; \} \} ,,, Investigate the significance of the 'drop location' * check if this cell represents the current DnD drop location >> JList.DropLocation dropLocation = list.getDropLocation(); * attach the custom cell render to the jlistbox or jcombobox ------------------------------------------------------------- JList listbox = new JList(aa); ColourCell renderer = new ColourCell(); renderer.setPreferredSize(new Dimension(200, 130)); listbox.setRenderer(renderer); ,,, * create a cellrenderer to make the selection white on red and the font big -------------------------------------------------- import javax.swing.*; import java.awt.*; import java.io.File; public class Test \{ public static void main(String[] args) \{ JFrame t = new JFrame(); JList fileList = new JList((new File(".")).listFiles()); ColourCell renderer = new ColourCell(); //renderer.setPreferredSize(new Dimension(200, 130)); fileList.setCellRenderer(renderer); JPanel pl = new JPanel(); pl.add(new JScrollPane(fileList)); t.getContentPane().add(pl); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setLocationRelativeTo(null); t.pack(); t.setVisible(true); \} \} class ColourCell extends JLabel implements ListCellRenderer \{ public ColourCell() \{ this.setOpaque(true); this.setFont(new Font("Georgia", Font.PLAIN, 30)); \} public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ this.setText(value.toString()); // Is the listbox item currently selected? if (isSelected) \{ this.setBackground(Color.RED); this.setForeground(Color.WHITE); \} else \{ this.setBackground(Color.WHITE); this.setForeground(Color.GRAY); \} return this; \} \} ,,, According to the Sun java tutorial site the índex param to the getListCellRendererComponent is not alway valid. Which seems odd. So instead we can use >> int selectedIndex = ((Integer)value).intValue(); ??? * create a cellrenderer to colour alternate rows light blue in the jlistbox -------------------------------------------------- import javax.swing.*; import java.awt.*; import java.io.File; public class Test \{ public static void main(String[] args) \{ JFrame t = new JFrame(); JList fileList = new JList((new File("..")).listFiles()); ColourCell renderer = new ColourCell(); fileList.setCellRenderer(renderer); JPanel pl = new JPanel(); pl.add(new JScrollPane(fileList)); t.getContentPane().add(pl); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setLocationRelativeTo(null); t.pack(); t.setVisible(true); \} \} class ColourCell extends JLabel implements ListCellRenderer \{ public ColourCell() \{ this.setOpaque(true); this.setFont(new Font("Georgia", Font.PLAIN, 20)); \} public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) \{ this.setText(value.toString()); if (isSelected) /* if the listbox element is currently selected */ \{ this.setBackground(Color.blue); this.setForeground(Color.white); \} else \{ this.setForeground(Color.darkGray); if ((index \\% 2) == 0) this.setBackground(Color.white); else //this.setBackground(new Color(0, 220, 250)); this.setBackground(new Color(Integer.decode("\\#ffffdd"))); \} return this; \} \} ,,, If the opacity of the cell renderer is false then the renderer doesnt seem to do its job properly >> this.setOpaque(true); JLIST EVENTS .... In order to fire events when an item is selected in a JListBox you need to implement an ListSelectionListener by defining one method 'public void valueChanged(ListSelectionEvent e). Using a mouseadaptor may be another way The getValueIsAdjusting() method returns true if the user is still manipulating the selection for example, is dragging the selection to include more elements. * An example of a valueChanged method for responding to listbox selections ------------------------------------------------------------- public void valueChanged(ListSelectionEvent e) \{ if (e.getValueIsAdjusting() == false) \{ if (list.getSelectedIndex() == -1) \{ /* No selection */ \} else \{ /* do something */ \} \} \} ,,, * create a listbox which reacts to changes of the selected item(s) -------------------------------------------------- import javax.swing.*; import javax.swing.event.*; import java.awt.*; public class BoxEvent extends JFrame implements ListSelectionListener \{ String[] ss = \{"Yew", "Oak", "Elder", "Myoporum"\}; JList list; public BoxEvent() \{ list = new JList(ss); list.addListSelectionListener(this); list.setFont(new Font("Georgia", Font.PLAIN, 40)); JPanel p = new JPanel(); p.add(list); this.getContentPane().add(p); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.setLocationRelativeTo(null); this.pack(); this.setVisible(true); \} public void valueChanged(ListSelectionEvent e) \{ if (e.getValueIsAdjusting() == false) \{ if (list.getSelectedIndex() == -1) \{ /* No selection */ \} else \{ System.out.println(list.getSelectedIndex()); \} \} \} public static void main(String[] args) \{ BoxEvent b = new BoxEvent(); \} \} ,,, * do something when a jlist item is double clicked -------------------------------------------------- final JList list = new JList(dataModel); MouseListener mouseListener = new MouseAdapter() \{ public void mouseClicked(MouseEvent e) \{ if (e.getClickCount() == 2) \{ int index = list.locationToIndex(e.getPoint()); System.out.println("Double clicked on Item " + index); \} \} \}; list.addMouseListener(mouseListener); ,,, PANELS Panels are important for grouping and laying out graphical components on a window. Panels can be created with a 'layout' which determines how the components (such as text-boxes, labels list boxes etc will be placed within the panel when the the 'add()' method of the panel is used. Panels, unless they have a border, are usually invisible to the user. * create a panel with a 2 by 2 gridlayout >> JPanel p = new JPanel(new GridLayout(2, 2)); * create a panel with 2 columns and unlimited rows >> JPanel p = new JPanel(new GridLayout(0, 2); * a simple frame window with a panel and 3 labels ------------------------------------------------- import javax.swing.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 1)); p.add(new JLabel("1st label")); p.add(new JLabel("2nd label")); p.add(new JLabel("3rd label")); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * create a 2 column grid layout, 5px vertical separation, 1px horizontal >> java.awt.GridLayout g = new GridLayout(0, 2, 5, 1)); * a panel containing a user-name and password entry fields ---------------------------------------------------------- import javax.swing.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); p.add(new JLabel("user")); p.add(new JTextField()); p.add(new JLabel("password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, The problem with the window above, it that it doesnt resize is a pleasant fashion, the text boxes become very large and the space between the labels increases. BORDERS @@ \url{http://leepoint.net/notes-java/GUI-appearance/borders/15bordersex.html} some good notes about creating borders * a panel with a titled, etched border -------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); Border eb = BorderFactory.createEtchedBorder(); Border tb = BorderFactory.createTitledBorder(eb, "Login"); p.setBorder(tb); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, The problem with the panel above is that it doesnt resize well. The text boxes become very large. * a panel with a title etched border with some extra space around it -------------------------------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); Border etchedBdr = BorderFactory.createEtchedBorder(); Border titledBdr = BorderFactory.createTitledBorder(etchedBdr, "Login"); Border emptyBdr = BorderFactory.createEmptyBorder(5,5,5,5); Border compoundBdr = BorderFactory.createCompoundBorder(titledBdr, emptyBdr); p.setBorder(compoundBdr); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * use a static method to create an etched border with extra space ----------------------------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ static final Border spaceBorder = BorderFactory.createEmptyBorder(5,5,5,5); static final Border etchedBorder = BorderFactory.createEtchedBorder(); public static Border titledBorder(String title) \{ return BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(etchedBorder, title), spaceBorder); \} public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); p.setBorder(titledBorder("Login")); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * create an etched border, with a title and some extra space ------------------------------------------------------------ import javax.swing.border.*; . . . JPanel p = new JPanel(); Border etchedBdr = BorderFactory.createEtchedBorder(); Border titledBdr = BorderFactory.createTitledBorder(etchedBdr, "Process"); Border emptyBdr = BorderFactory.createEmptyBorder(10,10,10,10); Border compoundBdr = BorderFactory.createCompoundBorder(titledBdr, emptyBdr); processPanel.setBorder(p); ,,, \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents different kinds of borders .. BorderFactory.createLineBorder(Color.black); .. BorderFactory.createEtchedBorder(); .. BorderFactory.createRaisedBevelBorder(); .. BorderFactory.createLoweredBevelBorder(); .. * putting a title in the border ------------------------------- TitledBorder titledBorder = BorderFactory.createTitledBorder ("Title"); //titledBorder = BorderFactory.createTitledBorder (border, "Title"); titledBorder.setTitleJustification (TitledBorder.CENTER); titledBorder.setTitlePosition (TitledBorder.BELOW\\_TOP); component.setBorder (titledBorder); ,,, * a panel with a titled, rounded corner border ---------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); Border eb = new LineBorder(Color.gray, 1, true); //Border eb = BorderFactory.createLineBorder(Color.gray, 2, true); Border tb = BorderFactory.createTitledBorder(eb, "Login"); p.setBorder(tb); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a green italic center aligned title border with extra space ------------------------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); Border eb = BorderFactory.createEtchedBorder(); Border tb = BorderFactory.createTitledBorder( eb, "Login", TitledBorder.CENTER, TitledBorder.TOP, new Font("Serif", Font.ITALIC, 10), Color.blue); Border sb = BorderFactory.createEmptyBorder(5,5,5,5); Border cb = BorderFactory.createCompoundBorder(tb, sb); p.setBorder(cb); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a green italic center aligned title border -------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JPanel p = new JPanel(new GridLayout(0, 2, 5, 1)); Border eb = BorderFactory.createEtchedBorder(); Border tb = BorderFactory.createTitledBorder( eb, "Login", TitledBorder.CENTER, TitledBorder.TOP, new Font("Serif", Font.ITALIC, 10), Color.blue); p.setBorder(tb); p.add(new JLabel("User")); p.add(new JTextField()); p.add(new JLabel("Password")); p.add(new JPasswordField()); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, TABBED PANES Tabbed panes are useful, and represent a modern and simple user interface element. * a simple tabbed pane example ------------------------------ import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane jtp = new JTabbedPane(); JPanel p1 = new JPanel(); p1.add(new JLabel("The 1st Tab Area")); JPanel p2 = new JPanel(); p2.add(new JLabel("The 2nd Tab Area")); jtp.addTab("Tab1", p1); jtp.addTab("Tab2", p2); f.getContentPane().add(jtp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a tabbed pane with tool tip text for the tabs ----------------------------------------------- import javax.swing.*; import java.awt.event.KeyEvent; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane tp = new JTabbedPane(); JPanel p1 = new JPanel(); p1.add(new JLabel("The 1st Tab Area")); JPanel p2 = new JPanel(); p2.add(new JLabel("The 2nd Tab Area")); tp.addTab("Tab1", null, p1, "View the first"); tp.addTab("Tab2", null, p2, "View the second"); f.getContentPane().add(tp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a tabbed pane with tabs at the right of the pane -------------------------------------------------- import javax.swing.*; import java.awt.event.KeyEvent; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane tp = new JTabbedPane(); tp.setTabPlacement(JTabbedPane.RIGHT); JPanel p1 = new JPanel(); p1.add(new JLabel("The 1st Tab Area")); JPanel p2 = new JPanel(); p2.add(new JLabel("The 2nd Tab Area")); tp.addTab("Tab1", null, p1); tp.addTab("Tab2", null, p2); f.getContentPane().add(tp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a tabbed pane with icons for the tabs and short cut keys (alt s/d) -------------------------------------------------------------------- import javax.swing.*; import java.awt.event.KeyEvent; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane tp = new JTabbedPane(); JPanel p1 = new JPanel(); p1.add(new JLabel("This the screen Tab Area (first)")); JPanel p2 = new JPanel(); p2.add(new JLabel("This is the drive Tab Area (second)")); ImageIcon icon1 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/chardevice.png"); tp.addTab("Screen", icon1, p1, "View the screen tab"); tp.setMnemonicAt(0, KeyEvent.VK\\_S); ImageIcon icon2 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/drive-cdrom.png"); tp.addTab("Drive", icon2, p2, "View the drive tab"); tp.setMnemonicAt(1, KeyEvent.VK\\_D); f.getContentPane().add(tp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * set the shortcut key for first tab on the pane to 'alt' + s >> tp.setMnemonicAt(0, KeyEvent.VK\\_S); If the text for the first tab on the tabbed pane contains an 's' then that letter will be automatically underlined. * set the shortcut key for second tab on the pane to 'alt' + D >> tp.setMnemonicAt(0, KeyEvent.VK\\_D); * a tabbed pane with icons but no text on the tabs -------------------------------------------------- import javax.swing.*; import java.awt.event.KeyEvent; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane tp = new JTabbedPane(); JPanel p1 = new JPanel(); p1.add(new JLabel("The 1st Tab Area")); JPanel p2 = new JPanel(); p2.add(new JLabel("The 2nd Tab Area")); ImageIcon icon1 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/chardevice.png"); tp.addTab(null, icon1, p1, "View the screen tab"); ImageIcon icon2 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/drive-cdrom.png"); tp.addTab(null, icon2, p2, "View the drive tab"); f.getContentPane().add(tp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a tabbed pane with icons and grid layout panels -------------------------------------------------- import javax.swing.*; import java.awt.event.KeyEvent; import java.awt.GridLayout; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Tabs"); JTabbedPane tp = new JTabbedPane(); JPanel p1 = new JPanel(new GridLayout(0, 1)); p1.add(new JLabel("The 1st Tab Area")); p1.add(new JLabel(" another label")); p1.add(new JLabel(" another label")); JPanel p2 = new JPanel(new GridLayout(0, 1)); p2.add(new JLabel("The 2nd Tab Area")); p2.add(new JLabel(" another label")); p2.add(new JLabel(" another label")); ImageIcon icon1 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/chardevice.png"); tp.addTab(null, icon1, p1, "View the screen tab"); ImageIcon icon2 = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/drive-cdrom.png"); tp.addTab(null, icon2, p2, "View the drive tab"); f.getContentPane().add(tp); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents useful methods for tabbed panes .. insertTab(String, Icon, Component, String, int) - insert a tab .. removeTabAt(3) - remove the 3rd tab .. pane.removeAll() - remove all the tabs .. pane.setSelectedIndex(2) - select the 2nd tab .. pane.setTitleAt(2, "file") - set the title of the 2nd tab to 'file' .. pane.setIconAt(2, icon) - set the icon for the 2nd tab .. LAYOUT MANAGERS A layout manager is a way of managing the way the components are arranged in a panel or other container component. The idea is to arrange components (buttons, boxes etc) in a way that is both aesthetically pleasing and reflects the logic of the application. BORDER LAYOUT .... A border layout is a simple design consisting of a centre location and north, south, east, west locations * a panel with a border layout ------------------------------------------------------------- JPanel panel = new JPanel(new BorderLayout()); panel.add(comp, BorderLayout.CENTER); ,,, * a borderlayout with gaps and a title -------------------------- JPanel p = new JPanel(new BorderLayout(5,5)); p.setBorder(new TitledBorder("Main GUI")); ,,, * create a panel with a border layout ------------------------------------------------------------- import javax.swing.*; import javax.swing.plaf.FontUIResource; import java.awt.*; public class BorderPanel extends JPanel \{ public BorderPanel() \{ super(new BorderLayout()); JButton b = new JButton("Center"); this.add(b, BorderLayout.CENTER); JButton bn = new JButton("North"); this.add(bn, BorderLayout.NORTH); JButton bw = new JButton("West"); this.add(bw, BorderLayout.WEST); \} public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel( "javax.swing.plaf.nimbus.NimbusLookAndFeel"); UIManager.put( "Button.font", new FontUIResource("Georgia", Font.PLAIN, 18)); JFrame f = new JFrame(""); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new BorderPanel()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, GRIDLAYOUT .... It's not possible to add a component to a grid layout at a particular cell. One must add all components to the layout sequencially (left to right, top to bottom). Use empty labels to not add anything to a partiular cell. @@ \url{http://leepoint.net/notes-java/GUI/layouts/30gridlayout.html} notes about grid layouts * create a layout with 1 column and unlimited rows >> GridLayout layout = new GridLayout(0, 1); * create a layout with a horizontal gap of 10 and vertical gap of 20 >> GridLayout layout = new GridLayout(0, 1, 10, 20); * create a swing panel with a gridlayout and a titled border JPanel p = new JPanel(new GridLayout(0,1)); p.setBorder(new TitledBorder("Main GUI")); ,,, * a 2 by 2 grid layout with gaps between cells ----------------------------------------------- import javax.swing.*; import java.awt.GridLayout; public class TwoByTwoGrid \{ public static void main(String[] args) \{ JFrame f = new JFrame("A 2x2 Grid Layout"); JPanel content = new JPanel(new GridLayout(2, 2, 5, 5)); content.add(new JButton("Walnut")); content.add(new JButton("Eucalypt")); content.add(new JLabel("")); // for empty cell content.add(new JButton("Myoporum")); f.getContentPane().add(content); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * create a panel with a 3 by 2 grid layout >> JPanel content = new JPanel(new GridLayout(3, 2, 10, 10)); * combine 2 gridlayout panels in a single frame ----------------------------------------------- import javax.swing.*; import java.awt.GridLayout; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Grid Layouts"); JPanel content = new JPanel(new GridLayout(2, 1)); JPanel buttonPane = new JPanel(new GridLayout(3, 3, 5, 5)); for (int ii = 0; ii < 9; ii++) \{ buttonPane.add(new JButton("" + ii)); \} JPanel textPane = new JPanel(new GridLayout(3, 1, 5, 5)); for (int ii = 0; ii < 3; ii++) \{ textPane.add(new JTextField(20)); \} content.add(buttonPane); content.add(textPane); f.getContentPane().add(content); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, GRIDBAGLAYOUT The GridBagLayout is possibly the most flexible of the layout managers. See also the 'GroupLayout' or use a graphical tool. * a simple use of GridBayLayout and GridBagConstraints ------------------------------------------------------ GridBagConstraints c = new GridBagConstraints (); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; add (textField, c); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.weighty = 1.0; ,,, JSCROLLPANES * If an element is likely to be too big, add a scrollpane to it >> JScrollPane scrollpane = new JScrollPane(element); * set the height of a scroll pane to 1/3 of what it would be ------------------------------------------------------------- Dimension tablePreferred = tableScroll.getPreferredSize(); tableScroll.setPreferredSize( new Dimension(tablePreferred.width, tablePreferred.height/3) ); ,,, JSPINNER A JSpinner element is a small box which allows a user to select a value by clicking the increment or decrement arrows * connect a JSpinner and a JSlider ---------------------------------- import java.awt.*; import javax.swing.*; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** @see \url{http://stackoverflow.com/questions/6067898} */ public class SpinSlider extends JPanel \{ public static void main(String args[]) \{ EventQueue.invokeLater(new Runnable() \{ @Override public void run() \{ JFrame f = new JFrame("SpinSlider!"); f.add(new SpinSlider()); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setVisible(true); \} \}); \} public SpinSlider() \{ this.setLayout(new FlowLayout()); final JSpinner spinner = new JSpinner(); final JSlider slider = new JSlider(); slider.addChangeListener(new ChangeListener() \{ @Override public void stateChanged(ChangeEvent e) \{ JSlider s = (JSlider) e.getSource(); spinner.setValue(s.getValue()); \} \}); this.add(slider); spinner.setModel(new SpinnerNumberModel(50, 0, 100, 1)); spinner.setEditor(new JSpinner.NumberEditor(spinner, "0'\\%'")); spinner.addChangeListener(new ChangeListener() \{ @Override public void stateChanged(ChangeEvent e) \{ JSpinner s = (JSpinner) e.getSource(); slider.setValue((Integer) s.getValue()); \} \}); this.add(spinner); \} \} ,,, EVENTS FOR JSPINNER .... addChangeLister() JSLIDER * how to use sliders >> \url{http://docs.oracle.com/javase/tutorial/uiswing/components/slider.html} * a JSlider example ---------------------------------------------------- JSlider slider= new JSlider(JSlider.HORIZONTAL,0,100,50); //min value 0, max value 100, initial value 50 slider.addChangeListener(this) JTextFox text = new JTextFox("50"); //... public void stateChanged(ChangeEvent e) \{ JSlider source = (JSlider)e.getSource(); int value = (int)source.getValue(); text.setText(Integer.toString(value)); \} ,,, * create a JSlider and set some of its properties ------------------------------------------------- gui = new JPanel(new BorderLayout(3,4)); quality = new JSlider(JSlider.VERTICAL, 0, 100, 75); quality.setSnapToTicks(true); quality.setPaintTicks(true); quality.setPaintLabels(true); quality.setMajorTickSpacing(10); quality.setMinorTickSpacing(5); quality.addChangeListener( new ChangeListener()\{ public void stateChanged(ChangeEvent ce) \{ // do something when the slider slides \} \} ); gui.add(quality, BorderLayout.WEST); ,,, JPROGRESSBAR Shows the progress for some activity which takes a noticeable amount of time, such as downloading a file * how to use progress bars >> \url{http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html} * an example of using jprogress bar and a timer ------------------------------------------------------------- import java.awt.event.*; import javax.swing.*; public class CountDownProgressBar \{ Timer timer; JProgressBar progressBar; CountDownProgressBar() \{ progressBar = new JProgressBar(JProgressBar.VERTICAL, 0, 10); progressBar.setValue(10); ActionListener listener = new ActionListener() \{ int counter = 10; public void actionPerformed(ActionEvent ae) \{ counter--; progressBar.setValue(counter); if (counter<1) \{ JOptionPane.showMessageDialog(null, "Kaboom!"); timer.stop(); \} \} \}; timer = new Timer(1000, listener); timer.start(); JOptionPane.showMessageDialog(null, progressBar); \} public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ CountDownProgressBar cdpb = new CountDownProgressBar(); \} \}); \} \} ,,, JCHECKBOX A check box is a small box in which the user can place a 'tick' or 'check' by clicking with the mouse. These elements are usually used in order to select more than one item in a list. * create a simple checkbox which is initially selected ------------------------------------------------------ import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JCheckBox b = new JCheckBox("Shopping"); b.setSelected(true); f.getContentPane().add(b); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a check box with a short cut key alt 's' and a tool tip -------------------------------------------------------------- import javax.swing.*; import java.awt.event.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JCheckBox b = new JCheckBox("Grow Trees"); b.setSelected(true); b.setMnemonic(KeyEvent.VK\\_S); b.setToolTipText( "Click here: you will find that " + " you
will start to want to grow some trees"); JPanel p = new JPanel(); p.add(b); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, The font bgcolor html doesnt work well be setting the * a check box with a large font ------------------------------- import javax.swing.*; import java.awt.Font; import java.awt.event.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JCheckBox b = new JCheckBox("Shopping"); b.setMnemonic(KeyEvent.VK\\_S); b.setToolTipText("click to go shopping"); b.setFont(new Font("Serif", Font.PLAIN, 20)); JPanel p = new JPanel(); p.add(b); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a check box with html text for the tool tip and the display text ------------------------------------------------------------------ import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Check-boxes"); JCheckBox b = new JCheckBox("Vim"); b.setToolTipText("Click to go shopping"); JPanel p = new JPanel(); p.add(b); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * a list of files with check boxes in the current folder -------------------------------------------------------- import java.io.File; import javax.swing.*; import java.awt.GridLayout; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JPanel p = new JPanel(new GridLayout(0,1)); File[] ff = (new File(".")).listFiles(); for (int ii = 0; ii < ff.length; ii++) \{ p.add(new JCheckBox(ff[ii].getName())); \} f.getContentPane().add(new JScrollPane(p)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * create a checkbox and do something when it is checked ------------------------------------------------------------- JCheckBox antialiasing = new JCheckBox("Anti-aliasing", false); ItemListener itemListener = new ItemListener()\{ public void itemStateChanged(ItemEvent e) \{ // do something \} \}; antialiasing.addItemListener(itemListener); ,,, JRADIOBUTTON Radio Buttons are similar to check boxes but may be configured to only allow one to be 'checked' at once. Only one button within a group may be selected. * a list of files with radio buttons ------------------------------------ import java.io.File; import javax.swing.*; import java.awt.GridLayout; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JPanel p = new JPanel(new GridLayout(0,1)); ButtonGroup group = new ButtonGroup(); JRadioButton r; File[] ff = (new File(".")).listFiles(); for (int ii = 0; ii < ff.length; ii++) \{ p.add(r = new JRadioButton(ff[ii].getName())); group.add(r); \} f.getContentPane().add(new JScrollPane(p)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, BUTTONS A button is a graphical component which can be 'clicked' with the users mouse device in order to carry out some action. In java buttons are implemented with the swing JButton class. * add an 'access key' to a button (pressing the key, 'clicks' the button) >> jbutton.setMnemonic(KeyEvent.VK\\_I); * create a button with 2 lines of text >> JButton b = new JButton("Two
lines"); * create a button with underlined 20 point text and a tool tip -------------------------------------------------------------- import javax.swing.*; import java.awt.Font; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JButton button = new JButton("Click"); button.setToolTipText("click to start the game"); button.setFont(new Font("Serif", Font.PLAIN, 20)); JPanel p = new JPanel(); p.add(button); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * put a button in a JFrame window ------------------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JButton button = new JButton("hello"); JPanel p = new JPanel(); p.add(button); f.add(p); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * set the font and colour for the button text --------------------------------------------- import javax.swing.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JButton button = new JButton("hello"); button.setFont(new Font("Serif", Font.ITALIC, 20)); button.setForeground(Color.green); f.getContentPane().add(button); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * extend the jframe class and place a button in it -------------------------------------------------- import javax.swing.*; public class Test extends JFrame \{ public Test () \{ JButton button = new JButton("hello"); JPanel p = new JPanel(); p.add(button); this.getContentPane().add(p); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.setLocationRelativeTo(null); this.pack(); this.setVisible(true); \} public static void main(String[] args) \{ Test t = new Test(); \} \} ,,, * a jframe class which contains a button and listens for clicks -------------------------------------------------------------- import javax.swing.*; import java.awt.event.*; public class Test extends JFrame implements ActionListener \{ public Test () \{ JButton button = new JButton("hello"); button.addActionListener(this); this.getContentPane().add(button); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.setLocationRelativeTo(null); this.pack(); this.setVisible(true); \} public void actionPerformed(ActionEvent e) \{ JOptionPane.showMessageDialog( this, "clicked " + e.getActionCommand()); \} public static void main(String[] args) \{ Test t = new Test(); \} \} ,,, * change a label when a button is clicked ----------------------------------------- import java.awt.event.*; import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("one button"); JButton button = new JButton("click"); final JLabel label = new JLabel("hello"); button.addActionListener(new ActionListener()\{ public void actionPerformed(ActionEvent e) \{ label.setText("bye"); \}\}); JPanel p = new JPanel(); p.add(button); p.add(label); f.add(p); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * make a click event handler for the button ------------------------------------------- final JButton b = new JButton("click"); b.addActionListener(new ActionListener()\{ public void actionPerformed(ActionEvent e) \{ b.setText("click"); \} \}); ,,, * make an action which is executed when a button is pushed ---------------------------------------------------------- Action showMessage = new AbstractAction() \{ \{ putValue(Action.NAME, "Message"); \} public void actionPerformed(ActionEvent e) \{ \} \}; JButton loadButton = new JButton(loadAction); panel.add(loadButton); ,,, * set the gap between the text and the icon in a button >> button.setIconTextGap(8); * the position of the icon and text in the button. -------------------------------------------------- button.setVerticalAlignment(SwingConstants.TOP); button.setHorizontalAlignment(SwingConstants.LEFT); ,,, * position the text relative to the icon in the button >> \url{http://www.exampledepot.com/egs/javax.swing/button\\_MoveIcon.html?l=rel} JLABELS Swing labels or JLabels are used to display a small amount of text and/or an ImageIcon. They are also used as the element in JLists and JComboBoxes * declare a new JLabel >> JLabel testLabel; * create a new JLabel with some initial text >> testLabel = new JLabel("A new label"); * change the text for the JLabel >> testLabel.setText("new file"); * create a label with an icon >> Icon icon = new Icon(...); JLabel l = new JLabel(icon); >> label.setIcon(...); * a label with text and an image >> l = new JLabel("Image and Text", icon, JLabel.CENTER); * add a label to a window ------------------------------------------ import javax.swing.*; public class LabelTest \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); JLabel label = new JLabel("Just A Label"); f.getContentPane().add(label); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * add a label with text and an image ------------------------------------------ import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); ImageIcon icon = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/chardevice.png"); JLabel label = new JLabel("Image and Text", icon, JLabel.CENTER); f.getContentPane().add(label); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * create a label with just an icon image and no text ---------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("a simple window"); ImageIcon icon = new ImageIcon( "/usr/share/icons/gnome/24x24/devices/chardevice.png"); JLabel label = new JLabel(icon); f.getContentPane().add(label); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * add a label and text field to a window frame ------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Labels"); JLabel label = new JLabel("Enter Name"); JTextField box = new JTextField(10); JPanel pl = new JPanel(); pl.add(label); pl.add(box); f.getContentPane().add(pl); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * display a 48pt centre aligned label in the default serifed font ------------------------------------------------------------------ import javax.swing.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Label Fonts"); JLabel title = new JLabel("A Big Label", JLabel.CENTER); title.setFont(new Font("Serif", Font.BOLD, 48)); f.getContentPane().add(title); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * display a label with a rounded corner border ---------------------------------------------- import javax.swing.*; import javax.swing.border.*; import java.awt.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame("Testing Label Fonts"); JLabel label = new JLabel("Rounded Corners"); label.setHorizontalAlignment(JLabel.CENTER); LineBorder line = new LineBorder(Color.blue, 2, true); label.setBorder(line); label.setFont(new Font("Serif", Font.BOLD, 48)); f.getContentPane().add(label); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * create a label with right aligned text >> JLabel label = new JLabel("label text", SwingConstants.RIGHT); * set the preferred size of a label >> jlabel.setPreferredSize(100, 100); * put an image in a label >> jlabel.setIcon(new ImageIcon("imagefilename"); * set the border for a label >> jlabel.setBorder(BorderFactory.createLineBorder(Color.black)); * set the background colour for a label >> jlabel.setBackground(color); setOpaque(true); * make text in a JLabel wrap to a particular pixel width ------------------------- import javax.swing.*; class FixedWidthLabel \{ public static void main(String[] srgs) \{ String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nulla urna. Donec sit amet risus nisl, a porta enim. Quisque luctus, ligula eu scelerisque gravida, tellus quam vestibulum urna, ut aliquet sapien purus sed erat. Pellentesque consequat vehicula magna, eu aliquam magna interdum porttitor..."; String html1 = ""; JOptionPane.showMessageDialog(null, new JLabel(html1+"200"+html2+s)); JOptionPane.showMessageDialog(null, new JLabel(html1+"300"+html2+s)); \} ,,, JTEXTFIELD TEXT FIELDS .... A JTextField is a one line text box * put a text field in a JFrame window containing text 'hello' ------------------------------------------------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame(); JTextField t = new JTextField("hello"); f.getContentPane().add(t); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * create a text field with 30 columns which does something * when [enter] is pressed. --------------------------- JTextField textfield = new JTextField ("Initial Text", 30); textfield.addActionListener (new MyActionListener ()); class MyActionListener implements ActionListener \{ public void actionPerformed (ActionEvent e) \{ JTextField textfield = (JTextField) e.getSource (); process (textfield.getText ()); \} \} ,,, * right justify the text in the JTextField >> textfield.setHorizontalAlignment(JTextField.RIGHT); PASSWORD BOXES .... A password box, or field is a field with one line of text which does not display the text which is typed. * a simple password box ----------------------- import javax.swing.*; public class Test \{ public static void main(String[] args) \{ JFrame f = new JFrame(); JPasswordField t = new JPasswordField("hello"); f.getContentPane().add(t); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, * make a password field which listens to the [enter] key -------------------------------------------------------- JPasswordField textfield = new JPasswordField("Initial Text"); textfield.setEchoChar('\\#'); textfield.addActionListener(actionListener); ,,, TEXT AREAS A text area is a box with several lines in which text can be entered. * create a text area with 20 rows and 30 columns ------------------------------------------------ JTextArea textarea = new JTextArea ("Initial Text"); textarea = new JTextArea ("Initial Text", 20, 30); ,,, * set the background colour of a JTextArea ------------------------------------------ JTextArea t = new JTextArea("hi"); t.setBackground (Color.green); ,,, * set the font, forground and background colours of a jtextarea --------------------------------------------------------------- final JTextArea ta = new JTextArea(); Font font = new Font("Courier", Font.PLAIN, 20); ta.setFont(font); ta.setForeground(Color.green); ta.setBackground(Color.black); ,,, JTEXTPANES A JTextPane is a devlishly complicated thing which can display all sorts of different types of text. But it seems quite difficult to use. * show an html page in a JTextPane ----- import javax.swing.*; import java.net.*; public class WebPane \{ public static void main(String args[]) throws Exception \{ JFrame f = new JFrame(); JScrollPane scroll = new JScrollPane(); JTextPane tp = new JTextPane(); tp.setText("loading..."); scroll.getViewport().add(tp); f.getContentPane().add(scroll); //jf.pack(); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); //jf.setSize(400,500); f.setVisible(true); URL url = new URL("http://bumble.sf.net"); tp.setPage(url); \} \} ,,, JEDITORPANE Complicated but useful * make hyperlinks work in a JEditorPane -------------------------------------- final JEditorPane editor = new JEditorPane(); editor.setEditorKit(JEditorPane.createEditorKitForContentType("text/html")); editor.setEditable(false); editor.setText("C, MSFT"); editor.addHyperlinkListener(new HyperlinkListener() \{ public void hyperlinkUpdate(HyperlinkEvent e) \{ if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) \{ // java 1.6+ if(Desktop.isDesktopSupported()) \{ Desktop.getDesktop().browse(e.getURL().toURI()); \} \} \} \}); ,,, MENUS * build menus with JMenuBar, JMenu, JMenuItem * add a JMenuBar to a Window (JFrame) >> JMenuBar menubar = new JMenuBar(); frame.setJMenuBar(menubar); * create a menu with control 0 shortcut key and an action listener ----------------------------------- JMenuItem screenshot = new JMenuItem("Screenshot"); screenshot.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK\\_0, InputEvent.CTRL\\_DOWN\\_MASK)); screenshot.addActionListener(new ActionListener()\{ public void actionPerformed(ActionEvent ae) \{ \}\}; JMenu menu = new JMenu("Other"); menu.add(screenshot); JMenuBar mb = new JMenuBar(); mb.add(menu); jframe.setJMenuBar(mb); ,,, MOUSE * mouse click listeners, and motion listeners. drawing in a panel ------------------------------------------------------------- import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class JavaPaintUI extends JFrame \{ private int tool = 1; int currentX, currentY, oldX, oldY; public JavaPaintUI() \{ initComponents(); \} private void initComponents() \{ // we want a custom Panel2, not a generic JPanel! jPanel2 = new Panel2(); jPanel2.setBackground(new java.awt.Color(255, 255, 255)); jPanel2.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); jPanel2.addMouseListener(new MouseAdapter() \{ public void mousePressed(MouseEvent evt) \{ jPanel2MousePressed(evt); \} public void mouseReleased(MouseEvent evt) \{ jPanel2MouseReleased(evt); \} \}); jPanel2.addMouseMotionListener(new MouseMotionAdapter() \{ public void mouseDragged(MouseEvent evt) \{ jPanel2MouseDragged(evt); \} \}); // add the component to the frame to see it! this.setContentPane(jPanel2); // be nice to testers.. this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); pack(); \}// private void jPanel2MouseDragged(MouseEvent evt) \{ if (tool == 1) \{ currentX = evt.getX(); currentY = evt.getY(); oldX = currentX; oldY = currentY; System.out.println(currentX + " " + currentY); System.out.println("PEN!!!!"); \} \} private void jPanel2MousePressed(MouseEvent evt) \{ oldX = evt.getX(); oldY = evt.getY(); System.out.println(oldX + " " + oldY); \} //mouse released// private void jPanel2MouseReleased(MouseEvent evt) \{ if (tool == 2) \{ currentX = evt.getX(); currentY = evt.getY(); System.out.println("line!!!! from" + oldX + "to" + currentX); \} \} public static void main(String args[]) \{ EventQueue.invokeLater(new Runnable() \{ public void run() \{ new JavaPaintUI().setVisible(true); \} \}); \} // Variables declaration - do not modify private JPanel jPanel2; // End of variables declaration // This class name is very confusing, since it is also used as the // name of an attribute! //class jPanel2 extends JPanel \{ class Panel2 extends JPanel \{ Panel2() \{ // set a preferred size for the custom panel. setPreferredSize(new Dimension(420,420)); \} @Override public void paintComponent(Graphics g) \{ super.paintComponent(g); g.drawString("BLAH", 20, 20); g.drawRect(200, 200, 200, 200); \} \} \} ,,, COMPONENTS All the swing components are subclasses of Component. We can therefore manipulate components in a gui in a generic way. * get a component from a built gui and cast it to its type. ------------------ Component c = tabPane.getComponentAt(tabPane.getSelectedIndex()); JScrollPane sp = (JScrollPane)c; ,,, CALENDERS java.util.Calender and java.util.Timezone are useful classes for getting information about times and dates. * use some methods of the Calender class ------------------------------------------------------------- Calender c = Calendar.getInstance(); miliSecond = c.get(Calendar.MILLISECOND); second = c.get(Calendar.SECOND); minute = c.get(Calendar.MINUTE); hour = c.get(Calendar.HOUR\\_OF\\_DAY); dayOfMonth = c.get(Calendar.DAY\\_OF\\_MONTH); dayOfYear = c.get(Calendar.DAY\\_OF\\_YEAR); dayOfWeek = c.get(Calendar.DAY\\_OF\\_WEEK); month = c.get(Calendar.MONTH); daysInMonth = c.getActualMaximum(Calendar.DAY\\_OF\\_MONTH); daysInYear = c.getActualMaximum(Calendar.DAY\\_OF\\_YEAR); ,,, TIME * get the current time in nanoseconds >> long lastTime = System.nanoTime(); * get the current time in milli seconds >> long startTime = System.currentTimeMillis(); TIMERS .... A javax.swing.Timer can be used to execute an action periodically. They are said to be superior to using a technique such as 'Thread.sleep()' * use a timer to update the text of a label each second ------------------------------------------------------- import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class TimerTest \{ public static void main(String[] args) \{ SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ final JLabel label = new JLabel("Timed Label"); ActionListener listener = new ActionListener() \{ @Override public void actionPerformed(ActionEvent ae) \{ label.setText(String.valueOf(System.nanoTime())); label.repaint(); \} \}; Timer timer = new Timer(1000, listener); timer.start(); JOptionPane.showMessageDialog(null, label); \} \}); \} \} ,,, * use a timer to change the color of textfield text every second ------------------------------------------------------------- import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class BlinkColorTextField \{ BlinkColorTextField() \{ final JTextField blinkingText = new JTextField("Red \\& Blue"); ActionListener blinker = new ActionListener() \{ boolean isRed = true; public void actionPerformed(ActionEvent ae) \{ if (isRed) \{ blinkingText.setForeground(Color.BLUE); \} else \{ blinkingText.setForeground(Color.RED); \} isRed = !isRed; \} \}; Timer timer = new Timer(1000, blinker); timer.start(); JOptionPane.showMessageDialog(null, blinkingText); \} public static void main(String[] args) \{ SwingUtilities.invokeLater(new Runnable()\{ public void run() \{ new BlinkColorTextField(); \} \}); \} \} ,,, EVENTS * A button which beeps when clicked --------------------------------------- import java.awt.*; import javax.swing.*; import java.awt.Toolkit; import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class Beeper extends JPanel implements ActionListener \{ JButton button; public Beeper() \{ super(new BorderLayout()); button = new JButton("Beep Button"); button.setPreferredSize(new Dimension(200, 80)); add(button, BorderLayout.CENTER); button.addActionListener(this); \} public void actionPerformed(ActionEvent e) \{ Toolkit.getDefaultToolkit().beep(); \} public static void main(String[] args) \{ javax.swing.SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ JFrame frame = new JFrame("Beeper"); frame.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); JComponent newContentPane = new Beeper(); newContentPane.setOpaque(true); frame.setContentPane(newContentPane); frame.pack(); frame.setVisible(true); \} \}); \} \} ,,, ACTIONS .... * a modern way to add an action to a button ------------------- JButton button = new JButton(new AbstractAction("Close") \{ @Override public void actionPerformed(ActionEvent e) \{ System.exit(0); \} \}); ,,, * create an action class with icon, text, tooltip text and alt/shortcut key. ------------------------ leftAction = new LeftAction( "Go left", anIcon, "This is the left button.", new Integer(KeyEvent.VK\\_L)); JButton test = new JButton(leftAction); class LeftAction extends AbstractAction \{ public LeftAction(String text, ImageIcon icon, String desc, Integer mnemonic) \{ super(text, icon); putValue(SHORT\\_DESCRIPTION, desc); putValue(MNEMONIC\\_KEY, mnemonic); \} public void actionPerformed(ActionEvent e) \{ displayResult("Action for first button/menu item", e); \} \} ,,, If this action is used on a button and menu item, both use the Alt-L key combination as a shortcut and the short description as a tool tip. The text and icon are used on both the menu item and the button. The advantage of creating Action classes is said to be that all gui components which use the Action are updated when a value of the Action is updated. * some notes for connecting through an http proxy System.setProperty("http.proxyHost", "proxy.utas.edu.au"); // System.setProperty("http.proxyPort", "8080"); ,,, * remove the icon from a menu item initialized with an Action -------------------------- menuItem = new JMenuItem(); menuItem.setAction(leftAction); menuItem.setIcon(null); ,,, * remove the text from a button itialized with an Action ---------------------------- button = new JButton(); button.setAction(leftAction); button.setText(""); ,,, * another way to create a new Action using an anonymous class ---------------------- Action colourAction = new AbstractAction() \{ // This defines the constructor within the anonymous class \{ putValue(Action.NAME, "Green On Black"); \} public void actionPerformed(ActionEvent e) \{ /* do something */ \} \}; ,,, The strange curly braces without any method signature are actually a way to define the constructor within an anonymous inner class. How odd. DRAG AND DROP Drag and Drop or DnD is the ability to click on a component and holding the mouse button down, move the mouse to another location on the screen and release the mouse button. The component should then be "imported" into the new part of the gui. A number of swing elements have a built in drag or drop functionality. For example you can drag a selected row from a JTable to a JTextArea and the row will be copied as text into the textarea. However if you wish to control how the information is dragged or dropped you need to implement a TransferHandler class. * enable drag and drop on various components ----------------------- textArea.setDragEnabled(toggle); textField.setDragEnabled(toggle); list.setDragEnabled(toggle); table.setDragEnabled(toggle); tree.setDragEnabled(toggle); colorChooser.setDragEnabled(toggle); ,,,, In the following example it is possible to drag a listbox item ontop of another (thereby replacing it) or drag it between two listbox items, inserting a new item (with the same text as the dragged item). It is also possible to drag a multiple selection. The several items get concatenated as a string and become the new element. This is not very useful but demonstrates what can be done within the createTransferable() method. * a drag and drop list box, -------------------------------------------------- import javax.swing.*; import java.awt.*; import java.awt.datatransfer.*; public class Box \{ public static void main(String[] args) \{ JFrame t = new JFrame(); DefaultListModel listModel = new DefaultListModel(); listModel.addElement("Cork Oak"); listModel.addElement("Elm"); listModel.addElement("Yew"); listModel.addElement("Siete Cueros"); listModel.addElement("Hevea Brasiliensis"); final JList list = new JList(listModel); list.setFont(new Font("Georgia", Font.PLAIN, 30)); list.setTransferHandler(new TransferHandler() \{ public boolean canImport(TransferHandler.TransferSupport info) \{ if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) \{ return false; \} JList.DropLocation dl = (JList.DropLocation)info.getDropLocation(); if (dl.getIndex() == -1) \{ return false; \} return true; \} public boolean importData(TransferHandler.TransferSupport info) \{ if (!info.isDrop()) \{ return false; \} if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) \{ JOptionPane.showMessageDialog(null, "List doesn't accept a drop of this type."); return false; \} JList.DropLocation dl = (JList.DropLocation)info.getDropLocation(); DefaultListModel listModel = (DefaultListModel)list.getModel(); // Get the string that is being dropped. Transferable t = info.getTransferable(); String data; try \{ data = (String)t.getTransferData(DataFlavor.stringFlavor); \} catch (Exception e) \{ return false; \} if (dl.isInsert()) \{ System.out.println("'" + data + "' inserted at index " + dl.getIndex()); \} else \{ System.out.println("'" + data + "' replacing index " + dl.getIndex()); \} if (dl.isInsert()) \{ listModel.add(dl.getIndex(), data); \} else \{ listModel.set(dl.getIndex(), data); \} return true; \} public int getSourceActions(JComponent c) \{ return COPY; \} protected Transferable createTransferable(JComponent c) \{ JList list = (JList)c; Object[] values = list.getSelectedValues(); StringBuffer buff = new StringBuffer(); for (int i = 0; i < values.length; i++) \{ Object val = values[i]; buff.append(val == null ? "" : val.toString()); if (i != values.length - 1) \{ buff.append("\\$\\backslash\\$n"); \} \} return new StringSelection(buff.toString()); \} \}); list.setDropMode(DropMode.ON\\_OR\\_INSERT); list.setDragEnabled(true); JPanel p = new JPanel(); p.add(list); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, DATAFLAVORS .... A dataflavor is the rather strange name that java gives to the mechanism by which it knows what type of data is being dragged, dropped cut or pasted. * create a new dataflavor for colour objects ------------------------------------------------------------- String colorType = DataFlavor.javaJVMLocalObjectMimeType + ";class=java.awt.Color"; DataFlavor colorFlavor = new DataFlavor(colorType); ,,, The dataflavor above will only funtion for drag and drop or cut and paste within the java application, not to other applications running on the system. LOOK AND FEEL OF THE WINDOWS The "look and feel" of a windowed application refers to the general style of the graphics used to display the application and the way that buttons change when they are clicked with the mouse Generally each look and feel may correspond to the visual style of an operating system. The default look and feel for java is not particularly attractive, which is why we want to change it. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents commonly installed look and feel classes .. Metal, javax.swing.plaf.metal.MetalLookAndFeel .. Nimbus, javax.swing.plaf.nimbus.NimbusLookAndFeel .. CDE/Motif, com.sun.java.swing.plaf.motif.MotifLookAndFeel .. Windows, com.sun.java.swing.plaf.windows.WindowsLookAndFeel .. Windows Classic, com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel .. The Windows classic is basically Windows 95 style components, Windows looks a lot better, Motif is an old X windows style, Metal is the default java style quite ugly, and Nimbus is the Apple osx style and therefor quite pretty. * The className is used with UIManager.setLookAndFeel() >> String className = info[i].getClassName(); * print out the names and classnames of available look and feels ------------------------------------------ import javax.swing.UIManager; public class LookAndFeel \{ public static void main(String[] args) throws Exception \{ UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels(); for (int i = 0; i < info.length; i++) \{ System.out.println("L \\& F name:" + info[i].getName()); System.out.println("L \\& F classname:" + info[i].getClassName()); \} \} \} ,,, * print the name of the native look and feel ------------------------------------------ import javax.swing.UIManager; public class LookAndFeel \{ public static void main(String[] args) throws Exception \{ System.out.println("Native look and feel: " + UIManager.getSystemLookAndFeelClassName()); \} \} ,,, * display a file chooser with the native operating system look and feel ------------------------------------------------ import javax.swing.*; public class NiceFileDialog \{ public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame f = new JFrame("Trying to make the FileChooser look nicer"); JFileChooser c = new JFileChooser(); if (c.showOpenDialog(f) == JFileChooser.CANCEL\\_OPTION) System.exit(-1); \} \} ,,, The result on a windows computer of using the system look and feel is much more aesthetically pleasing. Nimbus has a nice rounded corners but the colours are very cold and the fonts dont seem very good. * display a file chooser with the nimbus look and feel ------------------------------------------------ import javax.swing.*; import java.awt.Font; public class NiceFileDialog \{ public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); JFrame f = new JFrame("A Nimbus Style File Chooser"); JFileChooser c = new JFileChooser("C:\\$\\backslash\\$\\$\\backslash\\$"); c.setFont(new Font("Georgia", Font.PLAIN, 40)); if (c.showOpenDialog(f) == JFileChooser.CANCEL\\_OPTION) System.exit(-1); \} \} ,,, * a listbox with names of looks and feels ----------------------------------------- import javax.swing.*; import java.awt.*; public class LookAndFeelBox \{ public static void main(String[] args) \{ ListModel looks = new AbstractListModel() \{ UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels(); public int getSize() \{ return info.length; \} public Object getElementAt(int index) \{ return info[index].getClassName(); \} \}; Font font = new Font("Georgia", Font.PLAIN, 30); JList list = new JList(looks); list.setFont(font); list.setForeground(Color.gray); //JPanel p = new JPanel(); p.add(l); JFrame f = new JFrame(); f.getContentPane().add(list); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setLocationRelativeTo(null); f.pack(); f.setVisible(true); \} \} ,,, The Look and Feel does not effect the window decorations, which are controlled by the host operating system. The following fragment works but generates runtime exceptions, possible because I update the gui from within a function rather than from within the paint method. The nimbus look and feel seems to be the most pleasant at least on an ms windows computer. * show look and feels and change the look and feel when clicked -------------------------------------------------------------- import javax.swing.*; import javax.swing.event.*; import java.awt.*; public class LookAndFeel extends JFrame implements ListSelectionListener \{ JList list; ListModel looks = new AbstractListModel() \{ UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels(); public int getSize() \{ return info.length; \} public Object getElementAt(int index) \{ return info[index].getClassName(); \} \}; public LookAndFeel() \{ Font font = new Font("Georgia", Font.PLAIN, 20); list = new JList(looks); list.addListSelectionListener(this); list.setFont(font); list.setForeground(Color.gray); JButton button = new JButton("Does Nothing"); JPanel p = new JPanel(); p.add(list); p.add(button); JFrame f = new JFrame(); this.getContentPane().add(p); this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.pack(); this.setVisible(true); \} public void valueChanged(ListSelectionEvent e) \{ if (e.getValueIsAdjusting() == false) \{ if (list.getSelectedIndex() == -1) \{ /* No selection */ \} else \{ try \{ UIManager.setLookAndFeel(list.getSelectedValue().toString()); SwingUtilities.updateComponentTreeUI(this.getContentPane()); \} catch (Exception ex) \{\} \} \} \} public static void main(String[] args) \{ LookAndFeel t = new LookAndFeel(); \} \} ,,, * set the native system look and feel. ------------------------ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ try \{ UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); \} catch (Exception useDefault) \{\} initGui(); \} \}); \} ,,, * install a new look and feel. ------------------------------ try \{ UIManager. setLookAndFeel ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); \} catch (InstantiationException e) \{ \} catch (ClassNotFoundException e) \{ \} catch (UnsupportedLookAndFeelException e) \{ \} catch (IllegalAccessException e) \{ \} ,,, * change the look and feel >> UIManager.setLookAndFeel("..."); >> SwingUtilities.updateComponentTreeUI(getContentPane()); * set native look and feel >> UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); * set java look and feel >> Manager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); * set the window decorations to the host system look and feel >> JFrame.setDefaultLookAndFeelDecorated(true); >> JFrame frame = new JFrame("A window"); MODIFYING A LOOK AND FEEL .... We can modify any look and feel by changing its default attributes. For example we can change the default font or the default panel colours etc. * show the default font for a textfield in the current look and feel >> Font font = UIManager.getFont("TextField.font"); * change the default font for all textfield components >> UIManager.put("TextField.font", new FontUIResource()); * change the default font for a colorchooser >> UIManager.put("ColorChooser.font", new FontUIResource(new Font("Georgia", Font.PLAIN, 18))); * change the default font for all labels -------------------------------------------------- import javax.swing.*; import javax.swing.plaf.*; import java.awt.*; public class LabelFont \{ public static void main(String[] args) \{ Font font = new Font("Georgia", Font.PLAIN, 40); UIManager.put("Label.font", new FontUIResource(font)); JFrame f = new JFrame(); JPanel p = new JPanel(); for (int ii = 0; ii < 4; ii++) \{ JLabel l = new JLabel("This is the Georgia Font"); p.add(l); \} f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * a method to set the default font for all swing elements ------------------------------------------------------------- public static void setUIFont (javax.swing.plaf.FontUIResource f)\{ java.util.Enumeration keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) \{ Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof javax.swing.plaf.FontUIResource) UIManager.put(key, f); \} \} \} ,,, * List the UIManager keys in a listbox -------------------------------------------------- import java.util.Enumeration; import javax.swing.plaf.*; import javax.swing.*; import java.awt.Font; public class Box \{ public static void main(String[] args) \{ JFrame t = new JFrame(); DefaultListModel listModel = new DefaultListModel(); java.util.Enumeration keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) listModel.addElement(keys.nextElement().toString()); JList list = new JList(listModel); list.setFont(new Font("Georgia", Font.PLAIN, 30)); JPanel p = new JPanel(); p.add(new JScrollPane(list)); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * List the UIManager keys in a listbox -------------------------------------------------- import java.util.Enumeration; import javax.swing.plaf.*; import javax.swing.*; import java.awt.Font; public class KeysBox extends JList \{ public KeysBox() \{ super(); DefaultListModel model = new DefaultListModel(); Enumeration keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) model.addElement(keys.nextElement().toString()); this.setModel(model); this.setFont(new Font("Georgia", Font.PLAIN, 25)); \} public static void main(String[] args) \{ JFrame t = new JFrame(); JPanel p = new JPanel(); p.add(new JScrollPane(new KeysBox())); t.getContentPane().add(p); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.pack(); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * the above method can be executed with >> setUIFont(new javax.swing.plaf.FontUIResource("Serif",Font.ITALIC,12)); * set the default font for all swing components. -------------------------------------------------- import javax.swing.*; import javax.swing.plaf.*; import java.awt.*; public class LabelFont \{ public static void setUIFont (FontUIResource f)\{ java.util.Enumeration keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) \{ Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof javax.swing.plaf.FontUIResource) UIManager.put(key, f); \} \} public static void main(String[] args) \{ Font font = new Font("Georgia", Font.PLAIN, 40); LabelFont.setUIFont(new FontUIResource("Georgio",Font.ITALIC,25)); JFrame f = new JFrame(); JPanel p = new JPanel(); JLabel l = new JLabel("This is the Georgia Font"); p.add(l); JButton b = new JButton("Elm Trees"); p.add(b); f.getContentPane().add(p); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * show a file chooser dialog and determine the result ----------------------------------------------------- import javax.swing.*; import javax.swing.plaf.*; import java.awt.Font; public class ChooseFile \{ public static void main(String[] args) \{ Font font = new Font("Georgia", Font.PLAIN, 30); UIManager.put("FileChooser.font", new FontUIResource(font)); JFrame f = new JFrame("test file chooser"); JFileChooser chooser = new JFileChooser(); int result = chooser.showOpenDialog(f); java.io.File file = chooser.getSelectedFile(); \} \} ,,, JAVA DOCUMENTATION * includes a link to a method using suns online api documentation >> \url{http://java.sun.com/javase/6/docs/api/javax/sound/sampled/AudioSystem.html\\#getAudioInputStream(java.io.File)} * consult the java 1.5 documentation for the sound 'Clip' class >> \url{http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/sampled/Clip.html} * look up the online api documentation for the 'Class' class >> firefox java.sun.com/javase/6/docs/api/java/lang/Class.html This will open the javadoc documentation for the 'Class' class (used with the reflection classes) in a new firefox tab if firefox is already running * look up the java 6 documentation for the 'File' class >> firefox java.sun.com/javase/6/docs/api/java/io/File.html * a bash function to look up the documentation for a class >> jdoc()\{ firefox "java.sun.com/javase/6/docs/api/java/lang/\\$1.html"; \} This function can be used by typing 'jdoc String' to look up the Sun documentation for the 'String' class * a better java api documentation look-up bash function ------------------------------------------------- jdoc() \{ [ -z "\\$1" ] \\&\\& echo "usage: \\$FUNCNAME " \\&\\& return 1 c=\\$1; [[ \\$c != *.* ]] \\&\\& c=java/lang/\\$c || c=\\$\{c//./\\$\\backslash\\$/\} firefox "java.sun.com/javase/6/docs/api/\\$c.html"; \} jdoc java.io.File; jdoc String ,,, SOUND Java programs using sound can be written with javax.sound.sampled Since the early days, computers have been able to beep, and they still can. * play the classic beep >> java.awt.Toolkit.getDefaultToolkit().beep(); PLAYING SOUND .... @@ \url{http://forums.sun.com/thread.jspa?threadID=5401845} A Thread which talks about using Applet audioClip etc. @@ \url{http://forums.sun.com/thread.jspa?messageID=10780561\\#10780561} Simple code to play a sound file (as a 'clip') AndrewThompson65 (forums.sun.com) \url{http://forums.sun.com/profile.jspa?userID=590366} his posts on the sun forums, read and learn Richard G. Baldwin wrote some java audio tutorials @@ \url{http://forums.sun.com/thread.jspa?forumID=31\\&threadID=792949} Simple code for playing a sound using a SourceDataLine (not a Clip) PLAYING MP3 AND OGG VORBIS .... * example code for using mp3plugin.jar to play mp3s >> https://blogs.oracle.com/kashmir/entry/java\\_sound\\_api\\_2\\_mp3 * download mp3plugin.jar (from sun) and put in the current folder >> mp3plugin.jar * run your mp3 application with jar in current folder >> java -cp "mp3plugin.jar:." Mp3App \\#\\#(Linux) >> java -cp "mp3plugin.jar;." Mp3App \\#\\#(Windows) See below for code that actually plays mp3s. The mp3 format must be first converted to something that the java sound api can deal with. * copy the mp3plugin.jar to the extensions folder >> cp mp3plugin.jar \texttt{/usr/lib/jvm/jdk1.7.0/jre/lib/ext/} The above procedure avoids having to set the classpath on the command line, since the jre automatically loads classes from the \texttt{/lib/ext} folder. The jar file above does not need the JMF Java Media Framework in order to run. Strangely, even with the plugin you cant use the same code to play an mp3 as a wav. You need to convert the format first * play an mp3 with the mp3plugin.jar ------------------------------------------------------------- import javax.sound.sampled.*; import java.io.File; public class Player2 \{ // Buffer size = 44100 x 16 x 2 / 8 private static final int BUFFER\\_SIZE = 176400; public static void main(String[] args) throws Exception \{ byte[] buffer = new byte[BUFFER\\_SIZE]; AudioInputStream in = AudioSystem.getAudioInputStream( AudioFormat.Encoding.PCM\\_SIGNED, //AudioSystem.getAudioInputStream(new File(args[0]))); AudioSystem.getAudioInputStream(new File("abuztuan.mp3"))); AudioFormat audioFormat = in.getFormat(); SourceDataLine line = (SourceDataLine) AudioSystem.getLine( new DataLine.Info(SourceDataLine.class, audioFormat)); line.open(audioFormat); line.start(); while (true) \{ int n = in.read(buffer, 0, buffer.length); if (n < 0) \{ break; \} line.write(buffer, 0, n); \} line.drain(); line.close(); \} \} ,,, Success! The above code works. After many tries * the only difference in the code above is ------------------------------------------ AudioInputStream in = AudioSystem.getAudioInputStream( AudioFormat.Encoding.PCM\\_SIGNED, AudioSystem.getAudioInputStream(new File("abuztuan.mp3"))); ,,, USING TRITONIUS .... This procedure is untested. * play an mp3 file \begin{enumerate} \item get \url{http://www.javazoom.net/javalayer/sources.html} \item put the jar in the class path or current directory \item see \url{http://www.cs.princeton.edu/introcs/faq/mp3/MP3.java.html} \end{enumerate} put these in your classpath tritonus\\_share.jar, .... * put the tritonus class on the class path and run 'Test' >> java -cp ".:tritonus\\_share.jar:..." Test @@ \url{http://www.javazoom.net/mp3spi/documents.html} example code for playing mp3s @@ \url{http://www.jsresources.org} More examples of how to play mp3 sound files using the tritonius decoder classes. These examples tend to be difficult to understand because they include so much unnecessary code FORMATS AND ENCODERS .... Service Provider Interface The Java Sound API uses a Service Provider Interface to identify encoders \\& decoders for sound formats and sequence types. This way, adding support for a new format or type is as simple as providing a decoder and/or encoder for it, adding an SPI file to the manifest of the Jar it is in, then adding the Jar to the run-time class-path of the application. The mp3plugin.jar of the Java Media Framework supports decoding MP3s. AUDIO INFORMATION .... \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents sound glossary .. PCM - pulse-code modulation, a simple encoding technique .. encoding - eg PCM, mu-law, a-law. Turns wave pressure into numbers .. herz - the a frequency (eg samples/frames) per second .. sample - a digital approximation of a sound wave at a point in time .. frame - contains stereo samples and possibly other information .. frame rate - the number of frames per second (herz) .. sample rate - the number of samples per second (herz) .. Sound files consist of a file format (which in java is represented by the AudioFileFormat class). This file format contains header information and other metadata such as frame length. The sound file also has an audio format (represented by the class AudioFormat) which consists of the sampling rate, the sample bit size, mono or stereo etc. An audio format consists of the number of samples per second (hz), number of channels (stereo=2), bits per sample, and sample encoding * show the audio format for the file 'test.wav' -------------------------------------------- import javax.sound.sampled.*; import java.io.File; public class Test \{ public static void main(String[] args) throws Exception \{ File file = new File("test.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(file); AudioFormat format = ais.getFormat(); System.out.println(format); \} \} ,,, This produces output such as >> PCM\\_SIGNED 22050.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian * show more detailed audio format information -------------------------------------------- import javax.sound.sampled.*; import java.io.File; public class Test \{ public static void main(String[] args) throws Exception \{ File file = new File("test.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(file); AudioFormat format = ais.getFormat(); System.out.println( "encoding: " + format.getEncoding()); System.out.println( "frame rate: " + format.getFrameRate()); System.out.println( "frame size: " + format.getFrameSize() + "(bytes)"); System.out.println( "sample rate: " + format.getSampleRate()); System.out.println( "sample size: " + format.getSampleSizeInBits() + "(bits)"); System.out.println( "channels: " + format.getChannels()); System.out.println( "big endian: " + format.isBigEndian()); \} \} ,,, * show the audio file format for an audio file -------------------------------------------- import javax.sound.sampled.*; import java.io.File; public class Test \{ public static void main(String[] args) throws Exception \{ File file = new File("abuztuan.mp3"); AudioFileFormat af = AudioSystem.getAudioFileFormat(file); System.out.println("Audio Type: " + af.getType()); System.out.println("Audio File Format: " + af); \} \} ,,, * show what audio file formats can be written by the java sound system -------------------------------------------- import javax.sound.sampled.*; public class FileFormatList \{ public static void main(String[] args) throws Exception \{ AudioFileFormat.Type[] aa = AudioSystem.getAudioFileTypes(); for (int i = 0; i < aa.length; i++) System.out.println(aa[i].toString()); \} \} ,,, * check for a particular type of audio format ------------------------------------------------------------- af = AudioSystem.getAudioFileFormat(new File("Test.wav"); if (af.getType() != AudioFileFormat.Type.AIFF) ,,, * open a local file or within a jar file >> URL url = this.getClass().getClassLoader().getResource("test.wav"); * new audioformat in PCM encoding >> new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); * create an 8khz 8bit sample mono signed bigendian PCM format >> AudioFormat format = new AudioFormat(8000, 8, 1, true, true); This is a very low quality audioformat, but also of a small file size. * audio format constructor >> AudioFormat(AudioFormat.Encoding encoding, float sampleRate, int sampleSizeInBits, int channels, int frameSize, float frameRate, boolean bigEndian) * a PCM format at 44100 hz stereo, 16 bit sample, 4 byte frame >> AudioFormat(AudioFormat.Encoding.PCM\\_SIGNED, 44100.0, 16, 2, 4, 44100.0, false) * calculate bytes per second >> format.getFrameRate() * format.getFrameSize(); The above calculation is important if you wish to read, play or record a certain number of seconds of audio, which is a reasonably common request. SOURCE DATA LINES .... @@ \url{http://forums.sun.com/thread.jspa?forumID=31\\&threadID=5310813} very clear code for using source data lines in a class * a simple example of playing a sound found with a SourceDataLine ------------------------------------------------------------- import java.io.*; import javax.sound.sampled.*; public class SoundLineTest \{ public static void main(String[] args) throws Exception \{ SourceDataLine line = null; int BUFFERSIZE = 64*1024; // 64 KB File f = new File("rec.wav"); AudioInputStream stream = AudioSystem.getAudioInputStream(f); AudioFormat format = stream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); line = (SourceDataLine) AudioSystem.getLine(info); line.open(format); line.start(); int nBytesRead = 0; byte[] sampledData = new byte[BUFFERSIZE]; boolean stopped = false; while (!stopped) \{ nBytesRead = stream.read(sampledData, 0, sampledData.length); if (nBytesRead == -1) break; line.write(sampledData, 0, nBytesRead); \} line.drain(); line.close(); \} \} ,,, The boolean 'stopped' variable in the code above can be used to stop the play back if the user presses a button (which will set the stopped variable to true) * play a sound using a SourceDataLine catching Exceptions ------------------------------------------------------------- import java.io.*; import javax.sound.sampled.*; public class SoundLineTest \{ public static void main(String[] args) \{ SourceDataLine soundLine = null; int BUFFER\\_SIZE = 64*1024; // 64 KB try \{ File soundFile = new File("test.wav"); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile); AudioFormat audioFormat = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); soundLine = (SourceDataLine) AudioSystem.getLine(info); soundLine.open(audioFormat); soundLine.start(); int nBytesRead = 0; byte[] sampledData = new byte[BUFFER\\_SIZE]; while (nBytesRead != -1) \{ nBytesRead = audioInputStream.read(sampledData, 0, sampledData.length); if (nBytesRead >= 0) \{ soundLine.write(sampledData, 0, nBytesRead); \} \} \} catch (UnsupportedAudioFileException ex) \{ ex.printStackTrace(); \} catch (IOException ex) \{ ex.printStackTrace(); \} catch (LineUnavailableException ex) \{ ex.printStackTrace(); \} finally \{ soundLine.drain(); soundLine.close(); \} \} \} ,,, In the code above if the nBytesRead > 0 test is removed then an IllegalArgumentException is thrown at the end of the sound file CUTTING SOUND FILES .... One strategy for cutting an audio file is to construct a new AudioInputStream from another but limit the number of frames * create a new shorter stream ------------------------------------------------------------- AudioInputStream newStream = new AudioInputStream( oldStream, format, seconds * (int)format.getFrameRate()); AudioSystem.write(shortenedStream, fileFormat.getType(), destinationFile); ,,, Another strategy is to write bytes to an output stream. Then create an audio input stream from those bytes. * cut a section of a wav file and save to a new file ------------------------------------------------------------- import java.io.*; import javax.sound.sampled.*; class AudioFileProcessor \{ public static void copyAudio( String sourceFileName, String destinationFileName, int startSecond, int secondsToCopy) \{ AudioInputStream inputStream = null; AudioInputStream shortenedStream = null; try \{ File file = new File(sourceFileName); AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file); AudioFormat format = fileFormat.getFormat(); inputStream = AudioSystem.getAudioInputStream(file); int bytesPerSecond = format.getFrameSize() * (int)format.getFrameRate(); inputStream.skip(startSecond * bytesPerSecond); long framesOfAudioToCopy = secondsToCopy * (int)format.getFrameRate(); shortenedStream = new AudioInputStream(inputStream, format, framesOfAudioToCopy); File destinationFile = new File(destinationFileName); AudioSystem.write(shortenedStream, fileFormat.getType(), destinationFile); \} catch (Exception e) \{ println(e); \} finally \{ if (inputStream != null) try \{ inputStream.close(); \} catch (Exception e) \{ println(e); \} if (shortenedStream != null) try \{ shortenedStream.close(); \} catch (Exception e) \{ println(e); \} \} \} public static void main(String[] args) \{ copyAudio("/tmp/uke.wav", "/tmp/uke-shortened.wav", 2, 1); \} \} ,,, * A technique to write a byte array to a wav file, incomplete example ------------------------------------ File f = new File(exportFileName + ".tmp"); File f2 = new File(exportFileName); long l = f.length(); //byte[] buffer; // read into byte array using AudioInputStream ByteArrayInputStream bs = new ByteArrayInputStream(buffer); AudioInputStream ai = new AudioInputStream(bs,mainFormat,l/4); AudioSystem.write(ai, Type.WAVE, f2); fi.close(); f.delete(); ,,, * another technique for writing bytes to an audio file, incomplete example -------------------- ByteArrayOutputStream b\\_out = new ByteArrayOutputStream(); // Read a frame from the file. while (audioInputStream.read(audioBytes) != -1) \{ //Do stuff here.... b\\_out.write(outputvalue); \} // Hook output stream to output file ByteArrayInputStream b\\_in = new ByteArrayInputStream(b\\_out.toByteArray()); AudioInputStream ais = new AudioInputStream(b\\_in, format, length); AudioSystem.write(ais, inFileFormat.getType(), outputFile); ,,, CONVERT RAW AUDIO DATA TO WAV .... File f = new File(exportFileName+".tmp"); File f2 = new File(exportFileName); long l = f.length(); FileInputStream fi = new FileInputStream(f); AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4); AudioSystem.write(ai, Type.WAVE, f2); fi.close(); f.delete(); JOINING SOUND FILES .... * join 2 wav files -------------------------- import java.io.File; import java.io.IOException; import java.io.SequenceInputStream; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; public class WavAppender \{ public static void main(String[] args) \{ String wavFile1 = "wav1.wav"; String wavFile2 = "wav2.wav"; try \{ AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(wavFile1)); AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(wavFile2)); AudioInputStream appendedFiles = new AudioInputStream( new SequenceInputStream(clip1, clip2), clip1.getFormat(), clip1.getFrameLength() + clip2.getFrameLength()); AudioSystem.write(appendedFiles, AudioFileFormat.Type.WAVE, new File("joinwav.wav")); \} catch (Exception e) \{ e.printStackTrace(); \} \} \} ,,, PLAYING AUDIO .... * use a JToggleButton to stop and start a sound clip ------------------------------------------------------------- import java.net.URL; import java.awt.event.*; import javax.swing.*; import javax.sound.sampled.*; public class RestartableLoopSound \{ public static void main(String[] args) throws Exception \{ URL url = new URL("http://pscode.org/media/leftright.wav"); final Clip clip = AudioSystem.getClip(); AudioInputStream ais = AudioSystem.getAudioInputStream(url); clip.open(ais); SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ final JToggleButton b = new JToggleButton("Loop"); ActionListener listener = new ActionListener() \{ public void actionPerformed(ActionEvent ae) \{ if (b.isSelected()) \{ clip.loop(Clip.LOOP\\_CONTINUOUSLY); \} else \{ clip.stop(); \} \} \}; b.addActionListener(listener); JOptionPane.showMessageDialog(null, b); \} \}); \} \} ,,, CLIPS .... Clips are used for non streamed audio data. That is, all audio data is loaded into memory before playback \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents Things doable with a javax.sound.sampled.Clip .. getMicrosecondLength() - how many microseconds long is the audio .. getFrameLength() - how many sound frames the audio has .. setMicrosecondPosition(long) - set the current play position .. setLoopPoints(int, int) - loop between 2 particular frames in the audio .. long getMicrosecondPosition() - how long the audio has been playing for .. long getLongFramePosition() - the current frame position of the audio .. AudioFormat getFormat() - the format of the playing audio If a sound file/url is too large then the Clip will throw a javax.sound.sampled.LineUnavailableException with the message "Failed to allocate clip data: Requested buffer too large." * play a clip catching exceptions ------------------------------------------------------------- import java.io.*; import java.net.URL; import javax.sound.sampled.*; import javax.swing.*; public class SoundClipTest extends JFrame \{ public SoundClipTest() \{ this.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); this.setTitle("Test Sound Clip"); this.setSize(300, 200); this.setVisible(true); try \{ File f = new File("test.wav"); AudioInputStream audioIn = AudioSystem.getAudioInputStream(f); Clip clip = AudioSystem.getClip(); clip.open(audioIn); clip.start(); \} catch (UnsupportedAudioFileException e) \{ e.printStackTrace(); \} catch (IOException e) \{ e.printStackTrace(); \} catch (LineUnavailableException e) \{ e.printStackTrace(); \} \} public static void main(String[] args) \{ new SoundClipTest(); \} \} ,,, * play an audio file (obtained from the web) continuously --------------------------------------------------------- import javax.sound.sampled.*; import java.net.URL; import javax.swing.JOptionPane; public class AudioClipTest \{ public static void main(String[] args) throws Exception \{ URL url = new URL("http://pscode.org/media/100\\_2817.au"); AudioInputStream ais = AudioSystem.getAudioInputStream(url); Clip clip = AudioSystem.getClip(); clip.open(ais); clip.loop(Clip.LOOP\\_CONTINUOUSLY); JOptionPane.showMessageDialog(null, "Close to end.."); \} \} ,,,,, ,,, * play an audio clip beginning 1/2 a second after the beginning (using code above) >> clip.open(); clip.setMicrosecondPosition(); clip.start(); * play a sound file starting just after the beginning ------------------------------------------------------------- import javax.sound.sampled.*; import java.io.File; import javax.swing.JOptionPane; public class ClipTest \{ public static void main(String[] args) throws Exception \{ File f = new File("asagohan.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(f); Clip clip = AudioSystem.getClip(); clip.open(ais); clip.setMicrosecondPosition(500000); clip.start(); JOptionPane.showMessageDialog(null, "Close to end.."); \} \} ,,, * play the local file 'sound.wav' (in the current folder) 6 times ------------------------------------------------------------- import javax.sound.sampled.*; import java.io.File; import javax.swing.JOptionPane; public class MpgPlay \{ public static void main(String[] args) throws Exception \{ File f = new File("abuztuan.mp3"); AudioInputStream ais = AudioSystem.getAudioInputStream(f); Clip clip = AudioSystem.getClip(); clip.open(ais); clip.loop(6); clip.start(); JOptionPane.showMessageDialog(null, "Close to end.."); \} \} ,,, * check if the system supports playing mp3 sound files ------------------------------------------------------ import javax.sound.sampled.*; import java.io.File; public class MpgSupport \{ public static void main(String[] args) throws Exception \{ File f = new File("abuztuan.mp3"); try \{ AudioInputStream ais = AudioSystem.getAudioInputStream(f); System.out.println("Mp3 is Ok to play"); \} catch (UnsupportedAudioFileException e) \{ System.out.println("Mp3 is NOT supported"); \} \} \} ,,, The following may fail if the sound file is too big * create a simple loop to pause and restart a sound clip -------------- import javax.sound.sampled.*; import java.util.*; import java.io.File; public class PauseClip \{ public static void main(String[] args) throws Exception \{ File file = new File("test.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(file); Clip clip = AudioSystem.getClip(); clip.open(ais); clip.loop(1); clip.start(); Scanner scan = new Scanner(System.in); String s = ""; while (!s.equals("q")) \{ System.out.print("what? (p/s/q)>"); s = scan.nextLine(); if (s.equals("p")) \{ clip.stop(); \} if (s.equals("s")) \{ //clip.flush(); clip.start(); \} \} \} \} ,,, RECORDING SOUND .... @@ \url{http://www.jsresources.org} terribly complicated examples of using the javax.sound.sampled api. This will put you right off ever trying to use it. @@ \url{http://www.developer.com/java/other/article.php/2105421/Java-Sound-Capturing-Microphone-Data-into-an-Audio-File.htm} A tutorial on recording sound by Baldwin. * record cd quality stereo audio >> AudioFormat format = new AudioFormat( >> AudioFormat.Encoding.PCM\\_SIGNED, >> 44100.0F, 16, 2, 4, 44100.0F, false); * record a sound file from the computer microphone ------------------------ import java.io.*; import javax.sound.sampled.*; public class RecordAudio \{ public static void main(String[] args) throws Exception \{ /* Cd quality PCM 44.1 kHz, 16 bit signed, stereo. */ AudioFormat format = new AudioFormat( AudioFormat.Encoding.PCM\\_SIGNED, 44100.0F, 16, 2, 4, 44100.0F, false); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); line.start(); AudioInputStream ais = new AudioInputStream(line); System.out.println("Recording into 't.wav', [Cntrl] c to stop"); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("rec.wav")); line.stop(); line.close(); \} \} ,,, * record audio in a thread, this code is very messy and redundant ------------------------------------------------------------- import javax.sound.sampled.*; import javax.swing.*; import java.awt.event.*; import java.io.*; public class RecordAudio \{ private File audioFile; protected boolean running; private ByteArrayOutputStream out; private AudioInputStream inputStream; private AudioFormat format; private float level; private int frameSize; public RecordAudio()\{ getFormat(); \} private AudioFormat getFormat() \{ File file = new File("test.wav"); AudioInputStream stream; try \{ stream = AudioSystem.getAudioInputStream(file); format=stream.getFormat(); frameSize=stream.getFormat().getFrameSize(); return stream.getFormat(); \} catch (UnsupportedAudioFileException e) \{\} catch (IOException e) \{ \} return null; \} public void stopRecording() \{ running = false; \} public void recordAudio() \{ try \{ final AudioFormat format = getFormat(); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); line.start(); Runnable runner = new Runnable() \{ int bufferSize = (int) format.getSampleRate() * format.getFrameSize(); byte buffer[] = new byte[bufferSize]; public void run() \{ int readPoint = 0; out = new ByteArrayOutputStream(); running = true; int sum=0; while (running) \{ int count = line.read(buffer, 0, buffer.length); System.out.println(level); if (count > 0) \{ out.write(buffer, 0, count); \} \} line.stop(); \} \}; Thread captureThread = new Thread(runner); captureThread.start(); \} catch (LineUnavailableException e) \{ System.err.println("Line unavailable: " + e); System.exit(-2); \} \} public File getAudioFile() \{ byte[] audio = out.toByteArray(); InputStream input = new ByteArrayInputStream(audio); try \{ final AudioFormat format = getFormat(); final AudioInputStream ais = new AudioInputStream(input, format, audio.length / format.getFrameSize()); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("rec.wav")); input.close(); System.out.println("New file created!"); \} catch (IOException e) \{ System.out.println(e.getMessage()); \} return new File("rec.wav"); \} public static void main(String[] args) throws Exception \{ SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ final RecordAudio a = new RecordAudio(); final JToggleButton b = new JToggleButton("start recording"); ActionListener listener = new ActionListener() \{ public void actionPerformed(ActionEvent ae) \{ if (b.isSelected()) \{ a.recordAudio(); b.setText("stop recording"); \} else \{ b.setText("start recording"); a.stopRecording(); File f = a.getAudioFile(); \} \} \}; b.addActionListener(listener); JOptionPane.showMessageDialog(null, b); \} \}); \} \} ,,, SILENCE .... Silence can be calculated either by decibel dB levels or else by the RMS, or Root Mean Square. * Computes the Root Mean Square volume of signal sizes ranging from -1 to 1. */ ------------------------------------------------------------- public double volumeRMS(double[] raw) \{ double sum = 0d; if (raw.length==0) \{ return sum; \} else \{ for (int ii=0; ii> \url{http://stackoverflow.com/questions/7782721/java-raw-audio-output/7782749\\#7782749} MIDI .... Midi is a way of representing electronic music, symbolically rather than as a series of samples. * Playing a MIDI Sequence (a song) ------------------------ import javax.sound.midi.*; import javax.swing.JOptionPane; import java.net.URL; public class PlayMidi \{ public static void main(String[] args) throws Exception \{ URL url = new URL("http://pscode.org/media/EverLove.mid"); Sequence sequence = MidiSystem.getSequence(url); Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.setSequence(sequence); sequencer.start(); JOptionPane.showMessageDialog(null, "Everlasting Love"); \} \} ,,, RUNNING JAVA APPLICATIONS DEPLOYING JAVA APPLICATIONS Maven may be a valuable tool for deploying apps. It allows dependencies to be automatically downloaded from the internet. JAR ARCHIVES \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents tools .. fastjar - creates jar files .. AN EXAMPLE JAR MANIFEST .... * an example manifest file with the class path set ---- Main-Class: org.mypackage.HelloWorld Class-Path: lib/supportLib.jar ,,, CLASSPATH The classpath is the mechanism which the jre using to locate classes which are used in an application. The current directory is always included in the classpath. The classpath has a reputation for giving rise to tricky configuration problems. * place multiple jar files on the classpath (windows) >> java -cp "Test.jar;lib/*" my.package.MainClass * the same on Linux (colons and not semicolons!) >> java -cp "Test.jar:lib/*" my.package.MainClass * jar files can also be placed in the extension directory >> C:\\$\\backslash\\$JDK1.2.2\\$\\backslash\\$JRE\\$\\backslash\\$LIB\\$\\backslash\\$EXT \\#\\#(windows, very old java runtime) * a typical extension folder list for java 1.7 on Linux >> \texttt{/usr/lib/jvm/jdk1.7.0/jre/lib/ext:/usr/java/packages/lib/ext} * another way of copying a jar file to the extensions folder >> cp mp3plugin.jar \\$\{JAVA\\_HOME\}/jre/lib/ext * display the java classpath and the extensions folder ---- import java.util.Properties; public class GetClassPath \{ static Properties p = System.getProperties(); public static void main(String[] args) \{ System.out.println(p.getProperty("java.class.path", null)); System.out.println(p.getProperty("java.ext.dirs", null)); \} \} ,,, MODERN LOOPS More recent versions of Java have introduced new ways of looping through arrays and collections * loop through a the words of a string --------------------------------------------------- public class Test \{ public static void main(String[] args) \{ String s = "red yellow blue"; String[] splitString = (s.split("\\$\\backslash\\$\\$\\backslash\\$s+")); for (String ss: splitString) \{ System.out.println(ss); \} \} \} ,,, THREADS * create an anonymous thread ---------------------------- new Thread() \{ public void run() \{ // do something \} \}.start(); ,,, USING THE OPERATING SYSTEM * on windows execute the 'notepad' text editor in a new thread >> proc = Runtime.getRuntime().exec("notepad"); * get the operating system name and version ------------------ String s = "os.name: " + System.getProperty("os.name") + "\\$\\backslash\\$nos.version: " + System.getProperty("os.version"); ,,, REGULAR EXPRESSIONS * see if a string starts with a space (this prints 'false') >> System.out.println("A big tree".matches("\\^ .*")); * test if a string starts with a 'word' character (letter) >> System.out.println("A big tree".matches("\\^\\$\\backslash\\$\\$\\backslash\\$w.*")); This prints 'true' * Replace all whitespace with tab characters >> System.out.println("the green grass".replaceAll("\\$\\backslash\\$\\$\\backslash\\$s+", "\\$\\backslash\\$t")); * Replace all whitespace with a dot '.' >> System.out.println("the green grass".replaceAll("\\$\\backslash\\$\\$\\backslash\\$s+", ".")); * split a string into words using the 'split' method ---------------------------------------------------- public class Test \{ public static void main(String[] args) \{ String[] splitString = ("Some new words".split("\\$\\backslash\\$\\$\\backslash\\$s+")); for (String word : splitString) \{ System.out.println(word); \} \} \} ,,, * use compiled patterns and matching loops ------------------------------------------ Pattern pattern = Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$w+"); // Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$s+", Pattern.CASE\\_INSENSITIVE); Matcher matcher = pattern.matcher("some test string"); // Check all occurance while (matcher.find()) \{ System.out.print("Start index: " + matcher.start()); System.out.print(" End index: " + matcher.end() + " "); System.out.println(matcher.group()); \} ,,, * replace all occurances of whitespace with tabs ----------------------------------------------- Pattern pat = Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$s+"); Matcher m = pat.matcher("The green grass"); System.out.println(m.replaceAll("\\$\\backslash\\$t")); ,,, CONSTRUCTORS * make 2 object contructors, of which one uses a default value ---- public FileSystemModel() \{ this( System.getProperty("user.home")); \} public FileSystemModel( String startPath ) \{ root = startPath; \} ,,, JTREE TREE COMPONENT Like many of the other swing components which display a significant amount of information, the swing tree component uses a "model" interface to supply data to the tree component. To the new-comer to interface or object oriented programming this may seem daunting, but its not. There arrangement is simple: The model has a series of methods which allow the tree component to display each node or leaf on the tree. But the tree doesnt mind where that data comes from. This gives a great deal of flexibility to the programmer, who can use any kind of data to create a tree. * put a default jtree in a JFrame window ------------------------------------- import javax.swing.*; public class DefaultTree \{ public static void main(String[] args) \{ JFrame f = new JFrame(); JTree t = new JTree(); f.getContentPane().add(t); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * a file and directory TreeModel for use with a JTree element --------- import javax.swing.*; import java.awt.Font; import javax.swing.plaf.FontUIResource; import javax.swing.tree.*; import javax.swing.event.*; import java.io.*; public class FileSystemModel implements TreeModel \{ String root; public FileSystemModel() \{ this( System.getProperty( "user.home" ) ); \} public FileSystemModel( String startPath ) \{ root = startPath; \} public Object getRoot() \{ return new File( root ); \} public Object getChild( Object parent, int index ) \{ File directory = (File)parent; String[] children = directory.list(); return new File( directory, children[index] ); \} public int getChildCount( Object parent ) \{ File fileSysEntity = (File)parent; if ( fileSysEntity.isDirectory() ) \{ String[] children = fileSysEntity.list(); if (children == null) return 0; return children.length; \} return 0; \} public boolean isLeaf( Object node ) \{ return ((File)node).isFile(); \} public void valueForPathChanged( TreePath path, Object newValue ) \{\} public void removeTreeModelListener(TreeModelListener l) \{\} public void addTreeModelListener(TreeModelListener l) \{\} public int getIndexOfChild( Object parent, Object child ) \{ File directory = (File)parent; File fileSysEntity = (File)child; String[] children = directory.list(); int result = -1; for ( int i = 0; i < children.length; ++i ) \{ if ( fileSysEntity.getName().equals( children[i] )) result = i; break; \} return result; \} public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); UIManager.put("Tree.font", new FontUIResource("Georgia", Font.PLAIN, 18)); JFrame f = new JFrame("A File System Tree"); JTree t = new JTree(new FileSystemModel("..")); f.getContentPane().add(new JScrollPane(t)); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, JTABLE SWING TABLE COMPONENT .... If you do not add a swing table to a scrollpane, then it is necessary to add the table header seperately to the container component. * using tables and cell renderers >> \url{http://docs.oracle.com/javase/tutorial/uiswing/components/table.html\\#editrender} * create a swing table using a default table model ------------------------------------------------------------- DefaultTableModel tm = new DefaultTableModel(); tm.addColumn("Column 0"); tm.addColumn("Column 1"); tm.addColumn("Column 2"); tm.addRow(new String[]\{"Table 00", "Table 01", "Table 02"\}); tm.addRow(new String[]\{"Table 10", "Table 11", "Table 12"\}); tm.addRow(new String[]\{"Table 20", "Table 21", "Table 22"\}); tm.addRow(new String[]\{"Table 30", "Table 31", "Table 32"\}); table = new JTable(tm); ,,, * create a table using the DefaultTableModel ------------------------------------------------------------- import javax.swing.*; import javax.swing.table.*; import javax.swing.plaf.FontUIResource; import java.awt.Font; public class TableTest extends JPanel \{ JTable table; public TableTest() \{ super(); DefaultTableModel m = new DefaultTableModel(); m.addColumn("Tree"); m.addColumn("Origin"); m.addRow(new String[]\{"Eucalypt", "Australia"\}); m.addRow(new String[]\{"Cork Oak", "Europe"\}); m.addRow(new String[]\{"Siete Cueros", "Colombia"\}); m.addRow(new String[]\{"Walnut", "Europe"\}); table = new JTable(m); this.table = new JTable(m); this.add(new JScrollPane(this.table)); \} public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); UIManager.put("Table.font", new FontUIResource("Georgia", Font.PLAIN, 18)); JFrame f = new JFrame("A Table with the default table model"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new TableTest()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * create a table using the AbstractTableModel ------------------------------------------------------------- import javax.swing.*; import javax.swing.table.*; import javax.swing.plaf.FontUIResource; import java.awt.Font; public class TableTest extends JPanel \{ JTable table; TableModel model = new AbstractTableModel() \{ public int getColumnCount() \{ return 10; \} public int getRowCount() \{ return 10;\} public Object getValueAt(int row, int col) \{ return new Integer(row*col); //return "row \} \}; public TableTest() \{ super(); this.table = new JTable(this.model); this.add(new JScrollPane(this.table)); \} public static void main(String[] args) throws Exception \{ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); UIManager.put("Table.font", new FontUIResource("Georgia", Font.PLAIN, 18)); JFrame f = new JFrame("A Table with an AbstractTableModel"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new TableTest()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * a swing table with java properties values in it, sortable -------------------------------- import javax.swing.*; import javax.swing.border.*; import javax.swing.table.*; import javax.swing.plaf.FontUIResource; import java.awt.*; public class PropertiesTable extends JPanel \{ public PropertiesTable() \{ super(); this.setBorder(new TitledBorder("Properties Table")); String[] header = \{"Name", "Value"\}; String[] a = new String[0]; String[] names = System.getProperties().stringPropertyNames().toArray(a); String[][] data = new String[names.length][2]; for (int ii=0; ii> new Ellipse2D.Double(x, y, rectwidth, rectheight)); then set the stroke and the fill on the graphics objects, and then draw the shape, more or less. All drawing seems to have to take place within the 'paint' method of an awt component, or within the 'paintComponent' method of a swing component. This seems to mean that you have to subclass a component in order to draw. See below for specific examples. \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents creating shapes in the Graphics2D class .. straight line - new Line2D.Double(x1, y1, x2, y2) .. oval - new Ellipse2D.Double(x, y, rect-width, rect-height) .. rectangle - new Rectangle2D.Double(x1, y1, x2, y2); .. round rectangle - new RoundRectangle2D.Double(x1, y1, x2, y2, r1, r2)); .. quadratic curve - QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(...) .. With ovals or ellipses, the x and y parameters represent the top left hand corner of the bounding rectangle for the ellipse (not its centre). DRAWING TEXT .... * draw some rotated text ------------------------ radians = (vars[i]) * HPI; g.rotate(radians, x, y); g.drawString(s, x - w / 2, y + h); ,,, ANTIALIASING .... Antialiasing is a technique for smoothing curves. Antialiasing makes everything look much nicer so there is really no reason why you would not use it, ever. * turn on antialiasing for all drawing operations >> g2.setRenderingHint( >> RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); * draw shapes with antialiasing and without, to see the difference ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class AntialiasDraw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(20)); g2.draw(new RoundRectangle2D.Double(0, 0, 200, 200, 40, 40)); g2.draw(new Ellipse2D.Double(10, 20, 180, 120)); CubicCurve2D c = new CubicCurve2D.Double(); c.setCurve(80, 80, 100, 100, 120, 60, 150, 80); g2.draw(c); g2.setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); g2.draw(new RoundRectangle2D.Double(240, 0, 440, 200, 40, 40)); g2.draw(new Ellipse2D.Double(250, 20, 420, 120)); CubicCurve2D d = new CubicCurve2D.Double(); d.setCurve(320, 80, 340, 100, 360, 60, 390, 80); g2.draw(d); \} public AntialiasDraw() \{\} public Dimension getPreferredSize() \{ return new Dimension(800, 300); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing Shapes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new AntialiasDraw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, ARCS .... * draw a filled arc and get its start point ------------------------------------------- Graphics2D g2 = (Graphics2D) g; Arc2D arc = new Arc2D.Float(x, y, n, m, w, z, Arc2D.PIE); g2.fill(arch); Point2D p = arch.getStartPoint(); ,,, QUADRATIC CURVES .... A parabola is an example of a quadratic curve. In java, these curves have 2 end points and a point of inflexion (where the curve bends). * draw a quadratic curve ------------------------------------------------------------- QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(0, 0, 80, 80, 160, 0); g2.draw(q); ,,, >> q.setCurve(x1, y1, controlx, controly, x2, y2); \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents quadratic curve parameters .. x1 y1 - the first end point of the curve .. controlx controly - the point of inflexion of the curve .. x2 y2 - the 2nd end point of the curve .. CUBIC CURVES .... // c.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2); GENERAL PATHS .... General paths allow for the drawing of complex lines curves and shapes moveTo(float x, float y) – Moves the current path point to the given point lineTo(float x, float y) – Adds a line segment to the current path quadTo(float ctrlx, float ctrly, float x2, floaty2) – Adds a quadratic curve segment to the current path curveTo(float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x3, floaty3) – Adds a cubic curve segment to the current path closePath() – Closes the current path * draw a polygon using the GeneralPath class -------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class PolyDraw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(5)); int x1Points[] = \{0, 100, 0, 100\}; int y1Points[] = \{0, 50, 50, 0\}; GeneralPath polygon = new GeneralPath(GeneralPath.WIND\\_EVEN\\_ODD, x1Points.length); polygon.moveTo(x1Points[0], y1Points[0]); for (int index = 1; index < x1Points.length; index++) \{ polygon.lineTo(x1Points[index], y1Points[index]); \}; polygon.closePath(); g2.draw(polygon); \} public PolyDraw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(250, 250); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing a Polygon"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new PolyDraw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, EXAMPLES .... * draw a line ------------------------------ public void paint (Graphics g) \{ Graphics2D g2 = (Graphics2D) g; g2.draw(new Line2D.Double(x1, y1, x2, y2)); \} ,,, The getPreferredSize() method is necessary because otherwise the java jre doesnt know how big to make the window, and makes it very small. * draw a line on a component using the Graphics2D class ---------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class LineDraw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D) g; g2.draw(new Line2D.Double(0, 0, 200, 200)); \} public LineDraw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(220, 220); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing a Line"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new LineDraw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * draw a rounded rectangle, an oval and a quadratic curve ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class LineDraw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); g2.setStroke(new BasicStroke(5)); g2.draw(new RoundRectangle2D.Double(0, 0, 200, 200, 40, 40)); g2.draw(new Ellipse2D.Double(10, 20, 180, 120)); QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(0, 0, 80, 80, 160, 0); g2.draw(q); CubicCurve2D c = new CubicCurve2D.Double(); c.setCurve(80, 80, 100, 100, 120, 60, 150, 80); g2.draw(c); \} public LineDraw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(250, 250); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing a Line"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new LineDraw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * draw with a thick stroke and colours and gradient colours ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; Line2D line = new Line2D.Double(10, 10, 40, 40); g2.setColor(Color.blue); g2.setStroke(new BasicStroke(10)); g2.draw(line); Rectangle2D rect = new Rectangle2D.Double(20, 20, 100, 100); g2.draw(rect); g2.setPaint(new GradientPaint(0, 0, Color.blue, 50, 25, Color.green, true)); g2.fill(rect); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(150, 150); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing a Line"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, STROKES .... The stroke of a line or curve refers to its thickness, texture etc. By defining new strokes it is possible to create dotted lines, textured lines. The simplest technique is to use the BasicStroke class, and for more complicated needs, one can implement a stroke class. The stroke is set on the graphics object and then applies for all drawing operations until the stroke is changed. * draw with a thick stroke using the BasicStroke class ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.JFrame; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); RoundRectangle2D rect = new RoundRectangle2D.Double(40, 40, 300, 300, 80, 80); g2.setStroke(new BasicStroke(40)); g2.setColor(Color.darkGray); g2.draw(rect); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(400, 400); \} public static void main(String[] args) \{ JFrame f = new JFrame("Strokes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, There doesnt appear to be any antialiasing on the rounded corners of the above example * draw a rounded rectangle with a dashed line 6 pixels wide ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.JFrame; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); RoundRectangle2D rect = new RoundRectangle2D.Double(40, 40, 300, 300, 80, 80); float dash1[] = \{10.0f\}; BasicStroke dashed = new BasicStroke( 6, BasicStroke.CAP\\_BUTT, BasicStroke.JOIN\\_MITER, 10.0f, dash1, 0.0f); g2.setStroke(dashed); g2.setColor(Color.darkGray); g2.draw(rect); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(400, 400); \} public static void main(String[] args) \{ JFrame f = new JFrame("Strokes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, FILLING SHAPES .... Filling refers to painting the interior of a shape with a colour, a colour gradient or a texture. The .fill method draws the interior of a shape but not its border To create a GradientPaint, you specify a beginning position and color and an ending position and color. The gradient changes proportionally from one color to the other color along the line connecting the two positions. The position parameters for the gradient paint appear to be absolute, not relative to the shape you are trying to paint. * paint a rounded rectangle with gradient paint with no border ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.JFrame; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; GradientPaint grad = new GradientPaint(20,20,Color.BLUE,180, 180,Color.WHITE); g2.setPaint(grad); g2.fill(new RoundRectangle2D.Double(40, 40, 140, 140, 30, 30)); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(200, 200); \} public static void main(String[] args) \{ JFrame f = new JFrame("Strokes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, The example above uses the technique of placing the gradient end points outside of the shape to make the gradient more subtle. A better way would be to use colour shades which are closer together The following is an attempt to produce the bulgeing effect that is common in interfaces these days, but doesnt quite work. * a horizontal bar with a vertical green gradient paint ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.JFrame; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; Color limeGreen = new Color(Integer.decode("\\#32cd32")); Color drabOlive = new Color(Integer.decode("\\#6b8e23")); //Color lawnGreen = new Color(Integer.decode("\\#7CFC00")); //Color yellowGreen = new Color(Integer.decode("\\#ADFF2F")); GradientPaint grad = new GradientPaint(20, 20, limeGreen, 20, 40, drabOlive); g2.setPaint(grad); g2.fill(new Rectangle2D.Double(20, 20, 500, 40)); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(550, 100); \} public static void main(String[] args) \{ JFrame f = new JFrame("Strokes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * draw a dashed rounded rectangle and filled with a gradient paint ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.JFrame; public class Draw extends Component \{ public void paint(Graphics g) \{ Graphics2D g2 = (Graphics2D)g; RoundRectangle2D rect = new RoundRectangle2D.Double(40, 40, 200, 200, 80, 80); float dash1[] = \{10.0f\}; BasicStroke dashed = new BasicStroke( 6, BasicStroke.CAP\\_BUTT, BasicStroke.JOIN\\_MITER, 10.0f, dash1, 0.0f); g2.setStroke(dashed); g2.draw(rect); GradientPaint grad = new GradientPaint(0,0,Color.GREEN,200, 0,Color.WHITE); g2.setPaint(grad); g2.fill(rect); \} public Draw() \{ \} public Dimension getPreferredSize() \{ return new Dimension(400, 400); \} public static void main(String[] args) \{ JFrame f = new JFrame("Strokes"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new Draw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, SHAPES .... * create a shape (based on some text) and draw it on an image with a stroke ------------------------------ final BufferedImage textImage = new BufferedImage( width, height, BufferedImage.TYPE\\_INT\\_ARGB); Graphics2D g = textImage.createGraphics(); FontRenderContext frc = g.getFontRenderContext(); Font font = new Font("Arial", Font.BOLD, 250); GlyphVector gv = font.createGlyphVector(frc, "Cat"); Rectangle2D box = gv.getVisualBounds(); int xOff = 25+(int)-box.getX(); int yOff = 80+(int)-box.getY(); Shape shape = gv.getOutline(xOff,yOff); g.setColor(Color.WHITE); //g.setClip(null); g.setStroke(new BasicStroke(2f)); g.setColor(Color.BLACK); g.setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); g.draw(shape); g.dispose(); ,,, The code above draws the word cat in a big hollow font (its not really a font) GRADIENT PAINTS .... * a gradient paint from red to orange, top left to bottom right --------------------------- Graphics2D imageGraphics = image.createGraphics(); GradientPaint gp = new GradientPaint( 20f, 20f, Color.red, 380f, 280f, Color.orange); imageGraphics.setPaint(gp); imageGraphics.fillRect(0, 0, 400, 300); ,,, The above is a reasonably nice effect * another type of gradient paint with several colors\\$\\backslash\\$ --------------- Color[] colors = \{ Color.RED, Color.YELLOW, Color.GREEN \}; g2.setPaint(new LinearGradientPaint(start, end, dist, colors)); g2.fillRect(x, y, 100, 10); ,,, * draw a box with a green gradient paint -------------------- // This one alternates between deep opaque green and transparent green. // Note: the 4th arg to Color() constructor specifies color opacity g.setPaint(new GradientPaint(0, 0, new Color(0, 150, 0), 20, 20, new Color(0, 150, 0, 0), true)); g.setStroke(new BasicStroke(15)); // use wide lines g.drawRect(25, 25, WIDTH-50, HEIGHT-50); // draw the box ,,, * make a radial paint >> RadialPaint * CompoundPaint can use several different types of paint TEXTURE PAINTS .... Another technique for filling shapes is to tile an image within the shape. This uses the TexturePaint class. The pattern for the tiling of a TexturePaint class is defined by a BufferedImage class. To create a TexturePaint object, you specify the image that contains the pattern and a rectangle that is used to replicate and anchor the pattern. Then you use the setPaint() method as for gradient paints ADVANCED PAINTING .... If none of the available painting classes is suitable, you may implement the Paint interface, and pass your class to the setPaint method of the graphics object DRAWING ONTO IMAGES .... It is possible to draw onto a blank image. The purpose of this is to allow you to save the drawing. * skeleton code ------------------------------------------------------------- import java.awt.image.*; class Painting extends JPanel \{ BufferedImage grid; // declare the image public void paintComponent(Graphics g) \{ super.paintComponent(g); // paint background Graphics2D g2 = (Graphics2D)g; // we need a Graphics2D context if (grid == null) \{ // Compute the grid only one time int w = this.getWidth(); int h = this.getHeight(); grid = (BufferedImage)(this.createImage(w,h)); Graphics2D gc = grid.createGraphics(); for (int x=0; x> \url{http://docs.oracle.com/javase/tutorial/2d/advanced/transforming.html} * how to use the AffineTransform with Graphics2D >> \url{http://docs.oracle.com/javase/7/docs/api/java/awt/geom/AffineTransform.html} \title{} \author{bumble.sourceforge.net} \maketitle \tableofcontents some transformation methods for the Graphics2D class .. rotate() .. scale() .. translate() .. translate(AffineTransform) .. AWT DRAWING .... The old awt drawing methods are extremely limited. Here is an example * draw a some shapes using the old awt graphics class (limited) ------------------------------------------------------------- import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class ShapeDraw extends Component \{ public void paint(Graphics g) \{ g.drawLine(10,10,40,40); g.drawRect(20, 20, 100, 100); g.fillRect(120, 120, 200, 200); \} public ShapeDraw() \{\} public Dimension getPreferredSize() \{ return new Dimension(400, 600); \} public static void main(String[] args) \{ JFrame f = new JFrame("Drawing Stuff"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new ShapeDraw()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, IMAGES IMAGE INFORMATION .... * read an image from a url and get its height and width ----------------- URL url = new URL("http://i.stack.imgur.com/Nqf3H.jpg"); final BufferedImage originalImage = ImageIO.read(url); int width = originalImage.getWidth(); int height = originalImage.getHeight(); ,,, * create a new image icon >> ImageIcon i = new ImageIcon(imgURL, "some image"); * get an image size without reading the whole image -------------- ImageInputStream in = ImageIO.createImageInputStream(resourceFile); try \{ final Iterator readers = ImageIO.getImageReaders(in); if (readers.hasNext()) \{ ImageReader reader = (ImageReader) readers.next(); try \{ reader.setInput(in); return new Dimension(reader.getWidth(0), reader.getHeight(0)); \} finally \{ reader.dispose(); \} \} \} finally \{if (in != null) in.close(); \} ,,, * a small app which allows to load a set of images from a folder -------------------------------------------- import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.*; public class ImageApp extends Component implements KeyListener \{ BufferedImage img; File[] imageList; public void paint(Graphics g) \{ //g.drawImage(img, 0, 0, null); g.drawImage(img, 0, 0, 400, 600, null); g.setFont(new Font("Georgia", Font.ITALIC, 20)); g.drawString("Hello graphics", 20, 30); \} public ImageApp() \{ try \{ img = ImageIO.read(new File("villa.jpg"));\} catch (IOException e) \{ System.out.println("Image File not found"); \} this.addKeyListener(this); \} public void keyTyped(KeyEvent e) \{ char key = e.getKeyChar(); System.out.println("key typed:" + key); switch (key) \{ case 'h': this.setVisible(false); break; case 'l': JFileChooser c = new JFileChooser(); c.setFileSelectionMode(JFileChooser.DIRECTORIES\\_ONLY); int result = c.showOpenDialog(this); java.io.File folder = c.getSelectedFile(); System.out.println("folder selected:" + folder ); this.imageList = folder.listFiles(); System.out.println("Files:" + java.util.Arrays.toString(this.imageList)); break; default: break; \} \} public void keyPressed(KeyEvent e) \{\} public void keyReleased(KeyEvent e) \{\} public Dimension getPreferredSize() \{ if (img == null) \{ return new Dimension(100,100); \} else \{ //return new Dimension(img.getWidth(null), img.getHeight(null)); return new Dimension(400, 600); \} \} public static void main(String[] args) \{ JFrame f = new JFrame("Load Image Sample"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); ImageApp li = new ImageApp(); f.add(li); li.requestFocusInWindow(); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, LOADING IMAGES .... * load an image ------------------------ try \{ img = ImageIO.read(new File("villa.jpg"));\} catch (IOException e) \{ System.out.println("Image File not found"); \} ,,, * load an image: ---------------- java.net.URL imgURL = ImageDemo.class.getResource("path/to/image"); if (imgURL != null) \{ return new ImageIcon(imgURL, "a description"); \} else \{ System.err.println("Couldn't find file: " + path); return null; \} ,,, DISPLAYING IMAGES .... * load an image and display it scaled to 400 by 600 -------------------------------------------- import java.awt.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.*; public class DisplayImage extends Component \{ BufferedImage img; public void paint(Graphics g) \{ g.drawImage(img, 0, 0, 400, 600, null); \} public DisplayImage() \{ try \{ img = ImageIO.read(new File("villa.jpg"));\} catch (IOException e) \{ System.out.println("Image File not found"); \} \} public Dimension getPreferredSize() \{ return new Dimension(400, 600); \} public static void main(String[] args) \{ JFrame f = new JFrame("Load and Display Image Example"); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.getContentPane().add(new DisplayImage()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); \} \} ,,, * displaying an image in a tooltip for a JLabel using swing html (A. Thompson) ------------------------------ import javax.swing.*; import java.awt.GridLayout; class ThumbTip \{ private static final String HTML = ""; ThumbTip(String[] album) \{ JPanel p = new JPanel(new GridLayout(1,0,2,2)); for (String url : album) \{ String s = HTML + ""); l.setToolTipText(s + ">"); p.add(l); \} JOptionPane.showMessageDialog(null, p); \} public static void main(String[] args) \{ final String[] urls = \{ "http://pscode.org/media/stromlo1.jpg", "http://pscode.org/media/stromlo2.jpg" \}; SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ new ThumbTip(urls); \} \}); \} \} ,,, SCALING IMAGES .... * scale an image: ----------------- Image image = imageIcon.getImage (); int width = (int) (factor * image.getWidth (null)); int height = (int) (factor * image.getHeight (null)); Image newImage = image.getScaledInstance (width, height, Image.SCALE\\_SMOOTH); ImageIcon newImageIcon = new ImageIcon (newImage); ,,, * draw an image scaling to frame size >> g.drawImage(BuffImg,0,0,getWidth(),getHeight(),this): * resize (scale) an image ----------- BufferedImage resizedImage = new BufferedImage(IMG\\_WIDTH, IMG\\_HEIGHT, type); Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, IMG\\_WIDTH, IMG\\_HEIGHT, null); g.dispose(); ,,, This example is incomplete, because you still need to actually write the new image to file- but that is not difficult * scale all image files in a folder -------------------------- import java.awt.*; import java.awt.image.*; import javax.imageio.ImageIO; import java.io.File; /** * ImageScaler * * This class loads all images in a given directory and scales them to the * given sizes, saving the results as JPEG files in a new "scaled/" subdirectory * of the original directory. */ public class ImageScaler \{ // Default w/h values; overriden by command-line -width/-height parameters static int IMAGE\\_W = 150; static int IMAGE\\_H = 250; public static void main(String args[]) \{ // Default directory is current directory, overridden by -dir parameter String imagesDir = "."; for (int i = 0; i < args.length; ++i) \{ if (args[i].equals("-dir") \\&\\& ((i + 1) < args.length)) \{ imagesDir = args[++i]; \} else if (args[i].equals("-width") \\&\\& ((i + 1) < args.length)) \{ IMAGE\\_W = Integer.parseInt(args[++i]); \} else if (args[i].equals("-height") \\&\\& ((i + 1) < args.length)) \{ IMAGE\\_H = Integer.parseInt(args[++i]); \} \} // new subdirectory for scaled images String scaledImagesDir = imagesDir + File.separator + "scaled"; // directory that holds original images File cwd = new File(imagesDir); // directory for scaled images File subdir = new File(scaledImagesDir); subdir.mkdir(); File files[] = cwd.listFiles(); // temporary image for every scaled instance BufferedImage scaledImg = new BufferedImage(IMAGE\\_W, IMAGE\\_H, BufferedImage.TYPE\\_INT\\_RGB); Graphics2D gScaledImg = scaledImg.createGraphics(); // Note the use of BILNEAR filtering to enable smooth scaling gScaledImg.setRenderingHint(RenderingHints.KEY\\_INTERPOLATION, RenderingHints.VALUE\\_INTERPOLATION\\_BILINEAR); for (int i = 0; i < files.length; ++i) \{ try \{ // For every file in the directory, assume it's an image and // load it BufferedImage img = ImageIO.read(files[i]); // If we get here, we must have read the image file successfully. // Create a new File in the scaled subdirectory File scaledImgFile = new File(scaledImagesDir + File.separator + files[i].getName()); // Scale the original image into the temporary image gScaledImg.drawImage(img, 0, 0, IMAGE\\_W, IMAGE\\_H, null); // Save the scaled version out to the file ImageIO.write(scaledImg, "jpeg", scaledImgFile); \} catch (Exception e) \{ System.out.println("Problem with " + files[i]); \} \} \} \} ,,, \url{http://weblogs.java.net/blog/chet/archive/2004/07/imageio\\_just\\_an.html} good stuff about image scaling TRANSLUCENCY .... * code for making translucent images, and extending a JLabel ------------------------------------------------------------- import java.awt.*; import java.awt.image.*; import javax.swing.*; import javax.imageio.ImageIO; import java.net.URL; class TransparentIcon \{ public static void main(String[] args) throws Exception \{ String imgURL = "http://www.gravatar.com/avatar/" + "a1ab0af4997654345d7a949877f8037e"; final BufferedImage image = ImageIO.read(new URL(imgURL)); SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ ImageIcon icon = new ImageIcon(image); JPanel p = new JPanel(new GridLayout(2,3)); for (int ii=0; ii<6; ii++) \{ TransparentLabel tl = new TransparentLabel(); tl.setOpacity((ii+1)/6f); tl.setIcon(icon); p.add(tl); \} JOptionPane.showMessageDialog(null, p); \} \}); \} \} class TransparentLabel extends JLabel \{ float opacity = 1f; public void setOpacity(float opacity) \{ this.opacity = opacity; \} private Icon getTranslucentIcon(Icon icon) \{ if (icon!=null) \{ BufferedImage bi = new BufferedImage( icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE\\_INT\\_ARGB); Graphics2D g = bi.createGraphics(); AlphaComposite ac = AlphaComposite.getInstance( AlphaComposite.SRC\\_OVER, opacity); g.setComposite(ac); icon.paintIcon(this,g,0,0); g.dispose(); return new ImageIcon(bi); \} else \{ return null; \} \} public void setIcon(Icon icon) \{ super.setIcon( getTranslucentIcon(icon) ); \} \} ,,, CLIPPING IMAGES .... Clipping in this context refers to drawing an image within a particular shape, such as an oval or within the shape of text. * draw an image in the shape of some text using a clip, save image as png file ---------------------------------------------------------- // get the width and the height from the original image URL url = new URL("http://i.stack.imgur.com/Nqf3H.jpg"); final BufferedImage originalImage = ImageIO.read(url); int width = originalImage.getWidth(); int height = originalImage.getHeight(); final BufferedImage textImage = new BufferedImage( width, height, BufferedImage.TYPE\\_INT\\_ARGB); Graphics2D g = textImage.createGraphics(); FontRenderContext frc = g.getFontRenderContext(); Font font = new Font("Arial", Font.BOLD, 250); GlyphVector gv = font.createGlyphVector(frc, "Cat"); Rectangle2D box = gv.getVisualBounds(); int xOff = 25+(int)-box.getX(); int yOff = 80+(int)-box.getY(); Shape shape = gv.getOutline(xOff,yOff); g.setColor(Color.WHITE); g.setClip(shape); g.drawImage(originalImage,0,0,null); g.dispose(); ImageIO.write(textImage,"png",new File("cat-text.png")); ,,, IMAGE ICONS .... * create a jlabel with icon from a scaled buffered image ---------------------------- BufferedImage img = ...; JLable l = new JLabel(new ImageIcon(img.getScaledInstance( img.getWidth(null)/2, img.getHeight(null)/2, Image.SCALE\\_SMOOTH))); ,,, * convert an ImageIcon to a BufferedImage ------------------------------------------- ImageIcon imageIcon = new ImageIcon("http://pscode.org/media/stromlo2.jpg"); JLabel imageLabel = new JLabel( "A Horse", imageIcon, SwingConstants.CENTER); JOptionPane.showMessageDialog(null, imageLabel); Icon icon = imageLabel.getIcon(); BufferedImage bi = new BufferedImage( icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE\\_INT\\_RGB); Graphics g = bi.createGraphics(); // paint the Icon to the BufferedImage. icon.paintIcon(null, g, 0,0); ,,, SCREEN SHOTS .... A screen-shot is an image taken of what happens to be on the computer screen at a given time. * capture a screen shot. ------------------------ try \{ Robot robot = new Robot (); // Capture a particular area on the screen int x = 100; int y = 100; int width = 200; int height = 200; Rectangle area = new Rectangle (x, y, width, height); BufferedImage bufferedImage = robot.createScreenCapture (area); // Capture the whole screen area = new Rectangle (Toolkit.getDefaultToolkit ().getScreenSize ()); bufferedImage = robot.createScreenCapture (area); \} catch (AWTException e) \{ \} ,,, * get a buffered image of a jframe and write it to a png file --------------------------------------------- Component c = f.getContentPane(); BufferedImage i = getScreenShot(c); try \{ ImageIO.write(img, "png", new File("screenshot.png")); \} catch (Exception e) \{ e.printStackTrace(); \} public static BufferedImage getScreenShot(Component component) \{ BufferedImage image = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE\\_INT\\_RGB ); // call the Component's paint method, using // the Graphics object of the image. component.paint(image.getGraphics()); return image; \} ,,, SAVING IMAGES .... * save a jpeg image with a specified quality (and file compression) ------------------------------------------------------------- import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; ... float quality = 0.85f; File outfile = new File( "MyImage.jpg" ); BufferedImage image = ...; ImageWriter imgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); ImageOutputStream ioStream = ImageIO.createImageOutputStream( outfile ); imgWriter.setOutput( ioStream ); JPEGImageWriteParam jpegParams = new JPEGImageWriteParam( Locale.getDefault() ); jpegParams.setCompressionMode(ImageWriteParam.MODE\\_EXPLICIT); jpegParams.setCompressionQuality(quality); imgWriter.write(null, new IIOImage(image, null, null), jpegParams ); ioStream.flush(); ioStream.close(); imgWriter.dispose(); ,,,, * similar code to save a compressed jpeg image ------------------------------------------------------------- private Image getJpegCompressedImage(BufferedImage image) throws IOException \{ float qualityFloat = (float)quality.getValue()/100f; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ImageWriter imgWriter = ImageIO.getImageWritersByFormatName( "jpg" ).next(); ImageOutputStream ioStream = ImageIO.createImageOutputStream( outStream ); imgWriter.setOutput( ioStream ); JPEGImageWriteParam jpegParams = new JPEGImageWriteParam( Locale.getDefault() ); jpegParams.setCompressionMode( ImageWriteParam.MODE\\_EXPLICIT ); jpegParams.setCompressionQuality( qualityFloat ); imgWriter.write( null, new IIOImage( image, null, null ), jpegParams ); ioStream.flush(); ioStream.close(); imgWriter.dispose(); jpgSize = outStream.toByteArray().length; BufferedImage compressedImage = ImageIO.read(new ByteArrayInputStream(outStream.toByteArray())); return compressedImage; \} ,,, CONVERTING IMAGE FORMATS .... * convert to a png compressed image without saving ---------------------------------------------------- BufferedImage image = ...; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ImageIO.write(image, "png", outStream); pngSize = outStream.toByteArray().length; BufferedImage compressedImage = ImageIO.read(new ByteArrayInputStream(outStream.toByteArray())); ,,, ANIMATION * animation advice to reduce flicker In a JPanel, override paintComponent(Graphics) rather than paint(Graphics) Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See "Concurrency in Swing" for more details. * an animation to create 'marching ants' rectangle ------------------------------------------------------------- import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.Timer; public class AnimatedStroke \{ public static void main(String[] args) \{ SwingUtilities.invokeLater(new Runnable() \{ public void run() \{ BasicStroke dashedStroke; final int width = 100; final int height = 30; final BufferedImage image = new BufferedImage( width,height,BufferedImage.TYPE\\_INT\\_ARGB); final JLabel label = new JLabel(new ImageIcon(image)); int pad = 5; final Shape rectangle = new Rectangle2D.Double( (double)pad,(double)pad, (double)(width-2*pad), (double)(height-2*pad)); ActionListener listener = new ActionListener() \{ float dashPhase = 0f; float dash[] = \{5.0f,5.0f\}; @Override public void actionPerformed(ActionEvent ae) \{ dashPhase += 9.0f; BasicStroke dashedStroke = new BasicStroke( 1.5f, BasicStroke.CAP\\_ROUND, BasicStroke.JOIN\\_MITER, 1.5f, //miter limit dash, dashPhase ); Graphics2D g = image.createGraphics(); g.setColor(Color.WHITE); g.fillRect(0,0,width,height); g.setColor(Color.BLACK); g.setStroke(dashedStroke); g.draw(rectangle); g.dispose(); label.repaint(); /* if (dashPhase<100f) \{ try \{ ImageIO.write(image, "PNG", new File("img" + dashPhase + ".png")); \} catch(IOException ioe) \{\} \}*/ \} \}; Timer timer = new Timer(40, listener); timer.start(); JOptionPane.showMessageDialog(null, label); \} \}); \} \} ,,, The following animation doesnt flicker much on my pc. * a waveform animation ------------------------------------------------------------- import java.awt.*; import javax.swing.*; public class FlickerPanel extends JPanel implements Runnable \{ private float[] pixelMap = new float[0]; // Cached graphics objects to reduce flicker private Image screenBuffer; private Graphics bufferGraphics; public FlickerPanel () \{ Thread t = new Thread(this); t.start(); \} private float addNoise () \{ return (float)((Math.random()*2)-1); \} private synchronized void advance () \{ if (pixelMap == null || pixelMap.length == 0) return; float[] newPixelMap = new float[pixelMap.length]; for (int i=1; i> JSoup (jsoup.org) * convert html to text --------------------- public static String html2text(String html) \{ return Jsoup.parse(html).text(); \} \} ,,, HTML JAVA SOURCE CODE SYNTAX HIGHLIGHTING * convert 'Test.java' to syntax highlighted HTML >> webcpp Test.java Test.java.html -s * convert 'Test.java' to LaTeX and other formats >> highlight -i Test.java -o Test.java.html -L >> source-highlight .... \\#\\#(the gnu source highlighter) DEVELOPMENT TOOLS FOR JAVA ON MICROSOFT WINDOWS .... I am assuming that the windows computer is borrowed and that you dont really want to spend all your time developing in that environment. My preferences: install Vim, and GVim from \url{http://www.vim.org} - this is an somewhat annoying but useful text editor. install 'putty' and 'pscp' or 'pftp' so that you can upload your java files to some server. If you like, just put the .exe files for these programs in the directory where you are developing, otherwise add the location of the .exe files to the microsoft 'path' environment variable. Set up some useful mappings in the \\_vimrc file. See the section 'Vim and Java' for a long list of useful mappings. Put your \\_vimrc file somewhere like c:\\$\\backslash\\$program files\\$\\backslash\\$Vim VIM AND JAVA Its possible, though possibly not advisable to use the vim text editor as a java editor. By using mappings and commands we can simplify the process of compiling and running java programs. When using Microsoft windows the format of some of these commands are slightly different owing to the use of the \\$\\backslash\\$ backslash in Windows file names and the different command line syntax used by the Windows console (for example \\& and \\&\\& used to separated multiple commands on one line) For a great deal of detailed information and recipes about how to use Vim see bumble.sf.net/books/vim/vim-book.txt * save the current file to a sourceforge server >> :!scp \\% user,project@web.sf.net:folder/subfolder/ (\\#\\# unix) >> :!pscp \\% user,project@web.sf.net:folder/subfolder/ (\\#\\# windows) For the ms windows command, this requires that the pscp program has been installed, available from the 'putty' website. * make a command 'Sav' (placed in vimrc) to save the current file to sourceforge >> com Sav !scp \\% user,project@web.sf.net:folder/subfolder/ >> com Sav !pscp \\% user,project@web.sf.net:folder/subfolder/ (\\#\\# windows) The user can upload the current file to the sourceforge server by typing ':Sav' * map the key sequence ';jr' to compile and run the current file with java >> map ;jr :!javac \\% \\&\\& java \\%:r When the user types ';jr' in normal mode (not insert mode) the current file will be compiled and run. If the compilation with javac fails, then the mapping aborts * make an abbreviation to insert the main method in the file >> ab public static void main(String[] args) \{ * java abbreviations >> ab public static void main(String[] args) \{ public static void main(String[] args) \{ ab public class Test \{ public static void main(String[] args) \{\} \} public class Test \{ public static void main(String[] args) \{\} \} ,,, * make a mapping of ',jt' which inserts a simple skeleton program >> map ,jt 0i public class Test \{ public static void main(String[] args) \{\}\} * save a fragment (between '*' and ',,,') to a file >> :?\\$\\backslash\\$*?+1,/,,,/-1w Test.java * save a fragment to a file even if it exists >> :?\\$\\backslash\\$*?+1,/,,,/-1w! Test.java * save a fragment to a file and compile >> :?\\^ *---?+1,/,,,/-1w! Test.java | !javac Test.java * compile and run a java program (between '---' and ',,,') >> :?\\^ *---?+1,/,,,/-1w! Test.java | !javac Test.java; java Test Note that the java program between the markers must be complete with a main method * the same as above but also works on a Microsoft Windows computer >> :?\\^ *---?+1,/,,,/-1w! Test.java | !javac Test.java \\&\\& java Test * map ',jf' to compile and run a java program in the document on a unix system >> :map ,jf :?\\^ *---?+1,/,,,/-1w! Test.java \\$\\backslash\\$| !javac Test.java; java Test * and on Microsoft windows compile and run a java program >> :map ,jf :?\\^ *---?+1,/,,,/-1w! Test.java \\$\\backslash\\$| !javac Test.java \\&\\& java Test Actually the Windows mapping will also work on Unix systems, since \\&\\& has the same meaning in Unix (only execute the second command if the first was successful) For example, if the document contains the following text containing a simple java program. * the simplest java program --- public class Test \{ public static void main(String[] args) \{ System.out.println("hi"); \} \} ,,, Then typing ',jf' in 'normal' or 'command' mode will extract and compile and then run the java program contained within the lines containing '---' and ',,,' The only problem is that the code must use the class 'Test' * save and compile a java multiline fragment, inserting a class >> :?\\^ *---?+1,/,,,/-1w ! (echo -e 'public class Test \{\\$\\backslash\\$n public static void main(String[] args) \{'; sed 's/a/a/'; echo -e ' \}\\$\\backslash\\$n\}') > Test.java; javac Test.java; java Test.java * create a mapping which compiles and runs a java fragment >> map ,jfr :?\\^ *---?+1,/,,,/-1w ! (echo -e 'public class Test \{\\$\\backslash\\$n public static void main(String[] args) \{'; sed 's/a/a/'; echo -e ' \}\\$\\backslash\\$n\}') > Test.java; javac Test.java; java Test.java The above will compile and run a fragment of java code in the current document which is contained between '---' and ',,,,' EXTRACTING THE JAVA CLASS NAME WITH VIM .... These recipes below are working towards a function which will extract the java class name from a program within a text document. * put the text of the current line into a variable >> :let t = getline('.') | echo t * set a vim variable to the text of the line just above the next empty one >> :let line = search("\\^\\$") - 1 >> :let text = getline(line) * set a vim variable to the text of the next line containing the word elephant >> :let line = search("elephant") >> :let text = getline(line) * set the variable 't' to the next line containing the word 'public' >> :let l = search("public") | let t = getline(l) | echo t * split the words of the current line into an array and display the second word >> :let text = getline('.') | let words = split(text) | echo words[1] Using a one character variable name for the array doesnt seem to work. * use a variable as part of a shell command. >> :let n = '..' | exe "!dir " . n In order to use the value of the variable in the shell command we need to use the exe command which evaluates the concatenated string as a vim command * split the current line on each '(' character >> :let t = getline(".") | let res = split(t, '(') | echo res[0] * go back to the first line above which contains split >> :exe "?split?" * find the next java class name definition >> exe "/\\^ *public class /" | let words = split(getline('.')) | echo words[2] * just a fragment to test the mapping below ----------------------------------- public class Person \{ private String first; private String last; public Person(String f, String l) \{ this.first = f; this.last = l; \} public void print() \{ System.out.println(this.first + " " + this.last); \} public static void main(String[] args) \{ Person t = new Person("Bill", "King"); t.print(); \} \} ,,, * a mapping to extract the class name from a java program in a document >> :map ;jj ?\\^ *---? \\$\\backslash\\$| :let l = search("\\^ *public class ") \\$\\backslash\\$| echo split(getline(l))[2] The beginning of the java program in the document is marked by a line which starts with '---' * a mapping to extract the class name from a java program in a document >> :map ;jj ?\\^ *---? \\$\\backslash\\$| :let l = search("\\^ *public class ") \\$\\backslash\\$| echo split(getline(l))[2] \\$\\backslash\\$| :?\\^ *---?+1,/,,,/-1w! Frag.java * extract the class name from a fragment and write to a file with that name >> :map ,jr ?\\^ *---? \\$\\backslash\\$| :let l = search("\\^ *public class ") \\$\\backslash\\$| let class = split(getline(l))[2] \\$\\backslash\\$| exe ":?\\^ *---?+1,/,,,/-1w! " . class . ".java" * save, compile and run a fragment using the java class name >> :map ,jr ?\\^ *---? \\$\\backslash\\$| :let l = search("\\^ *public class ") \\$\\backslash\\$| let class = split(getline(l))[2] \\$\\backslash\\$| exe ":?\\^ *---?+1,/,,,/-1w! " . class . ".java" \\$\\backslash\\$| exe "!javac " . class . ".java \\&\\& java " . class The mapping above is the culmination of the entire preceding section. It uses several tricky aspects of Vims scripting language and variables. First is searches backwards for the start of the java code (---), then it finds the line with the java class name definition, then it assigned the class name to a variable by calling 2 functions to create an list of words and getting the 3rd word. Then it uses the "exe" function which is like an "eval" function in other languages to construct a shell command using the value of the variable which contains the Java class name. Finally it compiles and runs the java class >> :map ,jf :?\\^ *---?+1,/,,,/-1w! Test.java \\$\\backslash\\$| !javac Test.java \\&\\& java Test VIEWING METHODS WITH VIM .... * a dubious but useful way to show public method declarations >> :g/\\^ *public.*) *\{*\\$/ * a command to show most public methods in a java file >> :command! Me g/\\^ *public.*) *\{*\\$/ INDENTING WITHIN VIM .... * a mapping to indent a java fragment within a document using astyle >> map ,ji :?\\^ *---?+1,/\\^ *,,,/-1! astyle -s2 * a mapping to indent a java fragment and indent the result 2 spaces >> map ,ji :?\\^ *---?+1,/\\^ *,,,/-1! astyle -s2 sed 's/\\^/ /' * indent the whole java file >> :\\%! astyle -s2 \\#\\#(2 space indent with open brace on the same line) >> :\\%! astyle -bs2 \\#\\#(the same but with open brace on the next line) * map ',jii' to indent the whole java file with a 2 space indent >> :map ,jii \\%! astyle -s2 2 space indent with open brace on the same line GVIM .... If you are developing in java using vim on a microsoft computer, you will almost certainly want to use gvim, since the fonts are much nicer. In gvim select the font which you like, and then type >> :set guifont If you have select 'courier new' size 20, you will see something like >> guifont=Courier\\_New:h20:cANSI Now open the \\_vimrc file (windows) or .vimrc file (unix) and put the following line in the vimrc file >> set guifont=Courier\\_New:h20:cANSI This will ensure that everytime that gvim starts it will use the specified font. To do the same for the colorscheme, place the following in the vimrc file >> colorscheme elflord where you replace 'elflord' with whatever colorscheme you like. BASH AND JAVA The power and flexibility of the bash shell may help us in the somewhat clumsy process of developing java applications. * a bash function to show the methods and constructors of java class -------------------------------------------------------------------- function jcl \{ cat << xxx > JJJ.java import java.lang.reflect.*; public class JJJ \{ public static void main(String args[]) throws Exception \{ Class c = Class.forName("java.lang.\\$1"); Constructor cc[] = c.getDeclaredConstructors(); Method m[] = c.getMethods(); for (int i = 0; i < cc.length; i++) System.out.println(cc[i]); for (int i = 0; i < m.length; i++) System.out.println(m[i]); \} \} xxx javac JJJ.java; java JJJ \} ,,, INDENTING * astyle * view a java file nicely indented with 2 spaces >> cat test.java | astyle -s2 | less The indent program was written for the c language but may be used with java. astyle may be better. JAVA PEOPLE * Bill Joy One time head of sun, programmer. * fred swartz: made some good notes, at leepoint.net KNOWLEDGABLE PROGRAMMERS .... * Vineet Reynolds @ stackoverflow - knows about stuff in java * Andrew Thompson @ stackoverflow - a contributor to the stack overflow site. Writes very complete code examples on a range of java topics * x4u @ stackoverflow - knows about images GLOSSARY Tooltip - A little (usually yellow) that pops up when you move your mouse over an element in a Java Gui Application. The box is supposed to contain explanatory or helpful text relation to how to use the element highlighted. Data hiding: Garbage collection Memory Management: Decoupling Patterns: TESTING * initialization --------------- public class Test \{ public int x; public double d; public static void main(String[] args) \{ Test t = new Test(); System.out.println("x=" + t.d); \} \} ,,, * infinite recursion --------------- public class Test \{ public static void while() \{ Test.while(); \} public static void main(String[] args) \{ Test.while(); System.out.println("="); \} \} ,,, * testing char casts --------------- public class Test \{ public static void main(String[] args) \{ char c = 'e'; int i = (int)'A'; if ((c >= 'a') \\&\\& (c <= 'z')) \{ System.out.println("c=" + (int)c); System.out.println("i=" + i); \} \} \} ,,, * parseint --------------- public class Test \{ public static void main(String[] args) \{ String s = "-123"; int i = Integer.parseInt(s); System.out.println("i=" + i); \} \} ,,, * testing char casts --------------- public class Test \{ public static void main(String[] args) \{ char c = 'e'; int i = (int)'A'; if ((c >= 'a') \\&\\& (c <= 'z')) \{ System.out.println("c=" + (int)c); System.out.println("i=" + i); \} \} \} ,,, * testing char casts --------------- public class Test \{ public static void main(String[] args) \{ char c = 'a' + 4; System.out.println("c=" + c); \} \} ,,, NOTES This section contains notes which havent been placed in their appropriate chapter or section yet. * load an application resource from a jar (not a user resource) >> URL iconUrl = this.getClass().getResource("/icons/copy.jpg"); The code above has the disadvantage of downloading the images from the internet each time they are used. * display a (buffered) image in a message box >> JOptionPane.showMessageDialog(parent, new JLabel(new ImageIcon(theImage))); * a logger which publishes to the console ----------------------------- import java.util.logging.*; class LoggingLevels \{ public static void main(String[] args) \{ Logger logger = Logger.getAnonymousLogger(); // LOG this level to the log logger.setLevel(Level.FINER); ConsoleHandler handler = new ConsoleHandler(); // PUBLISH this level handler.setLevel(Level.FINER); logger.addHandler(handler); System.out.println("Logging level is: " + logger.getLevel()); for (int ii=0; ii<3; ii++) \{ logger.log(Level.FINE, ii + " " + (ii*ii)); logger.log(Level.INFO, ii + " " + (ii*ii)); \} \} \} ,,, * produces output like -------------- Logging level is: FINER Jun 11, 2011 9:39:23 PM LoggingLevels main INFO: 0 0 Jun 11, 2011 9:39:24 PM LoggingLevels main INFO: 1 1 Jun 11, 2011 9:39:24 PM LoggingLevels main INFO: 2 4 ,,, * to investigate, writing log files with the logging package -------------------- import java.util.logging.*; private Logger logger = Logger.getAnonymousLogger(); logger.log(Level.FINER, "Get column styles"); ,,, * update look and feel after gui has been displayed ----------------- try \{ UIManager.setLookAndFeel(plafInfos[index].getClassName() ); SwingUtilities.updateComponentTreeUI(frame); // not necessary to pack but good frame.pack(); frame.setMinimumSize(frame.getSize()); \} catch(Exception e) \{ e.printStackTrace(); \} ,,, * get a screen shot of a jframe component (using BufferedImage) >> \url{http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992\\#5853992} * set a window location depending on os >> jframe.setLocationByPlatform(true); MODERN LOOPS String s = "red yellow blue"; String[] splitString = (s.split("\\$\\backslash\\$\\$\\backslash\\$s+")); for (String ss: splitString) \{ System.out.println(ss); \} TODO \url{http://www.daniweb.com/software-development/java/threads/94567/writing-string-to-a-file} a nice visual effect of highlighted words with shadows StringBuilder since Java 1.5 not synchronized, more efficient, not to be used in threads StringBuffer can be used in threads Have the same methods Use StringBuilder unless you really are trying to share a buffer between threads * insert integers at the beginning of a StringBuilder, this is very inefficient\\$\\backslash\\$ ---------------------- StringBuilder sb = new StringBuilder(); for(int i=0;i<100;i++)\{ sb.insert(0, Integer.toString(i)); \} ,,, * use the built in javascript engine in java 1.6 to evaluate a sum ------------------------------- import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; public class Test \{ public static void main(String[] args) throws Exception\{ ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); String foo = "40+2"; System.out.println(engine.eval(foo)); \} \} ,,, * use javap to generate bytecode or java assembly ---------------------- 3: dup 4: ldc \\#3; //String bu 6: invokespecial \\#4; //Method StringBuilder."":(String;)V 9: astore\\_1 10: ldc \\#5; //String b 12: astore\\_2 13: ldc \\#6; //String u ,,, By using javap it may be possible to see how the java compiler generates bytecode. READING AND WRITING TEXT FILES FileReader and FileWriter can only use the default system encoding * read a file which is encoded in utf8 ----------- FileInputStream fis = new FileInputStream("test.txt"); InputStreamReader in = new InputStreamReader(fis, "UTF-8"); ,,, * write a text file encoded as utf8 ------------- FileOutputStream fos = new FileOutputStream("test.txt"); OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8"); ,,, If the encoding is not specified then the default system encoding is used * read utf8 text data from a file -------------------------- import java.io.*; public class test \{ public static void main(String[] args)\{ try \{ File file = new File("c:\\$\\backslash\\$\\$\\backslash\\$temp\\$\\backslash\\$\\$\\backslash\\$test.txt"); BufferedReader in = new BufferedReader( new InputStreamReader(new FileInputStream(file), "UTF8")); String str; while ((str = in.readLine()) != null) \{ System.out.println(str); \} in.close(); \} catch (UnsupportedEncodingException e) \{ System.out.println(e.getMessage()); \} catch (IOException e) \{ System.out.println(e.getMessage());\} catch (Exception e) \{ System.out.println(e.getMessage());\} \} \} ,,, REGULAR EXPRESSIONS Peter Boughton on Stackoverflow- knowledgable chap about regexes * replace all text between tree and leaf with "new" (this is non "greedy"?) >> String ResultString = subjectString.replaceAll("(tree).*?(leaf)", "\\$1new\\$2"); The \\$1 and \\$2 are back references. The .*? is non greedy matching * double all sequences of "a"s using a compiled regular expression ------------------ Pattern p = Pattern.compile("(a+)"); String ret = p.matcher(input).replaceAll("\\$1 \\$1"); ,,, Compiling the regular expression or pattern is supposed to be more efficient. * match any sequence of characters which are not word chars or \\# or \\$ >> Pattern p = Pattern.compile("\\^[\\$\\backslash\\$\\$\\backslash\\$w\\#\\$]+\\$"); * use a matcher to print each occurence of the 2nd subgroup found ----------------------------------------- String input = " ;1=2011-10-23T16:16:53+0530; 2=2011-10-23T16:17:53+0530;3=2011-10-23T16:18:53+0530;4=2011-10-23T16:19:53+0530;"; Pattern p = Pattern.compile("(;\\$\\backslash\\$\\$\\backslash\\$d+?)?=(.+?);"); Matcher m = p.matcher(input); while(m.find())\{ System.out.println(m.group(2)); \} ,,, * match a string starting with a digit or a non-word char or a whitespace char ------------- Pattern p = Pattern.compile("\\^\\$\\backslash\\$\\$\\backslash\\$d|\\^\\$\\backslash\\$\\$\\backslash\\$W|\\^\\$\\backslash\\$\\$\\backslash\\$s"); Matcher m = p.matcher("stack overflow"); // no matches with this input ,,, * parse a string into a date using a SimpleDateFormat -------------------- SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); try \{ final Date date = parser.parse(dateString); System.out.println(integer + " -> " + date); \} catch (final ParseException pe) \{ System.err.println("bad date: " + dateString + ": " + pe); \} ,,, WRITING TEXT * write utf8 text data to a file -------------------------- import java.io.*; public class test \{ public static void main(String[] args)\{ try \{ File file = new File("c:\\$\\backslash\\$\\$\\backslash\\$temp\\$\\backslash\\$\\$\\backslash\\$test.txt"); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file), "UTF8")); out.append("Website UTF-8").append("\\$\\backslash\\$r\\$\\backslash\\$n"); out.append("??????? UTF-8").append("\\$\\backslash\\$r\\$\\backslash\\$n"); out.flush(); out.close(); \} catch (UnsupportedEncodingException e) \{ System.out.println(e.getMessage()); \} catch (IOException e) \{ System.out.println(e.getMessage());\} catch (Exception e) \{ System.out.println(e.getMessage());\} \} \} ,,, The BufferedWriter class has a .newLine() method, but it uses the default newline character(s) for the system. EXEC * run a system command with environment variable ---------------------------- ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); Map env = pb.environment(); env.put("VAR1", "myValue"); env.remove("OTHERVAR"); env.put("VAR2", env.get("VAR1") + "suffix"); pb.directory("myDir"); Process p = pb.start(); ,,, * run a system command and read the output ------------------------------ import java.io.*; public class JavaRunCommand \{ public static void main(String args[]) \{ String s = null; try \{ Process p = Runtime.getRuntime().exec("ps -ef"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); // read the output from the command System.out.println("Here is the standard output of the command:\\$\\backslash\\$n"); while ((s = stdInput.readLine()) != null) \{ System.out.println(s); \} // read any errors from the attempted command System.out.println("Here is the standard error of the command (if any):\\$\\backslash\\$n"); while ((s = stdError.readLine()) != null) \{ System.out.println(s); \} System.exit(0); \} catch (IOException e) \{ System.out.println("exception happened - here's what I know: "); e.printStackTrace(); System.exit(-1); \} \} \} ,,, * create a temporary file and delete it when the program exits -------------------- File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); ,,, FILE SYSTEM TYPES * list file system labels or names ------------------------------------ import java.io.File; import java.util.Arrays; import java.util.List; import javax.swing.filechooser.FileSystemView; public class Test2 \{ public static void main(String args[])\{ List files = Arrays.asList(File.listRoots()); for (File f : files) \{ String s = FileSystemView.getFileSystemView().getSystemDisplayName(f); System.out.println("*" + s); \} /* output (French WinXP) * *REGA1 (C:) * *My Book (F:) */ \} \} ,,, * print the types of storage devices currently mounted as filesystems --------------------- import java.io.File; import java.util.Arrays; import java.util.List; import javax.swing.filechooser.FileSystemView; public class Test \{ public static void main(String args[]) \{ List files = Arrays.asList(File.listRoots()); for (File f : files) \{ String s = FileSystemView.getFileSystemView().getSystemTypeDescription(f); System.out.println("*" + s); \} /* sample output (French WinXP) *Disquette 3 1/2 pouces *Disque local *Lecteur CD *Disque local */ \} \} ,,, the above is from rgagnon.com * using printf style format strings, for those who live in the 80s >> String.format("http://\\%s/manager/list", \\_host + ":8080")); HTTP BASIC AUTHENTICATION * a possible alternative for authenticating with "basic" auth on a url ----------------------------- Authenticator.setDefault (new Authenticator() \{ protected PasswordAuthentication getPasswordAuthentication() \{ return new PasswordAuthentication ("username", "password".toCharArray()); \} \}); ,,, * from a Java program, a FileNotFoundException is thrown when you try to read from an InputStream associated with the basic authenticated URL. * upload a file to a server. The server has to know how to receive it -------------------------------------- public static void main(String[] args) throws IOException \{ File textFile = new File("D:\\$\\backslash\\$\\$\\backslash\\$file.zip"); String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique value for the boundary. HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/upslet/upload").openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); OutputStream output = connection.getOutputStream(); PrintWriter writer = new PrintWriter(output, true); // Send text file. writer.println("--" + boundary); writer.println("Content-Disposition: form-data; name=\\$\\backslash\\$"file1\\$\\backslash\\$"; filename=\\$\\backslash\\$"" + textFile.getName() + "\\$\\backslash\\$""); writer.println("Content-Type: application/octet-stream"); FileInputStream fin = new FileInputStream(textFile); writer.println(); IOUtils.copy(fin, output); writer.println(); // End of multipart/form-data. writer.println("--" + boundary + "--"); output.flush(); closeQuietly(fin, writer, output); // Above request will never be sent if .getInputStream() or .getResponseCode() or .getResponseMessage() does not get called. connection.getResponseCode(); \} ,,, * apache httpclient provides more advanced authentication The method below is said to work with java 1.1. see the method above for a more modern technique (use an authenticator) * access a url which is protected by "basic" authentication, untested... ---------------------- URL url = new URL(¿location address¿); URLConnection uc = url.openConnection(); String authorizationString = ¿Basic ¿ + Base64.encode("username:password"); uc.setRequestProperty ("Authorization", authorizationString); InputStream in = url.openStream(); ,,, but the Base64 encoding above is not part of standard java, try ------------ byte[] data = . . .; String encoded = javax.xml.bind.DataTypeConverter.printBase64Binary(data); byte[] decoded = javax.xml.bind.DatatypeConverter.parseBase64Binary(encoded); ,,, * read text from a url ---------------------- try \{ URL url = new URL("http://hostname:80/index.html"); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); String str; while ((str = in.readLine()) != null) \{ // str is one line of text; // readLine() strips the newline character(s) \} in.close(); \} catch (MalformedURLException e) \{ \} catch (IOException e) \{ \} ,,, * another almost identical way to read text from a webpage ---------------------------- URLConnection urlConnection = url.openConnection(); InputStream is = urlConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(is); int numCharsRead; char[] charArray = new char[1024]; StringBuffer sb = new StringBuffer(); while ((numCharsRead = isr.read(charArray)) > 0) \{ sb.append(charArray, 0, numCharsRead); \} String result = sb.toString(); ,,, I wonder if this is more efficient than readline/// * post data using a url and read the reply from the webserver ----------------------------------- try \{ String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8") + "\\&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8"); URL url = new URL("http://hostname:80/cgi"); URLConnection conn = url.openConnection(); conn.setDoOutput(true); OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(data); wr.flush(); // Get the response BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = rd.readLine()) != null) \{ // Process line... \} wr.close(); rd.close(); \} catch (Exception e) \{\} ,,, JTEXTPANE * get the default font for a text pane >> System.out.println(UIManager.get("TextPane.font")); * get the pixel position of the cursor (caret) in jtextpane ------------ Rectangle caretCoords = textpane.modelToView(caretposition); y = (int) caretCoords.getY(); ,,, * loop through a textpanes different styles ---------------- JTextPane jtp = new JTextPane(); ... HTMLDocument doc = (HTMLDocument) jtp.getDocument(); StyleSheet styles = doc.getStyleSheet(); Enumeration rules = styles.getStyleNames(); while (rules.hasMoreElements()) \{ String name = (String) rules.nextElement(); Style rule = styles.getStyle(name); System.out.println(rule.toString()); \} ,,, GRIDBAG LAYOUT using a grid bag, its not so hard, just like a table but with spans --------------------------- getContentPane().setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = 2; c.gridheight = 1; c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.weighty = 1.0; c.gridx = 0; c.gridy = 0; c.insets = new Insets(2, 2, 2, 2); getContentPane().add(new JScrollPane(pane), c); ,,, TEXT COMPONENTS \url{http://es.scribd.com/doc/89923641/31/JTextComponent-features} very good summary of JTextComponent features. .createPosition in a text component is like creating a bookmark. The bookmark doesnt change even when its offset from the start of the document changes JTextComponent is complex and is the ancestor of all java text components. Documents can have a structure such as chapter paragraph etc. textArea.setCaretPosition(textArea.getDocument().getLength()); sets the cursor to the end of the ta * create a shape by subtracting one area from another ------------------------- Area area = new Area(new Rectangle2D.Double(...)); Area inner = new Area(new Rectangle2D.Double(...)); area.subtract(inner); ,,, BORDERS Java swing provides a great deal of flexibility with how borders are painted around components. * create a new type of border by implementing the interface ----------------------------- public static class GradientBorder implements Border \{ private Insets margin; public GradientBorder ( int top, int left, int bottom, int right ) \{ super (); margin = new Insets ( top, left, bottom, right ); \} public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) \{ Graphics2D g2d = (Graphics2D) g; g2d.setPaint (new GradientPaint( x, y, Color.RED, x + width, y, Color.BLUE)); Area border = new Area ( new Rectangle ( x, y, width, height ) ); border.subtract ( new Area ( new Rectangle ( x + margin.left, y + margin.top, width - margin.left - margin.right, height - margin.top - margin.bottom ) ) ); g2d.fill ( border ); \} public Insets getBorderInsets ( Component c ) \{ return margin; \} public boolean isBorderOpaque () \{ return true; \} \} ,,, * a rounded corder border ------------------------------ class OldRoundedBorderLine extends AbstractBorder \{ private final static int MARGIN = 5; private static final long serialVersionUID = 1L; private Color color; OldRoundedBorderLine(Color clr) \{ color = clr; \} public void setColor(Color clr) \{ color = clr; \} @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) \{ ((Graphics2D) g).setRenderingHint( RenderingHints.KEY\\_ANTIALIASING, RenderingHints.VALUE\\_ANTIALIAS\\_ON); g.setColor(color); g.drawRoundRect(x, y, width, height, MARGIN, MARGIN); \} @Override public Insets getBorderInsets(Component c) \{ return new Insets(MARGIN, MARGIN, MARGIN, MARGIN); \} @Override public Insets getBorderInsets(Component c, Insets insets) \{ insets.left = MARGIN; insets.top = MARGIN; insets.right = MARGIN; insets.bottom = MARGIN; return insets; \} \} ,,, \url{http://stackoverflow.com/questions/4458982/repaint-swing-button-with-different-gradient/5845007\\#5845007} set the colour gradient on abutton * create a hexagon button ----------------- You will have to extend JButton class not AbstractButton. Try the following things and you will get idea The first move is to subclass JButton. Then, in your subclass, start by redefining the paintComponent(Graphics) method. If you want any changes. Then, override paintBorder(Graphics) to give it a shape of hexagon ,,, * create rounded corners on a border, but you cant control the radius >> LineBorder(Color color, int thickness, boolean roundedCorners) Creates a line border with the specified color, thickness, and corner shape. * set text antialiasing with something like this >> g2.setRenderingHint(RenderingHints.KEY\\_TEXTANTIALIASING, RenderingHints.VALUE\\_TEXTANTIALIAS\\_ON); * (com.sun.awt.AWTUtilities) to make your JFrame really transparent. -------------------------------- import com.sun.awt.AWTUtilities; /* "this" is the JFrame */ this.setUndecorated(true); AWTUtilities.setWindowOpaque(this, true); AWTUtilities.setWindowOpacity(this, 0.5f); AWTUtilities.setWindowShape(this, new RoundRectangle2D.Float(0f, 0f, (float) getWidth(), (float) getHeight(), 15f, 15f)); ,,, * another way to make a transparent top level window, w opaque component, but not on linux ---------------------------- JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); f.setBackground(new Color(0f, 0f, 0f, 0.1f)); f.setUndecorated(true); f.add(new JLabel("Testing
1, 2, 3")); f.pack(); ,,, \url{http://oreilly.com/catalog/java2d/chapter/ch04.html} a chapter on painting from an oreilly book idea: to create an angled stripy effect with two colours, use a gradient paint in cycle mode with the gradient very small, or tight. Then you could animate the gradient paint to create moving stripes. This technique can fill a shape with lots of stripes. * make an italic font in the same family >> Font f = g.deriveFont(Font.ITALIC); * make a text box with an image in it >> use CompoundBorder and MatteBorder \title{===========================================} \author{bumble.sourceforge.net} \maketitle \tableofcontents * a borderlayout with gaps and a title -------------------------- JPanel p = new JPanel( new BorderLayout(5,5) ); p.setBorder( new TitledBorder("Main GUI") ); ,,, * create a menu with control 0 shortcut key and an action listener ----------------------------------- JMenuItem screenshot = new JMenuItem("Screenshot"); screenshot.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK\\_0, InputEvent.CTRL\\_DOWN\\_MASK)); screenshot.addActionListener(new ActionListener() \{ public void actionPerformed(ActionEvent ae) \{ // do something here \}\}; JMenu menu = new JMenu("Other"); menu.add(screenshot); JMenuBar mb = new JMenuBar(); mb.add(menu); jframe.setJMenuBar(mb); ,,, * get a buffered image of a jframe and write it to a png file --------------------------------------------- Component c = f.getContentPane(); BufferedImage i = getScreenShot(c); try \{ ImageIO.write(img, "png", new File("screenshot.png")); \} catch (Exception e) \{ e.printStackTrace(); \} public static BufferedImage getScreenShot(Component component) \{ BufferedImage image = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE\\_INT\\_RGB ); component.paint(image.getGraphics()); return image; \} ,,, * create a jlabel with icon from a scaled buffered image ---------------------------- BufferedImage img = ...; JLable l = new JLabel( new ImageIcon(img.getScaledInstance( img.getWidth(null)/2, img.getHeight(null)/2, Image.SCALE\\_SMOOTH))); ,,, * get a screen shot of a jframe component (using BufferedImage) >> \url{http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992\\#5853992} * set a window location depending on os >> jframe.setLocationByPlatform(true); * set the native system look and feel. ------------------------ public static void main(String[] args) \{ SwingUtilities.invokeLater( new Runnable() \{ public void run() \{ try \{ UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); \} catch (Exception useDefault) \{\} initGui(); \} \}); \} ,,, MODERN LOOPS String s = "red yellow blue"; String[] splitString = (s.split("\\$\\backslash\\$\\$\\backslash\\$s+")); for (String ss: splitString) \{ System.out.println(ss); \} REGULAR EXPRESSIONS * use the String built in pattern matching public class Test \{ public static final String S = "This is my small example string for testing"; public static void main(String[] args) \{ System.out.println(S.matches("\\$\\backslash\\$\\$\\backslash\\$w.*")); String[] splitString = (S.split("\\$\\backslash\\$\\$\\backslash\\$s+")); for (String string : splitString) \{ System.out.println(string); \} // Replace all whitespace with tabs System.out.println(s.replaceAll("\\$\\backslash\\$\\$\\backslash\\$s+", "\\$\\backslash\\$t")); \} \} * use compiled patterns and matching loops ------- Pattern pattern = Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$w+"); // or Pattern pattern = Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$s+", Pattern.CASE\\_INSENSITIVE); Matcher matcher = pattern.matcher("some test string"); // Check all occurance while (matcher.find()) \{ System.out.print("Start index: " + matcher.start()); System.out.print(" End index: " + matcher.end() + " "); System.out.println(matcher.group()); \} ,,, * replace all occurance of whitespace with tabs --- Pattern replace = Pattern.compile("\\$\\backslash\\$\\$\\backslash\\$s+"); Matcher matcher2 = replace.matcher("some example string"); System.out.println(matcher2.replaceAll("\\$\\backslash\\$t")); ,,, CONSTRUCTORS * make 2 object contructors, of which one uses a default value ---- public FileSystemModel() \{ this( System.getProperty( "user.home" ) ); \} public FileSystemModel( String startPath ) \{ root = startPath; \} ,,, * read a file into a string buffer ---- BufferedReader br = new BufferedReader(fr); String buffer; StringBuffer result = new StringBuffer(); while ((buffer = br.readLine()) != null) \{ result.append(buffer); \} ,,, It would probably be faster to read into a larger buffer (8k ?) rather than just one line. * jlist with a list model ---- import java.awt.*; import javax.swing.*; public class List extends JFrame \{ public static void main(String[] args) \{ List t = new List(); ListModel bigData = new AbstractListModel() \{ public int getSize() \{ return Short.MAX\\_VALUE; \} public Object getElementAt(int index) \{ return "Index " + index; \} \}; JList bigDataList = new JList(bigData); //use the following method for performance reasons bigDataList.setPrototypeCellValue("Index 1234567890"); JScrollPane js = new JScrollPane(bigDataList); t.getContentPane().add(js); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setVisible(true); \} \} ,,, * displays a file list in the center of the screen ------ import java.awt.*; import javax.swing.*; import java.io.*; public class List extends JFrame \{ public static void main(String[] args) \{ List t = new List(); JList bigDataList = new JList((new File(".")).listFiles()); JScrollPane js = new JScrollPane(bigDataList); JPanel pl = new JPanel(); pl.add(js); t.getContentPane().add(pl); t.setSize(new Dimension(300, 300)); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setLocationRelativeTo(null); t.setVisible(true); \} \} ,,, * display list of files in the current folder in a list box ------ import java.awt.*; import javax.swing.*; import java.io.*; public class List extends JFrame \{ public static void main(String[] args) \{ List t = new List(); File dir = new File("."); File[] files = dir.listFiles(); JList bigDataList = new JList(files); JScrollPane js = new JScrollPane(bigDataList); JPanel pl = new JPanel(); pl.add(js); t.getContentPane().add(pl); t.setSize(new Dimension(300, 300)); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setVisible(true); \} \} ,,, * do something when a jlist item is double clicked -------- final JList list = new JList(dataModel); MouseListener mouseListener = new MouseAdapter() \{ public void mouseClicked(MouseEvent e) \{ if (e.getClickCount() == 2) \{ int index = list.locationToIndex(e.getPoint()); System.out.println("Double clicked on Item " + index); \} \} \}; list.addMouseListener(mouseListener); ,,, * list with model and unicode characters ------ import java.awt.*; import javax.swing.*; public class List extends JFrame \{ public static void main(String[] args) \{ List t = new List(); ListModel bigData = new AbstractListModel() \{ public int getSize() \{ return Short.MAX\\_VALUE; \} public Object getElementAt(int index) \{ return "unicode " + index + "=" + (char)index; \} \}; JList bigDataList = new JList(bigData); bigDataList.setPrototypeCellValue("Index 1234567890"); JScrollPane js = new JScrollPane(bigDataList); JPanel pl = new JPanel(); pl.add(js); t.getContentPane().add(pl); t.setSize(new Dimension(300, 300)); t.setDefaultCloseOperation(JFrame.EXIT\\_ON\\_CLOSE); t.setVisible(true); \} \} ,,, * a simple file directory TreeModel for use with a JTree element --------- import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; import java.io.*; public class FileSystemModel implements TreeModel \{ String root; public FileSystemModel() \{ this( System.getProperty( "user.home" ) ); \} public FileSystemModel( String startPath ) \{ root = startPath; \} public Object getRoot() \{ return new File( root ); \} public Object getChild( Object parent, int index ) \{ File directory = (File)parent; String[] children = directory.list(); return new File( directory, children[index] ); \} public int getChildCount( Object parent ) \{ File fileSysEntity = (File)parent; if ( fileSysEntity.isDirectory() ) \{ String[] children = fileSysEntity.list(); if (children == null) return 0; return children.length; \} return 0; \} public boolean isLeaf( Object node ) \{ return ((File)node).isFile(); \} public void valueForPathChanged( TreePath path, Object newValue ) \{\} public void removeTreeModelListener(TreeModelListener l) \{\} public void addTreeModelListener(TreeModelListener l) \{\} public int getIndexOfChild( Object parent, Object child ) \{ File directory = (File)parent; File fileSysEntity = (File)child; String[] children = directory.list(); int result = -1; for ( int i = 0; i < children.length; ++i ) \{ if ( fileSysEntity.getName().equals( children[i] ) ) \{ result = i; break; \} \} return result; \} public static void main(String[] args) \{ JFrame f = new JFrame(); JTree t = new JTree(new FileSystemModel()); f.getContentPane().add(t); f.setVisible(true); \} \} ,,, A SIMPLE FRAME TEMPLATE WITH A BUTTON public class Eg extends PPSFrame implements ActionListener \{ private JButton b; public Eg() \{ b = new JButton("click"); b.addActionListener(this); add(b); \} public void actionPerformed(ActionEvent e) \{ if (e.getSource() == b) \{\} if (e.getActionCommand().equals("click")) \{\} repaint(); \} public void paintComponent(Graphics g) \{\} public static void main(String[] args) \{\} \} THE FILLOVAL METHOD * fill an oval ------------- import java.awt.*; import javax.swing.*; public class Test extends JFrame \{ private boolean tracing; public void paintComponent(Graphics g) \{ super.paintComponent(g); this.setBackground(Color.YELLOW); g.setColor(Color.WHITE); g.fillOval(100,0,400,400); \} public static void main(String[] args) \{ Test t = new Test(); \} \} ,,, The origin (0,0) is the top left fillOval: public abstract void fillOval(int x, int y, int width, int height) Fills an oval bounded by the specified rectangle with the current color. PRINT >> System.out.println("hello " + i); >> System.out.print("hello " + i); SCAN >> import java.util.Scanner; >> Scanner s = new Scanner(System.in); >> int i = s.nextInt(); \\# get next integer >> String w = s.next(); \\# get the next word >> String w = s.nextLine(); \\# get whole line (but not '\\$\\backslash\\$n') RANDOM A random number from 0-9 >> java.util.Random g = new java.util.Random(); >> int i = g.nextInt(10); >> System.out.println("i=" + i); A random element of an array >> java.util.Random g = new java.util.Random(); >> char[] cc = new char[20]; >> int i = g.nextInt(cc.length); CONSTRUCTOR Constructors ARE methods. >> public Name(String f, int i) \{\} >> public Name() \{\} FINAL >> final String WORD = new String("tree"); >> private final String WORD = new String("tree"); METHODS !!! method names cant be reserved words ('do', 'while' etc) >> public void print() \{\} >> public boolean print() \{\} >> public String print(int i, double d) \{\} >> private static int[] doo() \{\} >> public static int doo(int i) \{\} >> public static void doo(char c) \{\} RECURSION Infinite recursion gives stack overflow error (compiles) DECLARE compile errors !!! variable uninitialised >> int x; System.out.print("x=" + x); >> int x; x=x+1 but NO error if var is an instance variable >> private int x; !! initialised to zero INTEGER >> int x = 2; parseInt is FUSSY, below throws number format exception >> int i = Integer.parseInt("123 ")' !!! NO >> int i = Integer.parseInt(" 123")' !!! NO >> int i = Integer.parseInt("123\\$\\backslash\\$n")' !!! NO Below is ok >> int i = Integer.parseInt("-123")' OPERATOR PRECEDENCE In normal order, prints '2' >> System.out.println("\\$\\backslash\\$n result=" + 10*2\\%3); DOUBLE Convert a string to a double >> double d = Double.parseDouble("-0.223"); >> java.lang.Math.pow(3,4) CHAR >> char letter = 'a'; >> char c = 'a' + 4; (c='e') Implicit casts to integer are OK in statements >> char c = 'A'; int i = 4 + c; Implicit casts to integer are NOT OK in methods >> Test.doo(25); !!! no if "doo(char c)" Comparisons with characters ok >> char c = 'A'; if (c <= 'B') \{\} >> 'a'=97, 'A'=65 >> lower case letter: if ((c >= 'a') \\&\\& (c <= 'z')) Convert case >> char c = Character.toLowerCase('A'); >> char c = Character.toUpperCase('a'); Convert a decimal digit to a character >> char c = Character.forDigit(4, 10); STRINGS >> String r, s, t; >> String s = new String("cat"); >> if (s.equals("tree") \{\} >> if (s.equalsIgnoreCase("trEE")) \{\} >> t = "TTR".toLowerCase(); >> t = "TTR ".trim(); >> t = "TTR".indexOf('R'); >> t = "TTR".indexOf("TT"); Starts with and ends with >> if ("big".startsWith("bi")) >> if ("big".endsWith("ig")) Matches >> if ("009".matches("\\$\\backslash\\$\\$\\backslash\\$d")) System.out.println("\\$\\backslash\\$n\\$\\backslash\\$nyes"); Split a string into words >> String[] ss = ("Some new words".split("\\$\\backslash\\$\\$\\backslash\\$s+")); System.out.println(ss[1]); Substrings >> "big".substring(0,2) == "bi" Comparing strings >> System.out.println("this".compareTo("this")); // prints 0 >> System.out.println("zed".compareTo("this")); // prints 6 >> System.out.println("us".compareTo("this")); // prints 1 >> System.out.println("this".compareTo("us")); // prints -1 >> System.out.println("this".compareTo("thks")); // prints -2 MOD get the hundreds >> i = 1234; i=i/100\\%10; LOOPS >> for (int i=0; i < 5; i++) \{\} >> for (int i=0; i < array.length; i++) \{\} USING THE GRAPHICS OBJECT import java.awt.*; import javax.swing.*; public class Test extends JFrame \{ private boolean tracing; public void paintComponent(Graphics g) \{ super.paintComponent(g); this.setBackground(Color.YELLOW); g.setColor(Color.WHITE); g.fillOval(0,0,400,400); g.setFont(new Font("SansSerif",Font.BOLD,32)); g.drawString("Target Practice", 130, 75); \} public static void main(String[] args) \{ Test t = new Test(); \} \} WATCH OUT FOR >> array.length() !!! no array.length >> Class.make() !!! is 'make' static??? >> method 'while()' !!! reserved word INVESTIGATE This section contains subjects and code snippets in java to investigate * what does this mean, a raster is a kind of pixel map >> WritableRaster wr = screen.getRaster(); * investigate Maps >> Map properties = ((TAudioFileFormat) fileFormat).properties(); * xml parsing code, zip extracting, logging code, by A. Thompson >> \url{http://stackoverflow.com/questions/8509302/is-this-ods-reader-functional} * investigate using JWindows for pop up dialogs or tool tips >> JWindow * initialize a boolean array (all element false) >> boolean[] array = new boolean[size]; * initialize a boolean array to true Boolean[] array = new Boolean[size]; Arrays.fill(array, Boolean.TRUE); ,,, * transfer a file via scp, Jsch has a reputation for being tricky to use >> use JSch * an alternative to jsch is sshj >> https://github.com/shikhar/sshj DOCUMENT-NOTES: \\# this section contains information about the document and \\# will not normally be printed. \\# a small icon to represent this book document-icon: \texttt{/img/icon/coffee-cup-grey.png} \\# a larger image document-image: \\# what sort of document is this document-type: book \\# in what kind of state (good or bad) is this document document-quality: not too bad \\# work carried out on this document document-history: @@ 2009 The document was begun sometime in 2009 in colombia @@ 28 feb 2010 added some information about using vim with java. @@ 23 march 2010 some information about playing sound files, and tree models, list models and table models @@ 28 april 2010 added some information about the JOptionPane dialog boxes and extended the 'gui' section of the booklet. Various things about gui interfaces, tabbed panes, labels, borders etc. The problem is that java examples tend to be long and bulky. @@ 30 april 2010 A few notes about arrays and reflection @@ 2 may 2010 a few corrections in the reflection section, and a bash documentation look-up function @@ 12 may 2012 trying to expand and improve the book, but just lost a lot of work because of a save error. Want to add sections on images sound. Trying to write an image edit app in java @@ 14 may 2012 Continuing work on this. Looking at the UIManager, CellRenderers for changing the appearance of components. Created a set of batch files for working on ms windows @@ 17 may 2012 more work. notes about drag and drop @@ 21 may 2012 incorporating some code from stackoverflow and A. Thompson who writes very complete code examples. Added notes about playing sounds. Finally a working mp3 play example. @@ 26 june 2012 in the process of incorporating the java-notes file into the java book. \\# who wrote this authors: mjb \\$\\verb|~| \url{http://bumble.sf.net} \\# a short description of the contents, possible used for doc lists short-description: Succinct java programming, if thats possible \\# what language are the code exampless in; code-language: java \\# the script which will be used to produce html (a webpage) make-html: ./booktohtml.cgi \\# the script which will produce 'LaTeX' output (for printing, pdf etc) make-latex: ./booktolatex.cgi \end{document} %end generated latex