Realhowto Java

  • Uploaded by: bakoma
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Realhowto Java as PDF for free.

More details

  • Words: 155,214
  • Pages: 810
Real's HowTo PDF version. This is the PDF version of the Real's HowTo Web site ( http://www.rgagnon.com/howto.html ). For up−to−date content, please refer to the Web site. There are 4 files : Real's Java , Real's Javascript, Real's Powerbuilder and Real's VBS and Misc Prog HowTo. Please don't make PDF versions available on the internet (it's ok in intranet) From the PDF, you can't run the examples and the links to other How−to's are not working. If you feel that effort has been useful to you, perhaps you will consider giving something back? You can make a donation through PayPal at https://www.paypal.com , make you donation to [email protected] Contributions via PayPal are accepted in any amount using a credit card or checking account. (Donations of any size gladly accepted) Real's Howto copyright notice ( [email protected] ) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions is met: * the source code is used in a development project Redistributions of source code or site content (even partially) in any publications (electronic or paper) is forbidden without permission. DISCLAIMER THIS SOFTWARE IS PROVIDED BY Real Gagnon "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Real Gagnon BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Real's [email protected] 1 Applet...............................................................................................................................................1 1.1 java−applet........................................................................................................................1 1.2 Goto to a new URL from an Applet....................................................................................1 1.3 Determine the host from where the Applet is loaded.........................................................3 1.4 Have a scrolling status line................................................................................................3 1.5 Use a search engine..........................................................................................................5 1.6 Have an on−screen clock..................................................................................................6 1.7 Have Applets on the same page communicate with each other........................................8 1.8 Have Applets on different frames communicates with each other.....................................9 1.9 Send a message from an Applet to another Applet on a different page..........................10 1.10 Have an applet launch an other applet..........................................................................12 1.11 Get the user name.........................................................................................................14 1.12 Access parameters passed in the URL..........................................................................14 1.13 Convert an Applet to Application....................................................................................16 1.14 Change the mouse cursor in Applet...............................................................................17 1.15 Use an Image as the Applet background.......................................................................17 1.16 Handle the new Control Activation mechanism in IE.....................................................18 1.16.1 Solution #1............................................................................................................19 1.16.2 Solution #2............................................................................................................19 1.16.3 Solution #3............................................................................................................20 1.17 Pass parameters to the Applet JVM (WIN)....................................................................21 1.18 See the Java Console Window Log (Java plugin).........................................................22 1.19 Display debugging infos for an Applet...........................................................................23 1.20 Have an invisible Applet.................................................................................................23 2 Date and Time...............................................................................................................................24 2.1 java−date.........................................................................................................................24 2.2 Have year on 4 digits from a Date object.........................................................................24 2.3 Get the current Date and Time........................................................................................24 2.4 Compute days between 2 dates......................................................................................25 2.5 Get the number of days in a month..................................................................................26 2.6 Validate a date.................................................................................................................27 2.6.1 Using DateFormat...................................................................................................27 2.6.2 Using GregorianCalendar.......................................................................................28 2.7 Determine to day of the week..........................................................................................29 2.8 Add/Substract Day/Month/Year to a Date........................................................................29 2.9 Get the correct TimeZone on DateFormat.......................................................................30 2.10 Simply format a date as "YYYYMMDD".........................................................................30 2.11 Compare 2 dates...........................................................................................................31 2.12 Parse a String to obtain a Date/GregorianCalendar object............................................31 2.13 Use System time to generate unique ID........................................................................32 2.14 Get the day name..........................................................................................................33 2.15 Find the current date format...........................................................................................33 2.16 Get a julian date.............................................................................................................34 2.17 Calculate the age...........................................................................................................36 2.18 Format a duration in ms into a string as "Days,Hours,minutes and seconds"...............37 2.19 Get the atomic time........................................................................................................38 2.20 Get a date interval..........................................................................................................40 2.21 Determine if an hour is between an interval...................................................................42 2.22 Set the computer clock..................................................................................................43

2.23 Use System time to generate unique ID

Real's [email protected] 2 Date and Time 2.23 Use System time to generate unique ID........................................................................43 3 AWT................................................................................................................................................45 3.1 java−awt...........................................................................................................................45 3.2 Use The CardLayout manager.........................................................................................45 3.3 Detect which card is visible with a CardLayout................................................................47 3.4 Use Popups.....................................................................................................................47 3.5 Use a File Dialog..............................................................................................................49 3.6 Use TrueType font...........................................................................................................50 3.7 Display available fonts.....................................................................................................51 3.8 Font with 3D effect...........................................................................................................52 3.9 Use the System Clipboard...............................................................................................52 3.10 Maximize a Frame.........................................................................................................53 3.11 Center a Frame/Dialog...................................................................................................54 3.12 Close a Frame...............................................................................................................55 3.13 Call events on a Frame from a Panel............................................................................56 3.14 Set the small top−left icon on a Frame..........................................................................58 3.15 Prevent a Frame to be resized.......................................................................................59 3.16 Embed an image into a Frame.......................................................................................60 3.17 Display a message box..................................................................................................62 3.18 Display a Splash screen................................................................................................63 3.19 Vibrate a Window...........................................................................................................65 3.20 Limit TextField input to numeric value...........................................................................67 3.21 Limit TextField input to a maximum length....................................................................69 3.22 React to the ENTER key in a Textfield..........................................................................70 3.23 Make the ENTER key act like the TAB key....................................................................70 3.24 Reset all textfields in one shot.......................................................................................71 3.25 Limit a TextField to Uppercase......................................................................................72 3.26 Have an ImageButton....................................................................................................73 3.27 Reset a checkbox group................................................................................................76 3.28 Set the listbox width.......................................................................................................76 3.29 Align the column in a List...............................................................................................77 3.30 Have a srolling text display............................................................................................77 3.31 Label dynamic resizing..................................................................................................78 3.32 Make a TextArea "word−wrap"......................................................................................80 3.33 Synchronize a TextArea vs a Choice.............................................................................80 3.34 Display underlined text...................................................................................................80 3.35 Display vertical text........................................................................................................81 3.36 Have Label with many lines...........................................................................................82 3.37 Have a Label with underlined text..................................................................................86 3.38 Have a Label acting as HTML HREF (URLLabel).........................................................87 3.39 Display a GIF in a Canvas.............................................................................................88 3.40 Embed an image into a Frame.......................................................................................89 3.41 Load several images from a single GIF.........................................................................91 3.42 Load an Image from a JAR file......................................................................................92 3.43 Load an Icon from a jar (again)......................................................................................93 3.44 Scale an Image..............................................................................................................94 3.45 Fade an image...............................................................................................................95 3.46 Rotate an image.............................................................................................................97

Real's [email protected] 3 AWT 3.47 Create a scrollable canvas.............................................................................................99 3.48 Use an Image as the Applet background.....................................................................103 3.49 Have a simple Image browser.....................................................................................104 3.50 Simulate a "mouse over" event to toggle an image.....................................................107 3.51 Hide the mouse cursor.................................................................................................108 3.52 Make a color transparent.............................................................................................109 3.53 Save an Image as a GIF or JPEG file..........................................................................110 3.54 Use the same background color as the browser..........................................................111 3.55 Do simple animation using Images..............................................................................112 3.56 Do simple animation to show "work in progress".........................................................113 3.57 Get the color of a specific pixel....................................................................................114 3.58 Do "rubber−band" drawing...........................................................................................115 3.59 Convert RGB value to Hexadecimal (to be used in HTML for example)......................117 3.60 Draw a line or set a pixel in my own image..................................................................117 3.61 Draw a dashed line......................................................................................................118 3.62 Draw a line with a thickness.........................................................................................119 3.63 Draw a pie chart...........................................................................................................121 3.64 Draw faster rectangles.................................................................................................123 3.65 Get a screen capture and save it as a JPEG...............................................................124 3.66 Display a TIF................................................................................................................124 3.67 Convert a multi−page TIF into single−page TIF...........................................................126 3.68 Convert an Image to a BufferedImage.........................................................................127 3.69 Detect a double click vs simple click............................................................................128 3.70 Detect the mouse button used when clicking...............................................................129 3.71 Exit an application from a menu...................................................................................130 3.72 Trigger a click on a Button...........................................................................................131 4 Environment................................................................................................................................133 4.1 java−env........................................................................................................................133 4.2 Read environment variables from an application...........................................................133 4.3 Retrieve environment variables (JDK1.5)......................................................................137 4.4 Retrieve environment variable (JNI)..............................................................................137 4.5 Use a MAKE file.............................................................................................................138 4.6 Detect the browser/JVM type.........................................................................................139 4.7 Fix the "Wrong magic number" error message..............................................................141 4.8 Use a precompiler "à la C" with Java.............................................................................141 4.9 Open source packages..................................................................................................141 4.10 Ant................................................................................................................................141 4.11 Simple boolean flag.....................................................................................................142 4.12 Determine what are the classes actually used in a Java Applet or application............143 4.13 Set the memory available to the JVM..........................................................................143 4.14 Generate the Javadoc "en français"............................................................................143 4.15 Use JDK1.5 new features............................................................................................145 4.16 Check the class version...............................................................................................145 4.17 Get the system properties or the JVM uptime..............................................................147 4.18 Detect if running in a 64bit JVM...................................................................................147 4.19 Set the default JVM type..............................................................................................148 4.20 Capture the output of JAVAC.......................................................................................149 4.21 Freeze the JVIEW window in MS VJ++.......................................................................150

4.22 Wrap a Java beans in a COM object

Real's [email protected] 4 Environment 4.22 Wrap a Java beans in a COM object...........................................................................150 4.23 Know details about the JAVA at run−time...................................................................151 4.24 Detect the Microsoft JVM version installed..................................................................153 4.25 Run JAVA as a Windows service.................................................................................153 4.26 Execute a class from Windows Explorer......................................................................153 4.27 Create an icon to launch java apps for Windows?.......................................................155 4.28 Fix the "out of environment" error when setting a new CLASSPATH..........................155 4.29 Query Windows registry...............................................................................................156 4.30 Quickly retrieve available Java JVM on a workstation (Windows)...............................158 4.31 Get the Windows "My Documents" path......................................................................159 4.32 Get a return code from a VBS......................................................................................160 4.33 List currently running processes (Windows)................................................................161 4.33.1 Using TASKLIST.EXE.........................................................................................161 4.33.2 Using a VBS........................................................................................................162 4.34 Check if a program or process is running (Windows)..................................................163 4.35 Windows registry vs. Java JDK/JRE installation..........................................................164 4.36 Create a Taglet to document database access (Javadoc)...........................................165 4.36.1 newMethod.........................................................................................................165 4.37 Generate the Javadoc "en français"............................................................................169 4.38 Document a package using Javadoc...........................................................................170 4.39 Display a comment in a Javadoc.................................................................................171 4.40 Display XML in a javadoc.............................................................................................172 4.41 Add a copyright notice to a Javadoc............................................................................172 4.42 Use a Log file...............................................................................................................173 4.43 Trace the execution.....................................................................................................175 4.44 Time the execution.......................................................................................................177 4.45 Log information efficiently (with Log4J)........................................................................178 4.46 Change the logging level on−the−fly (Log4J)..............................................................179 4.47 Use a JAR/ZIP/CAB file with an Applet........................................................................180 4.48 Make ZIP/JAR file always accessible from applet.......................................................182 4.49 Make a JAR executable...............................................................................................182 4.50 Accessing jars from within a jar...................................................................................184 4.51 Access a JAR outside the CLASSPATH......................................................................184 4.52 Extract a file from a Jar................................................................................................185 4.53 Determine if running from JAR.....................................................................................186 4.54 Get list of classes in package (in a Jar).......................................................................187 4.55 Add version to Jar packaging.......................................................................................188 4.56 Use ANT to Build a JAR with version/build number.....................................................190 4.57 Include all jars in the classpath definition.....................................................................193 4.58 Windows batch file.......................................................................................................194 4.59 JDK6............................................................................................................................194 4.60 JAR (and ANT).............................................................................................................195 4.61 Detect the browser/JVM type.......................................................................................196 4.62 Detect if Java is enabled from HTML...........................................................................198 4.63 See the Java Console Window Log (Java plugin).......................................................198 5 Internationalization.....................................................................................................................200 5.1 java−inter.......................................................................................................................200 5.2 Load resources based upon client environment at startup............................................200

Real's [email protected] 5 Internationalization 5.3 Load resources dynamically..........................................................................................203 5.4 Load resources via a resources file...............................................................................206 5.5 Display "special character" using Unicode.....................................................................210 5.6 Display chinese/japanese characters............................................................................211 5.7 Localize a JOptionPane dialog......................................................................................211 5.8 Validate/Convert a number using the current Locale()..................................................213 5.9 Localize a JFileChooser.................................................................................................214 5.10 Disable localization......................................................................................................216 5.11 Generate the Javadoc "en français"............................................................................217 5.12 Sort a String array........................................................................................................218 5.13 Accentuated characters in Properties/ResourceBundle file.........................................220 5.14 Compare accentuated letters.......................................................................................220 5.15 Unaccent letters...........................................................................................................221 5.16 Output french characters to the console......................................................................224 5.17 Get the default character set of the JVM.....................................................................225 5.18 Convert OEM (DOS) file to Ansi (Windows)................................................................225 5.19 Detect non−ASCII character in a String.......................................................................226 6 IO..................................................................................................................................................228 6.1 java−io...........................................................................................................................228 6.2 Redirect output(stdout/stderr) to a frame.......................................................................228 6.3 Redirect printStackTrace() to a String............................................................................229 6.4 Output french characters to the console........................................................................230 6.5 Clear the console and control attributes........................................................................231 6.6 Print text to a printer easily............................................................................................232 6.7 Print without a Dialog.....................................................................................................232 6.8 Simple input from the keyboard.....................................................................................233 6.9 Initialize and write to a serial port...................................................................................234 6.10 Redirect to a NULL device...........................................................................................235 6.11 Get the volume label....................................................................................................235 6.12 Easy keyboard input (JDK1.5).....................................................................................236 6.13 Open or close a CD/DVD drive....................................................................................236 6.14 Get faster console output (System.out.println() replacement).....................................238 6.15 Execute an external program.......................................................................................239 6.16 Using Runtime.exec()..................................................................................................239 6.17 Launch a Windows CMD (or BAT) file and retrieve the errorlevel or exitcode.............240 6.18 Launch a Unix script....................................................................................................241 6.19 Using the ProcessBuilder.............................................................................................241 6.20 Windows rundll32 utility...............................................................................................242 6.21 PDF (Windows only)....................................................................................................242 6.22 PDF (Mac only)............................................................................................................242 6.23 Path to executable with spaces in them.......................................................................243 6.24 VBSCRIPT...................................................................................................................243 6.25 HTML Help (Windows only).........................................................................................243 6.26 Start Excel....................................................................................................................243 6.27 Start a Windows application under another account....................................................244 6.28 Windows : execute something in Program Files..........................................................245 6.29 Launch the application associated with a file extension..............................................245 6.30 Launch an application from another application..........................................................246

6.31 Start the default browser from an application

Real's [email protected] 6 IO 6.31 Start the default browser from an application..............................................................248 6.32 Execute a Windows Shortcut (.lnk)..............................................................................250 6.33 Create a file association with a Java program.............................................................250 6.34 Capture the output from a VBS....................................................................................252 6.35 Get a return code from a VBS......................................................................................253 6.36 Execute a CMD file stored in a JAR.............................................................................254 6.37 Read the content of a file.............................................................................................255 6.38 Read a text file from a jar.............................................................................................257 6.39 Extract a file from a Jar................................................................................................260 6.40 Read a data file with floats...........................................................................................261 6.41 Write to the end of a file...............................................................................................262 6.42 Write "real" ascii file.....................................................................................................263 6.43 Copy a file....................................................................................................................264 6.44 Use a "log file"..............................................................................................................266 6.45 Delete files with a certain extension.............................................................................267 6.46 Insert a line in a file......................................................................................................268 6.47 Read a file into a variable in one shot..........................................................................269 6.48 Serialize an object to a file...........................................................................................269 6.49 Redirect stdout to a file................................................................................................271 6.50 Get the "last modified" date from a file.........................................................................271 6.51 Check if a file exists.....................................................................................................271 6.52 Detect file modification.................................................................................................272 6.53 File/directory polling to detect change.........................................................................274 6.54 jpoller (directory poller)................................................................................................274 6.55 JNotify..........................................................................................................................274 6.56 Java Native Access (JNA)...........................................................................................275 6.57 Call native methods in a DLL from Java (NativeCall)..................................................275 6.58 Java 7..........................................................................................................................275 6.59 The simple (and naive!) approach...............................................................................275 6.60 Get the current directory..............................................................................................275 6.61 Get the "root" of an application....................................................................................276 6.62 Get the content of a directory with a Filter...................................................................276 6.63 Get the content of a directory with subdirectories........................................................278 6.64 Make a directory..........................................................................................................279 6.65 Create a fixed−length file.............................................................................................280 6.66 Delete a non−empty directory......................................................................................280 6.67 Create a temporary file................................................................................................281 6.68 Get the default character set of the JVM.....................................................................282 6.69 Parse a pathname........................................................................................................282 6.70 Handle Excel files........................................................................................................283 6.71 JDBC−ODBC Excel driver...........................................................................................283 6.72 JExcel..........................................................................................................................283 6.73 POI...............................................................................................................................284 6.74 JXLS............................................................................................................................285 6.75 xlSQL...........................................................................................................................285 6.76 JCOM...........................................................................................................................286 6.77 OpenXLS Java Spreadsheet SDK...............................................................................287 6.78 Handle CSV file............................................................................................................289 6.79 com.Ostermiller.util CSV Utils......................................................................................289

Real's [email protected] 6 IO 6.80 opencsv........................................................................................................................289 6.81 ServingXML.................................................................................................................289 6.82 Super CSV...................................................................................................................289 6.83 csvreader.....................................................................................................................289 6.84 CSVFile........................................................................................................................289 6.85 FlatPack.......................................................................................................................289 6.86 Create an Excel file......................................................................................................290 6.87 Create or process a PDF file........................................................................................290 6.88 Create a PDF...............................................................................................................292 6.89 iText.............................................................................................................................292 6.90 Convert OEM (DOS) file to Ansi (Windows)................................................................293 6.91 Close a stream in a try/catch block..............................................................................294 6.92 Rename a file extension..............................................................................................295 6.93 Remove HTML tags from a file to extract only the TEXT.............................................295 6.94 Using regular expression.............................................................................................296 6.95 Using javax.swing.text.html.HTMLEditorKit.................................................................296 6.96 Get the Mime Type from a File....................................................................................297 6.96.1 Using javax.activation.MimetypesFileTypeMap..................................................297 6.96.2 Using java.net.URL.............................................................................................298 6.96.3 Using JMimeMagic..............................................................................................298 6.96.4 Using mime−util..................................................................................................298 6.96.5 Using Droid.........................................................................................................299 6.96.6 Aperture framework.............................................................................................299 6.97 Sort a directory listing..................................................................................................299 6.98 Filter a directory listing by date....................................................................................300 6.99 Display a comment in a Javadoc.................................................................................301 6.100 Create a compressed (ZIP) file..................................................................................302 6.101 Display compressed (ZIP) file content.......................................................................303 6.102 Expand the compressed (ZIP) file..............................................................................304 6.103 Emit a beep................................................................................................................305 6.104 Emit a Tone................................................................................................................305 6.105 Play an audio file from an application........................................................................306 7 JDBC............................................................................................................................................308 7.1 java−jdbc........................................................................................................................308 7.2 Connect to a database via JDBC−ODBC......................................................................308 7.3 SELECT data from a table.............................................................................................309 7.4 INSERT data into a table...............................................................................................310 7.5 MODIFY data in a table.................................................................................................311 7.6 DELETE data in a table.................................................................................................312 7.7 Test for an empty ResultSet..........................................................................................312 7.8 Store and retrieve an object from a table.......................................................................313 7.9 Retrieve an Image..........................................................................................................315 7.10 Insert an Image............................................................................................................315 7.11 Connect to an Oracle database with JDBC.................................................................315 7.12 Connect to Oracle using a connection pool.................................................................316 7.13 Get JDBC driver for major database vendors..............................................................319 7.14 Handle dates................................................................................................................319 7.15 Call a stored procedure................................................................................................320

7.16 Stored procedure with Input/Output parms and a ResultSet

Real's [email protected] 7 JDBC 7.16 Stored procedure with Input/Output parms and a ResultSet.......................................321 7.17 Fix incomplete field returned by the ResultSet............................................................322 7.18 Get a record count with a SQL Statement...................................................................322 7.19 Transfer a ResultSet to a JTable.................................................................................323 7.20 List tables in a database..............................................................................................323 7.21 Display ResultSet data in an HTML Table in Servlet...................................................324 7.22 Detect SQL errors or warnings....................................................................................325 7.23 Using DSN−less connection........................................................................................326 7.24 Read data from Excel worksheet.................................................................................327 7.25 Handle Excel files........................................................................................................329 7.26 JDBC−ODBC Excel driver...........................................................................................329 7.27 JExcel..........................................................................................................................329 7.28 POI...............................................................................................................................330 7.29 JXLS............................................................................................................................330 7.30 xlSQL...........................................................................................................................331 7.31 JCOM...........................................................................................................................331 7.32 OpenXLS Java Spreadsheet SDK...............................................................................333 7.33 Specify a CharSet when connecting to a DBMS..........................................................334 7.34 Get current date using JDBC.......................................................................................335 7.35 Enable JDBC logging...................................................................................................335 7.36 Detect if a table exists..................................................................................................337 7.37 Convert a ResultSet to XML........................................................................................337 7.38 Escape special character in a LIKE clause..................................................................339 7.39 Insert the current date..................................................................................................340 7.40 Log the SQL Statements..............................................................................................340 7.41 Plain JDBC Logging.....................................................................................................340 7.42 P6Spy..........................................................................................................................340 7.43 Proxool.........................................................................................................................341 8 JNI................................................................................................................................................342 8.1 java−jni...........................................................................................................................342 8.2 Use native code through JNI..........................................................................................342 8.3 Pass a string to/from Java to/from C..............................................................................342 8.4 Set the computer clock..................................................................................................344 8.5 Determine the signature of a method.............................................................................344 8.6 Use arrays......................................................................................................................346 8.7 Load a DLL....................................................................................................................347 8.8 Use the MouseWheel.....................................................................................................347 8.9 Throw an Exception (from JNI code).............................................................................347 8.10 Throw my own Exception (from JNI code)...................................................................348 8.11 JNI from a package......................................................................................................349 8.12 Make a Window "stay on top"......................................................................................349 8.13 Start a JVM from C......................................................................................................350 8.14 Retrieve environment variable (JNI)............................................................................351 8.15 Get the PID..................................................................................................................351 8.16 Clear the console, set color and cursor position (JNI).................................................352 8.17 Call Windows API (Open source solution)...................................................................355

Real's [email protected] 9 Javascript interaction.................................................................................................................356 9.1 java−js............................................................................................................................356 9.2 * Read me *....................................................................................................................356 9.3 Wake−up a Java applet.................................................................................................356 9.4 Call a Java method from Javascript...............................................................................358 9.5 Calling Java applets methods using DOM and JavaScript............................................360 9.6 Access Java variables from Javascript..........................................................................360 9.7 Call Javascript from a Java applet.................................................................................361 9.8 Create dynamic HTML from a Java applet....................................................................364 9.9 Have Applets on different frames communicates with each other.................................365 9.10 Send a message from an Applet to another Applet on a different page......................366 9.11 Retrieve values from a Java applet for HTML form (CGI)............................................368 9.12 Detect if an Applet is ready..........................................................................................369 9.13 Read/Write HTML field values from JAVA...................................................................370 9.14 Detect if Java is enabled..............................................................................................372 9.15 Detect if Java 1.1 (with event delegation) is available.................................................372 9.16 Access Cookies from a Java Applet............................................................................372 9.17 Set Applet PARAM VALUE from javascript.................................................................375 9.18 Pass an Array between Java and Javascript...............................................................376 9.19 Interaction without LiveConnect...................................................................................378 9.20 Directory listing on the Web server in a Java Applet...................................................382 9.21 Have a Java button close the browser window............................................................384 9.22 Detect if cookies are enabled.......................................................................................385 9.23 Display a page after all applets are loaded..................................................................386 10 Servlet/JSP................................................................................................................................387 10.1 java−jsp........................................................................................................................387 10.2 Read me......................................................................................................................387 10.3 Get parameters passed to a servlet.............................................................................387 10.4 Detect no argument condition in a Servlet...................................................................388 10.5 Set a Cookie from a servlet..........................................................................................389 10.6 Read a Cookie from a servlet......................................................................................389 10.7 Delete (or expire) a Cookie from a servlet...................................................................390 10.8 Ask for a password from a Servlet...............................................................................390 10.9 Talk to a CGI/Servlet....................................................................................................390 10.10 Test for Cookies.........................................................................................................391 10.11 Display ResultSet data in an HTML Table in Servlet.................................................392 10.12 Specify the filename to be used for a file sent by a Servlet.......................................393 10.13 Pass information to another servlet/jsp......................................................................393 10.14 Handle PDF output....................................................................................................394 10.15 Detect if the connection is via a secure channel........................................................394 10.16 In a Servlet, check if Form Field is present................................................................394 10.17 Get the root dir of a web app.....................................................................................395 10.18 Get client IP address from JSP..................................................................................395 10.19 Output a binary stream from a JSP............................................................................395 10.20 Use a connection cache from JSP.............................................................................396 10.21 Read a Web Application property..............................................................................397 10.22 Use EJB from JSP.....................................................................................................398 10.23 Define a method in a JSP page.................................................................................398 10.24 Precompile JSP pages...............................................................................................399

10.25 Get a list of directories for JSP

Real's [email protected] 10 Servlet/JSP 10.25 Get a list of directories for JSP..................................................................................400 10.26 Use and share a class in JSP pages.........................................................................400 10.27 Get the root dir of a web app.....................................................................................402 10.28 Launch an applet from a JSP.....................................................................................402 10.29 Prevent caching of a JSP output................................................................................403 10.30 Call another EJB........................................................................................................403 10.31 Keep java files generated from JSP (BEA WLS).......................................................404 10.32 Get the server version (BEA WLS)............................................................................404 10.33 Quickly create a Web application with BEA WLS......................................................405 10.34 Nicely display WEB.XML informations.......................................................................405 10.35 Reverse the CLASSLOADER order (BEA)................................................................406 10.36 Detect change in JSP and recompile (BEA)..............................................................407 11 Language...................................................................................................................................408 11.1 java−language.............................................................................................................408 11.2 * Read me *..................................................................................................................408 11.3 Obtain from where a Class is loaded...........................................................................409 11.4 Get the class name in a static method.........................................................................410 11.5 Get the current method name......................................................................................410 11.6 Call a method dynamically (Reflection)........................................................................411 11.7 Detect if a package is available...................................................................................413 11.8 Create an object from a string......................................................................................414 11.9 Get a variable value from the variable name...............................................................415 11.10 Make methods that have unspecified number of parameters....................................416 11.11 Create a java source dynamically, compile and call..................................................417 11.12 Launch an application from another application........................................................418 11.13 Access the enclosing class from an inner class.........................................................419 11.14 Access inner class from outside................................................................................420 11.15 Use globally defined constants..................................................................................421 11.16 Serialize an Object.....................................................................................................422 11.17 Serialize an Object over a socket..............................................................................424 11.18 Easily remove my debugging code............................................................................424 11.19 Have a singleton........................................................................................................425 11.20 Multiple expressions in for loops................................................................................426 11.21 Handle the List conflict...............................................................................................426 11.22 Use a generic toString().............................................................................................426 11.23 Use Object.clone().....................................................................................................428 11.24 Static field, constructor and exception.......................................................................429 11.25 Use a Label break......................................................................................................430 11.26 Put printStackTrace() into a String.............................................................................431 11.27 Use a Hashtable........................................................................................................431 11.28 Scan the content of a hashtable................................................................................432 11.29 Sort an array..............................................................................................................432 11.30 Initialize multidimensional array.................................................................................434 11.31 Get array upperbound................................................................................................434 11.32 Convert a String to an array.......................................................................................435 11.33 Sort in reverse order..................................................................................................436 11.34 Resize an array..........................................................................................................436 11.35 Dump array content...................................................................................................437

Real's [email protected] 11 Language 11.36 Initialize a static array................................................................................................438 11.37 Sort an Hashtable......................................................................................................439 11.38 Eliminate "[unchecked] unchecked call ..." compiler warning....................................440 12 ANT............................................................................................................................................442 12.1 Sort on many fields......................................................................................................442 12.2 Optimize Collection usage...........................................................................................444 12.3 Sort an HashMap.........................................................................................................446 12.4 Get a key from value with an HashMap.......................................................................446 12.5 Iterate a Collection and remove an item......................................................................447 12.6 Count distinct elements in a Vector.............................................................................448 12.7 Dump the content of a Collection (JDK 1.5).................................................................450 12.8 Use an INI file (properties)...........................................................................................450 12.9 Load a properties file...................................................................................................452 12.10 Accentuated characters in Properties/ResourceBundle file.......................................452 12.11 Have a multi−line value in a properties file................................................................453 12.12 Use XML with Properties...........................................................................................453 12.13 Use the Registry to store informations (Preferences API).........................................454 12.14 Sort Properties when saving......................................................................................455 13 Networking................................................................................................................................457 13.1 java−net.......................................................................................................................457 13.2 Extract network card address......................................................................................457 13.3 Get the workstation name/ip........................................................................................459 13.4 Find port number not in use.........................................................................................461 13.5 Disable DNS caching...................................................................................................461 13.6 Encode/Decode to/from Base64..................................................................................462 13.7 Using javax.mail.internet.MimeUtility...........................................................................463 13.8 Using Apache Commons Codec..................................................................................463 13.9 MiGBase64..................................................................................................................464 13.10 Lookup using MX record to validate mail server........................................................464 13.11 Send an email using the SMTP protocol....................................................................472 13.12 Check if there is mail waiting.....................................................................................474 13.13 Receive email............................................................................................................475 13.14 Send email with an attachment..................................................................................477 13.15 Send email with JavaMail..........................................................................................483 13.16 Send email with authentication..................................................................................485 13.17 Send HTML mail with images (Javamail)...................................................................486 13.18 Debug a Javamail Program.......................................................................................488 13.19 Send email with SMTPS (eg. Google GMail) (Javamail)...........................................489 13.19.1 Settings for well known mail providers..............................................................490 13.20 Mix plain text and HTML content in a mail.................................................................490 13.21 Read an Outlook MSG file.........................................................................................491 13.22 msgparser..................................................................................................................491 13.23 Apache POI HSMF....................................................................................................492 13.24 jmbox.........................................................................................................................492 13.25 Handle EML file with JavaMail...................................................................................492 13.26 Check if a file was modified on the server.................................................................493 13.27 Check if a page exists................................................................................................494

13.28 Connect through a Proxy

Real's [email protected] 13 Networking 13.28 Connect through a Proxy...........................................................................................495 13.29 Identify yourself using HTTP Authentification............................................................498 13.30 Talk to a CGI/Servlet..................................................................................................500 13.31 Write/Read cookies using HTTP................................................................................501 13.32 Read a GIF or CLASS from an URL save it locally....................................................503 13.33 Resolve a relative URL..............................................................................................504 13.34 File size from URL.....................................................................................................505 13.35 Use the HTTPS protocol............................................................................................505 13.36 Fetch a page from Google.........................................................................................506 13.37 Upload a file to a server.............................................................................................507 13.38 Connect through a Proxy...........................................................................................507 13.39 Have timeout on socket connection...........................................................................510 13.40 Ping a server..............................................................................................................510 13.41 Get the Date from server...........................................................................................511 13.42 Get the client IP address............................................................................................512 13.43 Use the java.net.Socket.setSoLinger method............................................................512 13.44 Use the java.net.Socket.setTcpNoDelay method......................................................513 13.45 Find out who is accessing my ServerSocket.............................................................513 13.46 Transfer a file via Socket...........................................................................................513 14 Security......................................................................................................................................516 14.1 java−security................................................................................................................516 14.2 Encrypt a password.....................................................................................................516 14.3 Create a checksum......................................................................................................518 14.4 Get the user name.......................................................................................................521 14.5 Get username using NT Challenge (NTLM)................................................................521 14.6 Check if the current user belongs a specific Windows group/role...............................523 14.7 Prompt for password from the console........................................................................523 14.8 Prevent XSS exploit.....................................................................................................524 14.9 Sanitize the input by removing suspicious tags...........................................................525 14.10 Sanitize the output by removing suspicious characters.............................................525 14.11 Display a simple username/password Dialog from an Applet....................................526 15 Swing.........................................................................................................................................529 15.1 java−swing...................................................................................................................529 15.2 * Read me *..................................................................................................................529 15.3 Change component default font...................................................................................529 15.4 Repaint problem under the mouse cursor (JDK1.2)....................................................530 15.5 Set the LookAndFeel...................................................................................................530 15.6 Use any LookAndFeel on any plateform......................................................................530 15.7 Use a Timer.................................................................................................................531 15.8 Share ActionEvent handler..........................................................................................531 15.9 Get default values for Swing−based user interface.....................................................533 15.10 Have a systray icon (Windows)..................................................................................534 15.11 Close a JFrame under condition................................................................................536 15.12 Maximize a JFrame....................................................................................................537 15.13 Capture System.out into a JFrame............................................................................538 15.14 Remove the titlebar of JInternalFrame.......................................................................540 15.15 Have borders on a JWindow/JFrame.........................................................................540

Real's [email protected] 15 Swing 15.16 Display HTML in a JScrollPane.................................................................................541 15.17 Use a JOptionPane....................................................................................................542 15.18 Localize a JOptionPane dialog..................................................................................543 15.19 Customize JOptionPane buttons...............................................................................545 15.20 Localize a JFileChooser.............................................................................................545 15.21 Select a directory with a JFileChooser.......................................................................548 15.22 Disable the JFileChooser's "New folder" button.........................................................549 15.23 Validate a filename from a JFileChooser...................................................................550 15.24 Make a JFrame looks like a JDialog..........................................................................552 15.25 Based on JTextField content, enable or disable a JButton........................................553 15.26 Apply special filter to a JtextField...............................................................................553 15.27 Limit JTextField input to a maximum length...............................................................556 15.28 Validate a value on the lostFocus event....................................................................557 15.29 Make sure that my jTextfield has the focus when a JFrame is created.....................559 15.30 Stop the beep on JFormattedTextField......................................................................560 15.31 Right justified JTextfield content................................................................................560 15.32 Set the focus on a particuliar JTextField....................................................................561 15.33 Make JTextField unselectable...................................................................................561 15.34 Use a JTree to navigate in a site...............................................................................562 15.35 Expand or collapse a JTree.......................................................................................568 15.36 Have a popup attached to a JTree.............................................................................570 15.37 Traverse a JTree........................................................................................................572 15.38 Show dotted lines in a JTree......................................................................................574 15.39 Explore directories with a JTree.................................................................................574 15.40 Prevent JTree collapsing...........................................................................................575 15.41 Single selection in a JTree.........................................................................................576 15.42 Reduce JTree children indentation............................................................................576 15.43 Use + or − for JTree Icons.........................................................................................576 15.44 Change the JTable header color................................................................................578 15.45 Double click on a JTable............................................................................................578 15.46 Read a data file into a JTable....................................................................................580 15.47 Disable row selection in a JTable..............................................................................583 15.48 Read a data file into a JTable and reload if data file have changed..........................583 15.49 Hide a column in JTable............................................................................................585 15.50 Scroll a JTable to the last row....................................................................................586 15.51 Transfer a ResultSet to a JTable...............................................................................587 15.52 Have on a JScrollPane/JTable an horizontal JScrollbar............................................587 15.53 Make a JList select an item on doubleclick or the ENTER key..................................588 15.54 Make a JList like a scrolling text display....................................................................589 15.55 Have images in a JList...............................................................................................590 15.56 Add a row and clear a JList........................................................................................592 15.57 Sort a JList.................................................................................................................593 15.58 Double click on a JList...............................................................................................595 15.59 Have a PopUp on a JList...........................................................................................596 15.60 Make a JLabel selectable with the mouse.................................................................597 15.61 Change JLabel background color..............................................................................598 15.62 Bold / Unbold a JLabel...............................................................................................598 15.63 Multi−line JLabel........................................................................................................598 15.64 Underline a string.......................................................................................................598

15.65 Update a JLabel

Real's [email protected] 15 Swing 15.65 Update a JLabel.........................................................................................................599 15.66 Display a blinking JLabel...........................................................................................599 15.67 Set the cursor position in a JTextArea.......................................................................601 15.68 Have Multi−line string in a JToolTip...........................................................................601 15.69 Change Tooltip color..................................................................................................602 15.70 Change a JTooltip font...............................................................................................602 15.71 Keep a JTooltip visible...............................................................................................603 15.72 Display icon associated with an executable...............................................................603 15.73 Have items in JMenubar at rightmost position...........................................................605 15.74 Have an JButton with an Image.................................................................................606 15.75 Trigger a click on a Button.........................................................................................607 16 Thread........................................................................................................................................609 16.1 java−thread..................................................................................................................609 16.2 Pipe the output of a thread to the input of another one................................................609 16.3 Pipe the output of a thread to the input of other threads..............................................611 16.4 Wait the for the completion of a thread........................................................................613 16.5 Control a thread from outside......................................................................................614 16.6 Create a Timer object..................................................................................................615 16.7 Pause the execution....................................................................................................616 16.8 Execute a method at a specified time interval.............................................................616 16.9 Execute a process at regular interval...........................................................................618 16.10 Handle concurrent read/write.....................................................................................619 16.11 Communicate between threads using a Queue.........................................................620 16.12 Get a unique identifier................................................................................................625 16.13 Using java.rmi.dgc.VMID...........................................................................................625 16.14 Using java.util.UUID...................................................................................................625 16.15 Using Apache commons............................................................................................626 16.16 Using java.util.concurrent.AtomicLong.......................................................................626 17 Varia...........................................................................................................................................627 17.1 java−varia....................................................................................................................627 17.2 Use System time to generate unique ID......................................................................627 17.3 Get a unique identifier..................................................................................................627 17.4 Using java.rmi.dgc.VMID.............................................................................................627 17.5 Using java.util.UUID.....................................................................................................628 17.6 Using Apache commons..............................................................................................628 17.7 Using java.util.concurrent.AtomicLong.........................................................................628 17.8 Get the hard disk serial number or Motherboard serial number..................................629 17.9 Motherboard serial number..........................................................................................629 17.10 Hard disk serial number.............................................................................................630 17.11 Sort an array..............................................................................................................631 17.12 Sort a String array......................................................................................................632 17.13 Do a selection sort.....................................................................................................634 17.14 Validate a Social Security Number (canadian)..........................................................635 17.15 Validate a Credit Card Number..................................................................................636 17.16 Obtain from where a Class is loaded.........................................................................639 17.17 Get the class name with or without the package.......................................................640 17.18 See the generated bytecode......................................................................................641

Real's [email protected] 17 Varia 17.19 Self replicating programs...........................................................................................644 17.20 A curiosity (strange Java code)..................................................................................645 17.21 Classic bugs...............................................................................................................646 17.22 Number of the beast!.................................................................................................647 17.23 Preventing multiple instances of an application.........................................................648 17.24 Trap JVM shutdown...................................................................................................651 17.25 Use Java scripting engine (JDK 1.6)..........................................................................651 18 XML............................................................................................................................................653 18.1 java−xml.......................................................................................................................653 18.2 Read me......................................................................................................................653 18.3 Display XML using plain HTML....................................................................................654 18.4 Transform XML into HTML using XSLT.......................................................................655 18.5 Parse using SAX or DOM............................................................................................656 18.6 Parse an XML string....................................................................................................658 18.7 Create an XML document with DOM...........................................................................659 18.8 Attach a stylesheet to an XML file................................................................................661 18.9 Create an XML file and attach an XSL.........................................................................662 18.10 Nicely display WEB.XML informations.......................................................................665 18.11 Serialize an object using XML....................................................................................666 18.12 Convert a flat file to XML (SAX).................................................................................667 18.13 Convert a flat file to XML (DOM)................................................................................669 18.14 Convert a ResultSet to XML......................................................................................672 18.15 Parse with XPath.......................................................................................................674 18.16 Strip extra spaces in a XML string.............................................................................675 18.17 Create an XML file and attach an XSL.......................................................................676 18.18 Use XML with Properties...........................................................................................679 18.19 Change a particular node in XML..............................................................................680 18.20 Create a RSS feed (part 1)........................................................................................681 18.20.1 RSS 2.0.............................................................................................................681 18.20.2 Atom..................................................................................................................682 18.20.3 Creating a feed..................................................................................................683 18.20.4 Creating a feed with Apache Commons Digester.............................................683 18.20.5 Creating a feed with Rome................................................................................685 18.21 Creating an RSS Feed (part 2)..................................................................................686 18.22 Parse a RSS XML file................................................................................................692 18.22.1 Parsing a feed with Apache Commons Digester...............................................692 18.22.2 Parsing a feed with ROME................................................................................693 18.22.3 RSS−UTIL.TLD.................................................................................................694 18.23 Add a Live bookmark.................................................................................................694 18.24 Validate a RSS feed...................................................................................................694 18.25 Attach a CSS to RSS feed.........................................................................................694 19 DEPRECATED...........................................................................................................................697 19.1 java−deprecated..........................................................................................................697 19.2 * Read me * (this howto is deprecated)......................................................................697 19.3 Keep the console open after execution (this howto is deprecated).............................697 19.4 Read the Registry (this howto is deprecated)..............................................................698 19.5 Call a Win API (this howto is deprecated)....................................................................698

19.6 Display a BMP image (this howto is deprecated)

Real's [email protected] 19 DEPRECATED 19.6 Display a BMP image (this howto is deprecated)........................................................700 19.7 Play a WAV audio file (this howto is deprecated)........................................................700 19.8 Detect if the MS JVM is used (this howto is deprecated).............................................701 19.9 Get the latest MS JVM (this howto is deprecated).......................................................701 19.10 Uninstalling the MS JVM (this howto is deprecated)..................................................701 19.11 Wrap a Java class in a COM object (this howto is deprecated).................................702 19.12 Sign an applet (this howto is deprecated)..................................................................704 19.13 Bypass the need for a certificate (this howto is deprecated).....................................704 19.14 Start an executable on the client (this howto is deprecated).....................................705 19.15 Get rid of the message "Warning − unsigned applet window" (this howto is deprecated).........................................................................................................................706 19.16 Read/write a local file from an Applet (this howto is deprecated)..............................706 19.17 Write "other−browser−friendly" code when using the Netscape Capabilities package (this howto is deprecated)....................................................................................707 19.18 Disable the JIT compiler in Netscape or IE (this howto is deprecated)......................708 19.19 Start automatically JAVA when opening Netscape (this howto is deprecated)..........709 19.20 Use Netscape Java Console hidden commands (this howto is deprecated).............709 19.21 Avoid the Netscape "Couldn't connect to '' with origin from 'local−classpath−classes'" message. (this howto is deprecated)........................................709 19.22 Post a message on a newsserver using NNTP protocol (this howto is deprecated).........................................................................................................................710 19.23 Read messages from a newsserver (this howto is deprecated)................................710 19.24 Get a list of headers from a newsgroup (this howto is deprecated)...........................711 19.25 Get a list of all available newsgroup from a newsserver (this howto is deprecated).........................................................................................................................712 19.26 Detect if Swing is installed (this howto is deprecated)...............................................713 19.27 Make Swing always available from Netscape (this howto is deprecated)..................713 20 String/Number...........................................................................................................................714 20.1 java−stringnumber.......................................................................................................714 20.2 * Read me *..................................................................................................................714 20.3 Convert from type X to type Y......................................................................................715 20.4 Strip certain characters from a String..........................................................................717 20.5 Replace/remove character in a String..........................................................................718 20.6 Replace every occurences of a string within a string...................................................719 20.7 "Tokenize" a string.......................................................................................................720 20.8 Split a string using String.split()...................................................................................725 20.9 Optimize String operations...........................................................................................729 20.10 Remove spaces from a string....................................................................................730 20.11 Test if a String starts with a digit or uppercase letter.................................................731 20.12 Get InputStream from a String...................................................................................731 20.13 Easy String padding...................................................................................................732 20.14 Replace \r\n with the
tag....................................................................................732 20.15 Unaccent letters.........................................................................................................733 20.16 Apply a mask to String...............................................................................................735 20.17 Format a String (JDK1.5)...........................................................................................736 20.18 Replace a "\" by "\\"....................................................................................................737 20.19 Substitute tokens in a String......................................................................................738 20.20 Compare accentuated letters.....................................................................................738

Real's [email protected] 20 String/Number 20.21 Create a String with fixed length and filled with a specific character.........................739 20.22 Unquote a String........................................................................................................740 20.23 Escape HTML special characters from a String.........................................................740 20.24 Unescape HTML special characters from a String....................................................742 20.25 Using HashMap.........................................................................................................743 20.26 Using Array................................................................................................................744 20.27 Detect non−ASCII character in a String.....................................................................745 20.28 Remove HTML tags from a file to extract only the TEXT...........................................746 20.29 Using regular expression...........................................................................................746 20.30 Using javax.swing.text.html.HTMLEditorKit...............................................................746 20.31 Convert a byte array to a Hex string..........................................................................747 20.32 Apply proper uppercase and lowercase on a String..................................................748 20.33 Encode/Decode to/from Base64................................................................................749 20.34 Using javax.mail.internet.MimeUtility.........................................................................749 20.35 Using Apache Commons Codec................................................................................750 20.36 MiGBase64................................................................................................................750 20.37 Justify a string with wordwrap....................................................................................750 20.38 Convert from type X to type Y....................................................................................751 20.39 Type conversion (JDK1.5).........................................................................................754 20.40 Round a double..........................................................................................................755 20.41 Display numbers with commas..................................................................................755 20.42 Display numbers in scientific notation........................................................................756 20.43 Display numbers with leading zeroes........................................................................757 20.44 Get a random number................................................................................................758 20.45 Convert an UNSIGNED byte to a JAVA type.............................................................758 20.46 Deal with big−endian and little−endian order.............................................................759 20.47 Pass an integer by reference.....................................................................................760 20.48 Pass floats as string literals to a method...................................................................760 20.49 Get random numbers.................................................................................................760 20.50 Convert number into words........................................................................................761 20.51 Arithmetic with double................................................................................................769 20.52 Detect even/odd number............................................................................................770 20.53 Convert bytes to megabytes......................................................................................770 20.54 Validate a number......................................................................................................771 20.55 Get a unique identifier................................................................................................772 20.56 Using java.rmi.dgc.VMID...........................................................................................772 20.57 Using java.util.UUID...................................................................................................772 20.58 Using Apache commons............................................................................................773 20.59 Using java.util.concurrent.AtomicLong.......................................................................773 20.60 Validate/Convert a number using the current Locale()..............................................773 21 Open Source.............................................................................................................................775 21.1 java−os........................................................................................................................775 21.2 Call Windows API (Open source solution)...................................................................775 21.3 Call COM object...........................................................................................................775 21.4 com4j...........................................................................................................................775 21.5 j−interop.......................................................................................................................776 21.6 j−xchange....................................................................................................................776 21.7 Run JAVA as a Windows service.................................................................................776

21.8 Create entity−relation diagram

Real's [email protected] 21 Open Source 21.8 Create entity−relation diagram.....................................................................................777 21.9 Java Remote desktop tool...........................................................................................777 21.10 Create entity−relation diagram...................................................................................777 21.11 Launch a java program as a Windows EXE file.........................................................778 21.12 WinRun4J..................................................................................................................778 21.13 JSmooth.....................................................................................................................778 21.14 Launch4J...................................................................................................................778 21.15 Handle CSV file..........................................................................................................779 21.16 com.Ostermiller.util CSV Utils....................................................................................779 21.17 opencsv......................................................................................................................779 21.18 ServingXML...............................................................................................................779 21.19 Super CSV.................................................................................................................779 21.20 csvreader...................................................................................................................779 21.21 CSVFile......................................................................................................................779 21.22 FlatPack.....................................................................................................................780 21.23 Handle Excel files......................................................................................................780 21.24 JDBC−ODBC Excel driver.........................................................................................780 21.25 JExcel........................................................................................................................780 21.26 POI.............................................................................................................................781 21.27 JXLS..........................................................................................................................781 21.28 xlSQL.........................................................................................................................782 21.29 JCOM.........................................................................................................................782 21.30 OpenXLS Java Spreadsheet SDK.............................................................................784 21.31 Browse a Queue (JMS/MQ).......................................................................................785 21.32 Convert a .class to .java file (decompiler)..................................................................786 21.33 Jad.............................................................................................................................786 21.34 JadClipse...................................................................................................................786 21.35 JarPlug.......................................................................................................................786 21.36 Deploy an application as only 1 jar............................................................................787 21.37 One−Jar.....................................................................................................................787 21.38 Fat Jar........................................................................................................................787 21.39 Read an Outlook MSG file.........................................................................................787 21.40 msgparser..................................................................................................................787 21.41 Apache POI HSMF....................................................................................................788 21.42 jmbox.........................................................................................................................788 21.43 File/directory polling to detect change.......................................................................789 21.44 jpoller (directory poller)..............................................................................................789 21.45 JNotify........................................................................................................................789 21.46 Java Native Access (JNA).........................................................................................789 21.47 Call native methods in a DLL from Java (NativeCall)................................................789 21.48 Java 7........................................................................................................................789 21.49 The simple (and naive!) approach.............................................................................790 21.50 Create a PDF.............................................................................................................790 21.51 iText...........................................................................................................................790

1 Applet 1.1 java−applet

1.2 Goto to a new URL from an Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0002.html You have to use getAppletContext().showDocument (new URL("http://www.whatever.com"));

or getAppletContext().showDocument (new URL("http://www.whatever.com"),"HTML FRAME ID");

If "HTML frame ID" do not exists then a new browser window will be opened. The following "HTML frame ID" have special meanings : "_self" "_parent" "_top" "_blank"

current frame parent frame base frame new window

For example, we want to display lowres.html page if resolution is 640x480 else the hires.html is used. import java.applet.*; import java.awt.*; import java.net.*; public class whatres extends Applet { public void init() { Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); if (dim.width==640 &dim.height==480) { try { getAppletContext().showDocument (new URL(getCodeBase()+"lowres.html"),"_top"); } catch (Exception ex) {} } else { try { getAppletContext().showDocument (new URL(getCodeBase()+"hires.html"),"_top"); } catch (Exception ex) {} }

1 Applet

} } NOTE: The previous example works only so long as the document was retrieved without specifying an actual document name, since getDocumentBase() returns the full URL including the name of the document. If the document name was specified, you should try something like this or specify the complete URL (thanks to Rob Judd): :

try { String docString = getDocumentBase().toString(); if (docString.endsWith("/")) { getAppletContext().showDocument (new URL(getDocumentBase()+"lowres.html"), "_top"); } else { getAppletContext().showDocument (new URL(getDocumentBase()+"/../lowres.html"), "_top"); } } catch (Exception e) {}

Another example, type a new URL in a textfield, and press a button to go to that page. import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*;

public class GotoURLButton extends Applet implements ActionListener { Button b; TextField t; public void init() { t = new TextField(20); t.setText("http://www.google.com"); add(t); b = new Button("Go to this URL"); add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) { try { getAppletContext().showDocument(new URL(t.getText())); } catch (Exception e) { e.printStackTrace(); } } } }

Try it here.

1 Applet

1.3 Determine the host from where the Applet is loaded Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0003.html import java.applet.*; import java.awt.*; public class FromWhere extends Applet { public void init() { Label label = new Label(getCodeBase().toString()); add(label); // // you can check the value of getCodeBase() // to implements a simple copy protection // scheme. If it's not equals to your // URL then quit. // NOTE : This is not a very strong protection! // } }

Try it here

1.4 Have a scrolling status line Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0010.html /* ScrollStatus.java Optional parameters: message, width Default values: message = "Isn't scrolling text in the status line annoying? " width = 36 Example usage: <param name="message" value="Hello World!"> <param name="width" value="24"> */ import java.util.*; import java.applet.Applet; public class ScrollStatus extends Applet implements Runnable { Thread thread; String message; StringBuffer buffer; int at; int width; public void init(){ message = getParameter("message"); if(message == null) message = " Isn't scrolling text in the status line annoying? ";

1.3 Determine the host from where the Applet is loaded

String ws = getParameter("width"); if(ws == null) { width = 36; } else{ width = Integer.valueOf(ws).intValue(); } if(width < 5 || width > 180) { width = 36; } buffer = new StringBuffer(width); buffer.setLength(width); at = 0; if(message.length() < width) { char buf[] = new char[width]; for(int i = 0; i < width; ++i) { buf[i] = ' '; } message.getChars (0, message.length(), buf, (width − message.length()) / 2); message = new String(buf); } } public void start(){ thread = new Thread(this); thread.start(); } public void stop(){ thread.stop(); } public void scroll(){ int ml = message.length(); int k = at; for(int i = 0; i < width; ++i, ++k){ if(k >= ml) { k = 0; } buffer.setCharAt(i, message.charAt(k)); } getAppletContext().showStatus(buffer.toString()); at++; if(at >= ml) { at = 0; } } public void run(){ while(true){ scroll(); try{ Thread.sleep(25); // wait 25 ms } catch(InterruptedException e){ break; } } } }

1.3 Determine the host from where the Applet is loaded

Try it here.

1.5 Use a search engine Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0011.html import java.applet.Applet; import java.net.*; import java.awt.*; public class SearchApplet extends Applet { TextField searchParameter; Choice searchEngine; Button searchButton; public void init() { setBackground(Color.white); searchParameter = new TextField(20); add(searchParameter); searchEngine = new Choice(); searchEngine.addItem("AltaVista"); searchEngine.addItem("WebCrawler"); searchEngine.addItem("Yahoo"); searchEngine.select(0); add(searchEngine); searchButton = new Button("Search"); add(searchButton); } // JDK1.02 style event handling public boolean action(Event e, Object o) { if (e.target.equals(searchButton)) { try { sendSearch(); } catch (Exception e1) { showStatus("Exception caught:" + e1.toString()); } } return true; } public void sendSearch() throws Exception { String url; String searchString = searchParameter.getText(); if (searchString.equals("")) { showStatus("Must enter a search string"); return; } switch (searchEngine.getSelectedIndex()) { case 0: url = "http://www.altavista.com/web/results?q="; break; case 1: url = "http://msxml.webcrawler.com/info.wbcrwl/search/web/"; break;

1.5 Use a search engine

case 2: url = "http://search.yahoo.com/bin/search?p="; break; default: showStatus("Invalid search engine selected."); return; } // encode the search data url += URLEncoder.encode(searchString); // launch the search engine showStatus("Connecting to search location " + url); getAppletContext().showDocument(new URL(url), "_top"); } }

Try it here. It's not easy to call Google from an Applet but you can do it in application as seen in this HowTo.

1.6 Have an on−screen clock Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0012.html import import import import

java.applet.*; java.awt.*; java.util.*; java.text.*;

public class MyClock extends Applet { MyPanel mp; public void init() { mp = new MyPanel(getParameter("format")); add(mp); } } class MyPanel extends Panel { MyClockThread mct; Color b, f; SimpleDateFormat formatter; String previousDateText = ""; String dateText; MyPanel(String df) { super(); formatter = new SimpleDateFormat(df); validate(); setBackground(new Color(0).black); setForeground(new Color(0).yellow); b = this.getBackground(); f = this.getForeground(); mct = new MyClockThread(this); mct.start(); } public Dimension getPreferredSize() { return new Dimension

1.6 Have an on−screen clock

(this.getFontMetrics(this.getFont()).stringWidth(getNow()) + 25, 30); } public void paint(Graphics g) { if (g != null) { g.setColor(b); g.drawString(previousDateText,10,15); g.setColor(f); dateText = getNow(); g.drawString(dateText,10,15); previousDateText = dateText; } } public String getNow() { return formatter.format(new Date()); } } class MyClockThread extends Thread { MyPanel mp; public MyClockThread(MyPanel a) { mp = a; } public void run() { while (true) { try { mp.repaint(); this.sleep(1000); } catch(InterruptedException e) { } } } } <APPLET CODE="MyClock.class" HEIGHT=25 WIDTH=200>

<APPLET CODE="MyClock.class" HEIGHT=25 WIDTH=200>

<APPLET CODE="MyClock.class" HEIGHT=25 WIDTH=200>

<APPLET CODE="MyClock.class" HEIGHT=25 WIDTH=200>

/BODY/HTML Try it here.

1.6 Have an on−screen clock

1.7 Have Applets on the same page communicate with each other Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0022.html [Applet1_0022.java] import java.awt.*; public class Applet1_0022 extends java.applet.Applet { TextField inputText; Button b; public void init() { setLayout(new FlowLayout()); inputText = new TextField( "", 15 ); b = new Button("Send to Applet 2"); add(inputText); add(b); } // JDK 1.02 style evant handling public boolean action(Event ev, Object arg) { if (ev.target instanceof Button) { String textMsg = inputText.getText().trim(); Applet2_0022 applet2 = (Applet2_0022)getAppletContext().getApplet("applet2"); if ( applet2 != null ) { applet2.append( textMsg ); return true; } else { System.out.println("Applet2 not found?"); return false; } } return false; } }

[Applet2_0022.java] import java.awt.*; public class Applet2_0022 extends java.applet.Applet { TextArea textBox; public void init() { setLayout(new FlowLayout()); textBox = new TextArea( 5, 40 ); add( textBox ); } public void append( String msg ) { textBox.append( msg ); textBox.append( "\n" ); } }

1.7 Have Applets on the same page communicate with each other

[HTML] <APPLET CODE="Applet1_0022.class" NAME="applet1" HEIGHT=200 WIDTH=150> <APPLET CODE="Applet2_0022.class" NAME="applet2" HEIGHT=200 WIDTH=400>

Try it here.

1.8 Have Applets on different frames communicates with each other Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0023.html It is possible to share data between different applets via static variables [HTML (java−0023.html)]

[HTML (java−0023−f1.html AND java−0023−f2.html)] <APPLET CODE="Java0023.class" HEIGHT=200 WIDTH=200>

[JAVA source (Java0023.java)] import java.awt.*; import java.applet.*; public class Java0023 extends Applet { TextField tf; Button a,b; public void init() { setLayout(new FlowLayout()); a = new Button("Send to Message"); b = new Button("Receive from Message"); add(a);

1.8 Have Applets on different frames communicates with each other

add(b); tf = new TextField(20); add(tf); } // JDK 1.02 style evant handling public boolean action(Event e, Object o) { if (e.target instanceof Button) { if (e.target == a) { StaticMessage.message = tf.getText(); } if (e.target == b) { tf.setText(StaticMessage.message); } return true; } return false; } } class StaticMessage { public static String message = ""; }

Try it here. Check this DDJ article for a more elaborate way to implement this principle. There is one way to do it by using a Javascript function as a bridge, take a look at this How−to.

1.9 Send a message from an Applet to another Applet on a different page Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0041.html FirstApplet encodes the message for SecondApplet in the search (or query) section of SecondApplet.html URL. Then SecondApplet decodes the search section of its URL and extract the message coming from FirstApplet. FirstAppletJ.html <APPLET CODE="FirstAppletJ.class" HEIGHT=100 WIDTH=300> /APPLET/BODY/HTML

FirstAppletJ.java import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*;

1.9 Send a message from an Applet to another Applet on a different page

public class FirstAppletJ extends Applet implements ActionListener { Button b; TextField t; public void init() { add(new Label("Message to 2nd applet :")); add(t= new TextField(20)); add(b = new Button("Load 2nd applet")); b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) { try { getAppletContext().showDocument (new URL(getCodeBase(), "SecondAppletJ.html?" + "message=" + URLEncoder.encode(t.getText()))); } catch (Exception e) { e.printStackTrace(); } } } }

SecondAppletJ.html <APPLET CODE="SecondAppletJ.class" HEIGHT=100 WIDTH=400> /APPLET/BODY/HTML

SecondApplet.java import java.applet.*; import java.awt.*; import java.net.*; public class public void Label l = add (l); TextField add(tf);

SecondAppletJ extends Applet { init() { new Label("Message from 1st Applet"); tf = new TextField( 50 );

// complete current URL String s = getDocumentBase().toString(); // extract the search (or query) section String theMessage = s.substring(s.indexOf('?') + 1); // remove message header theMessage = theMessage.substring("message=".length()); // decode the string (incomplete) theMessage = theMessage.replace('+',' '); /* with JDK1.2, the decoding can be done with java.net.URLDecoder.decode(theMessage).

1.9 Send a message from an Applet to another Applet on a different page

you to convert from a MIME format called "x−www−form−urlencoded" to a String To convert to a String, each character is examined in turn: . The ASCII characters 'a' through 'z', 'A' through 'Z', and '0' through '9' remain the same. . The plus sign '+' is converted into a space character ' '. . The remaining characters are represented by 3−character strings which begin with the percent sign, "%xy", where xy is the two−digit hexadecimal representation of the lower 8−bits of the character. */

tf.setText(theMessage); } } You can try it here! NOTE : On IE, you must be connected to the Internet

The decoding is incomplete but should be Ok for simple need! If you need to pass the message via the PARAM tag of the SecondApplet then take a look at this How−to.

1.10 Have an applet launch an other applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0025.html The idea is to load first a small Applet with a quick loading time, display a message to the user and then load a larger Applet. [HTML (testappletloader.html) <APPLET CODE="AppletLoader.class" NAME="AppletLoader" HEIGHT=200 WIDTH=200>

[JAVA source (AppletLoader.java)] import java.applet.Applet; import java.applet.AppletStub; import java.awt.*; public class AppletLoader extends Applet implements Runnable, AppletStub { String appletToLoad; Thread appletThread;

1.10 Have an applet launch an other applet

public void init() { appletToLoad = getParameter("appletToLoad"); setBackground(Color.white); } public void paint(Graphics g) { g.drawString("Loading the Second Applet ...", 30, 30); } public void run() { try { // // REMOVE THIS // for demo purpose only to see // the "loading message! // Thread.sleep(2000); // Class appletClass = Class.forName(appletToLoad); Applet realApplet = (Applet)appletClass.newInstance(); realApplet.setStub(this); setLayout( new GridLayout(1,0)); add(realApplet); realApplet.init(); realApplet.start(); } catch (Exception e) { System.out.println( e ); } validate(); } public void start(){ appletThread = new Thread(this); appletThread.start(); } public void stop() { appletThread.stop(); appletThread = null; } public void appletResize( int width, int height ){ resize( width, height ); } }

[SecondApplet0025.java for demonstration] import java.awt.*; public class SecondApplet0025 extends java.applet.Applet { TextField tf; public void init() { System.out.println("Starting Second applet"); add(new Label("Second Applet")); add(tf = new TextField( 10 ) ); String s = getParameter("SecondAppletParm"); tf.setText(s); } }

1.10 Have an applet launch an other applet

try it here.

1.11 Get the user name Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0048.html In application : String username; username = System.getProperty("user.name");

or in JDK1.5 public class Test { public static void main(String args[]) { com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem(); System.out.println(NTSystem.getName()); } }

In Applet there is no way unless you ask for it or use a signed applet. If you have access to a server−side, something like an ASP page can be used to detect the current NT user name if the client is configured correcty. See this related HowTo for a JSP hack!

1.12 Access parameters passed in the URL Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0049.html import java.applet.*; import java.util.*; public class AppletUrlParams extends Applet { Hashtable searchparms; public void init() { // dump to the console the URL, the search and search values // the URL http://myserver.com/mypage.html?value1=x&value2=y&value3=z // the search value1=x&value2=y&value3=z // the values value1=x // value2=y // value3=z // // then the values are stored in a Hashtable for easy reference. // ex. String name = searchparms.get("value2") doit(); } public void doit() { int i; String completeURL = getDocumentBase().toString();

1.11 Get the user name

System.out.println("Complete URL: " + completeURL); i = completeURL.indexOf("?"); if (i > −1) { String searchURL = completeURL.substring(completeURL.indexOf("?") + 1); System.out.println("Search URL: " + searchURL); StringTokenizer st = new StringTokenizer(searchURL, " while(st.hasMoreTokens()){ String searchValue=st.nextToken(); System.out.println("value :" + searchValue); } initHashtable(searchURL); dumpHashtable(); } } public void initHashtable(String search) { searchparms = new Hashtable(); StringTokenizer st1 = new StringTokenizer(search, " while(st1.hasMoreTokens()){ StringTokenizer st2 = new StringTokenizer(st1.nextToken(), "="); searchparms.put(st2.nextToken(), java.net.URLDecoder.decode(st2.nextToken())); } } public void dumpHashtable() { Enumeration keys = searchparms.keys(); System.out.println("−−−−−−−−"); while( keys.hasMoreElements() ) { String s = (String) keys.nextElement(); System.out.println("key : " + s + " value : " + searchparms.get(s)); } System.out.println("−−−−−−−−"); } }

Test it here. The resultat in the Java console should be : key : firsparam value : Hello key : secondparam value : World key : thirdparam value : Hello World

A note from mm300 Access parameters passed in the URL in line String completeURL = getDocumentBase().toString(); is a trap: NS won't return the whole URL, but only domain name and directory but without .html and parameters. In IE (5.5) it's ok. So: if we have www.domain.com/applets/win.html?winner=Maurice getDocumentBase () will return: NS: www.domain.com/applets/ IE: www.domain.com/applets/win.html?winner=Maurice

1.11 Get the user name

1.13 Convert an Applet to Application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0305.html Take this simple Applet import java.applet.*; import java.awt.*; public class UnderlineText extends Applet{ String s = "Java Howto"; int x=20; int y=50; public void init() { add(new Button("Real's")); } public void paint(Graphics g) { g.drawString(s, x,y); g.drawLine(x , y+2 , x+getFontMetrics(getFont()).stringWidth(s) , y+2 ); } }

You use it with the following HTML

<APPLET CODE=UnderlineText.class WIDTH=100 HEIGHT=100> /HMTL

To be able to use the same class as an application, we simply extend a Panel instead of an Applet, put it in Frame and call the init() method. import java.awt.*; public class UnderlineText extends Panel{ String s = "Java Howto"; int x=20; int y=50; public static void main(String[] args) { Frame f = new Frame(); f.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { System.exit(0); }; }); UnderlineText ut = new UnderlineText(); ut.setSize(100,100); // same size as defined in the HTML APPLET f.add(ut); f.pack(); ut.init(); f.setSize(100,100 + 20); // add 20, seems enough for the Frame title, f.show(); }

1.13 Convert an Applet to Application

public void init() { add(new Button("Real's")); } public void paint(Graphics g) { g.drawString(s, x,y); g.drawLine(x , y+2 , x+getFontMetrics(getFont()).stringWidth(s) , y+2 ); } }

1.14 Change the mouse cursor in Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0228.html [JDK1.0.2] // loop until the browser frame Frame browserFrame; Component parentComponent; parentComponent = getParent(); while ( parentComponent != null && !(parentComponent instanceof Frame)) { parentComponent = parentComponent.getParent(); } browserFrame = (Frame) parentComponent; browserFrame.setCursor(Frame.WAIT_CURSOR); // // // // // // //

CROSSHAIR_CURSOR, DEFAULT_CURSOR, E_RESIZE_CURSOR, HAND_CURSOR MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR; S_RESIZE_CURSOR,SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, W_RESIZE_CURSOR, WAIT_CURSOR

[JDK1.1] // setCursor is supported at the component level setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

1.15 Use an Image as the Applet background Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0233.html import java.applet.Applet; import java.net.*; // // // //

TILE BACKGROUND in the HTML use : PARAM NAME="bgImage" VALUE="images/myImage.jpg" in the APPLET tag

public class Tile extends Applet {

1.14 Change the mouse cursor in Applet

Image bgImage = null; public void init() { try { MediaTracker tracker = new MediaTracker (this); bgImage = getImage (new URL(getCodeBase(), getParameter("bgImage"))); tracker.addImage (bgImage, 0); tracker.waitForAll(); } catch (Exception e) { e.printStackTrace(); } setLayout(new FlowLayout()); add(new Button("Ok")); add(new TextField(10)); } public void update( Graphics g) { paint(g); } public void paint(Graphics g) { if(bgImage != null) { int x = 0, y = 0; while(y < size().height) { x = 0; while(x<size().width) { g.drawImage(bgImage, x, y, this); x=x+bgImage.getWidth(null); } y=y+bgImage.getHeight(null); } } else { g.clearRect(0, 0, size().width, size().height); } } }
<APPLET CODE=Tile.class WIDTH=150 HEIGHT=150> /HMTL

Try it here.

1.16 Handle the new Control Activation mechanism in IE Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0526.html Microsoft has now licensed the technologies from Eolas, removing the click to activate requirement in Internet Explorer. This change will be made part of the next pre−release versions of Windows Vista SP1 and Windows XP SP3. More at IEBlog

1.16 Handle the new Control Activation mechanism in IE

The latest IE patch introduces a new behavior with APPLETS or ActiveX controls on a page. This was done to resolve an issue concerning a patent problem with a company called Eolas. When a web page uses the APPLET, EMBED, or OBJECT elements to load an ActiveX control, the control's user interface is blocked until the user activates it. If a page uses these elements to load multiple controls, each interactive control must be individually activated. A tooltip "Click to activate and use this control" is shown. Then to activate an interactive control, either click it or use the TAB key to set focus on it and then press the SPACEBAR or the ENTER key. Interactive controls loaded from external script files immediately respond to user interaction and do not need to be activated. Check out this Microsoft's white paper on the subject.

1.16.1 Solution #1 The workaround for an APPLET (to bypass the manual activation) is to generate in Javascript the APPLET tag but you need to generate it from an outside JS page! <script src="myapplet.js">

and the myapplet.js is document.write ('')

NOTE If you uncheck the Disable Script Debugging (Internet Explorer) option in the Advanced Tab of the Internet Options Control Panel, controls will still require activation. NOTE: While inactive controls do not respond to direct user interaction; they do respond to script commands. Try a page with the regular APPLET tag here. And now the same APPLET but with an external JS file here. Both on the same page (same Applet), here!

The workaround suggested by Microsoft is fine with static APPLET tag but if your APPLET tag needs to be generated by a JSP ou Servlet (to adjust the PARAM parameters for example) then you're out of luck because the APPLET declaration is in a JS file which is a static file.

1.16.2 Solution #2 As seen in this article, all you need is to change the content from an outside file. So you need a generic JS function to rewrite the APPLET tag with the original and that's it! The main HTML (in BODY tag we call our "rewrite" function) :

1.16.1 Solution #1

This example "rewrite" the applet tag from an external JS. This way you can generate the Applet tag from a JSP like before.

<script language="Javascript1.2" src="./rewriteapplet.js"> <APPLET CODE="TextFieldWithLimitApplet.class" HEIGHT=100 WIDTH=300>

The generic JS routine to rewrite all APPLET tags. [rewriteapplet.js] function rewriteApplet() { var v=document.getElementsByTagName("applet"); for(i=0;i
Try it here! The same principle can be used for the OBJECT tag. This site http://www.ediy.co.nz/internet−explorer−flash−applet−activation−fix−xidc19237.html offers a really small JS script (only 292 bytes long) to handle the situation. IMPORTANT NOTES : • AFAIK, this trick does not work from a FRAME! • If you have PARAM tags associated with the applet then they will be replaced by two strange PARAMS (_CX and _CY)! So beware... It looks that this behaviour has something to do with the fact that the Java plugin is an ActiveX. Pre−XP SP2 installation are not supposed to do that kind of substitution (not verified!). • For simple applet with no param, this is an interesting generic solution.

1.16.3 Solution #3 This solution is a little bit ugly but there is no better solution when you have dynamic APPLET PARAM generated on the server−side. The requirement is to write only the APPLET tag from an outside JS file, the PARAMS can be handled by the main page like before! The trick is to have 2 external JS function, one to write the <APPLET> tag (and the static PARAM if any) and a second function to write the . The enclosed dynamic PARAM parameters are generated by the JSP (ASP page). [rewriteapplet.js] function writeHeader(urlApplet) { document.write ('') document.write

1.16.3 Solution #3

('

')

} function writeFooter() { document.write('
') }

The JSP or ASP ... <script language="Javascript1.2" src="<%= CONTEXT_PATH %>/scripts/rewriteapplet.js"> /script ... <script> writeHeader('<%=urlApplet %>'); <% if(resultVB.isObjectInResult(idObject)) { int i = 1; Iterator itPages = pages.iterator(); while (itPages.hasNext()) { String url = (String) itPages.next(); %> <% i++; } } else { %> <% } %> <script> writeFooter(); /script If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2007 [ home ]

1.17 Pass parameters to the Applet JVM (WIN) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0531.html It's possible to pass some parameters to the JVM in Applet but these have to be set in the browser and cannot be controlled by your applet. Each user that loads your applet has to adjust the JVM args themselves. Open the Java control panel (in Windows: Start > Control Panel > Java) and select the Java tab. Press View button of the Applet Runtime Settings, and add the required parameters in the 4th 1.17 Pass parameters to the Applet JVM (WIN)

column, it is editable event if it's grayed. You have to make sure that that the parameter you supply are correct, otherwise your browser will die when it tries to open the first applet. This can be useful to set a JVM property to resolve a compatibilty problem with graphic card like in this bug report : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4839812. You can force the language used in the Java console. In java control panel − java tab, you set a parameter for JRE Applet runtime. • Specify −Duser.language=en to override the default locale in java control panel −> java tab, you set a parameter for JRE Applet runtime.

1.18 See the Java Console Window Log (Java plugin) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0533.html The Java Console Window Log is also stored on disk. On the Windows plateform, it's in the folder : C:\Documents and Settings\ <username>\ Application Data\ Sun\ Java\ Deployment\ log

It's a file with the extension .trace If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ] 1.18 See the Java Console Window Log (Java plugin)

1.19 Display debugging infos for an Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0597.html Make sure that all browsers and JRE are closed. Start the Java Configuration Panel via Start−Parameters or you can launch C:\Program Files\Java\jre[version]\bin\javacpl.exe. On the Java tab, click to set the parameter for the applet runtime (plugin). Now add the following parameters in the column parameters. −Djavaplugin.trace=true −Djavaplugin.trace.option=basic|net|security|ext|liveconnect

Next, on the Advanced tab, select Java Console −> Display the console. The next time when loading an applet, the java console will display with a full trace. The log is stored in a file. For Windows, the file is C:\Documents and Settings\[YourAccount]\Application Data\Sun\Java\Deployment\log\plugin[version].log/trace

1.20 Have an invisible Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0620.html See this interesting article : http://windyroad.org/2006/08/14/reintroducing−javascript−and−hidden−applets−jaha/ The recommended way is to a CSS style to hide the Applet,

.. or you can insert your Applet into an invisible frame. See this HowTo for an example.

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

1.19 Display debugging infos for an Applet

2 Date and Time 2.1 java−date

2.2 Have year on 4 digits from a Date object Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0096.html You need to add 1900 to it to get the 4 digit year. int year = myDate.getYear() + 1900;

The getYear() method returns the number of years elapsed after the year 1900. So for year 2000, mydate.getYear() will return 100. So 100 + 1900 = 2000.

2.3 Get the current Date and Time Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0106.html import java.util.Calendar; import java.text.SimpleDateFormat; public class DateUtils { public static final String DATE_FORMAT_NOW = "yyyy−MM−dd HH:mm:ss"; public static String now() { Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW); return sdf.format(cal.getTime()); } public static void main(String arg[]) { System.out.println("Now : " + DateUtils.now()); } }

Here some formatting possibilities available through the SimpleDateFormat class. import java.util.Calendar; import java.text.SimpleDateFormat; public class DateUtils {

public static String now(String dateFormat) { Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); return sdf.format(cal.getTime());

2 Date and Time

} public static void main(String arg[]) { System.out.println(DateUtils.now("dd MMMMM yyyy")); System.out.println(DateUtils.now("yyyyMMdd")); System.out.println(DateUtils.now("dd.MM.yy")); System.out.println(DateUtils.now("MM/dd/yy")); System.out.println(DateUtils.now("yyyy.MM.dd G 'at' hh:mm:ss z")); System.out.println(DateUtils.now("EEE, MMM d, ''yy")); System.out.println(DateUtils.now("h:mm a")); System.out.println(DateUtils.now("H:mm:ss:SSS")); System.out.println(DateUtils.now("K:mm a,z")); System.out.println(DateUtils.now("yyyy.MMMMM.dd GGG hh:mm aaa")); } } Thanks to T. Guirado for the idea.

2.4 Compute days between 2 dates Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0097.html One technique is to compute by hand the number of milliseconds between two dates and then convert the result in days. import java.util.*;

public class DateUtils { private DateUtils() { } static final long ONE_HOUR = 60 * 60 * 1000L; public static long daysBetween(Date d1, Date d2){ return ( (d2.getTime() − d1.getTime() + ONE_HOUR) / (ONE_HOUR * 24)); } /* testing */ public static void main(String[] args) { java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd"); Calendar first = Calendar.getInstance(); first.set(2008, Calendar.AUGUST, 1); Calendar second = Calendar.getInstance(); System.out.println (daysBetween(first.getTime(),second.getTime()) + " day(s) between " + sdf.format(first.getTime()) + " and " + sdf.format(second.getTime())); /* * output : * 21 day(s) between 20080801 and 20080822 */ }

2.4 Compute days between 2 dates

} NOTE: The daysBetween() method works only on Dates set at midnight. One hour (known as the "fudge" factor) is added to the 2 Dates passed as parameters to take in account the possible DLS (Day Light Saving) one hour missing.

Another way would be to compute the julian day number of both dates and then do the substraction. See this HowTo. Thanks to P. Hill for the tip. The package java.util.concurrent.TimeUnit; provides a class to make conversion between milliseconds and days easier. import java.util.*; import java.util.concurrent.TimeUnit; public class DateUtils { private DateUtils() { } public static long getDifference(Calendar a, Calendar b, TimeUnit units) { return units.convert(b.getTimeInMillis()− a.getTimeInMillis(), TimeUnit.MILLISECONDS); } /* testing */ public static void main(String[] args) { java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd"); Calendar first = Calendar.getInstance(); first.set(2008, Calendar.AUGUST, 1); Calendar second = Calendar.getInstance(); System.out.println (getDifference(first,second,TimeUnit.DAYS) + " day(s) between " + sdf.format(first.getTime()) + " and " + sdf.format(second.getTime())); /* * output : * 21 day(s) between 20080801 and 20080822 */ } }

2.5 Get the number of days in a month Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0098.html public static int daysInMonth(GregorianCalendar c) { int [] daysInMonths = {31,28,31,30,31,30,31,31,30,31,30,31}; daysInMonths[1] += c.isLeapYear(c.get(GregorianCalendar.YEAR)) ? 1 : 0; return daysInMonths[c.get(GregorianCalendar.MONTH)]; }

Actually, the Calendar class provides a method to that very simply. For a given Calendar or GregorianCalendar object : 2.5 Get the number of days in a month

calObject.getActualMaximum(calobject.DAY_OF_MONTH)

In the Java API documentation there is a note saying that The version (getActualMaximum()) of this function on Calendar uses an iterative algorithm to determine the actual maximum value for the field. There is almost always a more efficient way to accomplish this (in most cases, you can simply return getMaximum()). GregorianCalendar overrides this function with a more efficient implementation. So it looks like it's a lot more efficient to call getActualMaximum from a GregorianCalendar object than a Calendar object. (Thanks to P. Harris for the tip) gregCalObject.getActualMaximum(gregCalObject.DAY_OF_MONTH)

2.6 Validate a date Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0099.html

2.6.1 Using DateFormat import java.text.*; public class DateUtils { public static boolean isValidDateStr(String date) { try { DateFormat df = DateFormat.getDateInstance (DateFormat.SHORT); // YYYY−MM−DD df.setLenient(false); // this is important! df.parse(date); } catch (ParseException e) { return false; } catch (IllegalArgumentException e) { return false; } return true; } public static void main(String[] args) { System.out.println(" 1900−12−13 valid ? " + DateUtils.isValidDateStr("1900−12−13")); // "1990−12/13" throws a ParseException System.out.println(" 1900−12/13 valid ? " + DateUtils.isValidDateStr("1900−12/13")); // "1990−13−12" throws a IllegalArgumentException System.out.println(" 1900−13−12 valid ? " + DateUtils.isValidDateStr("1900−13−12")); /* * output : * 1900−12−13 valid ? true * 1900−12/13 valid ? false * 1900−13−12 valid ? false */ } }

2.6 Validate a date

Using SimpleDateFormat package com.rgagnon.howto; import java.text.*; public class DateUtils { public static boolean isValidDateStr(String date, String format) { try { SimpleDateFormat sdf = new SimpleDateFormat(format); sdf.setLenient(false); sdf.parse(date); } catch (ParseException e) { return false; } catch (IllegalArgumentException e) { return false; } return true; } public static void main(String[] args) { System.out.println(" 1900−12−13 valid ? " + DateUtils.isValidDateStr("1900−12−13","yyyy−MM−dd")); // "1990−12/13" throws a ParseException System.out.println(" 1900−12/13 valid ? " + DateUtils.isValidDateStr("1900−12/13","yyyy−MM−dd")); // "1990−13−12" throws a IllegalArgumentException System.out.println(" 1900−13−12 valid ? " + DateUtils.isValidDateStr("1900−13−12","yyyy−MM−dd")); /* * output : * 1900−12−13 valid ? true * 1900−12/13 valid ? false * 1900−13−12 valid ? false */ } }

2.6.2 Using GregorianCalendar import java.util.*; public class jtest { public static void main(String args[]) { try { GregorianCalendar gc = new GregorianCalendar(); gc.setLenient(false); // must do this gc.set(GregorianCalendar.YEAR, 2003); gc.set(GregorianCalendar.MONTH, 42);// invalid month gc.set(GregorianCalendar.DATE, 1); gc.getTime(); // exception thrown here } catch (Exception e) { e.printStackTrace(); } } }

2.6.2 Using GregorianCalendar

2.7 Determine to day of the week Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0100.html For the day of the week for today : GregorianCalendar newCal = new GregorianCalendar( ); int day = newCal.get( Calendar.DAY_OF_WEEK );

For the day of the week for any date : Calendar newCal = new GregorianCalendar(); newCal.set(1997, 2, 1, 0, 0, 0); // BUG fix in Calendar class! newCal.setTime(newCal.getTime()); int day = newCal.get(Calendar.DAY_OF_WEEK); /* also available : newCal.get( Calendar.DAY_OF_MONTH ) newCal.get( Calendar.DAY_OF_WEEK_IN_MONTH ) newCal.get( Calendar.DAY_OF_YEAR ) newCal.get( Calendar.DATE ) */

2.8 Add/Substract Day/Month/Year to a Date Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0101.html add() and roll() are used to add or substract values to a Calendar object. You specify which Calendar field is to be affected by the operation (Calendar.YEAR, Calendar.MONTH, Calendar.DATE). add() adds or substracts values to the specified Calendar field, the next larger field is modified when the result makes the Calendar "rolls over". String DATE_FORMAT = "yyyy−MM−dd"; java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(DATE_FORMAT); Calendar c1 = Calendar.getInstance(); c1.set(1999, 0 , 20); // 1999 jan 20 System.out.println("Date is : " + sdf.format(c1.getTime())); c1.add(Calendar.DATE,20); System.out.println("Date + 20 days is : " + sdf.format(c1.getTime()));

To substract, simply use a negative argument. roll() does the same thing except you specify if you want to roll up (add 1) or roll down (substract 1) to the specified Calendar field. The operation only affects the specified field while add() adjusts other Calendar fields. See the following example, roll() makes january rolls to december in the same 2.7 Determine to day of the week

year while add() substract the YEAR field for the correct result. String DATE_FORMAT = "yyyy−MM−dd"; java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(DATE_FORMAT); Calendar c1 = Calendar.getInstance(); // roll down the month c1.set(1999, 0 , 20); // 1999 jan 20 System.out.println("Date is : " + sdf.format(c1.getTime())); c1.roll(Calendar.MONTH, false); // roll down, substract 1 month System.out.println ("Date roll down 1 month : " + sdf.format(c1.getTime())); // 1999 jan 20 c1.set(1999, 0 , 20); // 1999 jan 20 System.out.println("Date is : " + sdf.format(c1.getTime())); c1.add(Calendar.MONTH, −1); // substract 1 month System.out.println ("Date minus 1 month : " + sdf.format(c1.getTime())); // 1998 dec 20

Thanks to P. Rehley for the bug fix.

2.9 Get the correct TimeZone on DateFormat Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0102.html There is a bug in the DateFormat/SimpleDateFormat classes. We must set the TimeZone manually. System.out.println("Good TimeZone from Calendar : " + Calendar.getInstance().getTimeZone().getID()); DateFormat df = DateFormat.getDateInstance(); System.out.println("Bad TimeZone from DateFormat : " + df.getTimeZone().getID()); // fix the TimeZone df.setCalendar(Calendar.getInstance()); System.out.println("Good TimeZone from DateFormat : " + df.getTimeZone.getID());

2.10 Simply format a date as "YYYYMMDD" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0103.html The format "YYYYMMDD" can be useful when sorting records or comparing 2 dates. public static String getStrDate(GregorianCalendar c) { int m = c.get(GregorianCalendar.MONTH) + 1; int d = c.get(GregorianCalendar.DATE); String mm = Integer.toString(m); String dd = Integer.toString(d); return "" + c.get(GregorianCalendar.YEAR) + (m < 10 ? "0" + mm : mm) + (d < 10 ? "0" + dd : dd); }

2.9 Get the correct TimeZone on DateFormat

Thanks to Vladimir Garmaev for the bug fix

Or you can use the SimpleDateFormat from the java.text package. import java.util.Calendar; import java.text.SimpleDateFormat; public class TestDate { public static void main(String args[]){ String DATE_FORMAT = "yyyyMMdd"; SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); Calendar c1 = Calendar.getInstance(); // today System.out.println("Today is " + sdf.format(c1.getTime())); } }

2.11 Compare 2 dates Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0104.html import java.util.*; import java.util.*; import java.text.*; public class TestDate { public static void main(String args[]){ String DATE_FORMAT = "yyyy−MM−dd"; java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(DATE_FORMAT); Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); // remember months are zero−based : 0 jan 1 feb ... c1.set(1999, 11 , 31); c2.set(1999, 0 , 30); System.out.print(sdf.format(c1.getTime())); if (c1.before(c2)) { System.out.print(" is before "); } if (c1.after(c2)) { System.out.print(" is after "); } if (c1.equals(c2)) { System.out.print(" same as "); } System.out.println(sdf.format(c2.getTime())); } }

2.12 Parse a String to obtain a Date/GregorianCalendar object Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0105.html 2.11 Compare 2 dates

import import import import

java.util.Date; java.util.Locale; java.util.Calendar; java.text.SimpleDateFormat;

public class DateUtils { public static Calendar parseTimestamp(String timestamp) throws Exception { /* ** we specify Locale.US since months are in english */ SimpleDateFormat sdf = new SimpleDateFormat ("dd−MMM−yyyy HH:mm:ss", Locale.US); Date d = sdf.parse(timestamp); Calendar cal = Calendar.getInstance(); cal.setTime(d); return cal; } public static void main (String a[]) throws Exception{ String timestampToParse = "24−Feb−1998 17:39:35"; System.out.println("Timestamp : " + timestampToParse); SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy−MM−dd HH:mm:ss"); System.out.println("Calendar : " + sdf.format(parseTimestamp(timestampToParse).getTime())); /* output : Timestamp : 24−Feb−1998 17:39:35 Calendar : 1998−02−24 17:39:35 */ } }

2.13 Use System time to generate unique ID Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0385.html Since the granulaty of a PC can be as high as 55ms (down to 10ms), you can't use the System time to generate a unique ID because of the risk of getting duplicated IDs. This can be solved by using the following technique to make sure that the number returned is unique (in a single JVM). public class UniqueID { static long current= System.currentTimeMillis(); static public synchronized long get(){ return current++; } }

See also this HowTo

2.13 Use System time to generate unique ID

2.14 Get the day name Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0403.html import java.util.*; import java.text.SimpleDateFormat; import java.text.DateFormat;

public class GetDayName { public static void main(String[] args) { Date date1 = (new GregorianCalendar (1989, Calendar.OCTOBER, 17)).getTime(); Date date2 = new Date(); System.out.println ("1989−10−17 was a " + sayDayName(date1)); System.out.println("Today is a " + sayDayName(date2)); } public static String sayDayName(Date d) { DateFormat f = new SimpleDateFormat("EEEE"); try { return f.format(d); } catch(Exception e) { e.printStackTrace(); return ""; } } }

An alternate way : import import import import

java.util.Calendar; java.text.SimpleDateFormat; java.text.DateFormat; java.text.DateFormatSymbols;

public class GetDayName { public static void main(String[] args) { String dayNames[] = new DateFormatSymbols().getWeekdays(); Calendar date2 = Calendar.getInstance(); System.out.println("Today is a " + dayNames[date2.get(Calendar.DAY_OF_WEEK)]); } }

2.15 Find the current date format Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0413.html import java.text.*;

2.14 Get the day name

import java.util.*; public class Dtest { public static void main(String args[]) { SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT); System.out.println("The short date format is " + df.toPattern()); Locale loc = Locale.ITALY; df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, loc); System.out.println("The short date format is " + df.toPattern()); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content. Written and compiled by Réal Gagnon ©1998−2005 [ home ]

2.16 Get a julian date Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0506.html A Julian date is the number of elapsed days since the beginning of a cycle of 7,980 years invented by Joseph Scaliger in 1583. The purpose of the system is to make it easy to compute an integer (whole number) difference between one calendar date and another calendar date. The starting point for the first Julian cycle began on January 1, 4713 B.C. nd will end on January 22, 3268 (3268−01−22 G). The following day will begin the first day of the second Julian date period (or 7,980 year cycle). import java.util.Calendar; public class JulianDate { /** * Returns the Julian day number that begins at noon of * this day, Positive year signifies A.D., negative year B.C. * Remember that the year after 1 B.C. was 1 A.D. * * ref : * Numerical Recipes in C, 2nd ed., Cambridge University Press 1992 */ // Gregorian Calendar adopted Oct. 15, 1582 (2299161) public static int JGREG= 15 + 31*(10+12*1582); public static double HALFSECOND = 0.5; public static double toJulian(int[] ymd) { int year=ymd[0]; int month=ymd[1]; // jan=1, feb=2,... int day=ymd[2]; int julianYear = year; if (year < 0) julianYear++; int julianMonth = month; if (month > 2) { julianMonth++; } else { julianYear−−; julianMonth += 13;

2.16 Get a julian date

} double julian = (java.lang.Math.floor(365.25 * julianYear) + java.lang.Math.floor(30.6001*julianMonth) + day + 1720995.0); if (day + 31 * (month + 12 * year) >= JGREG) { // change over to Gregorian calendar int ja = (int)(0.01 * julianYear); julian += 2 − ja + (0.25 * ja); } return java.lang.Math.floor(julian); } /** * Converts a Julian day to a calendar date * ref : * Numerical Recipes in C, 2nd ed., Cambridge University Press 1992 */ public static int[] fromJulian(double injulian) { int jalpha,ja,jb,jc,jd,je,year,month,day; double julian = injulian + HALFSECOND / 86400.0; ja = (int) injulian; if (ja>= JGREG) { jalpha = (int) (((ja − 1867216) − 0.25) / 36524.25); ja = ja + 1 + jalpha − jalpha / 4; } jb = ja + 1524; jc = (int) (6680.0 + ((jb − 2439870) − 122.1) / 365.25); jd = 365 * jc + jc / 4; je = (int) ((jb − jd) / 30.6001); day = jb − jd − (int) (30.6001 * je); month = je − 1; if (month > 12) month = month − 12; year = jc − 4715; if (month > 2) year−−; if (year <= 0) year−−; return new int[] {year, month, day}; } public static void main(String args[]) { // FIRST TEST reference point System.out.println("Julian date for May 23, 1968 : " + toJulian( new int[] {1968, 5, 23 } )); // output : 2440000 int results[] = fromJulian(toJulian(new int[] {1968, 5, 23 })); System.out.println ("... back to calendar : " + results[0] + " " + results[1] + " " + results[2]); // SECOND TEST today Calendar today = Calendar.getInstance(); double todayJulian = toJulian (new int[]{today.get(Calendar.YEAR), today.get(Calendar.MONTH)+1, today.get(Calendar.DATE)}); System.out.println("Julian date for today : " + todayJulian); results = fromJulian(todayJulian); System.out.println ("... back to calendar : " + results[0] + " " + results[1] + " " + results[2]); // THIRD TEST double date1 = toJulian(new int[]{2005,1,1});

2.16 Get a julian date

double date2 = toJulian(new int[]{2005,1,31}); System.out.println("Between 2005−01−01 and 2005−01−31 : " + (date2 − date1) + " days"); /* expected output : Julian date for May 23, 1968 : 2440000.0 ... back to calendar 1968 5 23 Julian date for today : 2453487.0 ... back to calendar 2005 4 26 Between 2005−01−01 and 2005−01−31 : 30.0 days */ } }

There is a lot of variation around the idea of a "Julian date". You can have the Modified Julian Date (JD) or the Truncated Julian Date (TJD). The main difference is the starting for counting the days. Before Y2K, many applications (especially mainframe systems) were storing dates in a format called "the Julian format". This format is a 5 digit number, consisting of a 2 digit year and a 3 digit day−of−year number. For example, 17−July−1998 is stored as 98221, since 17−July is the 221th day of the year. This format is not really useful since Y2K! The main reason for using the 5−digits Julian date was to save disk space and still have a format easy to use to handle dates. If you find this article useful, consider making a small donation to show your support for this Web site and its content. Written and compiled by Réal Gagnon ©1998−2005 [ home ]

2.17 Calculate the age Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0547.html import java.util.GregorianCalendar; import java.util.Calendar; public class CalcAge { public static void main(String [] args) { // remember ... months are 0−based : jan=0 feb=1 ... System.out.println ("1962−11−11 : " + age(1962,10,11)); System.out.println ("1999−12−03 : " + age(1999,11,3)); } private static int age(int y, int m, int d) { Calendar cal = new GregorianCalendar(y, m, d); Calendar now = new GregorianCalendar(); int res = now.get(Calendar.YEAR) − cal.get(Calendar.YEAR); if((cal.get(Calendar.MONTH) > now.get(Calendar.MONTH)) || (cal.get(Calendar.MONTH) == now.get(Calendar.MONTH) &cal.get(Calendar.DAY_OF_MONTH) > now.get(Calendar.DAY_OF_MONTH))) { res−−; } return res;

2.17 Calculate the age

} }

2.18 Format a duration in ms into a string as "Days,Hours,minutes and seconds" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0585.html public class TimeUtils { public public public public

final final final final

static static static static

long long long long

ONE_SECOND ONE_MINUTE ONE_HOUR ONE_DAY

= = = =

1000; ONE_SECOND * 60; ONE_MINUTE * 60; ONE_HOUR * 24;

private TimeUtils() { } /** * converts time (in milliseconds) to * "<w> days, <x> hours, minutes and (z) seconds" */ public static String millisecondToDHMS(long duration) { String res = ""; long temp = 0; if (duration >= ONE_SECOND) { temp = duration / ONE_DAY; if (temp > 0) { res = temp + " day"; if (temp > 1) { res += "s"; } duration −= temp * ONE_DAY; if (duration >= ONE_MINUTE) { res += ", "; } } temp = duration / ONE_HOUR; if (temp > 0) { res += temp + " hour"; if (temp > 1) { res += "s"; } duration −= temp * ONE_HOUR; if (duration >= ONE_MINUTE) { res += ", "; } } temp = duration / ONE_MINUTE; if (temp > 0) { res += temp + " minute"; if (temp > 1) { res += "s"; } duration −= temp * ONE_MINUTE;

2.18 Format a duration in ms into a string as "Days,Hours,minutes and seconds"

if(duration >= ONE_SECOND) { res += " and "; } } temp = duration / ONE_SECOND; if (temp > 0) { res += temp + " second"; if (temp > 1) { res += "s"; } } return res; } else { return "0 second"; } } public static void main (String args []) { System.out.println(millisecondToDHMS(123)); System.out.println(millisecondToDHMS((5* ONE_SECOND) + 123)); System.out.println(millisecondToDHMS(ONE_DAY + ONE_HOUR)); System.out.println(millisecondToDHMS (ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE))); System.out.println(millisecondToDHMS ((4*ONE_DAY) + (3*ONE_HOUR) + (2 * ONE_MINUTE) + ONE_SECOND)); System.out.println(millisecondToDHMS ((5*ONE_DAY) + (4*ONE_HOUR) + ONE_MINUTE + (2 * ONE_SECOND) + 123)); /* output : 0 second 5 seconds 1 day, 1 hour 1 day, 1 hour, 2 minutes 4 days, 3 hours, 2 minutes and 1 second 5 days, 4 hours, 1 minute and 2 seconds */ } }

2.19 Get the atomic time Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0589.html We connect to a publicly accessible time server on the internet and parse the result. List of available time servers : http://tf.nist.gov/service/time−servers.html NOTE : All users should ensure that their software NEVER queries a server more frequently than once every 4 seconds. Systems that exceed this rate will be refused service. In extreme cases, systems that exceed this limit may be considered as attempting a denial−of−service attack. import import import import

java.io.*; java.text.*; java.util.*; java.net.*;

2.19 Get the atomic time

public final class DateUtils { // NIST, Boulder, Colorado (time−a.timefreq.bldrdoc.gov) public static final String ATOMICTIME_SERVER="http://132.163.4.101:13"; // NIST, Gaithersburg, Maryland (time−a.nist.gov) // public static final String ATOMICTIME_SERVER="http://129.6.15.28:13"; public final static GregorianCalendar getAtomicTime() throws IOException{ BufferedReader in = null; try { URLConnection conn = new URL(ATOMICTIME_SERVER).openConnection(); in = new BufferedReader (new InputStreamReader(conn.getInputStream())); String atomicTime; while (true) { if ( (atomicTime = in.readLine()).indexOf("*") > −1) { break; } } System.out.println("DEBUG : " + atomicTime); String[] fields = atomicTime.split(" "); GregorianCalendar calendar = new GregorianCalendar(); String[] date = fields[1].split("−"); calendar.set(Calendar.YEAR, 2000 + Integer.parseInt(date[0])); calendar.set(Calendar.MONTH, Integer.parseInt(date[1])−1); calendar.set(Calendar.DATE, Integer.parseInt(date[2])); // deals with the timezone and the daylight−saving−time TimeZone tz = TimeZone.getDefault(); int gmt = (tz.getRawOffset() + tz.getDSTSavings()) / 3600000; System.out.println("DEBUG : " + gmt); String[] time = fields[2].split(":"); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]) + gmt); calendar.set(Calendar.MINUTE, Integer.parseInt(time[1])); calendar.set(Calendar.SECOND, Integer.parseInt(time[2])); return calendar; } catch (IOException e){ throw e; } finally { if (in != null) { in.close(); } } } public static void main(String args[]) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy−MM−dd HH:mm:ss"); System.out.println("Atomic time : " + sdf.format(DateUtils.getAtomicTime().getTime())); } /* ref : http://www.bldrdoc.gov/doc−tour/atomic_clock.html 49825 95−04−18 22:24:11 50 0 0 50.0 UTC(NIST) * |

2.19 Get the atomic time

|

|

| | |

|

|

|

These are the last + five digits of the Modified Julian Date

| | | |

| | | |

| | | |

| | | |

| | | |

| | | |

| | | |

| | | |

Year, Month and Day // thanks to TrueJavaProgrammer for the idea!

It's not possible to set your local computer clock in pure Java. You need to use an external utility provided by the OS or call a JNI routine, see this HowTo.

2.20 Get a date interval Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0611.html This HowTo computes a date interval based on the current date or given reference date. The returned interval can be the previous week ou the previous month relative to the given reference date. import java.text.*; import java.util.*; public class DateUtils { public enum IntervalType { private DateUtils() {

Month, Week

}

}

public static Calendar[] getDateIntervals(IntervalType type, Calendar reference) { if (reference == null) { reference = Calendar.getInstance(); } Calendar startDate = (Calendar)reference.clone(); Calendar endDate = (Calendar)reference.clone(); if (type == IntervalType.Month) { // first date of the month startDate.set(Calendar.DATE, 1); // previous month startDate.add(Calendar.MONTH, −1); // first date of the month endDate.set(Calendar.DATE, 1); // previous month, last date endDate.add(Calendar.DATE, −1); } else { // previous week by convention (monday ... sunday) // you will have to adjust this a bit if you want // sunday to be considered as the first day of the week. // start date : decrement until first sunday then // down to monday int dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK); while (dayOfWeek != Calendar.SUNDAY) { startDate.add(Calendar.DATE, −1);

2.20 Get a date interval

dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK); } while (dayOfWeek != Calendar.MONDAY) { startDate.add(Calendar.DATE, −1); dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK); } // end date , decrement until the first sunday dayOfWeek = endDate.get(Calendar.DAY_OF_WEEK); while (dayOfWeek != Calendar.SUNDAY) { endDate.add(Calendar.DATE, −1); dayOfWeek = endDate.get(Calendar.DAY_OF_WEEK); } } return new Calendar[] { startDate, endDate }; } public static void main(String[] args) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy−MM−dd"); System.out.println("** previous month (relative today)"); Calendar [] results = DateUtils.getDateIntervals(IntervalType.Month, null); System.out.println(sdf.format(results[0].getTime())); System.out.println(sdf.format(results[1].getTime())); System.out.println("** previous week (relative today)"); results = DateUtils.getDateIntervals(IntervalType.Week, null); System.out.println(sdf.format(results[0].getTime())); System.out.println(sdf.format(results[1].getTime())); System.out.println("** previous month (relative jan 1, 2007)"); results = DateUtils.getDateIntervals(IntervalType.Month, new GregorianCalendar(2007, 00, 1)); System.out.println(sdf.format(results[0].getTime())); System.out.println(sdf.format(results[1].getTime())); System.out.println("** previous week (relative jan 1, 2007)"); results = DateUtils.getDateIntervals(IntervalType.Week, new GregorianCalendar(2007, 00, 1)); System.out.println(sdf.format(results[0].getTime())); System.out.println(sdf.format(results[1].getTime())); } catch (Exception e) { e.printStackTrace(); } } /* output : ** previous 2008−06−01 2008−06−30 ** previous 2008−06−30 2008−07−06 ** previous 2006−12−01 2006−12−31 ** previous 2006−12−25 2006−12−31

month (relative today)

week (relative today)

month (relative jan 1, 2007)

week (relative jan 1, 2007)

*/

2.20 Get a date interval

}

2.21 Determine if an hour is between an interval Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0624.html import java.util.Calendar; import java.text.SimpleDateFormat; public class DateUtils { // format 24hre ex. 12:12 , 17:15 private static String HOUR_FORMAT = "HH:mm"; private static SimpleDateFormat sdfHour; static { sdfHour = new SimpleDateFormat(HOUR_FORMAT); } private DateUtils() {

}

public static String getCurrentHour() { Calendar cal = Calendar.getInstance(); String hour = sdfHour.format(cal.getTime()); return hour; } /** * @param target hour to check * @param start interval start * @param end interval end * @return true true if the given hour is between */ public static boolean isHourInInterval(String target, String start, String end) { return ((target.compareTo(start) >= 0) && (target.compareTo(end) <= 0)); } /** * @param start interval start * @param end interval end * @return true true if the current hour is between */ public static boolean isNowInInterval(String start, String end) { return DateUtils.isHourInInterval (DateUtils.getCurrentHour(), start, end); } // TEST public static void main (String[] args) { String now = DateUtils.getCurrentHour(); String start = "14:00"; String end = "14:26"; System. out.println(now + " between " + start + "−" + end + "?"); System. out.println(DateUtils.isHourInInterval(now,start,end)); } }

2.21 Determine if an hour is between an interval

2.22 Set the computer clock Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0285.html Define the following prototype in the header file JNIEXPORT void JNICALL Java_JavaHowTo_setSystemTime (JNIEnv *, jobject, jshort, jshort);

the JNI function JNIEXPORT void JNICALL Java_JavaHowTo_setSystemTime (JNIEnv *env, jobject obj, jshort hour, jshort minutes) { SYSTEMTIME st; GetLocalTime( st.wHour = hour; st.wMinute = minutes; SetLocalTime( }

The Java JNI wrapper would be class JavaHowTo { public native void setSystemTime( short hour, short minutes); static { System.loadLibrary("javahowto"); } }

And finally, to use it public class JNIJavaHowTo { public static void main(String[] args) { short hour = 10; short minutes = 21; // this example will set the system at 10h21 using the Windows API // SetLocalTime. JavaHowTo jht = new JavaHowTo(); // set the time at 10h21 jht.setSystemTime(hour, minutes); } }

2.23 Use System time to generate unique ID Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0385.html 2.22 Set the computer clock

Since the granulaty of a PC can be as high as 55ms (down to 10ms), you can't use the System time to generate a unique ID because of the risk of getting duplicated IDs. This can be solved by using the following technique to make sure that the number returned is unique (in a single JVM). public class UniqueID { static long current= System.currentTimeMillis(); static public synchronized long get(){ return current++; } }

See also this HowTo

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

2.22 Set the computer clock

3 AWT 3.1 java−awt

3.2 Use The CardLayout manager Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0237.html import java.awt.*; import java.awt.event.*; import java.applet.*; public class CardLayoutDemo extends Applet implements ActionListener{ Panel p1,p2,p3,p0; Choice c1,c2; Button b1,b2,b3, b4; TextField t1, t2; public void init() { // The first Card p1 = new myPanel(new Color(0).red, new FlowLayout(), 100,100) ; Choice c1 = new Choice(); c1.addItem("Option 1"); c1.addItem("Option 2"); p1.add(c1); // The second Card p2 = new myPanel(new Color(0).blue, new FlowLayout(), 100, 100); c2 = new Choice(); c2.addItem("Option A"); c2.addItem("Option B"); c2.addItem("Option C"); p2.add(c2); // the third Card p3 = new myPanel(new Color(0).black, new FlowLayout(), 100, 100); t1 = new TextField(8); t1.setBackground(new Color(0).white); p3.add(t1); // Main card (receive the other) p0 = new myPanel(new Color(0).white, new CardLayout(0,0), 100,100); setLayout(new FlowLayout()); add(p0); // Add cards

3 AWT

p0.add("First card", p1); p0.add("2nd card", p2); p0.add("3rd card", p3);

add(b1 = new Button("card 1")); add(b2 = new Button("card 2")); add(b3 = new Button("card 3")); add(b4 = new Button("Which card is selected ?")); add(t2 = new TextField(2)); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); b4.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource() == b1) { //Show the first list ((CardLayout)p0.getLayout()).show(p0, "First card"); } else if (e.getSource() == b2) { //Show the second list ((CardLayout)p0.getLayout()).show(p0, "2nd card"); } else if (e.getSource() == b3) { //Show the third list ((CardLayout)p0.getLayout()).show(p0, "3rd card"); } else if (e.getSource() == b4) { // get the current card Component c[] = p0.getComponents(); int i = 0; int j = c.length; while (i < j) { if (c[i].isVisible()) { t2.setText("" + (i+1)); break; } else i ++; } } } } class myPanel extends Panel{ int w; int h; myPanel(Color co, LayoutManager la, int width, int height){ super(); w = width; h = height; setBackground(co); setLayout(la); } public Dimension getMinimumSize() { return new Dimension(w,h); } public Dimension getPreferredSize() {

3 AWT

return new Dimension(w,h); } }

<APPLET CODE=CardLayoutDemo.class WIDTH=300 HEIGHT=300> /HMTL

Try it here.

3.3 Detect which card is visible with a CardLayout Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0423.html Component getComponentShowing(Container c) { Component[] comps = c.getComponents(); int i = 0; while(i < comps.length &!comps[i].isVisible()) ++i; return (i == comps.length) ? null : comps[i]; } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

3.4 Use Popups Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0238.html [JDK1.1] import java.awt.*; import java.awt.event.*; import java.util.Hashtable; public class PopupTest extends Frame implements ActionListener, MouseListener { Hashtable popupTable = new Hashtable(); public PopupTest() { /* ** regular menu */ Menu m = new Menu("file"); MenuItem item = new MenuItem("file−1"); item.addActionListener(this); m.add(item); item = new MenuItem("file−2");

3.3 Detect which card is visible with a CardLayout

m.add(item); MenuBar mb = new MenuBar(); mb.add(m); setMenuBar(mb); setSize(100, 100); setLayout(new BorderLayout()); /* ** label with a popup */ Label l = new Label("label"); addPopup(l, "label"); add(l, "North"); /* ** panel with popup */ Panel p = new Panel(); p.setBackground(new Color(0).red); addPopup(p, "Panel"); add(p, "Center"); /* ** button with popup */ Button b = new Button("button"); addPopup(b, "button"); add(b, "South"); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setVisible(true); } public void actionPerformed(ActionEvent e) { /* ** handle actions related to popup */ System.out.println("actionPerformed, event=" + e ); System.out.println(" command=" + e.getActionCommand()); System.out.println(" param=" + e.paramString()); System.out.println(" source=" + e.getSource()); }

public void mouseClicked (MouseEvent e) { } public void mouseEntered (MouseEvent e) { } public void mouseExited (MouseEvent e) { } public void mousePressed (MouseEvent e) { mouseAction(e); } public void mouseReleased (MouseEvent e) { mouseAction(e); }

3.3 Detect which card is visible with a CardLayout

void mouseAction (MouseEvent e) { /* ** determine if we have to show a Popup */ Component c = e.getComponent(); if (e.isPopupTrigger()) { PopupMenu pm = getHash(c); pm.show(c, c.getSize().width/2, c.getSize().height/2); } } /* ** */

initialize a Popup for a particular Component

void addPopup(Component c, String name) { PopupMenu pm = new PopupMenu(); MenuItem mi1 = new MenuItem(name + "−1"); pm.add(mi1); mi1.addActionListener(this); MenuItem mi2 = new MenuItem(name + "−2"); pm.add(mi2); mi2.addActionListener(this); setHash(c, pm); c.add(pm); c.addMouseListener(this); } void setHash(Component c, PopupMenu p) { /* ** associate a Component with a particular Popup */ popupTable.put(c, p); } PopupMenu getHash(Component c) { /* ** return a Popup associated with a particular Component */ return (PopupMenu)(popupTable.get(c)); } public static void main (String argv[]) { new PopupTest(); } }

3.5 Use a File Dialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0247.html On the Win platform, the setFilenameFilter method don't work. We must use the setFile method instead to set a filter. import java.awt.*; public class UseFileDialog {

3.5 Use a File Dialog

public String loadFile (Frame f, String title, String defDir, String fileType) { FileDialog fd = new FileDialog(f, title, FileDialog.LOAD); fd.setFile(fileType); fd.setDirectory(defDir); fd.setLocation(50, 50); fd.show(); return fd.getFile(); } public String saveFile (Frame f, String title, String defDir, String fileType) { FileDialog fd = new FileDialog(f, title, FileDialog.SAVE); fd.setFile(fileType); fd.setDirectory(defDir); fd.setLocation(50, 50); fd.show(); return fd.getFile(); } public static void main(String s[]) { UseFileDialog ufd = new UseFileDialog(); System.out.println ("Loading : " + ufd.loadFile(new Frame(), "Open...", ".\\", "*.java")); System.out.println ("Saving : " + ufd.saveFile(new Frame(), "Save...", ".\\", "*.java")); System.exit(0); } }

to work with the full pathname, replace return fd.getFile();

by return fd.getDirectory() + System.getProperty("file.separator") + fd.getFile();

On other plateforms, setFilenameFilter may do the job, then you simply do : fd.setFilenameFilter(new FilenameFilter(){ public boolean accept(File dir, String name){ return (name.endsWith(".jpg") || name.endsWith(".gif")); } });

3.6 Use TrueType font Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0270.html [JDK1.4] The names of the most common fonts supported by Java are TimesRoman, Courier, and Helvetica. 3.6 Use TrueType font

To add fonts, simply edit the properties.font file located in the lib of your JDK installation. On a Windows system, to check what are the fonts available, go in the Font applet in the Parameters folder. Choose a font and doubleclick on it. Check the name of the font. For example, on my system, I have a font called Kaufmann, the real name is "Kaufmann BT". To be able to use this font, I add the following line in the properties.font file in the section called # for backword compatibility. Kaufmann.0=Kaufmann BT, ANSI_CHARSET

To use it, in a java program : setFont(new Font("Kaufmann", Font.BOLD, 20)); NOTE: The three common fonts are the only ones guaranteed to be supported across all systems. To be able to use other fonts, you must modify the properties.font file and these new fonts are not cross−plateform compatibles.

[JDK1.5] @todo

3.7 Display available fonts Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0278.html [JDK1.1] import java.awt.*; public class FontList { public static void main(String args[]) { String[] fontNames = Toolkit.getDefaultToolkit().getFontList(); int j = fontNames.length; for (int i = 0 ; i < j ;i++ ) { System.out.println(fontNames[i]); } } }

[JDK1.2] import java.awt.*; public class FontList { public static void main(String args[]) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fontNames[] = ge.getAvailableFontFamilyNames(); int j = fontNames.length; for (int i = 0 ; i < j ;i++ ) { System.out.println(fontNames[i]); } } }

3.7 Display available fonts

3.8 Font with 3D effect Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0312.html import java.awt.*; import java.applet.*; public class SimpleApplet extends Applet { public void init() { setBackground(new Color(255,255,255)); // white } public void paint(Graphics g) { g.setFont(new Font("Helvetica", Font.PLAIN, 42)); g.setColor(new Color(0,0,0)); // black g.drawString("Real's HowTo", 100, 100); g.drawString("Real's HowTo", 101, 101); g.setColor(getBackground()); g.drawString("Real's HowTo", 100, 100); g.setColor(new Color(0,0,0)); // black g.drawString("Real's HowTo", 100, 200); g.setColor(new Color(0,0,255)); // blue g.drawString("Real's HowTo", 102, 202); g.setColor(getBackground()); g.drawString("Real's HowTo", 101, 201); } }
<APPLET CODE=SimpleApplet.class WIDTH=410 HEIGHT=500> try it here

3.9 Use the System Clipboard Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0382.html import java.awt.datatransfer.*; import java.awt.*; public class Java2Clipboard implements ClipboardOwner { public static void main(String[] args) throws Exception { Java2Clipboard jc = new Java2Clipboard(); jc.toClipboard(); Frame f = new Frame ("Open a text editor and paste the message from Java"); f.setSize(600,10); f.show(); }

3.8 Font with 3D effect

public void toClipboard() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { sm.checkSystemClipboardAccess(); } catch (Exception e) {e.printStackTrace();} } Toolkit tk = Toolkit.getDefaultToolkit(); StringSelection st = new StringSelection("Hello world from Java"); Clipboard cp = tk.getSystemClipboard(); cp.setContents(st, this); } public void lostOwnership(Clipboard clip, Transferable tr) { System.out.println("Lost Clipboard Ownership?!?"); } } NOTE: You can only use text (no graphic) with this functionality provided by the current JDK (1.4).

3.10 Maximize a Frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0222.html // place this in the Frame constructor, after the show() this.move(0,0); resize(Toolkit.GetDefaultToolkit().getScreenSize());

JDK1.2 offers a new method, setState(), to minimize or maximize a Frame. frame.setState(Frame.ICONIFIED);

// minimize the frame

Latest JDK provides more ways to do that. JDK1.4 import java.awt.*; ... GraphicsDevice device; Frame frame = new Frame(); device = GraphicsEnvironment. getLocalGraphicsEnvironment(). getDefaultScreenDevice(); if ( device.isFullScreenSupported() ) { device.setFullScreenWindow(frame); } else { System.err.println("Full screen not supported"); }

The "full−screen" Frame is in exclusive mode. In this mode you can change the resolution import java.awt.*;

3.10 Maximize a Frame

class ScreenRes { public static void main(String args[]) { new ScreenRes().doit(); } public void doit() { Frame frame = new Frame(); GraphicsDevice device; device = GraphicsEnvironment. getLocalGraphicsEnvironment(). getDefaultScreenDevice(); if ( device.isFullScreenSupported() ) { device.setFullScreenWindow(frame); if (device.isDisplayChangeSupported()) { device.setDisplayMode( new DisplayMode( 1024, 768, 8, // bitDepth − 8 bits 256 colors DisplayMode.REFRESH_RATE_UNKNOWN )); } else { System.err.println("Change display mode not supported"); } } else { System.err.println("Full screen not supported"); } } }

When the JFrame is destroyed, the original resolution is restored. To remove (manually) the "exclusive mode" on the JFrame : device.setFullScreenWindow(null);

SWING jdk1.3 JFrame frame = new JFrame(); frame.setExtendedState(Frame.MAXIMIZED_BOTH); // can be // frame.setExtendedState(Frame.MAXIMIZED_HORIZ); // frame.setExtendedState(Frame.MAXIMIZED_VERT);

3.11 Center a Frame/Dialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0223.html // centers the dialog within the screen [1.1] // (put that in the Frame/Dialog class) public void centerScreen() { Dimension dim = getToolkit().getScreenSize(); Rectangle abounds = getBounds(); setLocation((dim.width − abounds.width) / 2, (dim.height − abounds.height) / 2); super.setVsible(true);

3.11 Center a Frame/Dialog

requestFocus(); } // centers the dialog within the parent container [1.1] // (put that in the Dialog class) public void centerParent () { int x; int y; // Find out our parent Container myParent = getParent(); Point topLeft = myParent.getLocationOnScreen(); Dimension parentSize = myParent.getSize(); Dimension mySize = getSize(); if (parentSize.width > mySize.width) x = ((parentSize.width − mySize.width)/2) + topLeft.x; else x = topLeft.x; if (parentSize.height > mySize.height) y = ((parentSize.height − mySize.height)/2) + topLeft.y; else y = topLeft.y; setLocation (x, y); super.setVsible(true); requestFocus(); }

New with JDK1.4, JDialog has method to position a JDialog relative to a parent. For a JWindow or a JFrame with no parent, then f.setSize(100,100); f.setLocationRelativeTo(NULL);

3.12 Close a Frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0225.html [JDK1.0.2] public boolean handleEvent(Event evt) { if (evt.id == Event.WINDOW_DESTROY) { System.exit(0); return true; } return super.handleEvent(evt); }

[JDK1.1 Method 1] public aFrame extends Frame implements WindowListener { public aFrame(){ addWindowListener( this ); }

3.12 Close a Frame

public public public public public public public

void void void void void void void

windowActivated(WindowEvent e){} windowDeactivated(WindowEvent e){} windowOpened(WindowEvent e){} windowClosing(WindowEvent e){ System.exit(0); } windowClosed(WindowEvent e){} windowIconified(WindowEvent e) {} windowDeiconified(WindowEvent e) {}

}

[JDK1.1 Method 2] public class aFrame extends Frame { public aFrame(){ addWindowListener( new Terminate() ); } } class Terminate extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(0); } }

[JDK1.1 Method 3] public class aFrame extends Frame { public aFrame() { addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); } }

For a Dialog or a Window, a System.exit(0) may not be appropriate, call the dispose() method instead. class SimplePopUp extends Dialog { SimplePopUp() { super(new Frame(), "simple popup"); this.addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); } } ); }

3.13 Call events on a Frame from a Panel Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0268.html

3.13 Call events on a Frame from a Panel

A component on a Panel can easily call events on the parent Frame. This way, we can put all the logic in one place. In this example, a Frame contains 1 button and a Panel with 2 buttons on it. The first button on the Panel will generate an event for the button on the Frame while the second panel button will trigger a request to close the Frame and the application. [TestEventPanel.java] import java.awt.*; import java.awt.event.*; public class TestEventPanel extends Panel { Button b1,b2; TestEventPanel(){ super(); setLayout(new FlowLayout()); setBackground(new Color(0).black); b1 = new Button("call event on the frame"); add(b1); b2 = new Button("close the parent frame"); add(b2); } }

The Frame after adding the Panel, will act as an ActionListener for events for the 2 Panel buttons. [TestEventFrame.java] import java.awt.*; import java.awt.event.*; public class TestEventFrame extends Frame implements ActionListener, WindowListener { TestEventPanel p1; Button b1; TestEventFrame(String title){ super(title); setLayout(new FlowLayout()); p1 = new TestEventPanel(); b1 = new Button("A dummy button"); add(b1); // the Panel with 2 buttons on it add(p1); createFrame(); // add the actionlistener b1.addActionListener(this); p1.b1.addActionListener(this); p1.b2.addActionListener(this); addWindowListener(this); } void createFrame() { Dimension d = getToolkit().getScreenSize(); setLocation(d.width/4,d.height/3); setSize(400,100); setVisible(true); }

3.13 Call events on a Frame from a Panel

public void actionPerformed(ActionEvent ae){ if (ae.getSource()==p1.b1) { System.out.println(ae.getActionCommand()); ActionEvent new_ae = new ActionEvent (b1, ActionEvent.ACTION_PERFORMED, "Panel b1 is calling the dummy button"); b1.dispatchEvent (new_ae); } if (ae.getSource()==b1) { System.out.println("dummy receive :" + ae.getActionCommand()); } if (ae.getSource()==p1.b2) { System.out.println(ae.getActionCommand()); processEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } } public void windowClosing(WindowEvent e) { this.dispose(); System.exit(0); } public void windowActivated(WindowEvent e) { public void windowDeactivated(WindowEvent e) public void windowDeiconified(WindowEvent e) public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { public void windowOpened(WindowEvent e) { }

} { } { } }

}

and finally [Java0268.java] import java.awt.*; public class Java0268 extends java.applet.Applet { TestEventFrame myTestEventFrame; public void init() { myTestEventFrame = new TestEventFrame("TestEvent Frame"); } }

Try it here.

3.14 Set the small top−left icon on a Frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0246.html There is a bug in JDK1.0.2 for Windows, so you are stuck with the JAVA coffee cup. 3.14 Set the small top−left icon on a Frame

In JDK1.1, this is fixed. You have to use a GIF file (not ICO file!). The GIF dimension should be 16x16. With 1.5, you can use a PNG or JPG file. You set the icon with : frame.setIconImage(Toolkit.getDefaultToolkit().getImage("myIcon.gif"));

To get the image from a Jar instead, do : frame.setIconImage (Toolkit.getDefaultToolkit() .getImage(getClass(). getResource("images/myIcon.gif")));

or frame.setIconImage( new ImageIcon( YourApp.class.getResource("logo.png") ).getImage() );

3.15 Prevent a Frame to be resized Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0252.html import java.awt.*; import java.awt.event.*; public class TestNoMaximize { MyFrame theFrame; public static void main (String args[]){ TestNoMaximize t = new TestNoMaximize(); t.theFrame = new MyFrame("A Dummy Frame"); t.theFrame.setVisible(true); } } class MyFrame extends Frame { public MyFrame(String title){ super(title); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); // no minimize or maximize this.setResizable(false); this.setSize(200,200); } public void paint(Graphics g) {

3.15 Prevent a Frame to be resized

g.drawString("try to resize me...", 50, 50); } }

There is no way to allow minimizing but not maximizing unless you trap the maximizing in the paint method and then resize to the original size. import java.awt.*; import java.awt.event.*; public class TestNoMaximize { MyFrame theFrame; public static void main (String args[]){ TestNoMaximize t = new TestNoMaximize(); t.theFrame = new MyFrame("A Dummy Frame"); t.theFrame.setVisible(true); } } class MyFrame extends Frame { public MyFrame(String title){ super(title); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); this.setSize(200,200); } public void paint(Graphics g) { Dimension d = this.getSize(); if (d.getHeight() != 200 &d.getWidth() != 200) this.setSize(200,200); g.drawString("try to maximize me...", 50, 50); } } NOTE: These How−to may not work with the Microsoft JVM. It's a feature...

3.16 Embed an image into a Frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0302.html A given image is tiled as the frame background. The result is not too good with Label... import java.awt.*; import java.awt.event.*; public class ImageFrame extends Frame private Image image;

3.16 Embed an image into a Frame

{

ImageFrame() { super(""); try { MediaTracker mt = new MediaTracker (this); // for Applet, change the method to retrieve the image // and of course use your own image! image = Toolkit.getDefaultToolkit().getImage("images/jht.gif"); mt.addImage(image, 0); mt.waitForID(0); } catch (Exception e) { e.printStackTrace(); } setLayout(new FlowLayout()); add(new TextField(10)); add(new Button("hello")); add(new List(20)); add(new TextArea(20,20)); // Label may not look too good ... add(new Label("Hello")); setSize(500, 500); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { // change this for an Applet System.out.println("Bye."); System.exit(0); } } ); } public void update( Graphics g) { paint(g); } public void paint(Graphics g) { if(image != null) { int x = 0, y = 0; while(y < getSize().height) { x = 0; while(x< getSize().width) { g.drawImage(image, x, y, this); x= x + image.getWidth(null); } y = y + image.getHeight(null); } } else { g.clearRect(0, 0, getSize().width, getSize().height); } } static public void main(String[] args) { ImageFrame iframe = new ImageFrame(); iframe.setVisible(true); } }

3.16 Embed an image into a Frame

The result :

3.17 Display a message box Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0242.html If using Swing then look at the JOptionPane component. With plain AWT, this simple class can be used as a Message Box. import java.awt.*; import java.awt.event.*; public class MsgBox extends Dialog implements ActionListener { private Button ok,can; public boolean isOk = false; /* * @param frame parent frame * @param msg message to be displayed * @param okcan true : ok cancel buttons, false : ok button only */ MsgBox(Frame frame, String msg, boolean okcan){ super(frame, "Message", true); setLayout(new BorderLayout()); add("Center",new Label(msg)); addOKCancelPanel(okcan); createFrame(); pack(); setVisible(true); } MsgBox(Frame frame, String msg){

3.17 Display a message box

this(frame, msg, false); } void addOKCancelPanel( boolean okcan ) { Panel p = new Panel(); p.setLayout(new FlowLayout()); createOKButton( p ); if (okcan == true) createCancelButton( p ); add("South",p); } void createOKButton(Panel p) { p.add(ok = new Button("OK")); ok.addActionListener(this); } void createCancelButton(Panel p) { p.add(can = new Button("Cancel")); can.addActionListener(this); } void createFrame() { Dimension d = getToolkit().getScreenSize(); setLocation(d.width/3,d.height/3); } public void actionPerformed(ActionEvent ae){ if(ae.getSource() == ok) { isOk = true; setVisible(false); } else if(ae.getSource() == can) { setVisible(false); } } public static void main(String args[]){ Frame f = new Frame(); f.setSize(200,200); f.setVisible(true); MsgBox message = new MsgBox (f , "Hey you user, are you sure ?", true); if (message.isOk) System.out.println("Ok pressed"); if (!message.isOk) System.out.println("Cancel pressed"); message.dispose(); } }

3.18 Display a Splash screen Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0267.html

3.18 Display a Splash screen

This Splash class display a window containing a specified image while a parent Frame is doing its initialization. When the parent is activated, the Splash window is destroyed. [JDK1.1] import java.awt.*; import java.awt.event.*; public class Splash extends Window { private Image splashImage; private int imgWidth, imgHeight; private String imgName; private static final int BORDERSIZE = 5; private static final Color BORDERCOLOR = Color.blue; Toolkit tk; public Splash(Frame f, String imgName) { super(f); this.imgName = imgName; tk = Toolkit.getDefaultToolkit(); splashImage = loadSplashImage(); showSplashScreen(); f.addWindowListener(new WindowListener()); } public Image loadSplashImage() { MediaTracker tracker = new MediaTracker(this); Image result; result = tk.getImage(imgName); tracker.addImage(result, 0); try { tracker.waitForAll(); } catch (Exception e) { e.printStackTrace(); } imgWidth = result.getWidth(this); imgHeight = result.getHeight(this); return (result); } public void showSplashScreen() { Dimension screenSize = tk.getScreenSize(); setBackground(BORDERCOLOR); int w = imgWidth + (BORDERSIZE * 2); int h = imgHeight + (BORDERSIZE * 2); int x = (screenSize.width − w) /2; int y = (screenSize.height − h) /2; setBounds(x, y, w, h); setVisible(true); } public void paint(Graphics g) { g.drawImage(splashImage, BORDERSIZE, BORDERSIZE, imgWidth, imgHeight, this); } class WindowListener extends WindowAdapter { // was windowActivated, thanks to H.Grippa for the fix! public void windowOpened(WindowEvent we) { setVisible(false); dispose(); } } }

3.18 Display a Splash screen

The following example use this image

(jht.gif) as the splash image.

import java.awt.*; import java.awt.event.*; public class TestSplash { MyFrame theFrame;

public static void main (String args[]){ TestSplash t = new TestSplash(); t.createMainFrame(); } private void createMainFrame() { theFrame = new MyFrame("A Dummy Frame"); theFrame.setVisible(true); } } class MyFrame extends Frame { Splash mySplash; public MyFrame(String title){ super(title); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); mySplash = new Splash(this, "jht.gif"); // dummy delay so we can see the Splash! for(int i = 0; i < 3000; i++) { System.out.println(i) ; } setSize(200,200); } }

3.19 Vibrate a Window Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0622.html This HowTo is based on this post : http://sdnshare.sun.com/view.jsp?id=2326 This can be useful to make a visual effect when an event is occuring. import java.awt.*; public class FrameUtils { private final static int VIBRATION_LENGTH = 20; private final static int VIBRATION_VELOCITY = 5; private FrameUtils() { }

3.19 Vibrate a Window

public static void vibrate(Frame frame) { try { final int originalX = frame.getLocationOnScreen().x; final int originalY = frame.getLocationOnScreen().y; for(int i = 0; i < VIBRATION_LENGTH; i++) { Thread.sleep(10); frame.setLocation(originalX, originalY + VIBRATION_VELOCITY); Thread.sleep(10); frame.setLocation(originalX, originalY − VIBRATION_VELOCITY); Thread.sleep(10); frame.setLocation(originalX + VIBRATION_VELOCITY, originalY); Thread.sleep(10); frame.setLocation(originalX, originalY); } } catch (Exception err) { err.printStackTrace(); } } }

To use it, simply pass a Frame to the vibrate method. FrameUtils.vibrate(myFrame);

To make it more Swing−oriented, you change the method signature for a JFrame instead. Here an example. We display a small window. When a file is added or deleted, the window is shaking for a brief moment and display the event. By default, the folder c:/temp is used but you can specify another one on the command line. First get the code to detect a file modfication in a folder (in this HowTo, you need the DirWatcher and DirFilterWatcher classes). Plus the following classes. import java.awt.*; import java.awt.event.*; public class DirWatchWindow extends Frame { Label folder; Label info; public DirWatchWindow() { setTitle("DirWatchWindow"); setSize(600, 100); setLayout(new BorderLayout()); folder = new Label(""); info = new Label(""); add(folder, BorderLayout.NORTH); add(info, BorderLayout.SOUTH); setVisible(true); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } );

3.19 Vibrate a Window

} public void setInfo(String text) { info.setText(text); } public void setFolder(String dir) { folder.setText("Watching folder : " + dir); } }

import java.util.*; import java.io.*; public class DirWatchTest { public static void main(String args[]) { String folderToWatch = "c:/temp"; if (args.length > 0) { folderToWatch = args[0]; } final DirWatchWindow dww = new DirWatchWindow(); dww.setFolder(folderToWatch); TimerTask task = new DirWatcher(folderToWatch, "txt" ) { protected void onChange( File file, String action ) { // here we code the action on a change dww.setInfo("File : "+ file.getName() +" action: " + action); FrameUtils.vibrate(dww); } }; Timer timer = new Timer(); timer.schedule( task , new Date(), 1000 ); } }

You can download an executable JAR here To launch the demo java −jar DirWatch.jar

to watch the default directory c:/temp or java −jar DirWatch.jar

c:/myfolder

to specify your own folder. This demo is watching for files with the extension txt only.

3.20 Limit TextField input to numeric value Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0226.html 3.20 Limit TextField input to numeric value

[JDK1.0.2] // You still have to trap the InvalidNumberFormat // Exception when converting textfield content to numeric // bug fixed! 980211 thanks to JM Guerra Chapa import java.awt.*; public class app extends java.applet.Applet { TextField textField1; public void init() { setLayout(new FlowLayout()); textField1 = new TextField(10); add(textField1); } public boolean handleEvent(Event event) { if (event.target==textfield1 &event.id == Event.KEY_PRESS) { char c = (char)event.key; if (c >= '0' &c <= '9') { // keep digit return super.handleEvent(event); } else if (Character.isISOControl(c)) { // keep control character (like del, bksp) return super.handleEvent(event); } else { // discard Character return true; } } return super.handleEvent(event); } }

[JDK1.1] thanks to Lionel Giltay

import java.awt.TextField ; import java.awt.event.KeyAdapter ; import java.awt.event.KeyEvent ; public class NumericTextField extends TextField { public NumericTextField (String _initialStr, int _col) { super (_initialStr, _col) ; this.addKeyListener(new KeyAdapter() { public void keyTyped (KeyEvent e) { char c = e.getKeyChar() ; if (! ((c==KeyEvent.VK_BACK_SPACE) || (c==KeyEvent.VK_DELETE) || (c== KeyEvent.VK_ENTER) || (c == KeyEvent.VK_TAB) || (Character.isDigit(c)))) { e.consume() ; } } });

3.20 Limit TextField input to numeric value

} public NumericTextField (int _col) { this ("", _col) ; } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

3.21 Limit TextField input to a maximum length Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0227.html [JDK11] import java.awt.*; import java.awt.event.*; public class TextFieldWithLimit extends TextField implements KeyListener { private int maxLength; public TextFieldWithLimit (String initialStr,int col,int maxLength) { super(initialStr,col); this.maxLength = maxLength; addKeyListener(this); } public TextFieldWithLimit (int col,int maxLength) { this("",col,maxLength); } public void keyPressed(KeyEvent e) { char c = e.getKeyChar(); int len = getText().length(); if (len <maxLength) { return; } else { if((c==KeyEvent.VK_BACK_SPACE)|| (c==KeyEvent.VK_DELETE) || (c==KeyEvent.VK_ENTER)|| (c==KeyEvent.VK_TAB)|| e.isActionKey()) return; else { e.consume(); } } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }

3.21 Limit TextField input to a maximum length

3.22 React to the ENTER key in a Textfield Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0253.html import java.applet.*; import java.awt.*; import java.awt.event.*; public class testENTER extends Applet implements KeyListener { TextField t; public void init(){ TextField t = new TextField("press ENTER"); add(t); t.addKeyListener(this); } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_ENTER) { Toolkit.getDefaultToolkit().beep(); System.out.println("ENTER pressed"); } } }

Or the short version using the KeyAdapter class. import java.applet.*; import java.awt.*; import java.awt.event.*; public class testENTER extends Applet{ TextField t; public void init(){ TextField t = new TextField("press ENTER"); add(t); t.addKeyListener (new KeyAdapter() { public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_ENTER) { Toolkit.getDefaultToolkit().beep(); System.out.println("ENTER pressed"); } } } ); } }

3.23 Make the ENTER key act like the TAB key Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0254.html

3.22 React to the ENTER key in a Textfield

First create a TextField that listen to the Enter and react like a Tab key [JDK11] import java.awt.*; import java.awt.event.*; public class MyTextField extends TextField { MyTextField(int len) { super(len); addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent evt) { int key = evt.getKeyCode(); if (key == KeyEvent.VK_ENTER) transferFocus();}}); } }

to use it, try something like this import java.applet.*; import java.awt.*; import java.awt.event.*; public class TestEnterAsTab extends Applet { MyTextField t1, t2; public void init(){ MyTextField t1 = new MyTextField(10); MyTextField t2 = new MyTextField(10); add(t1);add(t2); } }

3.24 Reset all textfields in one shot Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0274.html import java.applet.*; import java.awt.*; import java.awt.event.*; public class FirstApplet extends Applet implements ActionListener { TextField t1; TextField t2; TextField t3; TextField t4onPanel; Panel p1; Button b; public void init() { add(t1= new TextField(20)); add(t2= new TextField(20)); add(t3= new TextField(20)); t4onPanel = new TextField(20); p1 = new Panel(); p1.setBackground(new Color(0).yellow); p1.add(t4onPanel); add(p1); add(b = new Button("reset TextFields"));

3.24 Reset all textfields in one shot

b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) resetTextFields(this); } public static void resetTextFields(Container c) { Component [] components = c.getComponents(); for (int i = 0; i <APPLET CODE="FirstApplet.class" NAME="myApplet" HEIGHT=200 WIDTH=200>

3.25 Limit a TextField to Uppercase Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0279.html [JDK1.1] import java.awt.*; import java.awt.event.*; public class UpperTF extends Frame { public static void main(String argv[]) { new UpperTF().setVisible(true); } public UpperTF() { setLayout(new FlowLayout()); TextField tf = new TextField(10); add(tf); tf.addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { if (Character.isLetter(e.getKeyChar())) e.setModifiers(Event.SHIFT_MASK); } }); pack(); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); }

3.25 Limit a TextField to Uppercase

public Dimension getPreferredSize() { return new Dimension(200,200); } }

3.26 Have an ImageButton Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0245.html This implementation of an ImageButton requires JDK1.1 and is a good example of the new Event architecture. This ImageButton needs 2 GIF images representing the normal and pressed state ( ). Also a method to disable the button by using a special filter is given. [ImageButton.java] import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.net.*; public class ImageButton extends Canvas { protected ActionListener actionListener = null; int w,h; boolean clicked; boolean down; boolean enabled; Image UPimage; Image DOWNimage; Image disabledimage; public ImageButton(URL up_b, URL down_b) { clicked=false; down=false; enabled=true; InitImage(up_b,down_b); setSize(w,h); addMouseListener(new ImageButtonMouseListener()); addMouseMotionListener(new ImageButtonMouseMotionListener()); } public void InitImage(URL up, URL down) { MediaTracker tracker; try { UPimage = getToolkit().getImage(up); DOWNimage = getToolkit().getImage(down); tracker = new MediaTracker(this); tracker.addImage(UPimage,0); tracker.addImage(DOWNimage,1); tracker.waitForAll(); } catch (InterruptedException e) { e.printStackTrace(); } disabledimage=createImage(new FilteredImageSource (UPimage.getSource(),new ImageButtonDisableFilter())); w=UPimage.getWidth(this);

3.26 Have an ImageButton

h=UPimage.getHeight(this); } public void paint(Graphics g) { if (down) { g.drawImage(DOWNimage,0,0,this); } else { if (enabled) { g.drawImage(UPimage,0,0,this); } else { g.drawImage(disabledimage,0,0,this); } } } public void setEnabled(boolean b) { enabled=b; repaint(); } public boolean isEnabled() { return (enabled); } public void addActionListener(ActionListener l) { actionListener = AWTEventMulticaster.add(actionListener,l); } public void removeActionListener(ActionListener l) { actionListener = AWTEventMulticaster.remove(actionListener, l); } public class ImageButtonMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { Point p = e.getPoint(); if ((p.x < w)&&(p.y < h)&&(p.x > 0)&&(p.y > 0)&&(enabled==true)) { clicked=true; down=true; repaint(); } } public void mouseReleased(MouseEvent e) { Point p = e.getPoint(); if (down) { down=false; repaint(); } if ((p.x < w)&&(p.y < h)&&(p.x > 0)&&(p.y > 0)&&(clicked==true)) { ActionEvent ae = new ActionEvent(e.getComponent(),0,"click"); if (actionListener != null) { actionListener.actionPerformed(ae); } } clicked=false; } } public class ImageButtonMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) {

3.26 Have an ImageButton

Point p = e.getPoint(); if ((p.x < w)&&(p.y < h)&&(p.x > 0)&&(p.y > 0)&&(clicked==true)) { if (down==false) { down=true; repaint(); } } else { if (down==true) { down=false; repaint(); } } } } public Dimension getPreferredSize() { return (new Dimension(UPimage.getWidth(this), UPimage.getHeight(this))); } public Dimension getMinimumSize() { return getPreferredSize(); } class ImageButtonDisableFilter extends RGBImageFilter { public ImageButtonDisableFilter() { canFilterIndexColorModel=true; } public int filterRGB(int x, int y, int rgb) { return (rgb &~0xff000000) | 0x80000000; } } }

[TestImageButton.java] import import import import

java.awt.*; java.awt.event.*; java.applet.*; java.net.*;

public class TestImageButton extends Applet implements ActionListener,ItemListener { ImageButton ib; Checkbox c; public void init() { setLayout(new FlowLayout()); try { ib = new ImageButton (new URL(getCodeBase(), "Gumby.gif"), new URL(getCodeBase(), "Gumbyblu.gif")); c = new Checkbox("disable"); ib.addActionListener(this); c.addItemListener(this); add(ib); add(c); } catch (Exception e) { e.printStackTrace(); }

3.26 Have an ImageButton

} public void actionPerformed(ActionEvent e) { if (e.getSource() == ib) System.out.println("Click ImageButton"); } public void itemStateChanged(ItemEvent ie) { ib.setEnabled(!ib.isEnabled()); } }

3.27 Reset a checkbox group Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0221.html import java.applet.*; import java.awt.*; public class radio extends Applet { CheckboxGroup cbg; public void init() { add(new Label("Payment mode?")); cbg = new CheckboxGroup(); add(new Checkbox("Visa", cbg, false)); add(new Checkbox("Mastercard", cbg, false)); add(new Checkbox("American Express", cbg, false)); add(new Checkbox("Cash", cbg, true)); add(new Button("clear radio")); } public boolean action(Event e, Object o) { if (o.equals("clear radio")){ Checkbox current = cbg.getCurrent(); cbg.setCurrent( null ); current.setState( false ); return true; } return false; } }

3.28 Set the listbox width Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0231.html The width can be specified via the preferredSize method. This class lets you specify a font (fixed pitch) and calculate the appropriate width in pixels. class myListbox extends List { int width; int height; public myListbox(int r, int n, boolean m){ // (r) line number, (n) width, (m) multiselect this(r, n, m, new Font("Courier", Font.BOLD, 10));

3.27 Reset a checkbox group

width = n; height = r; } public myListbox(int r, int n, boolean m, Font f){ super(r,m); width = n; height = r; setFont(f); } public Dimension preferredSize (){ FontMetrics fm=getFontMetrics(getFont()); // the character W used as reference return new Dimension (fm.charWidth('W')*width, fm.getHeight()*height); } }

3.29 Align the column in a List Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0244.html The trick is to use a FIXED width character set like "Courier". ml = new List(); my.setFont(new Font("Courier", Font.BOLD, 10));

When inserting a line, we simply pad spaces as needed. Here the first column is 20 characters wide, the second 10 and the last one the remaining. insertItem(ml, "ARCHIVE", "STATUS", "PORT");

public void insertItem(List lbx, String col1, String col2, String col3) { String spaces2 = " "; String spaces10 = " "; String spaces20 = spaces10 + spaces10; lbx.addItem(col1 + spaces20.substring(0,20−col1.length()) + spaces2 + col2 + spaces10.substring(0,10−col2.length()) + col3); } In real life, the preferred way would be to extend the java.awt.List and override the addItem method.

3.30 Have a srolling text display Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0271.html 3.29 Align the column in a List

A srolling text display can be used to log informations or events. In this snippet, we are using a List component to display the data. We are keeping only the last 10 events. It's a good idea to limit the amount of data kept in the List , in fact we have no choice because the maximum capacity is about 32k (Win). import java.awt.*; import java.awt.event.*; public class TelnetLikeDisplay extends Applet implements ActionListener { Button b; int i = 0; static final int LINE_BUFFERED = 10; static final int LINE_DISPLAYED = LINE_BUFFERED − 1; List l; public void init() { setLayout(new FlowLayout(FlowLayout.LEFT)); add(b = new Button("New Line")); b.addActionListener(this); add(l = new List(5)); l.setSize(100,100); l.setForeground(new Color(0).yellow); l.setBackground(new Color(0).black); } public void actionPerformed(ActionEvent ae) { String newLine = "Line #" + i; if (i
3.31 Label dynamic resizing Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0232.html If there is no Layout Manager installed, try something like this: aLabel.setText ("A very long label"); aLabel.resize (aLabel.preferredSize());

With a Layout Manager, you have to validate() the layout to redraw the components invalidated. Label aLabel = new Label("short label"); aLabel.setText ("A very long label"); this.validate();

3.31 Label dynamic resizing

While this method works in Netscape or the Appletviewer, on IE4/5 there is no resizing. You may want to try this instead (thanks to Dan for the tip): Label aLabel = new Label("short label"); aLabel.setText(""A very long label"); aLabel.invalidate(); // make sure the component is marked as non−valid this.validate();

This example how to change a Label or a String drawn with the drawString method by clicking on a button. import java.awt.*; import java.awt.event.*; import java.applet.*; public class TestPaint extends Applet implements ActionListener { MyPanel p; Label l; Button b1, b2; TextField t1, t2; public void init() { setLayout(new FlowLayout()); t1 = new TextField(10); b1 = new Button("Change Label"); add(t1); add(b1); t2 = new TextField(10); b2 = new Button("Change drawString"); add(t2); add(b2); l = new Label("label text"); add(l); // a Panel with a drawString call p = new MyPanel(); add(p); b1.addActionListener(this); b2.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource() == b1) { l.setText(t1.getText()); l.invalidate(); validate(); } if (e.getSource() == b2) { p.someString = t2.getText(); p.repaint(); } } } class MyPanel extends Panel { String someString = "drawstring"; MyPanel() { super(); } public void paint (Graphics g) { g.drawString(someString, 10,50); }

3.31 Label dynamic resizing

public Dimension getPreferredSize() { return new Dimension (100,100); } }

3.32 Make a TextArea "word−wrap" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0241.html Simply create the TextArea with no horizontal scrollbar. myTextArea = new TextArea ("text", 3 , 100 , TextArea.SCROLLBARS_VERTICAL_ONLY);

3.33 Synchronize a TextArea vs a Choice Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0281.html import java.awt.*; import java.awt.event.*; class ChoiceEx extends Frame implements ItemListener { Choice choice = new Choice(); TextArea textarea = new TextArea(); ChoiceEx() { super(""); for (int i=0; i<10; i++) { choice.addItem("item "+i); } // Set listeners choice.addItemListener(this); add(choice, BorderLayout.SOUTH); add(textarea, BorderLayout.NORTH); pack(); setVisible(true); } // When list or choice is updated public void itemStateChanged(ItemEvent evt) { textarea.setText("Item #" + choice.getSelectedIndex()); } static public void main(String[] args) { new ChoiceEx(); } }

3.34 Display underlined text Current version of this HowTo : 3.32 Make a TextArea "word−wrap"

http://www.rgagnon.com/javadetails/../javadetails/java−0258.html import java.applet.*; import java.awt.*; public class underlineText extends Applet{ String s = "Underlined text"; int x=10; int y=10; public void init() {} public void paint(Graphics g) { g.drawString(s, x,y); g.drawLine(x , y+2 , x+getFontMetrics(getFont()).stringWidth(s) , y+2 ); } } Check this How−to for underlined text with a Label component. Check this How−to for underlined text in Swing.

3.35 Display vertical text Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0259.html import java.applet.*; import java.awt.*; public class verticalText extends Applet { String s = "Vertical text"; int x=10; int y=10; int v; public void init() {} public void paint(Graphics g) { v=g.getFontMetrics(getFont()).getHeight()+1; System.out.println(v); int j =0; int k= s.length(); while(j < k+1) { if (j == k) g.drawString(s.substring(j),x, y+(j*v)); else g.drawString(s.substring(j,j+1),x, y+(j*v)); j++; } } }

[JDK1.4] import java.awt.geom.AffineTransform; import java.awt.Graphics2D;

public void paint(Graphics g){

3.35 Display vertical text

Graphics2D g2d = (Graphics2D)g; // clockwise 90 degrees AffineTransform at = new AffineTransform(); // thanks to M.C. Henle for the bug fix! at.setToRotation(−Math.PI/2.0, width/2.0, height/2.0); g2d.setTransform(at); g2d.drawString("Vertical text", x, y); }

3.36 Have Label with many lines Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0269.html The Label component included in the AWT do not support "\n" in its definition. The following class implements a multi−line Label. Lines are separated byt the token "\n". Lines can be left, right or center justified. Plus, there is a possibility to have a border around the label. import java.awt.*; import java.util.*;

public class MultiLineLabel extends Canvas { public static final int LEFT = 0; public static final int CENTER = 1; public static final int RIGHT = 2; private String text; private String lines[]; private int num_lines; private int line_height; private int line_ascent; private int line_widths[]; private int max_width; private int alignment; private boolean border; private int topBottomMargin; private int leftRightMargin; private int x = 0; private int y = 0; Dimension offDimension; Image offImage; Graphics offGraphics; Color borderColor = new Color(0).black; public MultiLineLabel(String s, int i, boolean b) { // s the label // i alignement MultiLineLabel.CENTER, MultiLineLabel.RIGHT, // MultiLineLabel.LEFT // default MultiLineLabel.LEFT // b border present or not setAlignment(i); setText(s); setBorder(b); } public MultiLineLabel(String string, int i) { this(string, i, false); }

3.36 Have Label with many lines

public MultiLineLabel(String string) { this(string, 0); } public MultiLineLabel() { this("", 0); } public void addNotify() { super.addNotify(); calc(); } public void setX(int i) { x = i; public void setY(int i) { y = i;

} }

public int getLeftRightMargin() { return leftRightMargin; } public void setLeftRightMargin(int i) { // make sense only if alignment is MultiLineLabel.LEFT! if (i >= 0) leftRightMargin = i ; } public int getAlignment() { return alignment; } public void setAlignment(int i) { switch (alignment) { case 0: case 1: case 2: alignment = i; break; default: throw new IllegalArgumentException(); } repaint(); } public int getTopBottomMargin() { return topBottomMargin; } public void setTopBottomMargin(int i) { if (i >= 0) topBottomMargin = i; } public void setFont(Font font) { super.setFont(font); calc(); repaint(); } public Dimension getMinimumSize() { Dimension d = new Dimension (max_width + leftRightMargin * 2, num_lines * line_height + topBottomMargin * 2); if (d.width == 0) d.width = 10;

3.36 Have Label with many lines

if (d.height == 0) return d; }

d.height = 10;

public Dimension getPreferredSize() { return getMinimumSize(); } public boolean getBorder() { return border; } public void setBorder(boolean flag) { border = flag; } public void setText(String s) { // parse the string , "\n" is a the line separator StringTokenizer st = new StringTokenizer(s,"\n"); num_lines = st.countTokens(); lines = new String[num_lines]; line_widths = new int[num_lines]; for (int i = 0; i < num_lines; i++) lines[i] = st.nextToken(); calc(); repaint(); text = new String(s); } public String getText() { return text; } public Color getBorderColor() { return borderColor; } public void setBorderColor(Color c) { borderColor = c; } private void calc() { // calc dimension and extract maximum width Font f = getFont(); if (f != null) { FontMetrics fm = getFontMetrics(f); if (fm != null) { line_height = fm.getHeight(); line_ascent = fm.getAscent(); max_width = 0; for (int i = 0; i < num_lines; i++) { line_widths[i] = fm.stringWidth(lines[i]); if (line_widths[i] > max_width) max_width = line_widths[i]; } } } } public void update(Graphics g) { super.paint(g);

3.36 Have Label with many lines

Dimension d = getSize(); if ( (offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height) ) { offDimension = d; offImage = createImage(d.width, d.height); offGraphics = offImage.getGraphics(); } offGraphics.setColor(getBackground()); offGraphics.fillRect (x, y, getSize().width − 1, getSize().height − 1); if (border) { offGraphics.setColor(borderColor); offGraphics.drawRect (x, y, getSize().width − 1, getSize().height − 1); } int j = line_ascent + (d.height − num_lines * line_height) / 2; for (int k = 0; k < num_lines; ) { int i; switch (alignment) { case 0: i = 0; break; case 2: i = d.width − line_widths[k]; break; default: i = (d.width − line_widths[k]) / 2; break; } i += leftRightMargin; offGraphics.setColor(getForeground()); offGraphics.drawString(lines[k], i + x, j + y); k++; j += line_height; } g.drawImage(offImage,0,0,this); } public void paint(Graphics g) { update(g); } public static void main(String args[]){ Frame f = new Frame("Test MultiLineLabel"); f.setSize(200,200); f.setLayout(new FlowLayout()); f.setVisible(true); MultiLineLabel mll1 = new MultiLineLabel ("This a test!\nsecond line\nthird line", MultiLineLabel.LEFT, true); // mll1.setBorderColor(new Color(0).blue); mll1.setLeftRightMargin(15); mll1.setTopBottomMargin(15); f.add(mll1); Button b = new Button("Dummy"); f.add(b);

3.36 Have Label with many lines

MultiLineLabel mll2 = new MultiLineLabel ("123\n4\n567", MultiLineLabel.RIGHT, false); mll2.setForeground(new Color(0).yellow); mll2.setBackground(new Color(0).black); f.add(mll2); f.validate(); } }

3.37 Have a Label with underlined text Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0272.html [UnderlinedLabel.java] import java.awt.*; public class UnderlinedLabel extends Label public UnderlinedLabel(){ this(""); }

{

public UnderlinedLabel(String text){ super(text); } public void paint(Graphics g) { Rectangle r; super.paint(g); r = g.getClipBounds(); g.drawLine (0, r.height − this.getFontMetrics(this.getFont()).getDescent(), this.getFontMetrics(this.getFont()).stringWidth(this.getText()), r.height − this.getFontMetrics(this.getFont()).getDescent()); } }

[TestUnderlinedLabel.java] import java.applet.*; import java.awt.*; public class TestUnderlinedLabel extends Applet { public void init() { UnderlinedLabel ul1 = new UnderlinedLabel ("Java How−to"); add(ul1); } }

[testapplet.html] <APPLET CODE="TestUnderlinedLabel.class"

3.37 Have a Label with underlined text

NAME="myApplet" HEIGHT=200 WIDTH=200> /APPLET/BODY/HTML Check this How−to for underlined text in Swing.

3.38 Have a Label acting as HTML HREF (URLLabel) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0273.html [URLLabel.java] import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*;

public class URLLabel extends Label { private java.applet.Applet applet; private URL url; private String target = ""; private Color unvisitedURL = Color.blue; private Color visitedURL = Color.green; public URLLabel(Applet applet , String url, String text){ this(applet, url, text, "_self"); } public URLLabel (Applet applet , String url, String text, String target){ super(text); setForeground(unvisitedURL); try { this.applet = applet; this.url = new URL(url); this.target = target; addMouseListener( new Clicked() ); } catch (Exception e) { e.printStackTrace(); } } public void paint(Graphics g) { Rectangle r; super.paint(g); r = g.getClipBounds(); g.drawLine(0, r.height − this.getFontMetrics(this.getFont()).getDescent(), this.getFontMetrics(this.getFont()).stringWidth(this.getText()), r.height − this.getFontMetrics(this.getFont()).getDescent()); } public void setUnvisitedURLColor(Color c) { unvisitedURL = c; } public void setVisitedURLColor(Color c) {

3.38 Have a Label acting as HTML HREF (URLLabel)

visitedURL = c; } class Clicked extends MouseAdapter{ public void mouseClicked(MouseEvent me){ setForeground(visitedURL); applet.getAppletContext().showDocument(url, target); } } }

[TestURLLabel.java] import java.applet.*; import java.awt.*; public class TestURLLabel extends Applet { public void init() { URLLabel ull1 = new URLLabel(this, "http://www.rgagnon.com/howto.html", "Java How−to"); add(ull1); URLLabel ull2 = new URLLabel(this, "http://www.rgagnon.com/bigindex.html", "Java How−to BigIndex"); add(ull2); URLLabel ull3 = new URLLabel(this, "http://www.rgagnon.com/javadetails/java−0001.html", "Java How−to 0001"); add(ull3); URLLabel ull4 = new URLLabel(this, "http://www.rgagnon.com/javadetails/java−0002.html", "Java How−to 0002"); add(ull4); validate(); } }

[testapplet.html] <APPLET CODE="TestURLLabel.class" NAME="myApplet" HEIGHT=200 WIDTH=200>

Try it here.

3.39 Display a GIF in a Canvas Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0229.html import java.awt.*; import java.awt.image.*; public class ImageCanvas extends Canvas { Image image;

3.39 Display a GIF in a Canvas

public ImageCanvas(String name) { MediaTracker media = new MediaTracker(this); image = Toolkit.getDefaultToolkit().getImage(name); media.addImage(image, 0); try { media.waitForID(0); } catch (Exception e) {} } public ImageCanvas(ImageProducer imageProducer) { image = createImage(imageProducer); } public void paint(Graphics g) { g.drawImage(image, 0,0, this); } public static void main(String argv[]) { if (argv.length <1) { System.out.println ("usage: ImageCanvas.class [image file name]"); System.exit(0); } Frame frame = new Frame(argv[0]); frame.setLayout(new BorderLayout()); frame.add("Center", new ImageCanvas(argv[0])); frame.resize(400,400); frame.show(); } }

3.40 Embed an image into a Frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0302.html A given image is tiled as the frame background. The result is not too good with Label... import java.awt.*; import java.awt.event.*; public class ImageFrame extends Frame

{

private Image image; ImageFrame() { super(""); try { MediaTracker mt = new MediaTracker (this); // for Applet, change the method to retrieve the image // and of course use your own image! image = Toolkit.getDefaultToolkit().getImage("images/jht.gif"); mt.addImage(image, 0); mt.waitForID(0); }

3.40 Embed an image into a Frame

catch (Exception e) { e.printStackTrace(); } setLayout(new FlowLayout()); add(new TextField(10)); add(new Button("hello")); add(new List(20)); add(new TextArea(20,20)); // Label may not look too good ... add(new Label("Hello")); setSize(500, 500); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { // change this for an Applet System.out.println("Bye."); System.exit(0); } } ); } public void update( Graphics g) { paint(g); } public void paint(Graphics g) { if(image != null) { int x = 0, y = 0; while(y < getSize().height) { x = 0; while(x< getSize().width) { g.drawImage(image, x, y, this); x= x + image.getWidth(null); } y = y + image.getHeight(null); } } else { g.clearRect(0, 0, getSize().width, getSize().height); } } static public void main(String[] args) { ImageFrame iframe = new ImageFrame(); iframe.setVisible(true); } }

The result :

3.40 Embed an image into a Frame

3.41 Load several images from a single GIF Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0239.html It's a good idea to combine small GIFs into a single big one to speed up the loading process. In the following snippet, I assume that all images are the same height and width. You may want to get this GIF ( ) if you want to try the example on your workstation! import import import import

java.applet.*; java.awt.*; java.io.*; java.net.*;

public class strip extends Applet{ int iconHeight = 16; int iconWidth = 16; int iconCount = 2; Image icon[] = new Image[iconCount]; Image allIcons; public void init(){ loadImages("item.gif"); } public void paint(Graphics g) g.drawImage(allIcons, 0, 0, g.drawImage(icon[0], 0, 20, g.drawImage(icon[1], 0, 40, }

{ this); this); this);

public void loadImages(String s) { MediaTracker t=new MediaTracker(this);

3.41 Load several images from a single GIF

allIcons=createImage(1,1); try { URL u=new URL(getCodeBase(), s); allIcons=Toolkit.getDefaultToolkit().getImage(u); t.addImage(allIcons,0); } catch (MalformedURLException me) { System.out.println("MalformedURLException: " + me); } try { t.waitForAll(15000); } catch (InterruptedException e) { System.out.println("interrupted"); } for (int i=0; i < iconCount; i++) { Image z=createImage(iconWidth,iconHeight); Graphics g=z.getGraphics(); g.clipRect(0,0,iconWidth,iconHeight); g.drawImage(allIcons,−i*iconWidth,0,this); icon[i]=z; } } }

3.42 Load an Image from a JAR file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0240.html [JDK1.1 application] String imgName = "image.jpg"; URL imgURL = getClass().getResource(imgName); Toolkit tk = Toolkit.getDefaultToolkit(); Image img = null; try { MediaTracker m = new MediaTracker(this); img = tk.getImage(imgURL); m.addImage(img, 0); m.waitForAll(); } catch (Exception e) { e.printStackTrace(); }

[JDK 1.1 applet] Because of some security reason, it's not possible with some browser (like Netscape) to use the getResource() method from an Applet. Instead we must use the getResourceAsStream method. Image img = null; try { MediaTracker m = new MediaTracker(this); InputStream is = getClass().getResourceAsStream("image.gif"); // // if your image is in a subdir in the jar then // InputStream is = getClass().getResourceAsStream("img/image.gif"); // for example

3.42 Load an Image from a JAR file

// BufferedInputStream bis = new BufferedInputStream(is); // a buffer large enough for our image // // can be // byte[] byBuf = = new byte[is.available()]; // is.read(byBuf); or something like that... byte[] byBuf = = new byte[10000]; int byteRead = bis.read(byBuf,0,10000); img = Toolkit.getDefaultToolkit().createImage(byBuf); m.addImage(img, 0); m.waitForAll(); } } catch(Exception e) { e.printStackTrace(); }

[JDK 1.2 application] URL url = this.getClass().getResource("myIcon.gif"); button.setIcon(new ImageIcon(url)); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

3.43 Load an Icon from a jar (again) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0436.html public static ImageIcon getImageIcon(String name) { return new ImageIcon(ClassLoader.getSystemResource(name)); } ImageIcon img = getImageIcon("resources/images/icone.gif");

Remember that it is always possible to the Java built−in icons so that you don't have to include your own standard icons. public static Icon getIconForType(int iconType) { switch (iconType) { case 0: return UIManager.getIcon("OptionPane.errorIcon"); case 1: return UIManager.getIcon("OptionPane.informationIcon"); case 2: return UIManager.getIcon("OptionPane.warningIcon"); case 3: return UIManager.getIcon("OptionPane.questionIcon"); } return null; }

3.43 Load an Icon from a jar (again)

A list of what icons are available can be found here If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

3.44 Scale an Image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0243.html import java.awt.image.*; import java.awt.*; import java.net.*; public class app extends java.applet.Applet { Image source; Image resizedImage; public void init() { MediaTracker media = new MediaTracker(this); // java how−to image for example, can be JPG source = getImage(getDocumentBase(),"../images/jht.gif"); media.addImage(source,0); try { media.waitForID(0); // scale down, half the original size ImageFilter replicate = new ReplicateScaleFilter (source.getWidth(this)/2, source.getHeight(this)/2); ImageProducer prod = new FilteredImageSource(source.getSource(),replicate); resizedImage = createImage(prod); media.addImage(resizedImage,1); media.waitForID(1); } catch(InterruptedException e) {} } public void paint(Graphics g) { g.drawImage(source, 10,10,this); g.drawImage(resizedImage,10, 80,this); } }

Try it here. Modern JDK has now a complete library devoted to graphic manipulation. The following exampe takes a JPG file as input , rescale it to the passed parameters and writes the result in the specified output file. import import import import import

java.awt.*; java.awt.geom.*; java.awt.image.*; java.io.*; javax.imageio.*;

3.44 Scale an Image

public class ScaleJPG { public static void scale(String src, int width, int height, String dest) throws IOException { BufferedImage bsrc = ImageIO.read(new File(src)); BufferedImage bdest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bdest.createGraphics(); AffineTransform at = AffineTransform.getScaleInstance((double)width/bsrc.getWidth(), (double)height/bsrc.getHeight()); g.drawRenderedImage(bsrc,at); ImageIO.write(bdest,"JPG",new File(dest)); } public static void main(String[] args) { if (args.length == 4) { try { ScaleJPG.scale (args[0],Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]); } catch (Exception e) { e.printStackTrace(); } } else { System.out.println("\nUsage: java ScaleJPG src width height dest\n"); } } }

Example : >java ScaleJPG javahowto.jpg 250 70 javahowto2.jpg

Input:

Ouput:

3.45 Fade an image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0249.html This example display a GIF with a fade−in, fade−out effect. import import import import

java.applet.*; java.awt.*; java.awt.image.*; java.net.*;

3.45 Fade an image

public class FadeImage extends Applet { Image img, faded; int level, sign; MediaTracker tracker; AlphaFilter f; FilteredImageSource fis; public void init() { level = 0; sign = 15; tracker = new MediaTracker(this); try { img = getImage(new URL(getDocumentBase(), "../images/gumby.gif")); tracker.addImage(img,0); tracker.waitForID(0); } catch (Exception e) { e.printStackTrace(); } f = new AlphaFilter(); f.setLevel(level); fis = new FilteredImageSource(img.getSource(), f) ; FadeThread ft = new FadeThread(); ft.delayedFading(this, 20); ft.start(); } public void paint(Graphics g) { if (faded != null) { g.drawImage(faded,0,0,this); } } public void fadeIt() { Graphics g = this.getGraphics(); level += sign; if (level < 0) { level=0; sign = sign * −1; } if (level > 255) { level=255; sign = sign * −1; try { Thread.sleep(1000); } catch (Exception e) {} } f.setLevel(level); if (faded != null) faded.flush(); faded = this.createImage(fis); tracker.addImage(faded,0); try { tracker.waitForID(0); } catch (Exception ex) { ex.printStackTrace(); } repaint(); } class FadeThread extends Thread {

3.45 Fade an image

FadeImage fadeApplet; int delay; public void delayedFading(FadeImage f, int delay) { this.fadeApplet = f; this.delay = delay; } public void run() { while (true) { try { sleep(delay); fadeApplet.fadeIt(); } catch (Exception e) { e.printStackTrace(); } } } } class AlphaFilter extends RGBImageFilter { private int level; public AlphaFilter() { canFilterIndexColorModel = true; } public void setLevel(int lev) { level = lev; } public int filterRGB(int x, int y, int rgb) { int a = level * 0x01000000; return (rgb & 0x00ffffff) | a; } } }

Try it here.

3.46 Rotate an image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0248.html The following snippet rotates an image (90 degrees). The applet assumes the dimension 32x32 for the image. You may want to grap this image for testing purpose.

import java.applet.Applet; import java.net.*; public class rotateGumby extends Applet { Image img = null; Image rot = null; int buffer[] = new int[32 * 32]; int rotate[] = new int[32 * 32];

3.46 Rotate an image

public void init() { try { MediaTracker tracker = new MediaTracker (this); img = getImage(new URL(getDocumentBase(), "gumby.gif")); tracker.addImage (img, 0); tracker.waitForAll(); PixelGrabber grabber = new PixelGrabber(img, 0, 0, 32, 32, buffer, 0, 32); try { grabber.grabPixels(); } catch(InterruptedException e) { e.printStackTrace(); } for(int y = 0; y < 32; y++) { for(int x = 0; x < 32; x++) { rotate[((32−x−1)*32)+y] = buffer[(y*32)+x]; } } rot = createImage(new MemoryImageSource(32, 32, rotate, 0, 32)); } catch (Exception e) { e.printStackTrace(); } } public void update( Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(img, 0, 0,this); g.drawImage(rot,0, 40, this); } }

The next example will rotate a picture 5 degrees at a time. We are using the Java2D package (and Swing). import import import import

java.awt.*; java.awt.event.*; java.awt.geom.*; javax.swing.*;

public class RotatePanel extends JPanel { private Image image; private double currentAngle; public RotatePanel(Image image) { this.image = image; MediaTracker mt = new MediaTracker(this); mt.addImage(image, 0); try { mt.waitForID(0); } catch (Exception e) { e.printStackTrace(); } } public void rotate() {

3.46 Rotate an image

//rotate 5 degrees at a time currentAngle+=5.0; if (currentAngle >= 360.0) { currentAngle = 0; } repaint(); } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; AffineTransform origXform = g2d.getTransform(); AffineTransform newXform = (AffineTransform)(origXform.clone()); //center of rotation is center of the panel int xRot = this.getWidth()/2; int yRot = this.getHeight()/2; newXform.rotate(Math.toRadians(currentAngle), xRot, yRot); g2d.setTransform(newXform); //draw image centered in panel int x = (getWidth() − image.getWidth(this))/2; int y = (getHeight() − image.getHeight(this))/2; g2d.drawImage(image, x, y, this); g2d.setTransform(origXform); } public Dimension getPreferredSize() { return new Dimension (image.getWidth(this), image.getHeight(this)); }

public static void main(String[] args) { JFrame f = new JFrame(); Container cp = f.getContentPane(); cp.setLayout(new BorderLayout()); Image testImage = Toolkit.getDefaultToolkit().getImage("c:/temp/gumby.gif"); final RotatePanel rotatePanel = new RotatePanel(testImage); JButton b = new JButton ("Rotate"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { rotatePanel.rotate(); } }); cp.add(rotatePanel, BorderLayout.CENTER); cp.add(b, BorderLayout.SOUTH); f.pack(); f.setVisible(true); } }

3.47 Create a scrollable canvas Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0230.html JDK1.1 using a ScrollPane import java.applet.*; import java.awt.*; public class apptest extends Applet {

3.47 Create a scrollable canvas

Canvas c; ScrollPane s; public void init() { setLayout(new BorderLayout()); s = new ScrollPane(); s.setSize(100,100); add("Center", s); c = new myCanvas(); c.setSize(500,300); s.add(c); } class myCanvas extends Canvas { Image buffImage; Graphics offscreen; boolean initDone = false; myCanvas() { super(); } public void paint(Graphics g) { if (!initDone) initpaint(g); else g.drawImage(buffImage, 0, 0, this); } public void update(Graphics g) { g.drawImage(buffImage, 0, 0, this); } public void initpaint(Graphics g) { try { buffImage = this.createImage(500, 500); offscreen = buffImage.getGraphics(); offscreen.setColor(Color.black); offscreen.fillRect(0, 0, 500, 500); offscreen.setColor(Color.white); offscreen.setFont(new Font("Courier", Font.ITALIC, 42)); offscreen.drawString("Hello World!", 0, 50); initDone = true; g.drawImage(buffImage,0,0, this); } catch (Exception e) { e.printStackTrace(); } } } }

JDK1.0.2 using a Canvas with Scrollbar import java.applet.*; import java.awt.*; public class apptest extends Applet { ScrollCanvas sc; public void init() { setLayout(new FlowLayout()); sc = new ScrollCanvas (150,150, 300,200, Color.black, Color.white); add(sc); }

3.47 Create a scrollable canvas

public boolean handleEvent(Event e) { if (e.target instanceof Scrollbar) { switch (e.id) { case Event.SCROLL_ABSOLUTE: case Event.SCROLL_PAGE_DOWN: case Event.SCROLL_PAGE_UP: case Event.SCROLL_LINE_UP: case Event.SCROLL_LINE_DOWN: sc.redraw(); return true; } } return super.handleEvent(e); } } class ScrollCanvas extends Panel { int vw,vh; int rw,rh; Color b,f; myCanvas c; Scrollbar sv, sh; // constructor // visible h w // real h w // background foreground ScrollCanvas (int vw1, int vh1, int rw1, int rh1, Color b1, Color f1) { super(); vw = vw1; vh = vh1; rh = rh1; rw = rw1; b = b1; f = f1; int ScrollIncrement = 10; setLayout(new BorderLayout()); c = new myCanvas(vw, vh, rw, rh, b ,f); add("West", c); sv = new Scrollbar (Scrollbar.VERTICAL,0, ScrollIncrement, 0, rh); add("East", sv); sh = new Scrollbar (Scrollbar.HORIZONTAL, 0, ScrollIncrement, 0, rw); add("South", sh); } public void redraw() { int y = sv.getValue(); int x = sh.getValue(); c.draw(x,y); } public Dimension minimumSize() { return new Dimension(vw,vh); } public Dimension preferredSize() { return new Dimension(vw,vh); } } class myCanvas extends Canvas { int vw, vh;

3.47 Create a scrollable canvas

int rw, rh; Color b, f; int x, y; Image buffImage; Graphics offscreen; boolean initDone; myCanvas (int vw1, int vh1, int rw1, int rh1, Color b1, Color f1) { super(); vw = vw1; vh = vh1; rh = rh1; rw = rw1; b = b1; f = f1; initDone = false; repaint(); } public void paint(Graphics g) { if (!initDone) initpaint(g); else g.drawImage(buffImage, x, y, this); } public void update(Graphics g) { g.drawImage(buffImage, x, y, this); } public void initpaint(Graphics g) { try { buffImage = this.createImage(rw, rh); offscreen = buffImage.getGraphics(); offscreen.setColor(b); offscreen.fillRect(0, 0, rw, rh); offscreen.setColor(f); offscreen.setFont(new Font("Courier", Font.ITALIC, 42)); offscreen.drawString("Hello World!", 0, 50); initDone = true; g.drawImage(buffImage,0,0, this); } catch (Exception e) { System.out.println("oups..."); } } public void draw (int x1, int y1) x = −x1; y = −y1; update(getGraphics()); } public Dimension minimumSize() { return new Dimension(vw,vh); } public Dimension preferredSize() { return new Dimension(vw,vh); } }

3.47 Create a scrollable canvas

{

3.48 Use an Image as the Applet background Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0233.html import java.applet.Applet; import java.net.*; // // // //

TILE BACKGROUND in the HTML use : PARAM NAME="bgImage" VALUE="images/myImage.jpg" in the APPLET tag

public class Tile extends Applet { Image bgImage = null; public void init() { try { MediaTracker tracker = new MediaTracker (this); bgImage = getImage (new URL(getCodeBase(), getParameter("bgImage"))); tracker.addImage (bgImage, 0); tracker.waitForAll(); } catch (Exception e) { e.printStackTrace(); } setLayout(new FlowLayout()); add(new Button("Ok")); add(new TextField(10)); } public void update( Graphics g) { paint(g); } public void paint(Graphics g) { if(bgImage != null) { int x = 0, y = 0; while(y < size().height) { x = 0; while(x<size().width) { g.drawImage(bgImage, x, y, this); x=x+bgImage.getWidth(null); } y=y+bgImage.getHeight(null); } } else { g.clearRect(0, 0, size().width, size().height); } } }
<APPLET CODE=Tile.class WIDTH=150 HEIGHT=150> /HMTL

3.48 Use an Image as the Applet background

Try it here.

3.49 Have a simple Image browser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0277.html [imagelist.txt] jht.gif|JAVA How−to jsht.gif|Javascript How−to pht.gif|Powerbuilder How−to

[application version] import import import import

java.awt.*; java.awt.event.*; java.net.*; java.io.*;

public class ImageBrowser { public static void main(String s[]) { AFrame f = new AFrame(); } } class AFrame extends Frame implements ActionListener { List lbx; MyCanvas can; String url[] = new String[50]; public AFrame() { setTitle("Image selection, double click to display"); setLayout(new GridLayout(1,2)); setSize(800,600); lbx = new List(); can = new MyCanvas(); add(lbx); add(can); initLbx(); // action on listbox double click lbx.addActionListener(this); // to close the Frame addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setVisible(true); } public void actionPerformed (ActionEvent ae) { String theUrl = url[lbx.getSelectedIndex()]; MediaTracker media = new MediaTracker(this); Image image = Toolkit.getDefaultToolkit().getImage(theUrl); media.addImage(image, 0); try {

3.49 Have a simple Image browser

media.waitForID(0); can.setImage(image); } catch (Exception e) { e.printStacktrace();} } public void initLbx() { int i = 0; try { String aLine = ""; BufferedReader in = new BufferedReader(new FileReader("imagelist.txt")); while(null != (aLine = in.readLine())) { java.util.StringTokenizer st = new java.util.StringTokenizer(aLine, "|"); url[i++] = st.nextToken(); // lbx.addItem(st.nextToken()); lbx.add(st.nextToken()); } } catch(Exception e) { e.printStackTrace();} } } class MyCanvas extends Canvas { private Image image; public MyCanvas() { super(); } public void setImage(Image i) { image = i; repaint(); } public void paint(Graphics g) { if (image != null) g.drawImage(image, 0,0, this); } } NOTE : You can download this example here

[applet version] import import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*; java.io.*;

public class ImageBrowserApplet extends Applet { public void init() { APanel p = new APanel(this); setLayout(new BorderLayout()); add(p, "Center"); } } class APanel extends Panel implements ActionListener { private List lbx; private MyCanvas can;

3.49 Have a simple Image browser

private Applet parent = null; private String url[] = new String[50]; public APanel(Applet a) { parent = a; setLayout(new GridLayout(1,2)); lbx = new List(); can = new MyCanvas(); add(lbx); add(can); initLbx(); // action on listbox double click lbx.addActionListener(this); setBackground(new Color(0).white); } public void actionPerformed (ActionEvent ae) { try { URL theUrl = new URL(parent.getCodeBase(), url[lbx.getSelectedIndex()]); MediaTracker media = new MediaTracker(this); Image image = Toolkit.getDefaultToolkit().getImage(theUrl); media.addImage(image, 0); media.waitForID(0); can.setImage(image); } catch (Exception e) { e.printStackTrace();} } public void initLbx() { int i = 0; try { String aLine = ""; URL source = new URL(parent.getCodeBase(), "imagelist.txt"); BufferedReader in = new BufferedReader (new InputStreamReader(source.openStream()));; while(null != (aLine = in.readLine())) { java.util.StringTokenizer st = new java.util.StringTokenizer(aLine, "|"); url[i++] = st.nextToken(); // lbx.addItem(st.nextToken()); lbx.add(st.nextToken()); } } catch(Exception e) { e.printStackTrace();} } } class MyCanvas extends Canvas { private Image image; public MyCanvas() { super(); } public void setImage(Image i) { image = i; repaint(); } public void paint(Graphics g) { if (image != null)

3.49 Have a simple Image browser

g.drawImage(image, 0,0, this); } } NOTE : You can try this example here

3.50 Simulate a "mouse over" event to toggle an image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0264.html Use a special Canvas to preload 2 GIFs, and using a MouseListener simply toggle the image. [JDK1.1] import java.awt.*; import java.awt.event.*; import java.net.*; public class ToggleGifCanvas extends Canvas implements MouseListener { Image img1, img2; int index = 0; MediaTracker tracker; public ToggleGifCanvas(URL n1, URL n2) { tracker = new MediaTracker(this); try { img1 = Toolkit.getDefaultToolkit().getImage(n1); img2 = Toolkit.getDefaultToolkit().getImage(n2); tracker.addImage(img1,0); tracker.addImage(img2,1); tracker.waitForAll(); addMouseListener(this); } catch (Exception e) { e.printStackTrace(); } } public void paint(Graphics g) { if (img1 != null) { if (index == 0) { g.drawImage(img1,0,0,this); index++; } else { g.drawImage(img2,0,0,this); index−−; } } } public Dimension getPreferredSize (){ return new Dimension (img1.getHeight(this), img2.getWidth(this)); } public void mouseClicked(MouseEvent e) {}

3.50 Simulate a "mouse over" event to toggle an image

public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) { index = 1; repaint(); } public void mouseExited(MouseEvent e) { index = 0; repaint(); } }

To use such Canvas, try something like this. This example needs our Gumby GIFs ( ).

import java.applet.*; import java.awt.*; import java.net.*; public class TestToogleGifCanvas extends Applet { ToggleGifCanvas tgc; public void init() { try { tgc = new ToggleGifCanvas (new URL(getDocumentBase(),"images/gumby.gif"), new URL(getDocumentBase(),"images/gumby2.gif")); add(tgc); } catch (Exception e) { e.printStackTrace(); } } }

Try it here.

3.51 Hide the mouse cursor Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0440.html One way is to use a transparent GIF as the cursor or create one. int[] pixels = new int[16 * 16]; Image image = Toolkit.getDefaultToolkit().createImage( new MemoryImageSource(16, 16, pixels, 0, 16)); Cursor transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor (image, new Point(0, 0), "invisibleCursor");

3.51 Hide the mouse cursor

and

3.52 Make a color transparent Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0265.html Here we have an Image with a blue background like

and we want to display it in an Applet with

a white background. All we have to do is to look for the blue color with the "Alpha bits" set to opaque and make them transparent. [Transparency.java] import java.awt.*; import java.awt.image.*; public class Transparency { public static Image makeColorTransparent (Image im, final Color color) { ImageFilter filter = new RGBImageFilter() { // the color we are looking for... Alpha bits are set to opaque public int markerRGB = color.getRGB() | 0xFF000000; public final int filterRGB(int x, int y, int rgb) { if ( ( rgb | 0xFF000000 ) == markerRGB ) { // Mark the alpha bits as zero − transparent return 0x00FFFFFF &rgb; } else { // nothing to do return rgb; } } }; ImageProducer ip = new FilteredImageSource(im.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } }

[app.java] import java.awt.image.*; import java.awt.*; import java.net.*; public class app extends java.applet.Applet { Image GifOriginalWithWithBlueBackground; Image GifModifiedWithTransparentBackground; public void init() { setBackground(new Color(0).white); MediaTracker media = new MediaTracker(this); // image of our friend, Gumby with a blue background GifOriginalWithWithBlueBackground = getImage(getDocumentBase(),"gumbyblu.gif"); media.addImage(GifOriginalWithWithBlueBackground,0); try { media.waitForID(0); GifModifiedWithTransparentBackground =

3.52 Make a color transparent

Transparency.makeColorTransparent (GifOriginalWithWithBlueBackground, new Color(0).blue); } catch(InterruptedException e) {} } public void paint(Graphics g) { g.drawImage(GifOriginalWithWithBlueBackground, 10,10,this); g.drawImage(GifModifiedWithTransparentBackground,10, 80,this); } }

[x.html] <APPLET CODE="app.class" NAME="myApplet" HEIGHT=200 WIDTH=200>

3.53 Save an Image as a GIF or JPEG file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0266.html Take a look at the following package : http://www.obrador.com/essentialjpeg/jpeg.htm for JPEG http://www.acme.com for GIF http://rsb.info.nih.gov/ij/ can display BMP and save as GIF or TIFF With JDK1.2, Sun introduces a new package called JIMI (available for download at their Web site. With this package, it's easy to convert a Java Image to a JPEG image file. double w = 200.0; double h = 200.0; BufferedImage image = new BufferedImage( (int)w,(int)h,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D)image.getGraphics(); g.drawLine(0,0,w,h); try { File f = new File("myimage.jpg"); JimiRasterImage jrf = Jimi.createRasterImage(image.getSource()); Jimi.putImage("image/jpeg",jrf,new FileOutputStream(f)); } catch (JimiException je) { je.printStackTrace();}

Another way is to use the undocumented com.sun.image.codec.jpeg package. // [JDK1.2] // img is a Java Image // BufferedImage bimg = null;

3.53 Save an Image as a GIF or JPEG file

int w = img.getWidth(null); int h = img.getHeight(null); int [] pixels = new int[w * h]; PixelGrabber pg = new PixelGrabber(img,0,0,w,h,pixels,0,w); try { pg.grabPixels(); } catch(InterruptedException ie) { ie.printStackTrace(); } bimg = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); bimg.setRGB(0,0,w,h,pixels,0,w); // Encode as a JPEG FileOutputStream fos = new FileOutputStream("out.jpg"); JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(fos); jpeg.encode(bimg); fos.close();

Since JDK1.4.2, javax.imageio.ImageIO lets you save and restore Images to disk in a platform independent format. "png" and "jpeg" format are supported. With ImageIO, instead of Image you use BufferedImage which is a subclass of Image. import java.io.*; import javax.imageio.*; import java.awt.image.*; public class FileOperations { public static BufferedImage readImageFromFile(File file) throws IOException { return ImageIO.read(file); } public static void writeImageToJPG (File file,BufferedImage bufferedImage) throws IOException { ImageIO.write(bufferedImage,"jpg",file); } }

3.54 Use the same background color as the browser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0234.html // in the HTML, use // PARAM NAME="bgColor" VALUE="B8B5AE" // (where VALUE is the same hexadecimal value // as the HTML COLOR value) // in the APPLET tag // in the JAVA init method : Color bgcolor = new Color( Integer.valueOf(getParameter("BGCOLOR"), 16).intValue()); setBackground(bgcolor);

3.54 Use the same background color as the browser

3.55 Do simple animation using Images Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0262.html By using a Thread, we switch between 2 GIFs (

import import import import

and

)

java.applet.*; java.awt.*; java.awt.image.*; java.net.*;

public class AnimationGifApplet extends Applet { Image [] img; int index = 0; int maxImg; MediaTracker tracker; public void init() { img = new Image[2]; // 2 images in animation maxImg = img.length − 1; tracker = new MediaTracker(this); try { // images loading img[0] = getImage(new URL(getDocumentBase(), "images/gumby.gif")); img[1] = getImage(new URL(getDocumentBase(), "images/gumby2.gif")); tracker.addImage(img[0],0); tracker.addImage(img[1],1); tracker.waitForAll(); } catch (Exception e) { e.printStackTrace(); } AnimationThread at = new AnimationThread(); at.delayedAnimation(this, 500); at.start(); } public void paint(Graphics g) { if (img[0] != null) { g.drawImage(img[index],0,0,this); index = (index <maxImg) ? index + 1 : 0; } } public void animate() { repaint(); } class AnimationThread extends Thread { AnimationGifApplet animationApplet; int delay; public void delayedAnimation(AnimationGifApplet a, int delay) { this.animationApplet = a; this.delay = delay; }

3.55 Do simple animation using Images

public void run() { while (true) { try { sleep(delay); animationApplet.animate(); } catch (Exception e) { e.printStackTrace(); } } } } }

Try it here.

3.56 Do simple animation to show "work in progress" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0263.html Like the previous How−to, using a Thread, we switch between 2 GIFs, for example ( ). Click the button to simulate some work, click again to terminate the "work in progress" [JDK1.1] import import import import import

java.applet.*; java.awt.*; java.awt.image.*; java.awt.event.*; java.net.*;

public class AnimationProgress extends Applet implements ActionListener{ Image [] img; int index = 0; int maxImg; boolean working = false; Button b; MediaTracker tracker; public void init() { setLayout(new FlowLayout(FlowLayout.LEFT)); add(b = new Button("Working")); b.addActionListener(this); img = new Image[2]; // 2 images in animation maxImg = img.length − 1; tracker = new MediaTracker(this); try { // images loading img[0] = getImage(new URL(getDocumentBase(), "gumby.gif")); img[1] = getImage(new URL(getDocumentBase(), "gumby2.gif")); tracker.addImage(img[0],0);

3.56 Do simple animation to show "work in progress"

and

tracker.addImage(img[1],1); tracker.waitForAll(); } catch (Exception e) { e.printStackTrace(); } AnimationThread at = new AnimationThread(); at.delayedAnimation(this, 500); at.start(); } public void paint(Graphics g) { if (img[0] != null) { if (working) { g.drawImage(img[index],68,0,this); index = (index <maxImg) ? index + 1 : 0; } } } public void animate() { repaint(); } public void actionPerformed(ActionEvent ae) { working = !working; } class AnimationThread extends Thread { AnimationProgress animationApplet; int delay; public void delayedAnimation(AnimationProgress a, int delay) { this.animationApplet = a; this.delay = delay; } public void run() { while (true) { try { sleep(delay); animationApplet.animate(); } catch (Exception e) { e.printStackTrace(); } } } } }

3.57 Get the color of a specific pixel Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0257.html We assume that we have an Image called picture pixels = new int[width*height];

3.57 Get the color of a specific pixel

PixelGrabber pg = new PixelGrabber(picture, 0, 0, width, height, pixels, 0, width); try { pg.grabPixels(); } catch (InterruptedException e) { }

From here, individual pixel can be accessed via the pixels array. int c = pixels[index]; // or pixels[x * width + y] int red = (c &0x00ff0000) >> 16; int green = (c &0x0000ff00) >> 8; int blue = c &0x000000ff; // and the Java Color is ... Color c = new Color(red,green,blue);

Here another way to achieve this import javax.imageio.ImageIO; import java.awt.image.BufferedImage ... BufferedImage image = ImageIO.read(urlImage); int c = image.getRGB(x,y); int red = (c &0x00ff0000) >> 16; int green = (c &0x0000ff00) >> 8; int blue = c &0x000000ff; // and the Java Color is ... Color c = new Color(red,green,blue);

3.58 Do "rubber−band" drawing Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0251.html import java.applet.*; import java.awt.*; import java.util.Vector; public class SimpleCAD extends Applet { int w = 200; int h = 200; Vector lines = new Vector(); int np = 0; int x1,y1; int x2,y2; int xl,yl; Image offImg; Graphics offGra; Button btnClear, btnUndo; public void init() { setLayout(new FlowLayout()); btnClear = new Button("Clear"); btnUndo = new Button("Undo"); add(btnClear); add(btnUndo); setBackground(new Color(0).black);

3.58 Do "rubber−band" drawing

setForeground(new Color(0).white); } public void Dragupdate(Graphics g) { /* ** rubber−band effect */ g.setXORMode(getBackground()); setForeground(new Color(0).blue); if (xl != −1){ // erase the old line g.drawLine(x1, y1, xl, yl); if (x2 != −1) { // draw the new one g.drawLine(x1, y1, x2, y2); } } } public void update(Graphics g) { // draw an offScreen drawing Dimension dim = getSize(); if (offGra == null) { offImg = createImage(dim.width, dim.height); offGra = offImg.getGraphics(); } offGra.setColor(new Color(0).black); offGra.fillRect(0,0,dim.width, dim.height); offGra.setColor(new Color(0).white); offGra.setPaintMode(); for (int i=0; i < np; i++) { Rectangle p = (Rectangle)lines.elementAt(i); if (p.width != −1) { offGra.drawLine(p.x, p.y, p.width, p.height); } } // put the OffScreen image OnScreen g.drawImage(offImg,0,0,null); } public boolean handleEvent(Event e) { switch (e.id) { case Event.MOUSE_DOWN: // new starting point x1 = e.x; y1 = e.y; // begin an new drawing process x2 = −1; return true; case Event.MOUSE_UP: // end a drawing process lines.addElement(new Rectangle(x1, y1, e.x, e.y)); np++; x2 = xl = −1; repaint(); return true; case Event.MOUSE_DRAG: // xl yl line to be erased xl = x2; yl = y2; // x2 y2 last current point x2 = e.x; y2 = e.y;

3.58 Do "rubber−band" drawing

Dragupdate(getGraphics()); return true; } return super.handleEvent(e); } public boolean action(Event e, Object o) { if (e.target == btnClear) resetDrawing(); if (e.target == btnUndo) undo(); return true; } public void undo() { if (np>0) { lines.removeElementAt(np−1); np−−; repaint(); } } public void resetDrawing() { lines.removeAllElements(); np=0; repaint(); } }

3.59 Convert RGB value to Hexadecimal (to be used in HTML for example) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0255.html import java.awt.*; public class Color2Hex { public static void main( String[] args ) { if (args.length != 3) { System.out.println("Color2Hex r g b"); } else { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); int k = Integer.parseInt(args[2]); Color c = new Color(i,j,k); System.out.println ( "hex: " + Integer.toHexString( c.getRGB() &0x00ffffff ) ); } } }

3.60 Draw a line or set a pixel in my own image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0250.html

3.59 Convert RGB value to Hexadecimal (to be used in HTML for example)

import java.awt.image.*; import java.awt.*; import java.applet.*; public class CreateAnImage extends Applet { Image myImage; public void init() { int x = 100; int y = 100; myImage = createImage(x,y); Graphics g = myImage.getGraphics(); g.drawLine(0,0,x,y); g.drawLine(x,0,0,y); for(int i=0; i <x; i+=2){ setPixel(myImage, 50, i, new Color(0).blue); setPixel(myImage, i, 50, new Color(0).green); } } public void paint(Graphics g) { g.drawImage(myImage,0,0,this); } public void setPixel (Image image, int x, int y, Color color ) { Graphics g = image.getGraphics( ); g.setColor( color ); g.fillRect( x, y, 1, 1 ); g.dispose( ); } }

3.61 Draw a dashed line Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0224.html public void drawDashedLine(Graphics g,int x1,int y1,int x2,int y2, double dashlength, double spacelength) { if((x1==x2){ g.drawLine(x1,y1,x2,y2); return; } double linelength=Math.sqrt((x2−x1)*(x2−x1)+(y2−y1)*(y2−y1)); double yincrement=(y2−y1)/(linelength/(dashlength+spacelength)); double xincdashspace=(x2−x1)/(linelength/(dashlength+spacelength)); double yincdashspace=(y2−y1)/(linelength/(dashlength+spacelength)); double xincdash=(x2−x1)/(linelength/(dashlength)); double yincdash=(y2−y1)/(linelength/(dashlength)); int counter=0; for (double i=0;i
3.61 Draw a dashed line

(int) (y1+yincdashspace*counter), x2,y2); }

3.62 Draw a line with a thickness Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0260.html import java.awt.*; import java.applet.*; public class thickLine extends Applet { public void init( ) { } public void paint( Graphics g ) { drawThickLine (g, 0, 0, getSize().width, getSize().height, 5, new Color(0).black); drawThickLine (g, 0, getSize().height, getSize().width, 0, 5, new Color(0).red); drawThickLine (g, getSize().width/2, 0, getSize().width/2, getSize().height, 8, new Color(0).green); drawThickLine (g, 0, getSize().height/2, getSize().width, getSize().height/2, 12, new Color(0).blue); } public void drawThickLine( Graphics g, int x1, int y1, int x2, int y2, int thickness, Color c) { // The thick line is in fact a filled polygon g.setColor(c); int dX = x2 − x1; int dY = y2 − y1; // line length double lineLength = Math.sqrt(dX * dX + dY * dY); double scale = (double)(thickness) / (2 * lineLength); // The double double ddx += ddy += int dx int dy

x,y increments from an endpoint needed to create a rectangle... ddx = −scale * (double)dY; ddy = scale * (double)dX; (ddx > 0) ? 0.5 : −0.5; (ddy > 0) ? 0.5 : −0.5; = (int)ddx; = (int)ddy;

// Now we can compute the corner points... int xPoints[] = new int[4]; int yPoints[] = new int[4]; xPoints[0] xPoints[1] xPoints[2] xPoints[3]

= = = =

x1 x1 x2 x2

+ − − +

dx; dx; dx; dx;

yPoints[0] yPoints[1] yPoints[2] yPoints[3]

= = = =

g.fillPolygon(xPoints, yPoints, 4); }

3.62 Draw a line with a thickness

y1 y1 y2 y2

+ − − +

dy; dy; dy; dy;

}

Using JDK1.2 public void paint(Graphics g){ Graphics2D g2d = (Graphics2D)g; int width = 10; g2d.setStroke(new BasicStroke(width)); g2d.drawLine(x1, y1, x2, y2); }

On a Component int width = 10; BasicStroke bs = new BasicStroke(width); JLabel l = new JLabel(); l.getGraphics().setStroke(bs); l.drawLine(0,0,100,100);

Using JDK1.3 import javax.swing.*; import java.awt.*; import java.awt.geom.*; public class TestLine extends JFrame{ private MyPanel panel; public TestLine() { setSize(200, 200); panel = new MyPanel(); getContentPane().add( panel, "Center" ); } public static void main( String [] args ){ TestLine tl = new TestLine(); tl.setVisible( true ); } } class MyPanel extends JPanel { final static BasicStroke stroke = new BasicStroke(2.0f); final static BasicStroke wideStroke = new BasicStroke(8.0f); public MyPanel(){} public void paintComponent( Graphics g ){ Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke( stroke ); g2.draw(new Line2D.Double(10.0, 10.0, 100.0, 10.0)); g2.setStroke( wideStroke ); g2.draw(new Line2D.Double(10.0, 50.0, 100.0, 50.0)); } }

3.62 Draw a line with a thickness

3.63 Draw a pie chart Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0261.html import java.util.*; import java.awt.*; import java.applet.Applet; public class Graph extends Applet { int depth, radius; public void init() { float value; String at = getParameter("width"); radius = (at != null) ? Integer.valueOf(at).intValue() : 100; at = getParameter("depth"); depth = (at != null) ? Integer.valueOf(at).intValue() : 20; at = getParameter("values"); PieChartCanvas c = new PieChartCanvas(radius, depth); setLayout(new BorderLayout()); // Create Hashtable to map color name (String) to Color type Hashtable colors = new Hashtable(); colors.put("green", Color.green); colors.put("red", Color.red); colors.put("blue", Color.blue); colors.put("yellow", Color.yellow); colors.put("magenta", Color.magenta); colors.put("cyan", Color.cyan); colors.put("orange", Color.orange); colors.put("pink", Color.pink); colors.put("white", Color.white); colors.put("black", Color.black); // "value−color,value−color,..." StringTokenizer t = new StringTokenizer(at, ","); String s; int i; while (t.hasMoreTokens()) { s = t.nextToken(); i = s.indexOf('−'); value = Float.valueOf(s.substring(0, i)).floatValue(); c.addSlice(value, (Color)colors.get(s.substring(i + 1))); } resize(c.getMinimumSize().width, c.getMinimumSize().height); add("Center", c); } } class PieChartCanvas extends Canvas { /* ** author Ciaran Treanor [email protected] */ final double aspectFudge = 2.5; int radius, depth, called = 1, numSlices = 0; float total = 0, value[] = new float[10]; Color color[] = new Color[10]; Graphics offGraphics; Image gfxBuff;

3.63 Draw a pie chart

public PieChartCanvas(int radius, int depth) { this.value = value; this.color = color; this.radius = radius; this.depth = depth; } public void paint(Graphics g) { int startAngle; float angle; Dimension d = getSize(); if(gfxBuff == null) { gfxBuff = createImage(d.width, d.height); offGraphics = gfxBuff.getGraphics(); offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); } // do the 3d effect for(int x = depth; x >= 1; x−−) { startAngle = −45; for(int i = 0; i < numSlices; i++) { offGraphics.setColor(color[i].darker()); angle = Math.round(360 * (value[i] / total)); offGraphics.fillArc(0, x, radius, (int)(radius / aspectFudge), startAngle, (int)angle); startAngle += angle; } } // draw the pie slice startAngle = −45; for(int i = 0; i < numSlices; i++) { offGraphics.setColor(color[i]); angle = Math.round(360 * (value[i] / total)); offGraphics.fillArc(0, 0, radius, (int)(radius / aspectFudge), startAngle, (int)angle); startAngle += angle; } g.drawImage(gfxBuff, 0, 0, null); } public void addSlice(float value, Color color) { this.value[numSlices] = value; this.color[numSlices++] = color; total += value; } public Dimension getPreferredSize() { return getMinimumSize(); } public Dimension getMinimumSize() { return new Dimension(radius, (int)((radius / aspectFudge) + depth)); } }

[JavaPie.hmtl]
<APPLET CODE=Graph.class WIDTH=150 HEIGHT=150>

3.63 Draw a pie chart

item 1
item 2
item 3
Try it here

3.64 Draw faster rectangles Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0364.html Thanks to Chikirev Sergey

It seems that drawRoundRect(….) 1,5 faster then drawRect(…..) , because one of them is completely native. import java.awt.*; import java.awt.event.*; public class Class1 extends Frame implements ActionListener{ public void paint(Graphics g){ super.paint(g); long t=System.currentTimeMillis(); for(int i=0;i<10000;i++){ g.drawRect(10,70,100,50); } t=System.currentTimeMillis()−t; g.drawString(String.valueOf(t),10,70); t=System.currentTimeMillis(); for(int i=0;i<10000;i++){ g.drawRoundRect(10,130,100,50,0,0); } t=System.currentTimeMillis()−t; g.drawString(String.valueOf(t),10,130); } public void actionPerformed(ActionEvent p1){ repaint(0,10,200,300); } public static void main (String[] args){ Class1 c=new Class1(); c.setSize(300,300); c.setLayout(new BorderLayout()); Button b=new Button("Refresh"); c.add(BorderLayout.SOUTH , b); b.addActionListener(c); c.show(); } }

3.64 Draw faster rectangles

3.65 Get a screen capture and save it as a JPEG Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0489.html The screen capture is done with java.awt.Robot. import import import import import import import

java.awt.AWTException; java.awt.Robot; java.awt.Rectangle; java.awt.Toolkit; java.awt.image.BufferedImage; java.io.*; javax.imageio.ImageIO;

class ScreenCapture { public static void main(String args[]) throws AWTException, IOException { // capture the whole screen BufferedImage screencapture = new Robot().createScreenCapture( new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) ); // Save as JPEG File file = new File("screencapture.jpg"); ImageIO.write(screencapture, "jpg", file); // Save as PNG // File file = new File("screencapture.png"); // ImageIO.write(screencapture, "png", file); } }

To capture a specific area BufferedImage screencapture = new Robot().createScreenCapture( new Rectangle( 15, 15, 150, 150));

To capture a specific visual object BufferedImage image = new Robot().createScreenCapture( new Rectangle( myframe.getX(), myframe.getY(), myframe.getWidth(), myframe.getHeight() ) ); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

3.66 Display a TIF Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0605.html

3.65 Get a screen capture and save it as a JPEG

The regular JDK can only deal with JPG, GIF, BMP or PNG file with the package ImageIO, see this HowTo. To deal with TIF file, you must use the JAI (Java Advanced Imaging) package. This example will display a given TIF file. It will also display other types (JPG,...) by detecting the type. import import import import import import import import import import

javax.media.jai.PlanarImage; com.sun.media.jai.codec.ByteArraySeekableStream; com.sun.media.jai.codec.ImageCodec; com.sun.media.jai.codec.ImageDecoder; com.sun.media.jai.codec.SeekableStream; java.io.FileInputStream; java.nio.ByteBuffer; java.nio.channels.FileChannel; java.awt.Image; java.awt.image.RenderedImage;

import javax.swing.JOptionPane; import javax.swing.JLabel; import javax.swing.ImageIcon; public class ImageViewer

{

static Image load(byte[] data) throws Exception{ Image image = null; SeekableStream stream = new ByteArraySeekableStream(data); String[] names = ImageCodec.getDecoderNames(stream); ImageDecoder dec = ImageCodec.createImageDecoder(names[0], stream, null); RenderedImage im = dec.decodeAsRenderedImage(); image = PlanarImage.wrapRenderedImage(im).getAsBufferedImage(); return image; } public static void main(String[] args) throws Exception{ String path; if (args.length==0) { path = JOptionPane.showInputDialog(null, "Image Path", "c:/applications/sidebar.tif"); } else { path = args[0]; } FileInputStream in = new FileInputStream(path); FileChannel channel = in.getChannel(); ByteBuffer buffer = ByteBuffer.allocate((int)channel.size()); channel.read(buffer); Image image = load(buffer.array()); // make sure that the image is not too big // scale with a width of 500 Image imageScaled = image.getScaledInstance(500, −1, Image.SCALE_SMOOTH); // System.out.println("image: " + path + "\n" + image); // JOptionPane.showMessageDialog(null, new JLabel( new ImageIcon( imageScaled )) ); } }

3.65 Get a screen capture and save it as a JPEG

The JAI package is composed of 2 jars : jai_core.jar and jai_codec.jar http://java.sun.com/javase/technologies/desktop/media/jai/ https://jai.dev.java.net/#Downloads To write a TIF file, see this HowTo

3.67 Convert a multi−page TIF into single−page TIF Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0535.html Tagged Image File Format (abbreviated TIFF) is a file format for mainly storing images, including photographs and line art. TIFF was originally created as an attempt to get desktop scanner vendors of the mid−1980's to agree on a common scanned image file format, rather than have each company promulgate its own proprietary format. This HowTo takes a multi−page TIF (from a FAX) and convert it into many single−pages TIF. This is done with the JAI (Java Advance Image) package. http://java.sun.com/products/java−media/jai/index.jsp > import java.io.*; import import import import

com.sun.media.jai.codec.FileSeekableStream; com.sun.media.jai.codec.ImageDecoder; com.sun.media.jai.codec.ImageCodec; com.sun.media.jai.codec.TIFFEncodeParam;

import import import import

java.awt.image.RenderedImage; javax.media.jai.RenderedOp; javax.media.jai.JAI; java.awt.image.renderable.ParameterBlock;

public class TestTiff { public static void main(String[] args) throws IOException { new TestTiff().doitJAI(); } public void doitJAI() throws IOException { FileSeekableStream ss = new FileSeekableStream("d:/multi.tif"); ImageDecoder dec = ImageCodec.createImageDecoder("tiff", ss, null); int count = dec.getNumPages(); TIFFEncodeParam param = new TIFFEncodeParam(); param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4); param.setLittleEndian(false); // Intel System.out.println("This TIF has " + count + " image(s)"); for (int i = 0; i < count; i++) { RenderedImage page = dec.decodeAsRenderedImage(i); File f = new File("d:/single_" + i + ".tif"); System.out.println("Saving " + f.getCanonicalPath());

3.67 Convert a multi−page TIF into single−page TIF

ParameterBlock pb = new ParameterBlock(); pb.addSource(page); pb.add(f.toString()); pb.add("tiff"); pb.add(param); RenderedOp r = JAI.create("filestore",pb); r.dispose(); } } }

This solution is working but JAI is a slow performer. You may want to consider to use an external utility to do this kind on conversion. A nice one is irfanview (win), a (free) multi−purpose graphic utility. http://www.irfanview.com/ To do a TIF conversion, use this command line : C:\IrfanView\i_view32" d:\multi.tif /extract=(d:\,tif) /killmesoftly

irfanview is an amazing software when it comes to transform a graphic format to another one. You can use it from a command line or from a GUI. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

3.68 Convert an Image to a BufferedImage Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0601.html import import import import

java.awt.*; java.awt.image.*; javax.imageio.*; java.io.*;

public class ImageUtils { public static BufferedImage imageToBufferedImage(Image im) { BufferedImage bi = new BufferedImage (im.getWidth(null),im.getHeight(null),BufferedImage.TYPE_INT_RGB); Graphics bg = bi.getGraphics(); bg.drawImage(im, 0, 0, null); bg.dispose(); return bi; } public static BufferedImage readImageFromFile(File file) throws IOException { return ImageIO.read(file); }

3.68 Convert an Image to a BufferedImage

public static void writeImageToPNG (File file,BufferedImage bufferedImage) throws IOException { ImageIO.write(bufferedImage,"png",file); } public static void writeImageToJPG (File file,BufferedImage bufferedImage) throws IOException { ImageIO.write(bufferedImage,"jpg",file); } }

You need to do something to transform an Image to BufferedImage. But since BufferedImage extends Image, so there isn't a back−conversion, it's not needed.

3.69 Detect a double click vs simple click Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0235.html [JDK1.02] import java.applet.*; import java.awt.*; public class d extends Applet { int dClkRes = 300; // double−click speed in ms long timeMouseDown=0; // last mouse down time int lastX=0,lastY=0; // last x and y public boolean mouseDown(Event event, int x, int y){ /* ** check for double click */ long currentTime = event.when; if ((lastX==x) &(lastY==y) & ((event.when−timeMouseDown) < dClkRes)) { System.out.println("double click " + currentTime); return false; } else { //single click action could be added here System.out.println("simple click " + currentTime); timeMouseDown = event.when; lastX=x; lastY=y; } return true; } }

[JDK11]

3.69 Detect a double click vs simple click

import java.applet.*; import java.awt.*; import java.awt.event.*; public class d extends Applet implements MouseListener { public void init() { this.addMouseListener(this); } public void paint(Graphics g) { g.drawString("Click here", 10,10); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) { System.out.println ( "Click at (" + e.getX() + ":" + e.getY() + ")" ); if (e.getClickCount() == 2) System.out.println( " and it's a double click!"); else System.out.println( " and it's a simple click!"); } }

3.70 Detect the mouse button used when clicking Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0236.html [JDK11] import java.applet.*; import java.awt.*; import java.awt.event.*; public class d extends Applet implements MouseListener { public void init() { this.addMouseListener(this); } public void paint(Graphics g) { g.drawString("Click here", 10,10); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) { switch(e.getModifiers()) { case InputEvent.BUTTON1_MASK: { System.out.println("That's the LEFT button"); break;

3.70 Detect the mouse button used when clicking

} case InputEvent.BUTTON2_MASK: { System.out.println("That's the MIDDLE button"); break; } case InputEvent.BUTTON3_MASK: { System.out.println("That's the RIGHT button"); break; } } } }

3.71 Exit an application from a menu Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0276.html import java.awt.*; import java.awt.event.*; public class ExitFromMenu extends Frame implements ActionListener { Menu m = new Menu("Exit From Here"); ExitFromMenu() { super(""); MenuBar mb = new MenuBar(); mb.add(m); MenuItem m1 = m.add(new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X))); m1.setActionCommand("Exit"); m.addActionListener(this); setMenuBar(mb); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { // unique exit point System.out.println("Bye."); System.exit(0); } } ); add(new Label ("You can quit by clicking on the 'X'"),"South"); add(new Label ("You can quit by clicking on the menu item 'Exit'"),"Center"); add(new Label ("You can quit with the MenuShortcut 'ctrl−x'"),"North"); setSize(300, 300); show(); } public void actionPerformed(ActionEvent evt) { String what = evt.getActionCommand(); if (what.equals("Exit")) processEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));

3.71 Exit an application from a menu

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

3.72 Trigger a click on a Button Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0468.html In this example, when we click on a Button, we trigger the action attached to the another Button. Regular AWT (applet) import java.awt.*; import java.awt.event.*; import java.applet.*; public class TestEvent extends Applet implements ActionListener { Button b2, b1; TextField t1; public void init() { setLayout(new FlowLayout()); t1 = new TextField(30); b1 = new Button("Output"); add(b1); add(t1); b2 = new Button("Fire event 1st button"); add(b2); b1.addActionListener(this); b2.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource() == b1) { t1.setText("1st button clicked"); } if (e.getSource() == b2) { // from the b2 button, we creating an event to trigger a click // on the b1 button ActionEvent ae = new ActionEvent((Object)b1, ActionEvent.ACTION_PERFORMED, ""); Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae); // b1.dispatchEvent(ae); can be used too. } } }

With Swing (japplet) import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestEventSwing extends JApplet implements ActionListener {

3.72 Trigger a click on a Button

JButton b1, b2; JTextField t1; public void init() { setLayout(new FlowLayout()); t1 = new JTextField(30); b1 = new JButton("Output"); add(b1); add(t1); b2 = new JButton("Fire event 1st button"); add(b2); b1.addActionListener(this); b2.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource() == b1) { t1.setText("first button clicked"); } if (e.getSource() == b2) { // from the b2 button, we trigger a click on the b1 button. // As an added bonus, we have visual effect on b1! b1.doClick(); } } }

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

3.72 Trigger a click on a Button

4 Environment 4.1 java−env

4.2 Read environment variables from an application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0150.html NOTE: JDK1.5 or better provides a simpler way to achieve this, see this HowTo. JDK up to 1.4 Start the JVM with the "−D" switch to pass properties to the application and read them with the System.getProperty() method. SET myvar=Hello world SET myothervar=nothing java −Dmyvar="%myvar%" −Dmyothervar="%myothervar%" myClass

then in myClass String myvar = System.getProperty("myvar"); String myothervar = System.getProperty("myothervar");

If you don't know in advance, the name of the variable to be passed to the JVM, then there is no 100% Java way to retrieve them. One approach (not the easiest one), is to use a JNI call to fetch the variables, see this HowTo. A more low−tech way, is to launch the appropriate call to the operating system and capture the output. The following snippet puts all environment variables in a Properties class and display the value the TEMP variable. import java.io.*; import java.util.*; public class ReadEnv { public static Properties getEnvVars() throws Throwable { Process p = null; Properties envVars = new Properties(); Runtime r = Runtime.getRuntime(); String OS = System.getProperty("os.name").toLowerCase(); // System.out.println(OS); if (OS.indexOf("windows 9") > −1) { p = r.exec( "command.com /c set" ); } else if ( (OS.indexOf("nt") > −1) || (OS.indexOf("windows 2000") > −1 ) || (OS.indexOf("windows xp") > −1) ) { // thanks to JuanFran for the xp fix! p = r.exec( "cmd.exe /c set" ); } else {

4 Environment

// our last hope, we assume Unix (thanks to H. Ware for the fix) p = r.exec( "env" ); } BufferedReader br = new BufferedReader ( new InputStreamReader( p.getInputStream() ) ); String line; while( (line = br.readLine()) != null ) { int idx = line.indexOf( '=' ); String key = line.substring( 0, idx ); String value = line.substring( idx+1 ); envVars.setProperty( key, value ); // System.out.println( key + " = " + value ); } return envVars; } public static void main(String args[]) { try { Properties p = ReadEnv.getEnvVars(); System.out.println("the current value of TEMP is : " + p.getProperty("TEMP")); } catch (Throwable e) { e.printStackTrace(); } } } thanks to w.rijnders for the w2k fix.

An update from Van Ly : I found that, on Windows 2003 server, the property value for "os.name" is actually "windows 2003." So either that has to be added to the bunch of tests or just relax the comparison strings a bit: else if ( (OS.indexOf("nt") > −1) || (OS.indexOf("windows 2000") > −1 ) || (OS.indexOf("windows 2003") > −1 )

// ok // but specific to 2003

|| (OS.indexOf("windows xp") > −1) ) {

else if ( (OS.indexOf("nt") > −1) || (OS.indexOf("windows 20") > −1 )

// better, // since no other OS would // return "windows" || (OS.indexOf("windows xp") > −1) ) {

I started with "windows 200" but thought "what the hell" and made it "windows 20" to lengthen its longivity. You could push it further and use "windows 2," I suppose. The only thing to watch out for is to not overlap with "windows 9." On Windows, pre−JDK 1.2 JVM has trouble reading the Output stream directly from the SET command, it never returns. Here 2 ways to bypass this behaviour. First, instead of calling directly the SET command, we use a BAT file, after the SET command we print a known string. Then, in Java, when we read this known string, we exit from loop.

4 Environment

[env.bat] @set @echo **end [java] ... if (OS.indexOf("windows") > −1) { p = r.exec( "env.bat" ); } ... while( (line = br.readLine()) != null ) { if (line.indexOf("**end")>−1) break; int idx = line.indexOf( '=' ); String key = line.substring( 0, idx ); String value = line.substring( idx+1 ); hash.put( key, value ); System.out.println( key + " = " + value ); }

The other solution is to send the result of the SET command to file and then read the file from Java. ... if (OS.indexOf("windows 9") > −1) { p = r.exec( "command.com /c set > envvar.txt" ); } else if ( (OS.indexOf("nt") > −1) || (OS.indexOf("windows 2000") > −1 || (OS.indexOf("windows xp") > −1) ) { // thanks to JuanFran for the xp fix! p = r.exec( "cmd.exe /c set > envvar.txt" ); } ... // then read back the file Properties p = new Properties(); p.load(new FileInputStream("envvar.txt")); Thanks to JP Daviau

// UNIX public Properties getEnvironment() throws java.io.IOException { Properties env = new Properties(); env.load(Runtime.getRuntime().exec("env").getInputStream()); return env; } Properties env = getEnvironment(); String myEnvVar = env.get("MYENV_VAR");

To read only one variable : // NT version , adaptation for other OS is left as an exercise... Process p = Runtime.getRuntime().exec("cmd.exe /c echo %MYVAR%"); BufferedReader br = new BufferedReader ( new InputStreamReader( p.getInputStream() ) ); String myvar = br.readLine(); System.out.println(myvar);

Java's System properties contains some useful informations about the environment, for example, the TEMP and PATH environment variables (on Windows). public class ShowSome {

4 Environment

public static void main(String args[]){ System.out.println("TEMP : " + System.getProperty("java.io.tmpdir")); System.out.println("PATH : " + System.getProperty("java.library.path")); System.out.println("CLASSPATH : " + System.getProperty("java.class.path")); System.out.println("SYSTEM DIR : " + System.getProperty("user.home")); // ex. c:\windows on Win9x System.out.println("CURRENT DIR: " + System.getProperty("user.dir")); } }

Here some tips from H. Ware about the PATH on different OS. PATH is not quite the same as library path. In unixes, they are completely different−−−the libraries typically have their own directories. System.out.println("the current value of PATH is: p.getProperty("PATH")+"}");

{" +

System.out.println("LIBPATH: {" + System.getProperty("java.library.path")+"}");

gives the current value of PATH is: {/home/hware/bin:/usr/local/bin:/usr/xpg4/bin:/opt/SUNWspro/bin: /usr/ucb:/bin:/usr/bin:/home/hware/linux−bin:/usr/openwin/bin/: /usr/local/games:/usr/ccs/lib/:/usr/new:/usr/sbin/:/sbin/: /usr/openwin/lib:/usr/X11/bin:/usr/bin/X11/:/usr/local/bin/X11: /usr/bin/pbmplus:/usr/etc/:/usr/dt/bin/:/usr/lib: /usr/lib/nis:/usr/share/bin:/usr/share/bin/X11: /home/hware/work/cdk/main/cdk/../bin:.} LIBPATH: {/usr/lib/j2re1.3/lib/i386:/usr/lib/j2re1.3/lib/i386/native_threads: /usr/lib/j2re1.3/lib/i386/client:/usr/lib/j2sdk1.3/lib/i386:/usr/lib:/lib}

on my linux workstation. (java added all those except /lib and /usr/lib). But these two lines aren't the same on window either: This system is windows nt the current value of PATH is: {d:\OrbixWeb3.2\bin;D:\jdk1.3\bin;c:\depot\cdk\main\cdk\bin;c:\depot\ cdk\main\cdk\..\bin;d:\OrbixWeb3.2\bin;D:\Program Files\IBM\GSK\lib;H:\pvcs65\VM\win32\bin;c:\cygnus \cygwin−b20\H−i586−cygwin32\bin;d:\cfn\bin;D:\orant\bin; C:\WINNT\system32;C:\WINNT; d:\Program Files\Symantec\pcAnywhere; C:\Program Files\Executive Software\DiskeeperServer\;} LIBPATH: {D:\jdk1.3\bin;.;C:\WINNT\System32;C:\WINNT;D:\jdk1.3\bin; c:\depot\cdk\main\cdk\bin;c:\depot\cdk\main\cdk\..\bin; d:\OrbixWeb3.2\bin;D:\Program Files\IBM\GSK\lib; H:\pvcs65\VM\win32\bin;c:\cygnus\cygwin−b20\H−i586−cygwin32\bin;d:\cfn\bin; D:\orant\bin;C:\WINNT\system32; C:\WINNT;C:\Program Files\Dell\OpenManage\ResolutionAssistant\Common\bin; d:\Program Files\Symantec\pcAnywhere;

4 Environment

C:\Program Files\Executive Software\DiskeeperServer\;}

Java is prepending itself! That confused me−−− and broke my exec from ant.

4.3 Retrieve environment variables (JDK1.5) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0466.html JDK1.5 System.getenv() is back! import java.util.*; public class Test { public static void main(String args[]) { // just one System.out.println("PATH = " + System.getenv("PATH")); // all of them Map env = System.getenv(); for (Iterator it=env.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry)it.next(); System.out.println(entry.getKey() + " = " + entry.getValue()); } } }

See also this HowTo. See this Howto for common XP environment variables If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.4 Retrieve environment variable (JNI) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0460.html For some odd reasons, the getenv() method was removed from the JDK. Rumors is that a mechanism to retrieve an environment will be back in JDK1.5 (see this HowTo). But for now, you can use −D switch to retrieve named environment variable and pass them to the JVM (see this HowTo) or use this JNI routine : JNIEXPORT jstring JNICALL JavaHowTo_getenv (JNIEnv *env, jclass c, jstring jname){ if ( jname == NULL ) { return NULL ; } const char *name = (*env)−>GetStringUTFChars(env, jname, (jboolean *)NULL) ;

4.3 Retrieve environment variables (JDK1.5)

const char *value = getenv(name) ; (*env)−>ReleaseStringUTFChars(env, jname, name) ; return value ? (*env)−>NewStringUTF(env, value) : NULL ; }

NOTE : This is fine if the environment variable contains only regular 7−bit ASCII characters. See also this HowTo. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.5 Use a MAKE file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0158.html # jMAKEFILE a MAKEFILE for JAVA development # (Microsoft nMAKE) # nmake /f j.makefile.mak doc # to generate JAVADOC .SUFFIXES: .class .java JAVAHOME=c:\windev\jdk1.1.3 JAVAC= $(JAVAHOME)\bin\javac PATH=$(JAVAHOME)\bin;$(PATH) CLASSPATH=.;$(JAVAHOME)\lib\classes.zip;$(JSDKHOME)\lib\classes.zip DEST=. DOC=. JAVA=$(JAVAHOME)\bin\java JAVACFLAGS=−deprecation .SUFFIXES: .java .class .java.class: $(JAVAC) −classpath $(CLASSPATH) $(JAVACFLAGS) $< CLASSFILES

= GetImage.class \ myCanvas.class

SOURCEFILES = GetImage.java \ myCanvas.java

# begin −−−− JAR support −−−−−−−−−− JARFILE= theJAR.jar $(JARFILE): $(CLASSFILES) $(SOURCEFILES) jar cfm0 $(JARFILE) <<manifest.tmp $(DATAFILES) Name: GetImage.class Java−Bean: False Name: myCanvas.class Java−Bean: True <<

4.5 Use a MAKE file

$(CLASSFILES)

# end −−−− JAR support −−−−−−−−−− all : $(JARFILE) $(CLASSFILES) doc doc : $(CLASSFILES) javadoc −version −author −d $(DOC) $(SOURCEFILES) install : copy $CLASSESFILE $(DEST) clean: del $(CLASSFILES)

4.6 Detect the browser/JVM type Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0160.html One way is to instanciate a known browser−specific method and catch the Exception if not found import java.applet.*; public class BrowserDetector extends Applet { public void init() { if ( isNetscape() ) System.out.println("This browser is a Netscape Browser."); if ( isMicrosoft() ) System.out.println("This browser is a Microsoft Browser."); } public static boolean isNetscape() { try { Class.forName("netscape.applet.MozillaAppletContext"); } catch (ClassNotFoundException e) { System.out.println("This browser is not a Netscape Browser."); return false; } return true; } public static boolean isMicrosoft() { try { Class.forName("com.ms.applet.GenericAppletContext"); } catch (ClassNotFoundException e) { System.out.println("This browser is not a Microsoft Browser."); return false; } return true; } }

Or by examining the string representation of the getAppletContext() method String theBrowser = "APPLICATION"; String appletContext = getAppletContext().toString(); if (appletContext.startsWith("sun.applet.AppletViewer")) theBrowser = "APPLETVIEWER";

4.6 Detect the browser/JVM type

else if (appletContext.startsWith("netscape.applet.")) theBrowser = "NETSCAPE"; else if (appletContext.startsWith("com.ms.applet.")) theBrowser = "MICROSOFT"; else if (appletContext.startsWith("sunw.hotjava.tags.TagAppletPanel")) theBrowser = "HOTJAVA"; else if (appletContext.startsWith( "sun.plugin.navig.win32.AppletPlugin")) theBrowser = "NETSCAPEPLUGIN"; else if (appletContext.startsWith( "sun.plugin.ocx.ActiveXApplet")) theBrowser = "MICROSOFTPLUGIN; else if (appletContext.startsWith ( "sun.plugin.viewer.context.IExplorerAppletContext") theBrowser = "MICROSOFTPLUGINJRE1.4;

For an application, by looking at the string representation of the getDefaultToolkit() method, we detect the JVM type String theJVM = ""; String toolkit = Toolkit.getDefaultToolkit().toString(); if (theBrowser.equals("APPLICATION") { if (toolkit.startsWith( "sun.awt.windows.WToolkit")) theJVM = "JAVA"; else if (toolkit.startsWith( "com.ms.awt.WToolkit")) theJVM = "JVIEW"; }

For example, our MyApplet.class exists in three versions. One is using Microsoft−specific classes, the other is a JDK1.1 applet and finally a version for JDK102−only browser. The idea is to put all the required classes in an ARCHIVE file. By using a javascript entities, we decide which archive to use. During layout time, the javascript entity is remplaced by the right archive name. <SCRIPT> function isBrowser(b,v) { browserOk = false; versionOk = false; browserOk = (navigator.appName.indexOf(b) != −1); versionOk = (v <= parseInt(navigator.appVersion)); return browserOk &versionOk; } archiveToBeUsed = "java102.jar"; if (isBrowser("Microsoft", 4)) { archiveToBeUsed = "ie4.jar"; } else { if isBrowser("Netscape", 4) { archiveToBeUsed = "n4.jar"; } }

<APPLET CODE ="MyApplet.class" HEIGHT=100 WIDTH=400 ARCHIVE=}; >

4.6 Detect the browser/JVM type

NOTE: You may need to use the document.write() method to generate the right APPLET tag instead of a the Javascript entity to be compatible with Netscape and IE.

4.7 Fix the "Wrong magic number" error message Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0163.html The "magic number" is represented by the first few bytes of a given file. It is used to identified the file type. For Java classes, the magic number is 0xCAFEBABE (you can verify this by viewing a class file with hexadecimal editor or the DOS Debug utility). This is used by the browser JVM as a quick check of whether the called file is really a Java class. If the message is displayed and you are sure that you have uploaded a "real" class to web server then it's probably because the FTP download has been done in TEXT mode instead of BINARY so the resulting file on the server is corrupted.

4.8 Use a precompiler "à la C" with Java Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0164.html

4.9 Open source packages Check this list of what is available. Also take a look at JEnable

4.10 Ant For simple need, Ant can be used to do substitution in your sources. We insert into the code a special tag to delimit code that need to be stripped by the Ant script. Let's say we use //@STARTDEBUG@// and //@ENDDEBUG@//. package com.rgagnon.howto; import javax.swing.JFrame; public class Example { public static void main(String args[]){ JFrame f = new JFrame(); f.setSize(300,200); f.setVisible(true); f.setTitle("HowTo"); //@STARTDEBUG@// f.setTitle(f.getTitle() + " DEBUG version"); //@ENDDEBUG@// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

4.7 Fix the "Wrong magic number" error message

} }

If you execute this code, the JFrame title will have the word "DEBUG" appended to it. The Ant script to remove the debugging code is : <project default="buildme"> <javac srcdir="../out" /> <javac srcdir="." />



After running this script, the source (in the ..\out directory) package com.rgagnon.howto; import javax.swing.JFrame; public class Example { public static void main(String args[]){ JFrame f = new JFrame(); f.setSize(300,200); f.setVisible(true); f.setTitle("HowTo"); /* f.setTitle(f.getTitle() + " DEBUG version"); */ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

4.11 Simple boolean flag See this HowTo. This technique relies on the compiler optimization which remove code in the bytecode generated because it will never be executed.

4.11 Simple boolean flag

4.12 Determine what are the classes actually used in a Java Applet or application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0165.html In Netscape 1. Open the Java console 2. Press "9" to set the Debug level 3. Execute your applet. 4. Check the console and take note of the loaded classes. In application java −verbose:class MyApp NOTE: This can be useful if you want to trim a JAR to include only classes actually used.

4.13 Set the memory available to the JVM Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0131.html By default, the JVM will use up to 16Mb of RAM. If your program allocates a lot of memory, you may need to increase this value to give more room to the garbage collector. When starting the JVM, two parameters can be adjusted to suit your memory needs : −mx n Sets the maximum size of the memory allocation pool where n is in bytes, appending "m" to n will specified the number in megabytes, for example to set the maximum at 20Mb : java −mx 20m myApp

−ms n Sets the startup size of the memory allocation pool, where n is in bytes, appending "m" to n will specified the number in megabytes. The default is 1Mb. With JDK1.2, that syntax have changed, no space between ms/mx and the value : java −mx20m myApp

4.14 Generate the Javadoc "en français" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0437.html The javadoc utility uses the regular Java mechanism to internationalize its output. The tools.jar in the lib directory contains the resource bundle standard.properties used by Javadoc to generated the labels. To add a new language, you need to create the appropriate resource bundle, in our case for 4.12 Determine what are the classes actually used in a Java Applet or application

french, we need a file called standard_fr.properties. The new file must be in the package com.sun.tools.doclets.standard.resources. Extract from tools.jar, the standard.properties files (keep the directory structure). Copy it under the name standard_fr.properties. Translate it (or you can download my "incomplete" version here). [standard.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Packages doclet.SerialData=Serial Data\: doclet.Since=Since\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Subinterfaces of {0} in {1} doclet.Frame_Version=Frame version doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)

[standard_fr.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Paquetages doclet.SerialData=Donn\u00E9e s\u00E9rialis\u00E9e\: doclet.Since=Depuis\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Sous−interfaces de {0} dans {1} doclet.Frame_Version=Version avec cadres doclet.Generated_Docs_Untitled=Documentation g\u00E9n\u00E9r\u00E9e

Once everything translated, put your standard_fr.properties into the tools.jar making sure that the file is located in the right package (along standard.properties in com.sun.tools.doclets.standard.resources). To generate in french, use the −locale switch on the command line javadoc −locale fr ....

NOTE : Make sure the −locale switch is the first one. Using Ant, <javadoc locale="fr" sourcefiles="c:/client/Client.java" destdir="javadoc/Client" author="true" version="true" use="true" private="true" windowtitle="Client"> <doctitle>Client]]> Copyright © 2003 Real's Howto.]]> If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ] 4.12 Determine what are the classes actually used in a Java Applet or application

4.15 Use JDK1.5 new features Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0462.html • Download the JDK1.5 and install it. • From a shell, type java −version

The response should be something like java version "1.5.0−beta" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0−beta−b32c) JAVA HOTSPOT(TM) CLIENT VM (BUILD 1.5.0−BETA−B32C, MIXED MODE)

On Windows, if you have a "file not found" message, it's because the JVM can't be found through the PATH. Do it again but with the complete path (if the path contains spaces, make sure to use quotes!) : "c:\program files\java\j2sdk1.5.0\bin\java" −version

• Let's do our first jdk1.5 program : public class Test15 { public static void main(String ... args) { System.out.printf("Local time: %tT", java.util.Calendar.getInstance()); } }

• Compile it (again you may need to specify the complete path to the compiler if the PATH is not set correctly): "c:\program files\java\j2sdk1.5.0\bin\javac" −source 1.5 Test15.java

Note the switch "−source 1.5", if you don't specify it you won't be able to access the new features (like System.out.printf()). • Run it >"C:\Program Files\Java\j2sdk1.5.0\bin\java" Test15 Local time: 15:26:04 If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.16 Check the class version Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0544.html The first 4 bytes are a magic number, 0xCAFEBABe, to identify a valid class file then the next 2 bytes identify the class format version (major and minor). Possible major/minor value :

4.15 Use JDK1.5 new features

major 45 45 46 47 48 49 50

minor Java platform version 3 1.0 3 1.1 0 1.2 0 1.3 0 1.4 0 1.5 0 1.6

import java.io.*; public class ClassVersionChecker { public static void main(String[] args) throws IOException { for (int i = 0; i < args.length; i++) checkClassVersion(args[i]); } private static void checkClassVersion(String filename) throws IOException { DataInputStream in = new DataInputStream (new FileInputStream(filename)); int magic = in.readInt(); if(magic != 0xcafebabe) { System.out.println(filename + " is not a valid class!");; } int minor = in.readUnsignedShort(); int major = in.readUnsignedShort(); System.out.println(filename + ": " + major + " . " + minor); in.close(); } } > java ClassVersionChecker ClassVersionChecker.class ClassVersionChecker.class: 49 . 0

from The Java Virtual Machine Specification magic The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE. minor_version, major_version The values of the minor_version and major_version items are the minor and major version numbers of this class file.Together, a major and a minor version number determine the version of the class file format. If a class file has major version number M and minor version number m, we denote the version of its class file format as M.m. Thus, class file format versions may be ordered lexicographically, for example, 1.5 < 2.0 < 2.1. A Java virtual machine implementation can support a class file format of version v if and only if v lies in some contiguous range Mi.0 v Mj.m. Only Sun can specify what range of versions a Java virtual machine implementation conforming to a certain release level of the Java platform may support.

4.15 Use JDK1.5 new features

4.17 Get the system properties or the JVM uptime Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0549.html The RuntimeMXBean defines several convenient methods for accessing system properties about the Java virtual machine. [J2SE 1.5] import java.util.Date; import java.lang.management.RuntimeMXBean; import java.lang.management.ManagementFactory; class JMXTest { public static void main(String args[]) { JMXTest x = new JMXTest(); x.doit(); } public void doit() { try{ RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean(); System.out.println("BOOTCLASSPATH:\n" + mx.getBootClassPath()); System.out.println("CLASSPATH:\n" + mx.getClassPath()); // the input arguments passed to the Java virtual machine // which does not include the arguments to the main method. System.out.println("COMMAND LINE ARGS:\n" + mx.getInputArguments()); // a map of names and values of all system properties. System.out.println("SYSTEM PROPERTIES:\n" + mx.getSystemProperties()); System.out.println("VM start time : " + new Date(mx.getStartTime())); System.out.println("VM up time : " + mx.getUptime() + " ms"); } catch (Exception e) { e.printStackTrace(); } } }

4.18 Detect if running in a 64bit JVM Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0565.html public static boolean is64BitVM() { String bits = System.getProperty("sun.arch.data.model", "?"); if (bits.equals("64") { return true; } if (bits.equals("?") { // probably sun.arch.data.model isn't available // maybe not a Sun JVM? // try with the vm.name property

4.17 Get the system properties or the JVM uptime

return System.getProperty("java.vm.name") .toLowerCase().indexOf("64") >= 0; } // probably 32bit return false; } }

4.19 Set the default JVM type Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0566.html If you type, in a Shell > java −version

you get java version "1.5.0" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0−b64) Java HotSpot(TM) Client VM (build 1.5.0−b64, mixed mode, sharing)

The default JVM with a JIT (Just−In−Time compiler) for a "client" mode is used. The other available mode is "server". From the Hot Spot FAQ at http://java.sun.com/docs/hotspot/HotSpotFAQ.html#compiler_types. What's the difference between the −client and −server systems?

These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy. Where do I get the server and client systems? Client and server systems are both downloaded with the 32−bit Solaris and Linux downloads. For 32−bit Windows, if you download the JRE, you get only the client, you'll need to download the SDK to get both systems. For 64−bit, only the server system is included. On Solaris, the 64−bit JRE is an overlay on top of the 32−bit distribution. However, on Linux and Windows, it's a completely separate distribution. The default setting is defined the file jvm.cfg. On Debian GNU/Linux with Sun Java 1.5.0, the file is in /etc/java−1.5.0−sun. On Windows, it's in C:\Program Files\Java\jre1.5.0\lib\i386. A content like

4.19 Set the default JVM type

−client KNOWN −server KNOWN

defines the client as the default. −server KNOWN −client KNOWN

sets the server as the default.

4.20 Capture the output of JAVAC Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0147.html method 1a : redirect to a file // Win95 (?) javac −J−Djavac.pipe.output=true myClass.java >output.txt // WinNT (or better) javac MyClass.java 2output.txt

method 1a : redirect to stdout with a pause after each screen full // WinNT (or better) javac MyClass.java 21 | MORE

method 2 : use JAVA to capture the output // // // //

[JDK 1.1] to compile: java JC mySource.java (use redirection to keep the output) java JC mySource.java >output.txt

import java.io.*; public class JC { public static void main( String args[] ) throws IOException, InterruptedException { String fn = "JC.java"; if( args.length > 0 ) fn = args[0]; System.out.println( "BEGIN (" + fn + ")" ); Process p = Runtime.getRuntime().exec( "javac −verbose " + fn ); String buf; BufferedReader se = new BufferedReader ( new InputStreamReader( p.getErrorStream() ) ); while( (buf = se.readLine()) != null ) System.out.println( " : " + buf ); System.out.println( "END (rc:" + p.waitFor() + ")" ); } }

or you can always use a small text editor like Textpad where you can write with Java code (with syntax coloring), compile, capture compiler output and launch your Applet or Application directly from the editor.

4.20 Capture the output of JAVAC

4.21 Freeze the JVIEW window in MS VJ++ Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0148.html In your source, add the following line at the end : java.io.DataInputStream in = new java.io.DataInputStream(System.in); String aLine = in.readLine();

and the JVIEW window won't close until you hit ENTER. Or simply execute JVIEW directly in a DOS window with jview Check this How−to for a better way...

4.22 Wrap a Java beans in a COM object Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0045.html The previous How−to was using a Microsoft utility to enable access to Java objects from a COM−aware development tool. Sun provides a similar tool but you must package everything in a jar file and use the Beans technology. The tool is called packager, written in Java, you execute it from the sun.beans.ole package. The Java Plug−in 1.2 and the JDK1.2 must be installed on the system (for download, see Java Sun Web site). Let's try it with this simple class : package JavaCom; public class JavaBeanSays { private String _hello = "Hello World!"; public String getHello() { return _hello ; } public void setHello(String s) { _hello = s; } } NOTE: This is not really a Bean but let's keep it simple!

The next step is to build a manifest file to identify the bean in the jar. Here it is (manifest.txt): Name: JavaCom/JavaBeanSays Java−Bean: true NOTE: If no manifest is present all classes in the jar are treated as beans.

The JavaBeanSays class is in the directory JavaCom, the manifest.txt is the directory under it. From 4.21 Freeze the JVIEW window in MS VJ++

the directory under (the one containing manifest.txt), we built the jar with : jar cfm javacom.jar manifest.txt javacom\JavaBeanSays.class NOTE: You can download my JavaCom.jar if you to proceed more rapidly.

The next step is to run the packager. You run it from the JDK installation directory. If the JDK is installed in c:\dev\java\jdk1.2.1\ for example , you go there. And you start the packager with bin\java.exe −cp jre\lib\rt.jar;jre\lib\jaws.jar sun.beans.ole.Packager

A wizard is started, you follow the 5 steps to create the "JavaBeans bridge for ActiveX" for the JavabeanSays component. The first step is to specify where is located the JavaCom.jar file. When selected, the wizard should list the JavaCom.JavaBeanSays bean, press Next. The "ActiveX" name under which the beans will be seen is shown, press Next (in VbScript, the beans suffix must be added to this name). An output directory is needed, be careful because this directory name will be hard−coded in the generated files (REG and TLB), you need to specify a valid directory name. The packager assume that a subdirectory bin is present with the file beans.ocx in it. You can create it and then copy beans.ocx from the JRE\bin into it or edit the REG file to specify the original JRE\bin and update the registry with the good location. The Bean is now registered and ready to be used as a COM object. NOTE: There is a command−line interface available in the packager if you want to bypass the wizard.

To test it, try this VbScript (TestJavaBeansSays.vbs) ' VBSCRIPT connect to a Java Bean Dim objJava Set objJava = WScript.CreateObject("JavaBeanSays.Bean") strFromJava = objJava.getHello MsgBox strFromJava, _ 0, _ "JAVA BEAN OUTPUT" objJava.setHello("Bonjour le monde!") strFromJava = objJava.getHello MsgBox strFromJava, _ 0, _ "JAVA BEAN OUTPUT" NOTE: Check the JAVA PLUG−IN SCRIPTING documentation (jdk1.2) or (jsdk1.4). document for more infos.

4.23 Know details about the JAVA at run−time Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0149.html Applets can read certain system properties by invoking System.getProperty(String key)

4.23 Know details about the JAVA at run−time

java.version java.vendor java.vendor.url os.name os.arch file.separator path.separator line.separator java.class.version

Java version number Java vendor−specific string Java vendor URL Operating system name Operating system architecture File separator (eg, "/") Path separator (eg, ":") Line separator Java class version number

But applets are prevented from reading these system properties (for security reason): java.home java.class.path user.name user.home user.dir

Java installation directory Java classpath User account name User home directory User's current working directory

To read a system property from within an applet, simply invoke System.getProperty(key) on the property you are interested in. String s = System.getProperty("java.vendor");

Here a dump that can be useful in a log file: public String dump() { StringBuffer sb = new StringBuffer(); Runtime rt = Runtime.getRuntime(); long freeMemory = rt.freeMemory(); long totalMemory = rt.totalMemory(); sb.append("free memory=" + freeMemory); sb.append("\n"); sb.append("total memory=" + totalMemory); sb.append("\n"); java.util.Properties p = null; try { p = System.getProperties(); } catch(Exception e) { e.printStackTrace(); return ""; } java.util.Enumeration en = p.propertyNames(); while (en.hasMoreElements()){ String s = (String) en.nextElement(); String strValue= p.getProperty(s); sb.append(s + "=<" + strValue + ">"); sb.append("\n"); } // result to a string return sb.toString(); }

4.23 Know details about the JAVA at run−time

4.24 Detect the Microsoft JVM version installed Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0327.html class MSJVMversion { public static void main(String[] args) { String build; build=com.ms.util.SystemVersionManager.getVMVersion().getProperty ("BuildIncrement"); System.out.println("Microsoft JVM installed is " + build); } } NOTE:The above snippet will return the Microsoft VM version. This not the same thing as as the JDK version. In this case , Microsoft's Java environment only goes up to 1.1.4 and there is no plan to upgrade it.

4.25 Run JAVA as a Windows service Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0151.html A solution adapted to Java, is the Java Service Wrapper ( http://wrapper.tanukisoftware.org/doc/english/introduction.html ) (opensource). The setup is very simple with one configuration file and your Java service can be notified when the service is stopped. If you log in and log out from a machine and a java service is running then the service may be stopped. The fix is to use Java 1.3.1 or higher and start the process with the JVM switch −Xrs (Reduce Signals Xtended−switch) to stop the Windows signal from killing the JVM. For BEA JRockit, it's the −Xnohup Also, it's possible to the utility SRVANY.EXE, included with the NT resource Kit. http://www.techeez.com/windows_tips/service_under_nt.htm SVRANY is used to run any EXE as a windows service. In our situation, SVRANY will run the specified JAVA.EXE with our class a parameter. But this solution presents many problems. For exemple, if you kill the SVRANY.EXE process (stop the service) then the JAVA.EXE is not killed, you need to do it manually.

4.26 Execute a class from Windows Explorer Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0328.html This HowTo will you show how to start a class (with a main() method) without opening a DOS Shell or using a JAR file directly from Windows Explorer.

4.24 Detect the Microsoft JVM version installed

Type the following VBScript using a text editor and save it as WRunJava.vbs. You need to save the script in the SendTo subdirectory located in the Windows directory On a Win98 system, it's C:\Windows\SendTo. On XP, go to Documents and Settings folder then select the folder of a specific user, eg. c:\documents and settings\'user name'\SendTo. NOTE The SendTo folder is hidden by default. If it is not visible, on the Tools menu, click Folder Options. On the View tab, click Show hidden files and folders. SO you save the scripts shown below, into the SendTo folder. Then in Window Explorer, locate a class file that can be executed (with a main() method). Right click on it, select the Send To menu and you should see an entry called WRunJava.vbs. Simply select it and the class should be launched via javaw.exe . ' [WRunJava.vbs] start a java class without a console Dim WSHShell, FSO, javaclass, javacompletepath, cmdline Set WSHShell = WScript.CreateObject("WScript.Shell") Set FSO = WScript.CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 0 Then WScript.Echo "no argument on the command line." Else javaclass = WScript.Arguments(0) If fso.GetExtensionName(javaclass) = "class" Then javacompletepath = fso.GetAbsolutePathName(javaclass) javapath = fso.GetParentFolderName(javacompletepath) javaclass = fso.GetBaseName(javaclass) cmdline = "javaw.exe −cp " &javapath &" " &javaclass WSHShell.Run cmdline, 1, false ElseIf fso.GetExtensionName(javaclass) = "jar" Then javacompletepath = fso.GetAbsolutePathName(javaclass) cmdline = javaclass WSHShell.Run cmdline, 1, false Else WScript.Echo "Not a java class! (" &javaclass &")" End if End If Set WSHShell = Nothing Set FSO = Nothing WScript.Quit(0)

You need a second script to launch a java class with a console (useful to see debugging traces or text−only Java program). Called it CRunJava.vbs . Then you will have two choices from the SendTo menu, one for console−based program and one for GUI−based (Windows) program. ' [CRunJava.vbs] start a java class with a console Dim WSHShell, FSO, javaclass, javacompletepath, cmdline Set WSHShell = WScript.CreateObject("WScript.Shell") Set FSO = WScript.CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 0 Then

4.24 Detect the Microsoft JVM version installed

WScript.Echo "no argument on the command line." Else javaclass = WScript.Arguments(0) If fso.GetExtensionName(javaclass) = "class" Then javacompletepath = fso.GetAbsolutePathName(javaclass) javapath = fso.GetParentFolderName(javacompletepath) javaclass = fso.GetBaseName(javaclass) ' keep the console open cmdline = "cmd /k java.exe −cp " &javapath &" " &javaclass ' close the console ' cmdline = "cmd /c java.exe −cp " &javapath &" " &javaclass WSHShell.Run cmdline, 1, false ElseIf fso.GetExtensionName(javaclass) = "jar" Then javacompletepath = fso.GetAbsolutePathName(javaclass) cmdline = "java.exe −jar " &javaclass WSHShell.Run cmdline, 1, false Else WScript.Echo "Not a java class! (" &javaclass &")" End if End If Set WSHShell = Nothing Set FSO = Nothing 'WScript.Quit(0)

Note : A JAR can be made self executable (with double click), see this HowTo

4.27 Create an icon to launch java apps for Windows? Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0157.html Let's say you have a class named myApp.class and it is located in the directory myJavaApp on drive C:. Then create a Shortcut to the myApp.class. Next edit the properties of the Shortcut and change the line c:\myjavaapp\MyApp.class

to

javaw MyApp

In the properties tab panel, you also havethe possibility to assign an icon to the Shortcut. If you click on the newly created icon, your Java application will start without opening a DOS box. If your application is Text mode application use "java" instead of "javaw". If the Microsoft JVM is used then use "wjview" (instead of "jview") to start a GUI Java application from an icon.

4.28 Fix the "out of environment" error when setting a new CLASSPATH Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0159.html

4.27 Create an icon to launch java apps for Windows?

DOS has a limit on available environment space. You can adjust this in CONFIG.SYS. If your SHELL statement is set to COMMAND.COM, simply add/modify the SHELL parameter for adjusting the environment size: SHELL=C:\windows\command.com C:\windows /p /E:4096

will set off 4 Kb for environment variables. Command line in DOS has a limit of 127 characters. If you need more room to lanch the JVM then you have the following workaround. • Use environment variable like SET MYCLASSPATH = /files/classes/lib/examples.jar SET MYARGS = −Djava.security.policy=/files/policy java −cp %MYCLASSPATH% %MYARGS% myClass

• Use a BAT file.

4.29 Query Windows registry Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0480.html We launch the REG utility and capture the output. The performance is poor so it's a good idea to cache frequently used values. Note : The Microsoft ® Windows NT ® Server 4.0 Resource Kit contains REG.EXE. In Windows 2000 and later REG.EXE is a native command. The REG utility can be used to write values in the registry (reg add /? for more infos).

In this example,we query the registry to extract the personal folder path ("My Documents") and the processor ID and its name. import java.io.*; public class RegQuery { private static final String REGQUERY_UTIL = "reg query "; private static final String REGSTR_TOKEN = "REG_SZ"; private static final String REGDWORD_TOKEN = "REG_DWORD"; private static final String PERSONAL_FOLDER_CMD = REGQUERY_UTIL + "\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\" + "Explorer\\Shell Folders\" /v Personal"; private static final String CPU_SPEED_CMD = REGQUERY_UTIL + "\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\"" + " /v ~MHz"; private static final String CPU_NAME_CMD = REGQUERY_UTIL + "\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\"" + " /v ProcessorNameString"; public static String getCurrentUserPersonalFolderPath() { try { Process process = Runtime.getRuntime().exec(PERSONAL_FOLDER_CMD); StreamReader reader = new StreamReader(process.getInputStream()); reader.start(); process.waitFor(); reader.join();

4.29 Query Windows registry

String result = reader.getResult(); int p = result.indexOf(REGSTR_TOKEN); if (p == −1) return null; return result.substring(p + REGSTR_TOKEN.length()).trim(); } catch (Exception e) { return null; } } public static String getCPUSpeed() { try { Process process = Runtime.getRuntime().exec(CPU_SPEED_CMD); StreamReader reader = new StreamReader(process.getInputStream()); reader.start(); process.waitFor(); reader.join(); String result = reader.getResult(); int p = result.indexOf(REGDWORD_TOKEN); if (p == −1) return null; // CPU speed in Mhz (minus 1) in HEX notation, convert it to DEC String temp = result.substring(p + REGDWORD_TOKEN.length()).trim(); return Integer.toString ((Integer.parseInt(temp.substring("0x".length()), 16) + 1)); } catch (Exception e) { return null; } } public static String getCPUName() { try { Process process = Runtime.getRuntime().exec(CPU_NAME_CMD); StreamReader reader = new StreamReader(process.getInputStream()); reader.start(); process.waitFor(); reader.join(); String result = reader.getResult(); int p = result.indexOf(REGSTR_TOKEN); if (p == −1) return null; return result.substring(p + REGSTR_TOKEN.length()).trim(); } catch (Exception e) { return null; } } static class StreamReader extends Thread { private InputStream is; private StringWriter sw;

4.29 Query Windows registry

StreamReader(InputStream is) { this.is = is; sw = new StringWriter(); } public void run() { try { int c; while ((c = is.read()) != −1) sw.write(c); } catch (IOException e) { ; } } String getResult() { return sw.toString(); } } public static void main(String s[]) { System.out.println("Personal directory : " + getCurrentUserPersonalFolderPath()); System.out.println("CPU Name : " + getCPUName()); System.out.println("CPU Speed : " + getCPUSpeed() + " Mhz"); } }

See also this HowTo and this one. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2007 [ home ]

4.30 Quickly retrieve available Java JVM on a workstation (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0525.html Use regedit utility to query the Windows registry, the result is written into a file. start /w regedit /e jre.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment"

The content of jre.txt on my machine : Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment] "CurrentVersion"="1.5" [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.4] "JavaHome"="C:\\Program Files\\Java\\j2re1.4.1_02" "RuntimeLib"="C:\\Program Files\\Java\\j2re1.4.1_02\\bin\\client\\jvm.dll" "MicroVersion"="1"

4.30 Quickly retrieve available Java JVM on a workstation (Windows)

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.4.1_02] "JavaHome"="C:\\Program Files\\Java\\j2re1.4.1_02" "MicroVersion"="1" "RuntimeLib"="C:\\Program Files\\Java\\j2re1.4.1_02\\bin\\client\\jvm.dll" [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.5] "JavaHome"="C:\\Program Files\\Java\\jre1.5.0" "RuntimeLib"="C:\\Program Files\\Java\\jre1.5.0\\bin\\client\\jvm.dll" "MicroVersion"="0" [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.5.0] "JavaHome"="C:\\Program Files\\Java\\jre1.5.0" "MicroVersion"="0" "RuntimeLib"="C:\\Program Files\\Java\\jre1.5.0\\bin\\client\\jvm.dll"

A CMD file for Windows to display the default JRE used : @echo off ::Find the current (most recent) Java version start /w regedit /e reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" type reg1.txt | find "CurrentVersion" > reg2.txt if errorlevel 1 goto ERROR for /f "tokens=2 delims==" %%x in (reg2.txt) do set JavaTemp=%%~x if errorlevel 1 goto ERROR echo Java Version = %JavaTemp% del reg1.txt del reg2.txt

::Get the home directory of the most recent Java start /w regedit /e reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%Ja type reg1.txt | find "JavaHome" > reg2.txt if errorlevel 1 goto ERROR for /f "tokens=2 delims==" %%x in (reg2.txt) do set JavaTemp=%%~x if errorlevel 1 goto ERROR echo Java home path (per registry) = %JavaTemp% del reg1.txt del reg2.txt pause

The above script returns the default JVM if the PATH variable does not override it! If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

4.31 Get the Windows "My Documents" path Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0572.html This value is stored in the registry and there is no easy way to get it with regular Java unless you execute an external utility, see this HowTo. As an alternative, we can use a method provided by the JFileChooser class. 4.31 Get the Windows "My Documents" path

import javax.swing.JFileChooser; javax.swing.filechooser.FileSystemView; public class GetMyDocuments { public static void main(String args[]) { JFileChooser fr = new JFileChooser(); FileSystemView fw = fr.getFileSystemView(); System.out.println(fw.getDefaultDirectory()); } }

4.32 Get a return code from a VBS Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0575.html You can't detect directly if Windows service is running or not in Java. However, it's easy to do from a VBS. You execute the script from Java, wait for its completion and capture the return code. Obviously, this is useful only on the Windows plateform. import java.io.File; import java.io.FileWriter; public class VBSUtils { private VBSUtils() { } public static boolean isServiceRunning(String serviceName) { try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = "Set sh = CreateObject(\"Shell.Application\") \n" + "If sh.IsServiceRunning(\""+ serviceName +"\") Then \n" + " wscript.Quit(1) \n" + "End If \n" + "wscript.Quit(0) \n"; fw.write(vbs); fw.close(); Process p = Runtime.getRuntime().exec("wscript " + file.getPath()); p.waitFor(); return (p.exitValue() == 1); } catch(Exception e){ e.printStackTrace(); } return false; }

public static void main(String[] args){ // // DEMO // String result = ""; msgBox("Check if service 'Themes' is running (should be yes)");

4.32 Get a return code from a VBS

result = isServiceRunning("Themes") ? "" : " NOT "; msgBox("service 'Themes' is " + result + " running "); msgBox("Check if service 'foo' is running (should be no)"); result = isServiceRunning("foo") ? "" : " NOT "; msgBox("service 'foo' is " + result + " running "); } public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } }

4.33 List currently running processes (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0593.html

4.33.1 Using TASKLIST.EXE The Microsoft TASKLIST.EXE is used to dump the list of the currently running processes. It is similar to tasklist window but for the console. From a Java program, we are launching TASKLIST.EXE and capture its output. Note : TASKLIST.EXE is not included the HOME edition of XP. But you can download it from Web, for example : http://www.computerhope.com/download/winxp.htm. import java.io.*; import java.util.*; public class WindowsUtils { public static List<String> listRunningProcesses() { List<String> processes = new ArrayList<String>(); try { String line; Process p = Runtime.getRuntime().exec("tasklist.exe /fo csv /nh"); BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { if (!line.trim().equals("")) { // keep only the process name line = line.substring(1); processes.add(line.substring(0, line.indexOf("""))); } } input.close(); } catch (Exception err) { err.printStackTrace(); } return processes; } public static void main(String[] args){ List<String> processes = listRunningProcesses();

4.33 List currently running processes (Windows)

String result = ""; // display the result Iterator<String> it = processes.iterator(); int i = 0; while (it.hasNext()) { result += it.next() +","; i++; if (i==10) { result += "\n"; i = 0; } } msgBox("Running processes : " + result); } public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "WindowsUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } } Thanks to M. Korbel

4.33.2 Using a VBS Another technique to build the required VBScript on−the−fly, execute it and capture its output. import import import import import

java.io.BufferedReader; java.io.File; java.io.FileWriter; java.io.InputStreamReader; java.util.*;

public class VBSUtils { private VBSUtils() { } public static List<String> listRunningProcesses() { List<String> processList = new ArrayList<String>(); try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = + + + + + + + +

"Set WshShell = WScript.CreateObject(\"WScript.Shell\")\n" "Set locator = CreateObject(\"WbemScripting.SWbemLocator\")\n" "Set service = locator.ConnectServer()\n" "Set processes = service.ExecQuery _\n" " (\"select name from Win32_Process\")\n" "For Each process in processes\n" "wscript.echo process.Name \n" "Next\n" "Set WSHShell = Nothing\n";

fw.write(vbs); fw.close(); Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath()); BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream())); String line;

4.33.2 Using a VBS

while ((line = input.readLine()) != null) { processList.add(line); } input.close(); } catch(Exception e){ e.printStackTrace(); } return processList; } public static void main(String[] args){ List<String> processes = VBSUtils.listRunningProcesses(); String result = ""; Iterator<String> it = processes.iterator(); int i = 0; while (it.hasNext()) { result += it.next() +","; i++; if (i==10) { result += "\n"; i = 0; } } msgBox("Running processes : " + result); } public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } }

See this HowTo to check for a specific application is running or not.

4.34 Check if a program or process is running (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0610.html Based on this HowTo which list the currently running processes, we adapt it to check for a specific program name. In this example, we check if the text editor TextPad.exe is running. import import import import

java.io.BufferedReader; java.io.File; java.io.FileWriter; java.io.InputStreamReader;

public class VBSUtils { private VBSUtils() { } public static boolean isRunning(String process) { boolean found = false; try {

4.34 Check if a program or process is running (Windows)

File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = + + + + + + + +

"Set WshShell = WScript.CreateObject(\"WScript.Shell\")\n" "Set locator = CreateObject(\"WbemScripting.SWbemLocator\")\n" "Set service = locator.ConnectServer()\n" "Set processes = service.ExecQuery _\n" " (\"select name from Win32_Process where name='" + process +"'\")\n" "For Each process in processes\n" "wscript.echo process.Name \n" "Next\n" "Set WSHShell = Nothing\n";

fw.write(vbs); fw.close(); Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath()); BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream())); String line; line = input.readLine(); if (line != null) { if (line.equals(process)) { found = true; } } input.close(); } catch(Exception e){ e.printStackTrace(); } return found; } public static void main(String[] args){ boolean result = VBSUtils.isRunning("TextPad.exe"); msgBox("Is TextPad running ?

" + (result ? " Yes" : "No"));

} public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } }

4.35 Windows registry vs. Java JDK/JRE installation Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0604.html The JDK itself does not use the windows registry to run. It is the JRE that uses the system registry to run in some situations like an Applet or a program started with the WebStart technolgy. 4.35 Windows registry vs. Java JDK/JRE installation

Finally, the JRE will only use the registry if it is run from the Windows system directory (ex . C:/winnt/system32/java.exe). This would happen if the user just types "java" on the commandline in some random directory, because the system directory is always in the user's path. In this situation, the java.exe will locate the current Java installation by looking at the registry key [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\CurrentVersion]

and then get the path of the JRE from the corresponding key [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.5\JavaHome]

Beware that some software (eg. Oracle) installs themself at the beginning of the PATH definition, so it's their Java installation that will be found first. You can run the absolute path to the java.exe file, as in "C:\Program Files\Java\jre1.5.0\bin\java.exe" MyClass

It will not use the registry, and it will be guaranteed to use jre1.5.0. So for a regular Java SE program, it is safe to specify the complete path to the JRE to launch it. But for the Applet/Plugin or WebStart−based programs, the registry is always used to determine the current JRE.

4.36 Create a Taglet to document database access (Javadoc) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0473.html Since JDK1.4, it is possible to create a taglet to be used with javadoc to customized the generated documentation. This example implements a new javadoc tag to document which tables a class is dealing with. If a method interact with 2 tables, employee and address, then the javadoc tag /** *@table employee:firstname,lastname;address:city,country * @return value */ public String newMethod() { return "yo"; }

will be documented as

4.36.1 newMethod public java.lang.String newMethod()

4.36 Create a Taglet to document database access (Javadoc)

Returns: value Table(s): firstname lastname

city country

The "table" taglet source /* * Table.java */ package com.rgagnon.taglet; import com.sun.tools.doclets.Taglet; import com.sun.javadoc.*; import java.util.Map; /** * This is a taglet to document tables and fields used by a classes * example : @table employee:lastname,firstname;address:city,country * * @author Réal Gagnon */ public class Table implements Taglet{ private static final String NAME = "table"; private static final String HEADER = "Table(s):"; /** * Return the name of this custom tag. */ public String getName() { return NAME; } /** * Will return true since @todo * can be used in field documentation. * @return true since @todo * can be used in field documentation and false * otherwise. */ public boolean inField() { return false; } /** * Will return true since @todo * can be used in constructor documentation. * @return true since @todo * can be used in constructor documentation and false * otherwise. */ public boolean inConstructor() { return true; } /** * Will return true since @todo * can be used in method documentation. * @return true since @todo * can be used in method documentation and false

4.36 Create a Taglet to document database access (Javadoc)

* otherwise. */ public boolean inMethod() { return true; } /** * Will return true since @todo * can be used in method documentation. * @return true since @todo * can be used in overview documentation and false * otherwise. */ public boolean inOverview() { return true; } /** * Will return true since @todo * can be used in package documentation. * @return true since @todo * can be used in package documentation and false * otherwise. */ public boolean inPackage() { return true; } /** * Will return true since @todo * can be used in type documentation (classes or interfaces). * @return true since @todo * can be used in type documentation and false * otherwise. */ public boolean inType() { return true; } /** * Will return false since @todo * is not an inline tag. * @return false since @todo * is not an inline tag. */ public boolean isInlineTag() { return false; } /** * Register this Taglet. * @param tagletMap the map to register this tag to. */ public static void register(Map tagletMap) { Table tag = new Table(); Taglet t = (Taglet) tagletMap.get(tag.getName()); if (t != null) { tagletMap.remove(tag.getName()); } tagletMap.put(tag.getName(), tag); }

4.36 Create a Taglet to document database access (Javadoc)

/** * Given the Tag representation of this custom * tag, return its string representation. * @param tag the Tag representation of this custom tag. */ public String toString(Tag tag) { String output = ""; String tables [] = tag.text().split(";"); int j = tables.length; if (j > 0) { output = "
" + HEADER + "
"; for (int i=0; i < j ; i++){ // deals with the current table and its fields String current[] = tables[i].split(":"); output += "
"; output += ""; if (current.length > 1) { String fields[] = current[1].split(","); int k = fields.length; for (int n=0; n < k ; n++) { output += ""; } } output += "
" + current[0] + "
" + fields[n] + "
"; } output += "
"; } return output; } /** * Given an array of Tags representing this custom * tag, return its string representation. * @param tags the array of Tags representing of this custom tag. */ public String toString(Tag[] tags) { if (tags.length == 0) { return null; } String result = ""; for (int i = 0; i < tags.length; i++) { result += toString(tags[i]); } return result ; } }

Compile your taglet. Use javac compiler version 1.4.0 (or later) in the Java 2 SDK. The required class files are in the lib\tools.jar file in the SDK. Assuming the SDK is installed at C:\Program Files\j2sdk1.4.1 : javac −classpath "C:\Program Files\j2sdk1.4.1\lib\tools.jar" com\rgagnon\taglet\Table.java

4.36 Create a Taglet to document database access (Javadoc)

Run the javadoc tool using the −taglet and −tagletpath options. For example, if your taglet class file is defined to be in package com.rgagnon.taglet and is stored in C:\taglets\com\rgagnon\taglet\Table.class, then you should set tagletpath to C:\taglets. This example calls javadoc on package com.package1, including Table taglet tags: C:\dev\Work\java\taglet>javadoc −taglet com.rgagnon.taglet.Table −tagletpath c:\dev\work\java\taglet com.package1

Download this taglet here. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.37 Generate the Javadoc "en français" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0437.html The javadoc utility uses the regular Java mechanism to internationalize its output. The tools.jar in the lib directory contains the resource bundle standard.properties used by Javadoc to generated the labels. To add a new language, you need to create the appropriate resource bundle, in our case for french, we need a file called standard_fr.properties. The new file must be in the package com.sun.tools.doclets.standard.resources. Extract from tools.jar, the standard.properties files (keep the directory structure). Copy it under the name standard_fr.properties. Translate it (or you can download my "incomplete" version here). [standard.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Packages doclet.SerialData=Serial Data\: doclet.Since=Since\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Subinterfaces of {0} in {1} doclet.Frame_Version=Frame version doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)

[standard_fr.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Paquetages doclet.SerialData=Donn\u00E9e s\u00E9rialis\u00E9e\: doclet.Since=Depuis\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Sous−interfaces de {0} dans {1} doclet.Frame_Version=Version avec cadres doclet.Generated_Docs_Untitled=Documentation g\u00E9n\u00E9r\u00E9e

Once everything translated, put your standard_fr.properties into the tools.jar making sure that the file is located in the right package (along standard.properties in 4.37 Generate the Javadoc "en français"

com.sun.tools.doclets.standard.resources). To generate in french, use the −locale switch on the command line javadoc −locale fr ....

NOTE : Make sure the −locale switch is the first one. Using Ant, <javadoc locale="fr" sourcefiles="c:/client/Client.java" destdir="javadoc/Client" author="true" version="true" use="true" private="true" windowtitle="Client"> <doctitle>Client]]> Copyright © 2003 Real's Howto.]]> If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.38 Document a package using Javadoc Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0502.html Suppose I have a package called com.rgagnon with one HelloWorld class. com rgagnon HelloWorld.java

In the directory containing HelloWorld.java, add a file called package.html. This must be a complete HTML file (with HEAD and BODY). the first line of the body will be used a the package description by javadoc. this is com.rgagnon package description, see web site

Now execute the javadoc utility located in [JDK]\bin directory from the root of the com.rgagnon package. \progra~1\Java\jdk1.5.0\bin\javadoc −d javadoc0 −linksource com.rgagnon

4.38 Document a package using Javadoc

where −d javadoc0 is used to specify the output directory and −linksource to create HTML version of the source file. See the result. Since JDK 1.5, to create a package comment file, you have a choice of two files to place your comments: • package−info.java − Can contain a package declaration, package annotations, package comments and Javadoc tags. This file is new in JDK 5.0, and is preferred over package.html. • package.html − Can contain only package comments and Javadoc tags, no package annotations. See http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#packagecomment If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.39 Display a comment in a Javadoc Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0615.html Use the numerical identity to represent the / in the javadoc section to avoid any conflict with a real comment. import java.awt.*; public class Example { /** * Simple Frame * <pre> * /* create a frame */ * Frame f = new Frame() * * @param args */ public static void main(String args[]){ Frame f = new Frame(); f.setSize(200,200); f.setVisible(true); } }

and the javadoc output is :

You can represent any character with a numerical identity, the syntax is &#nnn; where nnn is the Unicode code (decimal value) of the character.

4.39 Display a comment in a Javadoc

4.40 Display XML in a javadoc Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0623.html Let's say you have a comment like this /** * To use this class use this XML * * <xml> * <parameter>foo * bar * * */

The XML will not be visible since it will embedded in the HTML as tag and not as text. With Javadoc 1.5, you can use the {@code ... } command. : /** * To use this class use this XML * <pre> * {@code * <xml> * <parameter>foo * bar * * } * */

With the previous versions, one way was to add a space after the <. /** * To use this class use this XML * <pre> * < xml> * < parameter>foo< /parameter> * < value>bar< /value> * < /xml> * } * */

4.41 Add a copyright notice to a Javadoc Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0626.html Use the −bottom parameter to the javadoc command line. −bottom 'Reals HowTo
© 2008 rgagnon.com
'

4.40 Display XML in a javadoc

The result looks like this :

4.42 Use a Log file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0501.html Since 1.4, a logging functionnality is included with the JDK. It's the java.util.logging package. import java.util.logging.*; import java.io.*; public class TestLog { public static Logger logger; static { try { boolean append = true; FileHandler fh = new FileHandler("TestLog.log", append); //fh.setFormatter(new XMLFormatter()); fh.setFormatter(new SimpleFormatter()); logger = Logger.getLogger("TestLog"); logger.addHandler(fh); } catch (IOException e) { e.printStackTrace(); } } public static void main(String args[]) { logger.severe("my severe message"); logger.warning("my warning message"); logger.info("my info message"); } }

and the result is 2005−02−28 21:19:28 TestLog main GRAVE: my severe message 2005−02−28 21:19:28 TestLog main ATTENTION: my warning message 2005−02−28 21:19:28 TestLog main INFO: my info message

if the XMLFormatter is in use then the output is 2005−02−28T21:21:09 <millis>1109643669250 <sequence>0 TestLog

4.42 Use a Log file

SEVERE TestLog <method>main 10 <message>my severe message
2005−02−28T21:21:09 <millis>1109643669328 <sequence>1 TestLog WARNING TestLog <method>main 10 <message>my warning message 2005−02−28T21:21:09 <millis>1109643669328 <sequence>2 TestLog INFO TestLog <method>main 10 <message>my info message


to customize the output, you can provide you own formatter import java.util.logging.*; import java.io.*; public class TestLog { public static Logger logger; static { try { boolean append = true; FileHandler fh = new FileHandler("TestLog.log", append); fh.setFormatter(new Formatter() { public String format(LogRecord rec) { StringBuffer buf = new StringBuffer(1000); buf.append(new java.util.Date()); buf.append(' '); buf.append(rec.getLevel()); buf.append(' '); buf.append(formatMessage(rec)); buf.append('\n'); return buf.toString(); } }); logger = Logger.getLogger("TestLog"); logger.addHandler(fh); } catch (IOException e) { e.printStackTrace(); } }

4.42 Use a Log file

public static void main(String args[]) { logger.severe("my severe message"); logger.warning("my warning message"); logger.info("my info message"); } }

then the output is Mon Feb 28 21:30:54 EST 2005 SEVERE my severe message Mon Feb 28 21:30:54 EST 2005 WARNING my warning message Mon Feb 28 21:30:54 EST 2005 INFO my info message

To limit the log file size and set a rolling pattern int limit = 1000000; // 1 Mb int numLogFiles = 3; FileHandler fh = new FileHandler("TestLog%g.log", limit, numLogFiles);

will give TestLog0.log, TestLog1.log and so on. Default values are defined in JRE_HOME/lib/logging.properties. To use a different properties file, you specify a filename with the java.util.logging.config.file system property. java −Djava.util.logging.config.file=mylogging.props TestLog

To suppress the logging output to the console Logger rootLogger = Logger.getLogger(""); Handler[] handlers = rootLogger.getHandlers(); if (handlers[0] instanceof ConsoleHandler) { rootLogger.removeHandler(handlers[0]); }

or modify the logging.properties file located in JRE_HOME/lib (default). Look for the property handlers and remove the value java.util.logging.ConsoleHandler You may want to take a look at another popular logging mechanism : Log4J. See also this HowTo and this one If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.43 Trace the execution Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0301.html This class generate a stackTrace and then parse it according to the parameters received. [StackTrace.java] 4.43 Trace the execution

public class StackTrace { public static void displayStack() { displayStack("", 0); } public static void displayStack(int deep) { displayStack("", deep); } public static void displayStack(String msg) { displayStack(msg, 0); } public static void displayStack(String msg, int deep) { // // msg a message to appear in the Trace // deep = 0 complete stack // n from "n" levels // String output = "" ; StringWriter sw = new StringWriter(); new Throwable("").printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString(); // to clean up the stacktrace StringTokenizer st = new StringTokenizer(stackTrace, "\n"); // get ride of the first line String s=st.nextToken(); // get ride of line(s) for the Trace class if (!msg.equals("")) output = msg + "\n" ; s=st.nextToken(); s=st.nextToken(); if ( s.indexOf("StackTrace.displayStack") < 0 ) output += s + "\n"; // process the stack if (deep == 0) { while (st.hasMoreTokens()) { output += st.nextToken() + "\n"; } } else { while (deep > 1) { if (st.hasMoreTokens()){ output += st.nextToken() + "\n"; deep−−; System.out.println("**" + deep); } else deep = 0; } } System.out.println("Trace: " + output); } }

[SimpleTrace.java] import java.io.*; import java.util.*;

4.43 Trace the execution

public class SimpleTrace { public static void main(String args[]){ SimpleTrace s = new SimpleTrace(); s.doit(); } public void doit() { MyClass s = new MyClass(); s.aMethod(); } } class MyClass { MyClass() { } public void aMethod() { StackTrace.displayStack("Howto Trace only 1 level", 1); StackTrace.displayStack("Howto Trace all levels"); } }

And the output should be Trace: Howto Trace only 1 level at MyClass.aMethod(SimpleTrace.java:20) Trace: Howto Trace all levels at MyClass.aMethod(SimpleTrace.java:21) at SimpleTrace.doit(SimpleTrace.java:12) at SimpleTrace.main(SimpleTrace.java:7) NOTES: The stackTrace() formatting may be different with the JVM used, in this example, it's the Sun's JDK 1.2.1.

See also this HowTo. You may want to look at this How−to to disable the Trace mechanism in the "release" version of your classes to achieve the best performance. Remember that line numbers are not available when a JIT is in function. To disable it, check this How−to

4.44 Time the execution Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0132.html public class ExecutionTimer { private long start; private long end; public ExecutionTimer() { reset(); } public void start() { start = System.currentTimeMillis(); }

4.44 Time the execution

public void end() { end = System.currentTimeMillis(); } public long duration(){ return (end−start); } public void reset() { start = 0; end = 0; } public static void main(String s[]) { // simple example ExecutionTimer t = new ExecutionTimer(); t.start(); for (int i=0; i < 80; i++){ System.out.print(".");} t.end(); System.out.println("\n" + t.duration() + " ms"); } }

See this HowTo to format a duration in ms into a string as "Days , Hours , minutes and seconds".

4.45 Log information efficiently (with Log4J) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0527.html In production code, a good practice is to only log what is necessary in the context. With Log4J, you can have different levels of message written into your log. public class MyClass { /** * Logger log4j */ static Logger logger = Logger.getLogger(MyClass.class.getName()); ... logger.debug("I'm here"); logger.info(e.getMessage()); logger.warning("something wrong " + e.getMessage()); logger.error("omg " + e.getMessage()); ...

While you can set the level in your code with something like logger.setLevel(Level.WARN);

it's more flexible to do it from the Log4J properties file ; can be OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL log4j.threshold=WARN

4.45 Log information efficiently (with Log4J)

You put the properties file in the classpath and then from your code URL url = ClassLoader.getSystemResource("log4j.props"); PropertyConfigurator.configure(url);

Logging activities have a cost. Even if you set the level at DEBUG level, the logger.debug(...) is interpreted. Consider this line : logger.setLevel(Level.DEBUG); logger.debug("something wrong with the value of " + myValue.toString());

the toString() method will be called and the result concatened to a String even if the DEBUG level is disabled. The best practice is to check if the level is enabled or not. logger.setLevel(Level.DEBUG); if (logger.isDebugEnabled()) { logger.debug("something wrong with the value of " + myValue.toString()); }

This way you will not incur the cost of parameter construction if debugging is disabled for logger. You can even remove the unwanted logging operation from the bytecode! See this HowTo.

Finally it's a good idea to design a robust toString() method for your class like this one : public String toString(){ StringBuffer sb = new StringBuffer(); sb.append(getClass().getName()) sb.append(" myValue=[").append(this.myValue).append("]"); sb.append(" anotherValue=[").append(this.anotherProperty).append("]"); return sb.toString(); }

even if myValue is null, this toString() method will display "null" as the value and not throw a NullPointerExeception. See also this HowTo and this one If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

4.46 Change the logging level on−the−fly (Log4J) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0621.html While you can set the logging level through the configuration properties file ; can be OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL log4j.threshold=WARN

4.46 Change the logging level on−the−fly (Log4J)

It may be useful to change it on−the−fly for debugging purpose. You need to get the Log4J "root" Logger and then change its "level". ... setLogLevel("DEBUG"); ... setLogLevel("INFO"); ... private void setLogLevel(String level) { Logger root = Logger.getRootLogger(); if ("DEBUG".equals(level)) { root.setLevel(org.apache.log4j.Level.DEBUG); } else { root.setLevel(org.apache.log4j.Level.INFO); } }

4.47 Use a JAR/ZIP/CAB file with an Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0153.html [JAR format] JAR (Java ARchive) is a platform−independent file format that allows you to bundle a Java applet and its requisite components (.class files, images and sounds) into a single JAR file. JAR supports compression, which reduces the file size, further improving the download time. The applet author can digitally sign individual entries in a JAR file to authenticate their origin (using the JAVAKEY utility). However, to sign JAR to be used with a "real−world" browser (eg. Netscape), you must use Netscape's utilities ZIGbert or GUI JAR Archiver to sign it. These utilities can be freely downloaded from the Netscape Web site. For more infos about signing Applet for Netscape, check this JAVA How−to. The browser need to be JDK1.1 compatible to handle JAR file. If a JAR file is used with an Applet, the browser will look first into the JAR to load all classes. If the search fails in the JAR file, then the browser looks in the applet's base directory. To specify the use of a JAR file with an applet: <APPLET CODE=a.class ARCHIVE="abc.jar" WIDTH=100 HEIGHT=100>

In theory, you can specify many JARs in one ARCHIVE tag. But the current version of Netscape will only load the first JAR and ignore the others. Microsoft IEv4 can handle multiple JAR files. In an application, simply include the JAR in the CLASSPATH : 4.47 Use a JAR/ZIP/CAB file with an Applet

java −classpath c:\jdk1.1.3\lib\classes.zip;.;.\HelloWorld.jar HelloWorld

To create a JAR file (compressed), use the JAR utility included with JDK1.1 jar cvf abc.jar a.class b.class c.class According to some JAVA developers, JAR in CLASSPATH needs to be uncompressed (JDK1.1). To create uncompressed JAR:

jar cvfO myArchive.jar *.class

[ZIP format] JDK1.0.2 introduces the ZIP "un−compressed" format. To create an archive, simply use a ZIP tool that supports the long filename format and specify the ZERO compression mode. You can use Sun's JAR utility (included with JDK1.1) to create a JDK1.0.2 compatible ZIP file: jar cvfO myArchive.zip *.class

or check for InfoZIP at http://www.cdrom.com/pub/infozip/ To use a ZIP archive, simply use the HTML ARCHIVE tag <APPLET CODE="a.class" ARCHIVE="abc.zip" WIDTH=618 HEIGHT=410>

[CAB format] CAB (for CABINET) is used only by Microsoft Internet Explorer. It offers compression (like the JAR but the ZIP format is un−compressed). To create a CAB file, use the CABARC utility from Microsoft : CABARC n myArchive.cab *.*

to create myArchive.cab. It is possible sign a CAB file using the Authenticode mechanism, check the Microsoft Web site for more infos. To associate a CAB file with an Applet, simply use the HTML : <APPLET CODE="a.class" WIDTH=100 HEIGHT=100>

the cabbase parameter will be interpreted only by MSIE, non−MS browsers browser will simply ignore it. An Applet can support ZIP and CAB format by using the following HTML: <APPLET CODEBASE="." ARCHIVE=abc.zip CODE=a.class

4.47 Use a JAR/ZIP/CAB file with an Applet

width=610 height=600 >

while Netscape will use the ZIP file and ignore de CAB parameter, MSIE will use CAB and ignore the ZIP file. Written and compiled by Réal Gagnon ©1998−2000 mailto:[email protected]

[ home ]

4.48 Make ZIP/JAR file always accessible from applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0154.html [Netscape 4] Manual method Copy the ZIP/JAR file in the PLUGINS directory and remove the reference in the ARCHIVE parameter of the APPLET tag. For example, to be able use SWING classes from Netscape, copy SWING.JAR and ROSE.JAR in the PLUGINS directory and restart Netscape. Automatic method Automatic installation can be done with Netscape using the SmartUpdate mechanism. The JAR must be signed with the Netscape Signing Tool.Check the following links for more infos: http://developer.netscape.com/docs/manuals/communicator/jarman/ http://developer.netscape.com/docs/manuals/signedobj/overview.html

4.49 Make a JAR executable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0166.html In the manifest file of a JAR, it is possible to specify the class to be used when the JVM is lauched with the JAR as parameter. The class must have a main(). Try with this simple class import java.awt.*; import java.awt.event.*; public class MyClass { public static void main(String[] args) { Frame f = new Frame(); f.addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }

4.48 Make ZIP/JAR file always accessible from applet

} ); f.add(new Label("Hello world")); f.setSize(200,200); f.setVisible(true); } }

Then create this manifest file (manifest.mft) with any text editor. Manifest−Version: 1.0 Main−Class: MyClass Class−path: .

Main−Class specifies the entry point with the main(String args[]) method. The Class−path is used to specify the dependency of this jar (if any). You add the directories and jars separated by a space. It is important because when running a jar , the CLASSPATH definition (as defined by the environnement variable) is overridden. Next, you include the manifest file in the JAR (MyJar.jar) with the MyClass class. jar cvfm myjar.jar manifest.mft *.class

Then you are able to start the MyClass.class by double−clicking on the MyJar.jar file (if the JRE is correctly installed) or by typing java −jar myjar.jar

If you need to pass parameters, use the −D switch before the −jar switch and use the getProperty() method to get the value. The file association mechanism is made during the installation of the JRE. You can verify that everything is ok with the following command from a DOS Shell >assoc .jar .jar=jarfile >ftype jarfile jarfile="C:\Program Files\Java\jre1.5.0_10\bin\javaw.exe" −jar "%1" %*

If the association is broken or you need to change the JRE used then by using the assoc/ftype utilities, you can modify the association easily (use /? to display the syntax of the assoc and ftype utilities). NOTE: On WinXp (or better), your user account needs to be at the Admin level. On Windows (NT or better), you can also make JARs run from the command−line by setting the PATHEXT environment variable, for example SET PATHEXT=.EXE;.BAT;.CMD;.JAR

Then if you have the jar file MyJar.jar accessible via the PATH environment variable, typing "MyJar" on the DOS command line will invoke "javaw −jar MyJar.jar" .

4.48 Make ZIP/JAR file always accessible from applet

4.50 Accessing jars from within a jar Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0319.html Supposed we have a jar called Main.jar for the application. This application needs Second.jar and Third.jar . In the manifest file of the first jar (Main.jar), you adjust the Class−Path setting : Manifest−Version: 1.0 Main−Class: MyClass Class−Path: Second.jar Third.jar

The value of the Class−Path attribute specifies the relative URLs of the extensions or libraries that this application or extension needs. URLs are separated by one or more spaces. The application or extension class loader uses the value of this attribute to construct its internal search path. You can use the −i option to speed up your application's class loading time: jar −i main.jar

This will build an an INDEX.LIST file in the META−INF directory which will enable the application class loader to download the right jar files when it is searching for classes or resources.

4.51 Access a JAR outside the CLASSPATH Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0409.html import java.net.*; import java.io.*; public class ExtraLoader { public static void main(String[] args) { try { URL urlA = new File("C:/xtras/xercesImpl.jar").toURL(); URL urlB = new File("C:/xtras/xmlParserAPIs.jar").toURL(); URL[] urls = { urlA,urlB }; URLClassLoader ulc = new URLClassLoader(urls); // Class c = Class.forName ("org.apache.xerces.dom.ChildNode", true, ulc); // System.out.println(c.getName()); } catch(Exception e) { e.printStackTrace(); } } }

4.50 Accessing jars from within a jar

4.52 Extract a file from a Jar Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0429.html The following snippet extract a file (mydb.mdb) from a jar. import java.io.*; import java.util.jar.*; import java.util.zip.*;

public class ExtractFromJAR { public void extractMyMDBromJAR(String dest){ try { String home = getClass().getProtectionDomain(). getCodeSource().getLocation().toString(). substring(6); JarFile jar = new JarFile(home); ZipEntry entry = jar.getEntry("mydb.mdb"); File efile = new File(dest, entry.getName()); InputStream in = new BufferedInputStream(jar.getInputStream(entry)); OutputStream out = new BufferedOutputStream(new FileOutputStream(efile)); byte[] buffer = new byte[2048]; for (;;) { int nBytes = in.read(buffer); if (nBytes <= 0) break; out.write(buffer, 0, nBytes); } out.flush(); out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args []){ new ExtractFromJAR().extractMyMDBFromJAR("."); } }

Grab this auto−run Jar if you want to try it. To create an auto−run JAR, first create a manifest.mft Manifest−Version: 1.0 Classpath: .\mydb.jar Main−Class: ExtractFromJAR

Create the JAR C:\jdk141\bin\jar cvfm mydb.jar manifest.mft ExtractFromJAR.class mydb.mdb

4.52 Extract a file from a Jar

Run it ... and the mydb.mdb file should appear in the current directory. java −jar mydb.jar

(A tip from Fred Hommersom) Your code reads: String home = getClass().getProtectionDomain(). getCodeSource().getLocation().toString().substring(6);

I got a problem when the jar file was located in C:\Program Files\xyz due to the embedded space. So I modified the code to String home = getClass().getProtectionDomain() .getCodeSource().getLocation() .getPath().replaceAll("%20", " "); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.53 Determine if running from JAR Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0391.html package com.rgagnon; public class HelloClass { public static void main(String[] args) { new HelloClass().say(); } public void say() { String className = this.getClass().getName().replace('.', '/'); String classJar = this.getClass().getResource("/" + className + ".class").toString(); if (classJar.startsWith("jar:")) { System.out.println("*** running from jar!"); } System.out.println(classJar); } }

The output >jar cvfm Hello.jar manifest.mft com\rgagnon\HelloClass.class added manifest adding: com/rgagnon/HelloClass.class (in=1059) (out=601) (deflated 43%) >java com.rgagnon.HelloClass file:/C:/DEV/WORK/JAVA/com/rgagnon/HelloClass.class >java −jar Hello.jar *** running from jar! jar:file:/C:/DEV/WORK/JAVA/Hello.jar!/com/rgagnon/HelloClass.class

4.53 Determine if running from JAR

See these related HowTo's : 1 2

4.54 Get list of classes in package (in a Jar) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0513.html import java.util.jar.*; import java.util.*; import java.io.*; public class PackageUtils { private static boolean debug = true; public static List getClasseNamesInPackage (String jarName, String packageName){ ArrayList classes = new ArrayList (); packageName = packageName.replaceAll("\\." , "/"); if (debug) System.out.println ("Jar " + jarName + " looking for " + packageName); try{ JarInputStream jarFile = new JarInputStream (new FileInputStream (jarName)); JarEntry jarEntry; while(true) { jarEntry=jarFile.getNextJarEntry (); if(jarEntry == null){ break; } if((jarEntry.getName ().startsWith (packageName)) & (jarEntry.getName ().endsWith (".class")) ) { if (debug) System.out.println ("Found " + jarEntry.getName().replaceAll("/", "\\.")); classes.add (jarEntry.getName().replaceAll("/", "\\.")); } } } catch( Exception e){ e.printStackTrace (); } return classes; } /** * */ public static void main (String[] args){ List list = PackageUtils.getClasseNamesInPackage ("C:/j2sdk1.4.1_02/lib/mail.jar", "com.sun.mail.handlers"); System.out.println(list); /* output : Jar C:/j2sdk1.4.1_02/lib/mail.jar looking for com/sun/mail/handlers Found com.sun.mail.handlers.text_html.class Found com.sun.mail.handlers.text_plain.class Found com.sun.mail.handlers.text_xml.class

4.54 Get list of classes in package (in a Jar)

Found com.sun.mail.handlers.image_gif.class Found com.sun.mail.handlers.image_jpeg.class Found com.sun.mail.handlers.multipart_mixed.class Found com.sun.mail.handlers.message_rfc822.class [com.sun.mail.handlers.text_html.class, com.sun.mail.handlers.text_xml.class, com .sun.mail.handlers.image_jpeg.class, , com.sun.mail.handlers.message_rfc822.class] */ } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

4.55 Add version to Jar packaging Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0388.html Let's say we have the following class (package is mandatory) package com.rgagnon; public class Hello { public static void main(String[] args) { new Hello().say("Hello World!"); } public void say(String s) { System.out.println(s); } }

First create a MANIFEST.MF file : Manifest−Version: 1.0 Main−Class: com.rgagnon.Hello

Then build the executable Jar and run it. >jar cvfm hello.jar MANIFEST.MF com\rgagnon\Hello.class >java −jar hello.jar Hello World!

Now modify the manifest to include versioning information. Manifest−Version: 1.0 Main−Class: com.rgagnon.Hello Specification−Version: 2.1 Implementation−Version: 1.1

Modify the class to display the version. 4.55 Add version to Jar packaging

package com.rgagnon; public class Hello { public static void main(String[] args) { new Hello().say("Hello World!"); } Hello() { Package p = this.getClass().getPackage(); System.out.println("Hello Specification Version : " + p.getSpecificationVersion()); System.out.println("Hello Implementation Version : " + p.getImplementationVersion()); } public void say(String s) { System.out.println(s); } }

Compile and rebuild the Jar and execute > jar cvfm hello.jar MANIFEST.MF com\rgagnon\Hello.class > java −jar hello.jar Specification Version : 2.1 Implementation Version : 1.1 Hello World!

See also this Howto. This example opens a given Jar and outputs its version information. package com.rgagnon.howto; import java.util.jar.*; public class JarUtils { public static String getJarImplementationVersion(String jar) throws java.io.IOException { JarFile jarfile = new JarFile(jar); Manifest manifest = jarfile.getManifest(); Attributes att = manifest.getMainAttributes(); return att.getValue("Implementation−Version"); } public static String getJarSpecificationVersion(String jar) throws java.io.IOException { JarFile jarfile = new JarFile(jar); Manifest manifest = jarfile.getManifest(); Attributes att = manifest.getMainAttributes(); return att.getValue("Specification−Version"); } public static void main(String[] args) throws java.io.IOException{ String javaMailJar = "C:/Program Files/Java/jre1.5.0/lib/mail.jar"; System.out.println("Specification−Version: " + JarUtils.getJarSpecificationVersion(javaMailJar)); System.out.println("Implementation−Version: " + JarUtils.getJarImplementationVersion(javaMailJar));

4.55 Add version to Jar packaging

/* * output : * Specification−Version: 1.3 * Implementation−Version: 1.3.1 */ } }

4.56 Use ANT to Build a JAR with version/build number Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0532.html • Download ANT from http://ant.apache.org/bindownload.cgi • Unzip into the root of C: (Windows), rename the folder to \Ant • Create a file call antenv.cmd. Before using ANT, you must execute this file to set up the environment. You may need to adjust the values according to your installation! set ANT_HOME=c:\ant set JAVA_HOME=C:\Progra~1\Java\jdk1.5.0 set PATH=%ANT_HOME%\bin;%JAVA_HOME%\bin;%path%

• Create a simple Hello class as shown below (you need have a package). package howto; public class Hello { public static void main( String[] args ){ System.out.println( "Hello World" ); } }

• Execute your antenv.cmd to set the environment • Compile your Hello class and make a jar to check if your environment is ok. > javac howto/Hello.java > jar −cvf hello.jar howto/Hello.class added manifest adding: howto/hello.class(in = 415) (out= 284) (deflated 31%) > java −cp hello.jar howto.Hello Hello World

• Create a build.xml which is the default ant build file ... • ... and load it into your favorite editor. Type the following ant script and save it. <project default="buildHello"> <javac srcdir="." />

Go back to the DOS shell and launch Ant with > ant compile Buildfile: build.xml compile: [javac] Compiling 1 source file

• Go back to the editor and add the jar building command. The target compile is also executed since the target jar depends on it. <project default="buildHello"> <javac srcdir="." />

4.56 Use ANT to Build a JAR with version/build number

<jar destfile="hello.jar" basedir="." includes="**/*.class" />

• Execute your Ant script : > ant jar Buildfile: build.xml compile: jar: [jar] Building jar: /Dev/hello.jar BUILD SUCCESSFUL Total time: 2 seconds $ jar −tvf hello.jar jar −tvf hello.jar 0 Wed May 03 17:06:32 55 Wed May 03 17:06:32 55 Wed May 03 17:06:32 335 Wed May 03 16:36:16

EST EST EST EST

2006 2006 2006 2006

META−INF/ META−INF/MANIFEST.MF howto/ howto/Hello.class

• Try your new Jar file > java −cp Hello.jar howto.Hello Hello World

• Make your Jar auto−executable by specifying the Main class into a MANIFEST.MF file to be included in the Jar. Add the following lines to build.xml <project default="buildHello"> <javac srcdir="." /> <delete file="hello.jar"/> <delete file="MANIFEST.MF"/> <manifest file="MANIFEST.MF"> <jar destfile="hello.jar" basedir="." includes="**/*.class" manifest="MANIFEST.MF" />

• Now you can launch Hello with only > ant jar ... > java −jar hello.jar Hello World

• Add a build number with the Ant task buildnumber . Ant will create (if necessary) and increment a property in a file called build.num (so you need to keep it!). Then a property, build.number, is 4.56 Use ANT to Build a JAR with version/build number

available in your Ant script. The version number is also a property. Here it is hard−coded in the script but you can read it from a file. <project default="buildHello"> <javac srcdir="." /> <delete file="hello.jar"/> <delete file="MANIFEST.MF"/> <property name="version.num" value="1.00"/> <manifest file="MANIFEST.MF"> <jar destfile="hello.jar" basedir="." includes="**/*.class" manifest="MANIFEST.MF" />

• If you examine the MANIFEST.MF, you now see a new entry Implementation−Version: 1.00−b1

• and after the next build operation, the entry will be Implementation−Version: 1.00−b2

• Modify the Hello class to read the Implementation−Version information and display it. package howto; public class Hello { public static void main( String[] args ){ System.out.println( "Hello World "); System.out.println("version : " + Hello.class.getPackage().getImplementationVersion() ); } }

• Finally we add a target to cleanup and the main target to build everything to the build.xml file. <project default="buildHello"> <javac srcdir="." /> <delete file="hello.jar"/> <property name="version.num" value="1.00"/> <manifest file="MANIFEST.MF"> <jar destfile="hello.jar"

4.56 Use ANT to Build a JAR with version/build number

basedir="." includes="**/*.class" manifest="MANIFEST.MF" />
<delete>

• Build and launch the Hello class > ant buildHello ... > java −jar hello.jar Hello World version : 1.00−b3

b3 == build #3 (if it's your third build !) Build number is great but a Built date is useful too! ... <delete file="hello.jar"/> <property name="version.num" value="1.00"/> <manifest file="MANIFEST.MF"> <jar destfile="hello.jar" basedir="." includes="**/*.class" manifest="MANIFEST.MF" /> See also this Howto .

4.57 Include all jars in the classpath definition Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0587.html

4.57 Include all jars in the classpath definition

Specifying all the required jar in the classpath can be a pain. Here some techniques to set the classpath definition automatically.

4.58 Windows batch file For Windows 2000 (or better), we need a set of 3 CMD files to scan a given directory and build the classpath defintion with all the jars found. main.cmd @echo off call buildclasspath.cmd .\lib Echo The Classpath definition is %CLASSPATH% ... java MyClass

buildclasspath.cmd set _CLASSPATH=%CLASSPATH% set CLASSPATH=%1 for %%i in ( %1\*.jar ) do call buildclasspath_append.cmd %%~fsi if "%_CLASSPATH%" == "" goto END set CLASSPATH=%_CLASSPATH%;%CLASSPATH% :END

buildclasspath_append.cmd set CLASSPATH=%CLASSPATH%;%1

With XP (or better), it's simpler ... a single batch file can do the job. @echo off setlocal ENABLEDELAYEDEXPANSION if defined CLASSPATH (set CLASSPATH=%CLASSPATH%;.) else (set CLASSPATH=.) FOR /R .\lib %%G IN (*.jar) DO set CLASSPATH=!CLASSPATH!;%%G Echo The Classpath definition is %CLASSPATH% ... java MyClass

4.59 JDK6 According to http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html, there is a new way to include jars in a given directory without explicitly to specify each one of them. As a special convenience, a class path element containing a basename of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR (a java program cannot tell the difference between the two invocations). For example, if directory foo contains a.jar and b.JAR, then the class path element foo/* is expanded to a A.jar:b.JAR, except that the order of jar files is unspecified. All jar files in the specified directory, even hidden ones, are included in

4.58 Windows batch file

the list. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory. The CLASSPATH environment variable, where defined, will be similarly expanded.

Note : There is a bug when using this feature with JAVAW, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6510337 Note : Use quote to avoid problem during the wildcard expansion, ex. javac −cp "C:\mylib\*" HelloWorld.java

4.60 JAR (and ANT) The best solution when you have a jar is to try to include the required jars into the manifest declaration. Manifest−Version: 1.0 Class−Path: customer_client.jar mailer_client.jar signon_client.jar

The manifest file format restrictions mandated by the JDK requires the use of a space ' ' character as the line continuation character, so ensure that your editor is not set up to trim trailing spaces on saves and exits. The line with the Class−Path: header must end with a space character and each of the lines referencing the client jar's should start and end with a space ' ' character and the manifest file as a whole must end with a blank line. Remember that when you launch an application with java −jar myjar.jar

the CLASSPATH definition (as defined by the environment variable) is overriden by the "class−path" defined the jar's manifest. See http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html Ant can be used to build your Jar and built the manifest class−path definition. <jar destfile="${dist}/${jar}"> <manifest>

It's possible (but not so simple) to do it automatically without specifying each jar one by one : <path id="build.classpath">

4.60 JAR (and ANT)

<pathconvert property="manifest.classpath" pathsep=" "> <path refid="build.classpath"/> <mapper> <jar jarfile="${basedir}/${test.jar}"> <manifest>

Latest Ant version (1.7) includes a task called ManifestClassPath which converts a classpath into a space−separated list of items used to set the Manifest Class−Path attribute. See http://ant.apache.org/manual/CoreTasks/manifestclasspath.html

<path id="build−classpath"> <manifestclasspath property="lib.list" jarfile="${build.dir}/${jar.file}"> <jar> ... <manifest> ...

4.61 Detect the browser/JVM type Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0160.html One way is to instanciate a known browser−specific method and catch the Exception if not found import java.applet.*; public class BrowserDetector extends Applet { public void init() { if ( isNetscape() ) System.out.println("This browser is a Netscape Browser."); if ( isMicrosoft() )

4.61 Detect the browser/JVM type

System.out.println("This browser is a Microsoft Browser."); } public static boolean isNetscape() { try { Class.forName("netscape.applet.MozillaAppletContext"); } catch (ClassNotFoundException e) { System.out.println("This browser is not a Netscape Browser."); return false; } return true; } public static boolean isMicrosoft() { try { Class.forName("com.ms.applet.GenericAppletContext"); } catch (ClassNotFoundException e) { System.out.println("This browser is not a Microsoft Browser."); return false; } return true; } }

Or by examining the string representation of the getAppletContext() method String theBrowser = "APPLICATION"; String appletContext = getAppletContext().toString(); if (appletContext.startsWith("sun.applet.AppletViewer")) theBrowser = "APPLETVIEWER"; else if (appletContext.startsWith("netscape.applet.")) theBrowser = "NETSCAPE"; else if (appletContext.startsWith("com.ms.applet.")) theBrowser = "MICROSOFT"; else if (appletContext.startsWith("sunw.hotjava.tags.TagAppletPanel")) theBrowser = "HOTJAVA"; else if (appletContext.startsWith( "sun.plugin.navig.win32.AppletPlugin")) theBrowser = "NETSCAPEPLUGIN"; else if (appletContext.startsWith( "sun.plugin.ocx.ActiveXApplet")) theBrowser = "MICROSOFTPLUGIN; else if (appletContext.startsWith ( "sun.plugin.viewer.context.IExplorerAppletContext") theBrowser = "MICROSOFTPLUGINJRE1.4;

For an application, by looking at the string representation of the getDefaultToolkit() method, we detect the JVM type String theJVM = ""; String toolkit = Toolkit.getDefaultToolkit().toString(); if (theBrowser.equals("APPLICATION") { if (toolkit.startsWith( "sun.awt.windows.WToolkit")) theJVM = "JAVA"; else if (toolkit.startsWith( "com.ms.awt.WToolkit")) theJVM = "JVIEW"; }

For example, our MyApplet.class exists in three versions. One is using Microsoft−specific classes, the other is a JDK1.1 applet and finally a version for JDK102−only browser. The idea is to put all 4.61 Detect the browser/JVM type

the required classes in an ARCHIVE file. By using a javascript entities, we decide which archive to use. During layout time, the javascript entity is remplaced by the right archive name. <SCRIPT> function isBrowser(b,v) { browserOk = false; versionOk = false; browserOk = (navigator.appName.indexOf(b) != −1); versionOk = (v <= parseInt(navigator.appVersion)); return browserOk &versionOk; } archiveToBeUsed = "java102.jar"; if (isBrowser("Microsoft", 4)) { archiveToBeUsed = "ie4.jar"; } else { if isBrowser("Netscape", 4) { archiveToBeUsed = "n4.jar"; } }

<APPLET CODE ="MyApplet.class" HEIGHT=100 WIDTH=400 ARCHIVE=}; > NOTE: You may need to use the document.write() method to generate the right APPLET tag instead of a the Javascript entity to be compatible with Netscape and IE.

4.62 Detect if Java is enabled from HTML Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0161.html For a Javascript solution, check this How−to

<APPLET CODE="MyApplet.class" NAME="myApplet" HEIGHT=400 WIDTH=400 ALT="Oups! You don't have JAVA enabled"> Oups! You don't have JAVA enabled, click here.

4.63 See the Java Console Window Log (Java plugin) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0533.html

4.62 Detect if Java is enabled from HTML

The Java Console Window Log is also stored on disk. On the Windows plateform, it's in the folder : C:\Documents and Settings\ <username>\ Application Data\ Sun\ Java\ Deployment\ log

It's a file with the extension .trace If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

4.62 Detect if Java is enabled from HTML

5 Internationalization 5.1 java−inter

5.2 Load resources based upon client environment at startup Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0133.html There are two ways to include resources based on the current Locale. One way is to use Properties files and the other are classes extending the ListResourceBundle base class. You need to follow a naming standard so that the JVM retrieves the right resources bundle. Note that if a resource is missing for the current locale then the default definition is used. [International.java (main program)] import import import import import

javax.swing.*; java.awt.*; java.awt.event.*; java.util.*; java.text.*;

public class International extends JFrame implements ActionListener { JLabel aLabel; JLabel vLabel; JCheckBox aCheckbox; JButton aButton; JButton vButton; JTextField aTextField; NumberFormat nf; public void initGUI(){ setLayout(new FlowLayout()); // String aLabel = new JLabel (MyResources.rb.getString("aLabel")); add(aLabel); // Object aCheckbox = (JCheckBox)MyResources.rb.getObject("aCheckbox"); add(aCheckbox); // String concatenation with MessageFormat Date d = new Date(); MessageFormat mf = new MessageFormat (MyResources.rb.getString("aButton")); aButton = new JButton (mf.format(new Object [] { d })); add(aButton);

5 Internationalization

// Number format output double dn = 3.1416; nf = (NumberFormat) (MyResources.rb.getObject("aNumber")); aTextField = new JTextField(6); add(aTextField); aTextField.setText(nf.format(dn)); // Number input validation vButton = (JButton)MyResources.rb.getObject("vButton"); add(vButton); vButton.addActionListener(this); vLabel = new JLabel("validation message ..."); add(vLabel); setSize(400,400); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == vButton) { try { nf.parse(aTextField.getText()); vLabel.setText(MyResources.rb.getString("numOK")); vLabel.invalidate(); this.validate(); } catch (ParseException pe) { pe.printStackTrace(); vLabel.setText(MyResources.rb.getString("numERR")); vLabel.invalidate(); this.validate(); } } } public static void main(String args[]) { System.out.println("Current Local : " + Locale.getDefault()); Thread t = new Thread () { public void run() { International frame = new International(); frame.initGUI(); frame.setVisible(true); } }; SwingUtilities.invokeLater(t); } }

[MyResources.java (default resources)] import java.util.*; import javax.swing.*; import java.text.*; public class MyResources extends ListResourceBundle { public static ResourceBundle rb = ResourceBundle.getBundle("MyResources"); public Object [][] getContents() { return contents;

5 Internationalization

} static { { { { { { { };

final Object[][] contents = { "myLabel" , "A Label" } , "aCheckbox", new JCheckBox("Yes") } , "aButton" , "Today {0,date,long}"}, "aNumber" , new DecimalFormat("0.####")}, "vButton" , new JButton("Validate number")}, "numOK" , "Valid!" }, "numERR" , "Invalid"}

}

[MyResources_en.java (english language resources)] The classname format is [name][language ID][country code].java. You can retrieve a list of language IDs and country codes at the Unicode organization Web site

import java.util.*; public class MyResources_en extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "aLabel" , "a Label (en)" } }; }

[MyResources_fr.java (french language resources)] import java.util.*; import javax.swing.*; public class MyResources_fr extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "aLabel" , "une étiquette (fr)" } , { "aCheckbox", new JCheckBox("Oui (fr)")} , { "vButton" , new JButton("Validation du nombre")}, { "numOK" , "Valide!"}, { "numERR", "Invalide"} }; }

[MyResources_fr_CA.java (french language (for Canada) resources)] import java.util.*; public class myResources_fr_CA extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "aLabel" , "une étiquette (fr CA)" } , }; }

5 Internationalization

This example uses ListResourceBundle classes to store the required resources. It is possible to substitute them for Properties files without any change to the code. The properties files must have the .properties extension. See this How−to.

5.3 Load resources dynamically Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0134.html This HowTo lets you select a language and change its GUI to reflect the choice. We are using a special class, a ListResourceBundle, to store our resources. We have a class per Locale. If a specific resource is not in a specific Locale ListResourceBundle then the default resource is used. To use a properties file instead of a class to store resources then look at this HowTo. [InternationalDynamic.java (main program)] import import import import import

java.util.*; java.text.*; java.awt.*; java.awt.event.*; javax.swing.*;

public class InternationalDynamic extends JFrame implements ActionListener { static Locale[] localesSupported = { Locale.US, Locale.FRANCE, Locale.GERMANY }; int localeChoosen = 0; Locale localeCurrent; ResourceBundle rb; ButtonGroup bg; JButton btnQuit; JRadioButton r0, r1, r2; JLabel today; boolean defaultDone = false; public void initLocale(){ localeCurrent = localesSupported[localeChoosen]; this.setLocale(localeCurrent); rb = ResourceBundle.getBundle("ResourcesDynamic", localeCurrent); } public void initText() { setTitle (rb.getString("title")); r0.setText(rb.getString("r0")); r1.setText(rb.getString("r1")); r2.setText(rb.getString("r2")); btnQuit.setText(rb.getString("btnQuit"));

5.3 Load resources dynamically

Date d = new Date(); MessageFormat mf = new MessageFormat (rb.getString("today"), localeCurrent); today.setText(mf.format(new Object [] { d })); } public void initGUI(){ setLayout(new FlowLayout()); // RADIO buttons bg = new ButtonGroup(); r0 = new JRadioButton(); r1 = new JRadioButton(); r2 = new JRadioButton(); bg.add(r0); bg.add(r1); bg.add(r2); add(r0); add(r1); add(r2); // default RADIO button if (!defaultDone) { String rDef = rb.getString("rDefault"); if (rDef.equals("r0")) r0.setSelected(true); else if (rDef.equals("r1")) r1.setSelected(true); else r2.setSelected(true); defaultDone = true; } else { if (localeChoosen == 0) r0.setSelected(true); else if (localeChoosen == 1) r1.setSelected(true); else r2.setSelected(true); } // QUIT button btnQuit = new JButton(); add(btnQuit); // today label today = new JLabel(); add(today); // r0.addActionListener(this); r1.addActionListener(this); r2.addActionListener(this); btnQuit.addActionListener(this); setSize(400,100); setVisible(true); } public void actionPerformed(ActionEvent ae){ if (ae.getSource() == btnQuit) { System.exit(0); }

5.3 Load resources dynamically

else if (ae.getSource() == r0) localeChoosen = 0; else if (ae.getSource() == r1) localeChoosen = 1; else if (ae.getSource() == r2) localeChoosen = 2; initLocale(); initText(); pack(); } public static void main(String args[]) { System.out.println("Current Locale : " + Locale.getDefault()); Thread t = new Thread () { public void run() { InternationalDynamic i = new InternationalDynamic(); i.initLocale(); i.initGUI(); i.initText(); i.pack(); } }; SwingUtilities.invokeLater(t); } }

[ResourcesDynamic.java (default resources)] import java.util.*; public class ResourcesDynamic extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "title", "Example" }, { "r0" , "United States" } , { "r1", "France" } , { "r2" , "Germany"}, { "rDefault" , "r0" }, { "btnQuit" , "Quit"}, { "today" , " (def) {0,date,long}"}, }; }

[ResourcesDynamic_en.java (english language resources)] import java.util.*; public class ResourcesDynamic_en extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "title", "Example" }, { "r0" , "United States" } , { "r1", "France" } , { "r2" , "Germany"}, { "rDefault" , "r0" }, { "btnQuit" , "Quit"}, { "today" , " (en) {0,date,long}"}, }; }

5.3 Load resources dynamically

[ResourcesDynamic_fr.java (french language resources)] import java.util.*; public class ResourcesDynamic_fr extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "title", "Exemple" }, { "r0" , "Etats−Unis" } , { "r1", "France" } , { "r2", "Allemagne" }, { "rDefault", "r1" }, { "btnQuit", "Quitter" }, { "today" , " (fr) {0,date, dd/MM/yyyy}"}, }; }

[ResourcesDynamic_de.java (german language resources)] import java.util.*; public class ResourcesDynamic_de extends ListResourceBundle { public Object [][] getContents() { return contents; } static final Object[][] contents = { { "title", "Beispiel" }, { "r0" , "Vereinigte Staaten" } , { "r1", "Frankreich" } , { "r2", "Deutschland" }, { "rDefault", "r2" }, { "btnQuit", "verlassen"}, { "today" , " (de) {0,date,dd.MM.yyyy}"}, }; } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2007 [ home ]

5.4 Load resources via a resources file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0135.html With the previous JAVA How−to, the resources were stored in classes. The drawback is when there is a modification, we must recompile the class. With a resources file, we simply add or modify the resource in a special file with a regular text editor. The JDK provides a class, PropertyResourceBundle, to use properties file very easily. In fact, from the programmer's point of view, there is no difference if the resources are stored in classes or properties files. The ResourceBundle will look first for classes and if not found, it will look for properties files. We don't have to specify filenames, the ResourceBundle will construct the filename using the same 5.4 Load resources via a resources file

mechanism used for classes. The file must have the extension .properties. The ResourceBundle try to load the properties file from the current classpath. If the properties are stored in subdirectory , use "." instead of "/". For example, let's say that the properties file is in a subdirectory called "subdir" (from the current directory). Then you can load the ResourcesDynamic resources file with ResourceBundle.getBundle("subdir.ResourcesDynamic", localeCurrent);

[InternationalDynamic.java] import import import import import

java.util.*; java.text.*; java.awt.*; java.awt.event.*; javax.swing.*;

public class InternationalDynamic extends JFrame implements ActionListener { static Locale[] localesSupported = { Locale.US, Locale.FRANCE, Locale.GERMANY }; int localeChoosen = 0; Locale localeCurrent; ResourceBundle rb; ButtonGroup bg; JButton btnQuit; JRadioButton r0, r1, r2; JLabel today; boolean defaultDone = false; public void initLocale(){ localeCurrent = localesSupported[localeChoosen]; this.setLocale(localeCurrent); rb = ResourceBundle.getBundle("res.ResourcesDynamic", localeCurrent); }

public void initText() { setTitle (rb.getString("title")); r0.setText(rb.getString("r0")); r1.setText(rb.getString("r1")); r2.setText(rb.getString("r2")); btnQuit.setText(rb.getString("btnQuit")); Date d = new Date(); MessageFormat mf = new MessageFormat (rb.getString("today"), localeCurrent); today.setText(mf.format(new Object [] { d })); } public void initGUI(){ setLayout(new FlowLayout()); // RADIO buttons bg = new ButtonGroup();

5.4 Load resources via a resources file

r0 = new JRadioButton(); r1 = new JRadioButton(); r2 = new JRadioButton(); bg.add(r0); bg.add(r1); bg.add(r2); add(r0); add(r1); add(r2); // default RADIO button if (!defaultDone) { String rDef = rb.getString("rDefault"); if (rDef.equals("r0")) r0.setSelected(true); else if (rDef.equals("r1")) r1.setSelected(true); else r2.setSelected(true); defaultDone = true; } else { if (localeChoosen == 0) r0.setSelected(true); else if (localeChoosen == 1) r1.setSelected(true); else r2.setSelected(true); }

// QUIT button btnQuit = new JButton(); add(btnQuit); // today label today = new JLabel(); add(today); // r0.addActionListener(this); r1.addActionListener(this); r2.addActionListener(this); btnQuit.addActionListener(this); setSize(400,100); setVisible(true); } public void actionPerformed(ActionEvent ae){ if (ae.getSource() == btnQuit) { System.exit(0); } else if (ae.getSource() == r0) localeChoosen = 0; else if (ae.getSource() == r1) localeChoosen = 1; else if (ae.getSource() == r2) localeChoosen = 2; initLocale(); initText(); pack(); } public static void main(String args[]) { System.out.println("Current Locale : " + Locale.getDefault());

5.4 Load resources via a resources file

Thread t = new Thread () { public void run() { InternationalDynamic i = new InternationalDynamic(); i.initLocale(); i.initGUI(); i.initText(); i.pack(); } }; SwingUtilities.invokeLater(t); } }

[RresourcesDynamic.properties] title=Example r0=United States r1=France r2=Germany rDefault=r0 btnQuit=Quit today=(def) {0,date,long}

[RresourcesDynamic_en.properties] title=Example r0=United States r1=France r2=Germany rDefault=r0 btnQuit=Quit today=(en) {0,date,long}

[ResourcesDynamic_fr.properties] title=Exemple r0=Etats−Unis r1=France r2=Allemagne rDefault=r1 btnQuit=Quitte today=(fr) {0,date, dd/MM/yyyy}

[ResourcesDynamic_de.properties] title=Beispiel r0=Vereinigte Staaten r1=Frankreich r2=Deutschland rDefault=r2 btnQuit=Verlassen today=(de) {0,date,dd.MM.yyyy} If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2007 [ home ]

5.4 Load resources via a resources file

5.5 Display "special character" using Unicode Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0136.html The copyright symbol © : String COPYRIGHT = "\u00a9"";

The registered symbol ® : String REGISTERED = "\u00ae";

The euro−currency sign € : String EURO = "\u20ac"

For example : import java.awt.*; public class TestUnicode extends java.applet.Applet { public static final String COPYRIGHT = "\u00a9"; public static final String REGISTERED = "\u00ae"; public static final String EURO = "\u20ac"; public void init () { setLayout(new FlowLayout()); Label a = new Label(COPYRIGHT + " R\u00e9al Gagnon"); Label b = new Label(REGISTERED + " R\u00e9al's Software " + " price : 100 " + EURO); add(a); add(b); } }

Output : Java not enabled! A list of Unicode characters is available at the Unicode organization Web site. Here a quick list for accented letters : á à â é è ê î ç

\u00e0 \u00e1 \u00e2 \u00e9 \u00e8 \u00ea \u00ee \u00e7

Á À Â É È Ê Î Ç

\u00c0 \u00c1 \u00c2 \u00c9 \u00c8 \u00ca \u00ce \u00c7

5.5 Display "special character" using Unicode

5.6 Display chinese/japanese characters Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0137.html A useful link to integrate international characters set in Netscape is http://developer.netscape.com/software/jdk/i18n.html and check also http://www.geocities.com/Tokyo/Pagoda/1675/ for a more complete overview.

5.7 Localize a JOptionPane dialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0138.html This example will show 2 radio buttons, one for english messages and buttons and the other one for french. Press the button to display a localized JOptionPane according to the radio button selected. Create 2 properties files, one for english , one for french. [JOptionPane_en.properties] Yes=Yes No=No Cancel=Cancel SaveMsg=Do you want to save your data [JOptionPane_fr.properties] Yes=Oui No=Non Cancel=Annuler SaveMsg=Voulez−vous sauvegarder vos donnees

Then import import import import

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

public class MessageBoxExample extends JPanel implements ActionListener { JButton go; AbstractButton button; ButtonGroup group; Locale locale; String msg ; public MessageBoxExample() { group = new ButtonGroup(); locale = Locale.US; // default value button = new JRadioButton("English", true); button.setActionCommand("en"); button.addActionListener(this); group.add(button); add(button);

5.6 Display chinese/japanese characters

button = new JRadioButton("Francais"); button.setActionCommand("fr"); button.addActionListener(this); group.add(button); add(button); go = new JButton("Do it"); go.addActionListener(this); add(go); locale = Locale.US; } public void setUILanguage() { ResourceBundle rb; rb = ResourceBundle.getBundle("JOptionPane", locale); UIManager.put("OptionPane.yesButtonText", rb.getString("Yes")); UIManager.put("OptionPane.noButtonText", rb.getString("No")); UIManager.put("OptionPane.cancelButtonText", rb.getString("Cancel")); msg = rb.getString("SaveMsg"); } public void actionPerformed(ActionEvent e) { int result; if (e.getSource() instanceof JRadioButton) { if (e.getActionCommand().equals("en")) locale = Locale.US; else locale = Locale.FRANCE; setUILanguage(); } else { // the button action result = JOptionPane.showConfirmDialog(this,msg); System.out.println(result); } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); MessageBoxExample panel = new MessageBoxExample(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } }

5.6 Display chinese/japanese characters

5.8 Validate/Convert a number using the current Locale() Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0139.html Depending on the International setting, numbers with comma as decimal separator may be permitted. The NumberFormat class can handle this based on the current Locale(). import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; public class NumberUtils { public static double getDoubleValue(String value) throws ParseException { // use the default locale return NumberUtils.getDoubleValue(Locale.getDefault(), value); } public static double getDoubleValue(Locale loc, String value) throws ParseException { // use the default locale return NumberFormat.getInstance(loc).parse(value).doubleValue(); } public static String convertStringAsStringNumberUnLocalized(String value) throws ParseException { // use the default locale return convertStringAsStringNumberUnLocalized(Locale.getDefault(), value); } public static String convertStringAsStringNumberUnLocalized (Locale loc, String value) throws ParseException { double d = NumberUtils.getDoubleValue(loc, value); return NumberFormat.getInstance(new Locale("us")).format(d); }

public static void main(String[] args) throws Exception{ System.out.println(Locale.getDefault()); System.out.println(NumberUtils.getDoubleValue("42,24")); System.out.println(NumberUtils.getDoubleValue("42.24")); System.out.println(NumberUtils.convertStringAsStringNumberUnLocalized (new Locale("fr"), "42,24")); /* * output * fr_CA * 42.24 * 42.0 * 42.24 */ } }

5.8 Validate/Convert a number using the current Locale()

5.9 Localize a JFileChooser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0299.html Modern Swing release have now built−in ready−to−use translations for the JFileChooser. The language is choosen based on the current Locale. So you don't have to do anything to display the JFileChooser in the right language. The user interface elements provided by the J2SE Runtime Environment 5.0, include Swing dialogs, messages written by the runtime environment to the standard output and standard error streams, as well as messages produced by the tools provided with the JRE. These user interface elements are localized into the following languages: Sun Supported Locales This example will show 2 radio buttons, one for english, one for french. Press the button to display a localized JFileChooser according to the radio button selected. Create 2 properties files, one for english , one for french (these files are incomplete but should be enough to get you started). [JFileChooser_en.properties] Title=Real's JFileChooser lookInLabelText=Current filesOfTypeLabelText=File type upFolderToolTipText=go up

[JFileChooser_fr.properties] Title=JFileChooser de R\u00e9al lookInLabelText=Courant filesOfTypeLabelText=Type de fichier upFolderToolTipText=Remonte

Then [LocalizeJFileChooser.java] import import import import

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

public class LocalizeJFileChooser extends JPanel implements ActionListener { JButton go; AbstractButton button; ButtonGroup group; Locale locale;

5.9 Localize a JFileChooser

String msg ; protected JFileChooser z_chooser; String z_choosertitle; public LocalizeJFileChooser() { group = new ButtonGroup(); locale = Locale.US; // default value button = new JRadioButton("English", true); button.setActionCommand("en"); button.addActionListener(this); group.add(button); add(button); button = new JRadioButton("Francais"); button.setActionCommand("fr"); button.addActionListener(this); group.add(button); add(button); go = new JButton("Do it"); go.addActionListener(this); add(go); locale = Locale.US; } public void setUILanguage() { ResourceBundle rb; rb = ResourceBundle.getBundle("JFileChooser", locale); z_choosertitle = rb.getString("Title"); UIManager.put ("FileChooser.lookInLabelText", rb.getString("lookInLabelText")); UIManager.put ("FileChooser.filesOfTypeLabelText", rb.getString("filesOfTypeLabelText")); UIManager.put ("FileChooser.upFolderToolTipText", rb.getString("upFolderToolTipText")); /* do the same with : FileChooser.fileNameLabelText FileChooser.homeFolderToolTipText FileChooser.newFolderToolTipText FileChooser.listViewButtonToolTipTextlist FileChooser.detailsViewButtonToolTipText FileChooser.saveButtonText=Save FileChooser.openButtonText=Open FileChooser.cancelButtonText=Cancel FileChooser.updateButtonText=Update FileChooser.helpButtonText=Help FileChooser.saveButtonToolTipText=Save FileChooser.openButtonToolTipText=Open FileChooser.cancelButtonToolTipText=Cancel FileChooser.updateButtonToolTipText=Update FileChooser.helpButtonToolTipText=Help Almost all Swing widgets can be customize this way. You can

5.9 Localize a JFileChooser

examine the Swing sources to get these values or check http://www.gargoylesoftware.com/papers/plafdiff.html for a list of them. */ } public void actionPerformed(ActionEvent e) { int result; if (e.getSource() instanceof JRadioButton) { if (e.getActionCommand().equals("en")) locale = Locale.US; else locale = Locale.FRANCE; setUILanguage(); } else { z_chooser = new JFileChooser(); z_chooser.setCurrentDirectory(new java.io.File(".")); z_chooser.setDialogTitle(z_choosertitle); if (z_chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); LocalizeJFileChooser panel = new LocalizeJFileChooser(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } }

5.10 Disable localization Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0418.html By default, the JVM uses the current locale as defined by the OS. To bypass this configuration, you specify on the command line the locale to be used : java −Duser.language=en −Duser.region=US MyApplication

5.10 Disable localization

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

5.11 Generate the Javadoc "en français" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0437.html The javadoc utility uses the regular Java mechanism to internationalize its output. The tools.jar in the lib directory contains the resource bundle standard.properties used by Javadoc to generated the labels. To add a new language, you need to create the appropriate resource bundle, in our case for french, we need a file called standard_fr.properties. The new file must be in the package com.sun.tools.doclets.standard.resources. Extract from tools.jar, the standard.properties files (keep the directory structure). Copy it under the name standard_fr.properties. Translate it (or you can download my "incomplete" version here). [standard.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Packages doclet.SerialData=Serial Data\: doclet.Since=Since\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Subinterfaces of {0} in {1} doclet.Frame_Version=Frame version doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)

[standard_fr.properties (extract)] doclet.Window_Split_Index={0}\: {1}−Index doclet.Packages=Paquetages doclet.SerialData=Donn\u00E9e s\u00E9rialis\u00E9e\: doclet.Since=Depuis\: doclet.Warn_inline_taglet=Inline tag {0} should only be used with a {1}. doclet.ClassUse_Subinterface=Sous−interfaces de {0} dans {1} doclet.Frame_Version=Version avec cadres doclet.Generated_Docs_Untitled=Documentation g\u00E9n\u00E9r\u00E9e

Once everything translated, put your standard_fr.properties into the tools.jar making sure that the file is located in the right package (along standard.properties in com.sun.tools.doclets.standard.resources). To generate in french, use the −locale switch on the command line javadoc −locale fr ....

NOTE : Make sure the −locale switch is the first one. Using Ant, <javadoc

5.11 Generate the Javadoc "en français"

locale="fr" sourcefiles="c:/client/Client.java" destdir="javadoc/Client" author="true" version="true" use="true" private="true" windowtitle="Client"> <doctitle>Client]]> Copyright © 2003 Real's Howto.]]> If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

5.12 Sort a String array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0343.html Sort utilities are now part of latest JDK versions. Case sensitive java.util.Arrays.sort(myArray);

Case insensitive java.util.Arrays.sort(myArray, String.CASE_INSENSITIVE_ORDER);

Sort with international characters. Take the following example : import java.util.*; import java.io.*; public class TestSort1 { String [] words = { "Réal", "Real", "Raoul", "Rico" }; public static void main(String args[]) { new TestSort1().doit(); } public void doit() { try { // to be able output french character at the console Writer w = new BufferedWriter (new OutputStreamWriter(System.out, "Cp850")); // w.write("Before :\n"); for(int i=0; i < 4 ; i++) { w.write(words[i] + " ");

5.12 Sort a String array

} java.util.Arrays.sort(words); w.write("\nAfter :\n"); for(int i=0; i < 4 ; i++) { w.write(words[i] + " "); } w.write("\n"); w.flush(); w.close(); } catch(Exception e){} } }

The output is : Before : Réal Real Raoul Rico After : Raoul Real Rico Réal

which is wrong since we expect to find "Réal" after "Real". To solve the problem , replace java.util.arrays.sort(words);

by java.util.arrays.sort(words, java.text.collator.getInstance(Locale.FRENCH));

and the output will be : Before : Réal Real Raoul Rico After : Raoul Real Réal Rico

Or you can do it the long way : ... Locale loc = Locale.FRENCH; sortArray(Collator.getInstance(loc), words); ... public static void sortArray(Collator collator, String[] strArray) { String tmp; if (strArray.length == 1) return; for (int i = 0; i < strArray.length; i++) { for (int j = i + 1; j < strArray.length; j++) { if( collator.compare(strArray[i], strArray[j] ) > 0 ) { tmp = strArray[i]; strArray[i] = strArray[j]; strArray[j] = tmp; } } } }

5.12 Sort a String array

5.13 Accentuated characters in Properties/ResourceBundle file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0492.html The rules are • Only use ISO Latin 1 characters in the Properties/ResourceBundle files • For other characters use the \u.... notation • To avoid having to type all the \u... notation manually, use the native2ascii tool (included with the SDK). If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

5.14 Compare accentuated letters Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0496.html class Test { public static void main(String args[]) { String s1 = "état"; String s2 = "famille"; // // // // // // // //

(javadoc) The result of String.compareTo() is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object) method would return true.

// here we are expecting "é" < "f" if (s1.compareTo(s2) > 0) { // s1 lexicographically follows s2 which is not true! System.out.println("not ok s1 > s2 "); } // (javadoc) // Collator.compare() compares the source string to the target string // according to the collation rules for this Collator. // Returns an integer less than, equal to or greater than zero // depending on whether the source String is less than, // equal to or greater than the target string. java.text.Collator frCollator = java.text.Collator.getInstance(java.util.Locale.FRANCE); frCollator.setStrength(java.text.Collator.CANONICAL_DECOMPOSITION); // or frCollator.setStrength(java.text.Collator.SECONDARY); // to be non case sensitive

5.13 Accentuated characters in Properties/ResourceBundle file

if (frCollator.compare(s1, s2) < 0) { // s2 lexicographically follows s1 System.out.println("ok s1 < s2 "); } } }

Equality class Test { public static void main(String args[]) { String s1 = "état"; String s2 = "État"; // here we are expecting "état" == "État" if (s1.compareTo(s2) != 0) { System.out.println("not ok s1 != s2 "); } java.text.Collator frCollator = java.text.Collator.getInstance(java.util.Locale.FRANCE); frCollator.setStrength(java.text.Collator.SECONDARY); if (frCollator.compare(s1, s2) == 0) { // s2 lexicographically follows s1 System.out.println("ok s1 == s2 "); } } }

NOTE: Also, another possibility is to convert to uppercase/lowercase both items to be compared. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

5.15 Unaccent letters Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0456.html The following snippet removes from a String accented letters and replace them by their regular ASCII equivalent. This can be useful before inserting data into a database to made sorting easier. Technique 1 It's a simple using the sun.text.Normalizer class. However, since the class is in sun.* package, it is considered outside of the Java platform, can be different across OS platforms (Solaris, Windows, Linux, Macintosh, etc.) and can change at any time without notice with SDK versions (1.2, 1.2.1, 1.2.3, etc). In general, writing java programs that rely on sun.* is risky: they are not portable, and are not supported. For an alternative to the sun.text.Normalizer class, you may to take a look at IBM's ICU4J project on SourceForge.

5.15 Unaccent letters

We are calling the normalize() with the option DECOMP (for decomposition, see Unicode Normalization). So if we pass à, the method returns a + ` . Then using a regular expression, we clean up the string to keep only valid US−ASCII characters. JDK1.4 import sun.text.Normalizer; public class Accent { public static String value = "é à î _ @"; public static void main(String args[]) throws Exception{ System.out.println(formatString(value)); // output : e a i _ @ } public static String formatString(String s) { String temp = Normalizer.normalize(s, Normalizer.DECOMP, 0); return temp.replaceAll("[^\\p{ASCII}]",""); } }

A note from ajmacher: The Normalizer API changed in JDK6... it can now be found in java.text.Normalizer and its usage is slightly different (but enough to break it), so Technique 1 will cause compiler errors in JDK6. Try : java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFD);

Technique 2 As an alternative, replaceAll() and regular expressions on a String can also be used : public class Test { public static void main(String args[]) { String s = "È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô"; s s s s s

= = = = =

s.replaceAll("[èéêë]","e"); s.replaceAll("[ûù]","u"); s.replaceAll("[ïî]","i"); s.replaceAll("[àâ]","a"); s.replaceAll("Ô","o");

s s s s s

= = = = =

s.replaceAll("[ÈÉÊË]","E"); s.replaceAll("[ÛÙ]","U"); s.replaceAll("[ÏÎ]","I"); s.replaceAll("[ÀÂ]","A"); s.replaceAll("Ô","O");

System.out.println(s); // output : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o } }

Technique 3 While the two techniques above are ok... there are a little bit slow. The following HowTo is faster because we using one String to contain all the possible characters to be converted and a String with the ASCII equivalent. So we need to detect the position in the first 5.15 Unaccent letters

String and then do a lookup in the second String.

public class AsciiUtils { private static final String PLAIN_ASCII = "AaEeIiOoUu" // grave + "AaEeIiOoUuYy" // acute + "AaEeIiOoUuYy" // circumflex + "AaOoNn" // tilde + "AaEeIiOoUuYy" // umlaut + "Aa" // ring + "Cc" // cedilla + "OoUu" // double acute ; private static final String UNICODE = "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9" + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD" + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177" + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1" + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF" + "\u00C5\u00E5" + "\u00C7\u00E7" + "\u0150\u0151\u0170\u0171" ; // private constructor, can't be instanciated! private AsciiUtils() { } // remove accentued from a string and replace with ascii equivalent public static String convertNonAscii(String s) { if (s == null) return null; StringBuffer sb = new StringBuffer(); int n = s.length(); for (int i = 0; i < n; i++) { char c = s.charAt(i); int pos = UNICODE.indexOf(c); if (pos > −1){ sb.append(PLAIN_ASCII.charAt(pos)); } else { sb.append(c); } } return sb.toString(); } public static void main(String args[]) { String s = "The result : È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô,ç"; System.out.println(AsciiUtils.convertNonAscii(s)); // output : // The result : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o,c } } Thanks to MV Bastos for the "tilde" bug fix Thanks to L.. Tama for the missing Ñ ! Thanks to T. Hague for the missing "double acute";

5.15 Unaccent letters

5.16 Output french characters to the console Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0046.html Since Java string are Unicode encoded, you must specified a different encoding when printing to a DOS console. This is done via the OutputStreamWriter class. import java.io.*; public class DosString { public static void main(String args[]){ String javaString = "caractères français : à é \u00e9"; // Unicode for "é" try { // output to the console Writer w = new BufferedWriter (new OutputStreamWriter(System.out, "Cp850")); w.write(javaString); w.flush(); w.close(); } catch (Exception e) { e.printStackTrace(); } } }

An alternative is to start the JVM and pass on the command line the default file encoding to be used. Then you will be able to use regular System.out.println(). java −Dfile.encoding=Cp850 MyApp

Alternate technique import java.io.*; public class test { public static void main(String[] args) { PrintStream ps = null; String javaString = "caractères français : à é \u00e9"; // Unicode for "é" try { ps = new PrintStream(System.out, true, "Cp850"); } catch (UnsupportedEncodingException error) { System.err.println(error); System.exit(0); } ps.println(javaString); } } Note : List of supported encodings here

5.16 Output french characters to the console

5.17 Get the default character set of the JVM Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0505.html public class Hello { public static void main(String args[]) throws Exception{ // not crossplateform safe System.out.println(System.getProperty("file.encoding")); // jdk1.4 System.out.println( new java.io.OutputStreamWriter( new java.io.ByteArrayOutputStream()).getEncoding() ); // jdk1.5 System.out.println(java.nio.charset.Charset.defaultCharset().name()); } }

Output example (winXP) >java Hello Cp1252 Cp1252 windows−1252

See also java encoding table for the encoding sets supported. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

5.18 Convert OEM (DOS) file to Ansi (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0524.html We are using an InputStreamReader which convert the specified input encoding to Unicode and an OutputStreamWriter which from Unicode to the specified output encoding. This can be useful when migrating data from a legacy database (ex. Clipper, dBase) to newer DBMS (ex. mySQL, Sybase). import java.io.*; public class OemToAnsi { public static void main(String args[]) throws Exception{ if (args.length != 2) { System.out.println( "Usage : java OemToAnsi inputdosfile outputansifile" ); System.out.println( " note : codepage input Cp850 codepage output Cp1252" );

5.17 Get the default character set of the JVM

System.exit(1); } // input FileInputStream fis = new FileInputStream(args[0]); BufferedReader r = new BufferedReader(new InputStreamReader(fis, "Cp850")); // output FileOutputStream fos = new FileOutputStream(args[1]); Writer w = new BufferedWriter(new OutputStreamWriter(fos, "Cp1252")); String oemString = ""; while ( (oemString= r.readLine()) != null) { w.write(oemString); w.flush(); } w.close(); r.close(); System.exit(0); } }

See also this related HowTo If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

5.19 Detect non−ASCII character in a String Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0536.html import import import import import

java.nio.ByteBuffer; java.nio.CharBuffer; java.nio.charset.Charset; java.nio.charset.CharsetDecoder; java.nio.charset.CharacterCodingException;

public class TestAscii { public static void main (String args[]) throws Exception { // this String throws an Exception, it contains an accented letter String test = "Réal"; // this String is OK //String test = "Real"; byte bytearray [] = test.getBytes(); System.out.println("Test string : " + test); CharsetDecoder d = Charset.forName("US−ASCII").newDecoder(); try { CharBuffer r = d.decode(ByteBuffer.wrap(bytearray)); r.toString(); } catch(CharacterCodingException e) { System.out.println("only regular ASCII characters please!"); // interrupt the processing

5.19 Detect non−ASCII character in a String

throw new Exception(e); } System.out.println("Ok, it's ASCII only!"); } }

Another way is to use a regular expression, see this Javascript HowTo for a hint!

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

5.19 Detect non−ASCII character in a String

6 IO 6.1 java−io

6.2 Redirect output(stdout/stderr) to a frame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0028.html [JDK1.1] import java.awt.*; import java.awt.event.*; import java.io.*; public class RedirectedFrame extends Frame { TextArea aTextArea = new TextArea(); PrintStream aPrintStream = new PrintStream( new FilteredStream( new ByteArrayOutputStream())); boolean logFile; RedirectedFrame(boolean logFile) { this.logFile = logFile; System.setOut(aPrintStream); System.setErr(aPrintStream); setTitle("Error message"); setSize(500,300); setLayout(new BorderLayout()); add("Center" , aTextArea); displayLog(); addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } } ); } class FilteredStream extends FilterOutputStream { public FilteredStream(OutputStream aStream) { super(aStream); } public void write(byte b[]) throws IOException { String aString = new String(b); aTextArea.append(aString); } public void write(byte b[], int off, int len) throws IOException { String aString = new String(b , off , len); aTextArea.append(aString); if (logFile) {

6 IO

FileWriter aWriter = new FileWriter("error.log", true); aWriter.write(aString); aWriter.close(); } } } public void displayLog() { Dimension dim = getToolkit().getScreenSize(); Rectangle abounds = getBounds(); Dimension dd = getSize(); setLocation((dim.width − abounds.width) / 2, (dim.height − abounds.height) / 2); setVisible(true); requestFocus(); } public static void main(String s[]){ try { // force an exception for demonstration purpose Class.forName("unknown").newInstance(); } catch (Exception e) { // for applet, always RedirectedFrame(false) RedirectedFrame r = new RedirectedFrame(true); e.printStackTrace(); } } } Check also this simple Swing solution.

6.3 Redirect printStackTrace() to a String Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0029.html import java.io.*; public class TestStack2String { public static void main(String s[]){ try { // force an exception for demonstration purpose Class.forName("unknown").newInstance(); // or this could be changed to: // throw new Exception(); } catch (Exception e) { System.out.println(stack2string(e)); } } public static String stack2string(Exception e) { try { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); return "−−−−−−\r\n" + sw.toString() + "−−−−−−\r\n"; }

6.3 Redirect printStackTrace() to a String

catch(Exception e2) { return "bad stack2string"; } } }

6.4 Output french characters to the console Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0046.html Since Java string are Unicode encoded, you must specified a different encoding when printing to a DOS console. This is done via the OutputStreamWriter class. import java.io.*; public class DosString { public static void main(String args[]){ String javaString = "caractères français : à é \u00e9"; // Unicode for "é" try { // output to the console Writer w = new BufferedWriter (new OutputStreamWriter(System.out, "Cp850")); w.write(javaString); w.flush(); w.close(); } catch (Exception e) { e.printStackTrace(); } } }

An alternative is to start the JVM and pass on the command line the default file encoding to be used. Then you will be able to use regular System.out.println(). java −Dfile.encoding=Cp850 MyApp

Alternate technique import java.io.*; public class test { public static void main(String[] args) { PrintStream ps = null; String javaString = "caractères français : à é \u00e9"; // Unicode for "é" try { ps = new PrintStream(System.out, true, "Cp850"); } catch (UnsupportedEncodingException error) { System.err.println(error); System.exit(0); } ps.println(javaString);

6.4 Output french characters to the console

} } Note : List of supported encodings here

6.5 Clear the console and control attributes Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0047.html On Win9x, this can be done with the driver ANSI.SYS is loaded via the CONFIG.SYS file. For example, on Win9x installation, you need something like this in the CONFIG.SYS : device=c:\windows\command\ansi.sys

Then you send the appropriate escape codes to the console public class AnsiConsole { public static void main(String args[]) { String ANSI_CLS = "\u001b[2J"; String ANSI_HOME = "\u001b[H"; String ANSI_BOLD = "\u001b[1m"; String ANSI_AT55 = "\u001b[10;10H"; String ANSI_REVERSEON = "\u001b[7m"; String ANSI_NORMAL = "\u001b[0m"; String ANSI_WHITEONBLUE = "\u001b[37;44m"; System.out.println(ANSI_CLS); System.out.println (ANSI_AT55 + ANSI_REVERSEON + "Hello world" + ANSI_NORMAL); System.out.println (ANSI_HOME + ANSI_WHITEONBLUE + "Hello world" + ANSI_NORMAL); System.out.print (ANSI_BOLD + "Press a key..." + ANSI_NORMAL); try {System.in.read();}catch(Exception e){} System.out.println(ANSI_CLS); } } NOTE: Check this "old" text file to have an overview of ANSI.SYS's Escape Sequences.

NT's CMD.EXE does not support ANSI escape sequences. The Good news is that you can use COMMAND.COM instead. To use ANSI.SYS, add the following lines in the CONFIG.NT file: dosonly device=c:\winnt\system32\ansi.sys

But the bad news is that you are restricted this way to run only DOS−based application so it won't work for Java stuff!!! So the only solution left for NT (unless you write some JNI functions, see this HowTo) is to use brute force. for (int i=0; i<25; i++) System.out.println();

6.5 Clear the console and control attributes

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.6 Print text to a printer easily Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0051.html A quick and simple way to output some text to a printer is to print to OS logical device attached a printer. For example, on a Windows machine : import java.io.*; public class SimplePrinting { public static void main(String[] args) { try { FileWriter out = new FileWriter("lpt1"); out.write("Hello world"); out.write(0x0D); // CR out.close(); } catch (IOException e) { e.printStackTrace(); } } }

6.7 Print without a Dialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0350.html JobAttributes theJobAttribs = new JobAttributes(); PageAttributes thePageAttribs = new PageAttributes(); theJobAttribs.setDialog(JobAttributes.DialogType.NONE); theJobAttribs.setPrinter("HP DeskJet 610C"); // the printer to be used PrintJob myJob = getToolkit().getPrintJob(this, "PrintJob", theJobAttribs, thePageAttribs); if (myJob != null) { Graphics g = myJob.getGraphics(); if (g != null) { String s = myArea.getText(); // what you like to print printText(myJob, g, s); g.dispose(); } myJob.end(); }

6.6 Print text to a printer easily

6.8 Simple input from the keyboard Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0053.html First method import java.io.*; public class TestReadLine { public static void main (String args[]) { StreamTokenizer Input=new StreamTokenizer(System.in); try { System.out.print(" Your first name : "); Input.nextToken(); System.out.println("Hi " + Input.sval + "!"); } catch (Exception e) { e.printStackTrace(); } } }

Second method JDK1.0.2 java.io.DataInputStream in = new java.io.DataInputStream(System.in); String aLine = in.readLine();

Third method JDK1.1 In you program, use EasyInput.inputStr("<prompt>") to input a String or EasyInput.InputInt("<prompt>") for an integer. public class EasyInput { public static int inputInt(String s) { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); System.out.print(s); int i =0; try { i = Integer.parseInt(input.readLine()); } catch (Exception e) { e.printStackTrace(); } return i; } public static String inputStr(String s) { String aLine = ""; BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); System.out.print(s); try { aLine = input.readLine(); } catch (Exception e) { e.printStackTrace(); } return aLine; }

6.8 Simple input from the keyboard

public static void main(String s[]) { while(true) { int y = inputInt(" Year: "); int m = inputInt("Month: "); int d = inputInt(" Day: "); String you = inputStr("Your name: "); System.out.println(you + " " + y + m + d); } } }

NOTE: JDK 1.5 provides the Scanner class to do this, see this HowTo.

6.9 Initialize and write to a serial port Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0062.html This is for JAVA application only (JDK1.1). (Win)Initialization is done via the MODE.COM utility. Then to write, simply open a stream using the OS logical name attached to the serial port. You can use the same technique to print to the printer port (in this case the local name would be "LPTx:"). public class SerialTest { public static void main( String args[]) { Runtime rt = Runtime.getRuntime(); Process p = null; String portname = "com1:"; // for Win95 : c:\\windows\\command.com // c:\\windows\\command\\mode.com String cmd[] = { "c:\\winnt\\system32\\cmd.exe", "/c", "start", "/min", "c:\\winnt\\system32\\mode.com", portname, "baud=9600", "parity=n", "data=8", "stop=1", }; try { p = rt.exec( cmd ); if( p.waitFor() != 0 ) { System.out.println("Error executing command: " + cmd ); System.exit( −1 ); } byte data[] = "Writing a byte stream out of a serial port.".getBytes(); FileOutputStream fos = new FileOutputStream( portname ); BufferedOutputStream bos = new BufferedOutputStream( fos ); fos.write( data, 0, data.length ); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } }

6.9 Initialize and write to a serial port

6.10 Redirect to a NULL device Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0453.html This can be useful if you want to suppress all output. // Unix style PrintStream nps = new PrintStream(new FileOutputStream("/dev/null")); System.setErr(nps); System.setOut(nps); //Windows style PrintStream nps = new PrintStream(new FileOutputStream("NUL:")); System.setErr(nps); System.setOut(nps);

//One−liner style : subclass OutputStream to override the write method ... System.setOut(new java.io.PrintStream(new java.io.OutputStream() { public void write(int b){}})); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.11 Get the volume label Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0455.html This will retrieve the hard disk volume label : import java.io.*; import javax.swing.filechooser.*; public class VolumeLabel { private VolumeLabel() { } public static void main(String[] args) { System.out.println("\"" + get(args[0]) + "\""); } public static String get(String path) { FileSystemView view = FileSystemView.getFileSystemView(); File dir = new File(path); String name = view.getSystemDisplayName(dir); if (name == null) { return null; } name = name.trim(); if (name == null || name.length() < 1) { return null; } int index = name.lastIndexOf(" ("); if (index > 0) { name = name.substring(0, index); }

6.10 Redirect to a NULL device

return name; } }

The output Running from c:\temp >java VolumeLabel c: "temp" >java VolumeLabel c:\ "HARDDISK1" If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.12 Easy keyboard input (JDK1.5) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0491.html A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values of different types using the various next methods. import java.util.*; class TestScanner { public static void main(String args[]) { String input = "10:11:12"; Scanner sc = new Scanner(input).useDelimiter(":"); while (sc.hasNextInt()) { int i = sc.nextInt(); System.out.println(i); } } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.13 Open or close a CD/DVD drive Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0574.html Java provides no way to interact with a cd drive. One easy way on the Windows plateform is to call a VBS script. 6.12 Easy keyboard input (JDK1.5)

In this HowTo, we are creating a temporary vbs file and execute it. This technique is useful to do something that a regular Java can't do because it's too specific to OS where the Java is running. The vbs file is created in the "temporary" folder and is deleted by the JVM at the end. import java.io.File; import java.io.FileWriter; public class CDUtils { private CDUtils() { } public static void open(String drive) { try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = "Set wmp = CreateObject(\"WMPlayer.OCX\") \n" + "Set cd = wmp.cdromCollection.getByDriveSpecifier(\"" + drive + "\") \n" + "cd.Eject"; fw.write(vbs); fw.close(); Runtime.getRuntime().exec("wscript " + file.getPath()).waitFor(); // thanks to TrueJavaProgammer for the waitFor() tip! // Runtime.getRuntime().exec("wscript " + file.getPath()).waitFor(); // Thread.sleep(2000); } catch(Exception e){ e.printStackTrace(); } } public static void close(String drive) { try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new FileWriter(file); // to close a CD, we need eject two times! String vbs = "Set wmp = CreateObject(\"WMPlayer.OCX\") \n" + "Set cd = wmp.cdromCollection.getByDriveSpecifier(\"" + drive + "\") \n" + "cd.Eject \n " + "cd.Eject "; fw.write(vbs); fw.close(); Runtime.getRuntime().exec("wscript " + file.getPath()).waitFor(); // thanks to TrueJavaProgammer for the waitFor() tip! // Runtime.getRuntime().exec("wscript "+ file.getPath()); // Thread.sleep(2000); } catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args){ javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, "Press OK to open CD", "CDUtils", javax.swing.JOptionPane.DEFAULT_OPTION); CDUtils.open("D:\\"); javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, "Press OK to close CD", "CDUtils", javax.swing.JOptionPane.DEFAULT_OPTION);

6.12 Easy keyboard input (JDK1.5)

CDUtils.close("D:\\"); } } NOTE : Windows Media Player version 7 or later is required

6.14 Get faster console output (System.out.println() replacement) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0603.html If your program is doing a lot printing to the console using System.out.println() then it is possible to get a good performance boost by using an alternative to do the console output. By default, System.out.print() is only line−buffered and does a lot work related to Unicode handling. Because of its small buffer size, System.out.println() is not well suited to handle many repetitive outputs in a batch mode. Each line is flushed right away. If your output is mainly ASCII−based then by removing the Unicode−related activities, the overall execution time will be better. Consider this program : import import import import

java.io.BufferedWriter; java.io.FileDescriptor; java.io.FileOutputStream; java.io.OutputStreamWriter;

public class Test { public static void main(String...args) throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { System.out.print("abcdefghijk "); System.out.print(String.valueOf(i)); System.out.print('\n'); } System.err.println("Loop time: " + (System.currentTimeMillis() − start)); } }

The result is >java Test >NUL Loop time: 7000

Now, rewrite this program to use a 512−bytes buffer and specify the ASCII as character−encoding to be used. import import import import

java.io.BufferedWriter; java.io.FileDescriptor; java.io.FileOutputStream; java.io.OutputStreamWriter;

public class Test { public static void main(String...args) throws Exception { BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new

6.14 Get faster console output (System.out.println() replacement)

FileOutputStream(java.io.FileDescriptor.out), "ASCII"), 512); long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { out.write("abcdefghijk "); out.write(String.valueOf(i)); out.write('\n'); } out.flush(); System.err.println("Loop time: " + (System.currentTimeMillis() − start)); } }

The result is >java Test >NUL Loop time: 672

Note that your result will vary depending on your machine/java version but the performance gain should in the same magnitude.

6.15 Execute an external program Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0014.html Be sure to read this Javaworld article. It describes the various pitfalls related to the Runtime.exec() method.

6.16 Using Runtime.exec() This example will capture the output (from stdio) of an external program. import java.io.*; public class CmdExec { public static void main(String argv[]) { try { String line; Process p = Runtime.getRuntime().exec (System.getenv("windir") +"\\system32\\"+"tree.com /A"); BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (Exception err) { err.printStackTrace(); } } }

6.15 Execute an external program

The next example, launch CMD.EXE, grab stdin/stdout and push to stdin command to be interpreted by the shell. String line; OutputStream stdin = null; InputStream stderr = null; InputStream stdout = null; // launch EXE and grab stdin/stdout and stderr Process process = Runtime.getRuntime ().exec ("/folder/exec.exe"); stdin = process.getOutputStream (); stderr = process.getErrorStream (); stdout = process.getInputStream (); // "write" the parms into stdin line = "param1" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); line = "param2" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); line = "param3" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); stdin.close(); // clean up if any output in stdout BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout)); while ((line = brCleanUp.readLine ()) != null) { //System.out.println ("[Stdout] " + line); } brCleanUp.close(); // clean up if any output in stderr brCleanUp = new BufferedReader (new InputStreamReader (stderr)); while ((line = brCleanUp.readLine ()) != null) { //System.out.println ("[Stderr] " + line); } brCleanUp.close();

6.17 Launch a Windows CMD (or BAT) file and retrieve the errorlevel or exitcode // win xp import java.io.*; public class CmdExec { public static void main(String argv[]) { try { String line; Process p = Runtime.getRuntime().exec("test.cmd"); p.waitFor(); System.out.println(p.exitValue()); } catch (Exception err) { err.printStackTrace(); }

6.17 Launch a Windows CMD (or BAT) file and retrieve the errorlevel or exitcode

} }

test.cmd (set the errorlevel manually) @echo hello world @exit 42

test.cmd (set the errorlevel 1 (problem detected) @java −garbage

test.cmd (set the errorlevel 0 (execution Ok) @java −version

6.18 Launch a Unix script String[] cmd = {"/bin/sh", "−c", "ls > hello"}; Runtime.getRuntime().exec(cmd);

6.19 Using the ProcessBuilder Since 1.5, the ProcessBuilder class provides more controls overs the process to be started. It's possible to set a starting directory. import java.io.*; import java.util.*; public class CmdProcessBuilder { public static void main(String args[]) throws InterruptedException,IOException { List<String> command = new ArrayList<String>(); command.add(System.getenv("windir") +"\\system32\\"+"tree.com"); command.add("/A"); ProcessBuilder builder = new ProcessBuilder(command); Map<String, String> environ = builder.environment(); builder.directory(new File(System.getenv("temp"))); System.out.println("Directory : " + System.getenv("temp") ); final Process process = builder.start(); InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } System.out.println("Program terminated!"); } }

6.18 Launch a Unix script

6.20 Windows rundll32 utility Windows File association Any program using the Windows file association mechanism can be started with the rundll32 utility. // "file" is the filename of the data file // ex. myresume.doc // to start Word if the doc extension is associated with it. Runtime.getRuntime().exec ("rundll32 SHELL32.DLL,ShellExec_RunDLL " + file.getAbsolutePath());

See also this HowTo about the new Desktop API, the recommended solution (but you need JDK1.6). See also this one to open the default browser. The following example start a Dial−up connection on the Win plateform : [Dialup.java] public class Dialup { public static void main(String[] args) throws Exception { Process p = Runtime.getRuntime() .exec("rundll32.exe rnaui.dll,RnaDial MyConnection"); p.waitFor(); System.out.println("Done."); } }

The "MyConnection" is the DUN and it's case sensitive. You still need to press ENTER to CONNECT, there is an option in the Connection properties to connect automatically. On NT and W2K, rnaui.dll is not available. Use rasdial.exe instead. rasdial "connection name" rasdial "connection name" /d to drop rasdial /? for more options

6.21 PDF (Windows only) public class ShowPDF { public static void main(String[] args) throws Exception { Process p = Runtime.getRuntime() .exec("rundll32 url.dll,FileProtocolHandler c:/pdf/mypdf.pdf"); p.waitFor(); System.out.println("Done."); } }

6.22 PDF (Mac only) public class ShowPDF { public static void main (String[] args) throws Exception{ Process p = Runtime.getRuntime().exec("open /Documents/mypdf.pdf"); }

6.20 Windows rundll32 utility

}

More runddl32 examples

6.23 Path to executable with spaces in them You can include a path for the program to be executed. On the Win plateform, you need to put the path in quotes if the path contains spaces. public class Test { public static void main(String[] args) throws Exception { Process p = Runtime.getRuntime().exec( "\"c:/program files/windows/notepad.exe\""); p.waitFor(); } }

If you need to pass arguments, it's safer to a String array especially if they contain spaces. String[] cmd = { "myProgram.exe", "−o=This is an option" }; Runtime.getRuntime().exec(cmd);

If using the start command and the path of the file to be started contains a space then you must specified a title to the start command. String fileName = "c:\\Applications\\My Documents\\test.doc"; String[] commands = {"cmd", "/c", "start", "\"DummyTitle\"",fileName}; Runtime.getRuntime().exec(commands);

6.24 VBSCRIPT // Win9x Runtime.getRuntime().exec("start myscript.vbs"); // WinNT Runtime.getRuntime().exec("cmd /c start myscript.vbs"); or // with a visible console Runtime.getRuntime().exec("cscript myscript.vbs"); // with no visible console Runtime.getRuntime().exec("wscript myscript.vbs");

6.25 HTML Help (Windows only) Runtime.getRuntime().exec("hh.exe myhelpfile.chm");

6.26 Start Excel import java.io.IOException; class StartExcel { public static void main(String args[]) throws IOException

6.23 Path to executable with spaces in them

{ Runtime.getRuntime().exec("cmd /c start excel.exe"); } }

To load a worksheet import java.io.IOException; class StartExcel { public static void main(String args[]) throws IOException { String fileName = "c:\\temp\\xls\\test2.xls"; String[] commands = {"cmd", "/c", "start", "\"DummyTitle\"",fileName}; Runtime.getRuntime().exec(commands); } }

It's important to pass a dummy title to the Windows start command where there is a possibility that the filename contains a space. It's a feature.

6.27 Start a Windows application under another account You use the RUNAS command from the command line to start an application under another account (not available with XP Home edition). There are many switches that can enhance the behaviour of RUNAS. Typing "runas /?" from the command prompt gets you all the options. String commands [] = new String [] { "CMD.EXE", "/C", "RUNAS /profile /savecred /user:" + "administrator" + " " + "regedit.exe" }; Runtime.getRuntime().exec(commands);

/SaveCred option allows you to save a password for that account and then reuse it later. For example, The command runas /savecred /user:administrator regedit.exe prompts for the password, and then Regedit runs. Next time you use the same command, there is no password prompt. One potential problem is that when /SaveCred saves the credentials it saves it for whenever RUNAS invokes that user account. This can be a huge security risk so be careful using it! RUNAS capability can be disabled by editing the Registry or by disabling the RUNAS or Secondary Logon Services. The appropriate registry key is HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer, create a new DWORD value named HideRunAsVerb and assign it a value of 1 to disable Run as. RUNAS doesn't work when used from a Windows service.

6.27 Start a Windows application under another account

6.28 Windows : execute something in Program Files We want to execute the textpad editor located in C:\Program Files\TextPad 4 but without hard coding the path since it can be different for a localized version of Windows. We simply extract to environnment variable called %programfiles% and build the complete path from there. [JDK1.5] public class Exec { static String WIN_PROGRAMFILES = System.getenv("programfiles"); static String FILE_SEPARATOR = System.getProperty("file.separator"); public static void main(String[] args) throws Exception { String[] commands = {"cmd.exe", "/c", WIN_PROGRAMFILES + FILE_SEPARATOR + "textpad 4" + FILE_SEPARATOR + "textpad.exe"}; Runtime.getRuntime().exec(commands); } }

NOTE : Prior Vista, System folders were localized on disk like C:\Program Files −> C:\Archivos de programa on the Windows with the Spanish localization. Since Vista, System Folders always exists with the english name BUT when viewed through Explorer, the localized name is shown. See http://msmvps.com/blogs/carlosq/archive/2007/02/12/windows−vista−junctions−points−mui−and−localized−f

6.29 Launch the application associated with a file extension Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0579.html JDK1.6 The java.awt.Desktop class uses your host operating system's file associations to launch applications associated with specific file types. First it's a good idea to check if the Desktop operations are supported on the running plateform. import java.awt.*; ... if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); for (Desktop.Action action : Desktop.Action.values()) { System.out.println("action " + action + " supported? " + desktop.isSupported(action)); } }

6.28 Windows : execute something in Program Files

The possible actions are • BROWSE. launching the user−default browser to show a specified URI • MAIL. launching the user−default mail client with an optional mailto URI; • OPEN. launching a registered application to open a specified file. • EDIT. launching a registered application to edit a specified file. • PRINT. launching a registered application to print a specified file. then // application associated to a file extension public static void open(File document) throws IOException { Desktop dt = Desktop.getDesktop(); dt.open(document); } public static void print(File document) throws IOException { Desktop dt = Desktop.getDesktop(); dt.print(document); } // default browser public static void browse(URI document) throws IOException { Desktop dt = Desktop.getDesktop(); dt.browse(document); } // default mail client // use the mailto: protocol as the URI // ex : mailto:[email protected]?SUBJECT=Love me tender&BODY=love me sweet public static void mail(URI document) throws IOException { Desktop dt = Desktop.getDesktop(); dt.mail(document); }

See the javadoc at http://java.sun.com/javase/6/docs/api/java/awt/Desktop.html See also this HowTo and this one.

6.30 Launch an application from another application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0394.html While you can exec("java myaotherapp"), it is more appropriate to instanciate and called the main method of the other application. For example, take this simple application : public class Program2 { public static void main(String arg[]) { System.out.println("Hello from Program2"); } }

To call the above application from another

6.30 Launch an application from another application

public class Program1a { public static void main(String arg[]) { System.out.println("Hello from Program1a"); new Thread(){ public void run() { Program2.main(new String[]{});} }.start(); } }

The above example is used when the class is hard−coded. The dynamic version is little more tricky. public class Program1b { public static void main(String arg[]) { System.out.println("Hello from Program1b"); new Program1b().execute("Program2"); } public void execute(String name) { Class params[] = {String[].class}; // if you need parameters // String[] args = new String[] { "Hello", "world" }; // Class params[] = new Class[] { args.getClass() }); try { Class.forName(name). getDeclaredMethod("main", params). invoke(null, new Object[] {new String[] {}}); } catch(Exception e){ e.printStackTrace();} } }

Launch many programs using Thread and use join() to wait for the completion. [Program2.java] public class Program2 { public static void main(String arg[]) { System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); } } [Program1a.java] public class Program1a { public static void main(String arg[]) throws Exception{ System.out.println("Hello from Program1a"); Thread t1 = new Thread(){ public void run() { Program2.main(new String[]{});} }; t1.start(); t1.join(); System.out.println("Hello from Program1a"); } }

6.30 Launch an application from another application

The output : C:\>java Program1a Hello from Program1a Hello from Program2 Hello from Program2 Hello from Program2 Hello from Program2 Hello from Program1a

6.31 Start the default browser from an application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0071.html In this snippet, we initialize a Listbox from a file containing some URLs. When we double click an item, the default browser is started with the selected HTML page as parameter. This example is Windows oriented since I have used the start command which supports the file association. [urlList.txt] http://www.rgagnon.com/javadetails/java−0001.html|JAVA http://www.rgagnon.com/javadetails/java−0002.html|JAVA http://www.rgagnon.com/javadetails/java−0003.html|JAVA http://www.rgagnon.com/javadetails/java−0004.html|JAVA http://www.rgagnon.com/javadetails/java−0005.htmL|JAVA

[StartBrowser.java]

How−to How−to How−to How−to How−to

import import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*; java.io.*;

public class StartBrowser { public static void main(String s[]) { AFrame f = new AFrame(); } } class AFrame extends Frame implements ActionListener { List lbx; String url[] = new String[50]; public AFrame() { // dispaly setup setTitle("URL selection"); setSize(400,400); lbx = new List(); add(lbx); initLbx(); // action on listbox double click lbx.addActionListener(this); // to close the Frame addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) {

6.31 Start the default browser from an application

1 2 3 4 5

System.exit(0); } } ); setVisible(true); } public void actionPerformed (ActionEvent ae) { String theUrl = url[lbx.getSelectedIndex()]; // start the default browser (Win95 platform) // on listbox double click String cmdLine = "start " + theUrl; // on NT, you need to start cmd.exe because start is not // an external command but internal, you need to start the // command interpreter // String cmdLine = "cmd.exe /c " + cmdLine; try { Process p = Runtime.getRuntime().exec(cmdLine); } catch (Exception e) { e.printStackTrace(); } } public void initLbx() { int i = 0; try { String aLine = ""; BufferedReader in = new BufferedReader(new FileReader("urlList.txt")); while(null != (aLine = in.readLine())) { java.util.StringTokenizer st = new java.util.StringTokenizer(aLine, "|"); url[i++] = st.nextToken(); lbx.addItem(st.nextToken()); // lbx.add(st.nextToken()); in JDK1.2 } } catch(Exception e) { e.printStackTrace(); } } }

Another way on Windows platform to start the default browser is ; Runtime.getRuntime().exec ("rundll32 url.dll,FileProtocolHandler " + theUrl);

You may have difficulty to open a URL ending with .htm. All you need is to replace the last m with %6D, like rundll32 url.dll,FileProtocolHandler http://www.rgagnon.com/howto.htm for rundll32 url.dll,FileProtocolHandler http://www.rgagnon.com/howto.ht%6D

JDK1.6 has java.awt.Desktop.open(File)

6.31 Start the default browser from an application

See http://java.sun.com/javase/6/docs/api/java/awt/Desktop.html JDIC provides the equivalent API for 1.4 and later. See https://jdic.dev.java.net try { Desktop.browse(new URL("http://www.rgagnon.com"); } catch (MalformedURLException e1) { e1.printStackTrace(); } catch (DesktopException e2) { e2.printStackTrace(); }

See also this HowTo.

6.32 Execute a Windows Shortcut (.lnk) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0571.html A Shortcut is stored in a file with the extension lnk. // we assume that the .lnk is in the current directory String currentDir = new File(".").getCanonicalPath(); try { Runtime.getRuntime().exec ("cmd /c start " + currentDir + "/viewLog.lnk"); } catch (Exception e){ JOptionPane.showMessageDialog (null, e.getMessage(),"Oups", JOptionPane.ERROR_MESSAGE); }

6.33 Create a file association with a Java program Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0592.html In this example, a file with the extension .xox will be defined and associated with a java program (display the first 10 lines of selected .xox file). First the java program to be associated with the .xox file type. import java.io.*; public class Head { static final int MAX_LINES = 10; public static void main(String args[]) throws Exception{

6.32 Execute a Windows Shortcut (.lnk)

String line = null; int i = 0 ; FileInputStream fin = new FileInputStream(args[0]); BufferedReader myInput = new BufferedReader (new InputStreamReader(fin)); while ( (line = myInput.readLine()) != null) { System.out.println(line); i++; if (i == MAX_LINES) break; } BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); System.out.print("*** Press any key..."); input.readLine(); } }

With Windows, two commands are used to define a file association, assoc and ftype. You need to execute these commands from an account with Administrator privilege. To know more about these commands, type assoc /? or ftype /? .

First we define the .xox file type. The assoc command sets up an association between a file name extension and a file type. >assoc .xox=Xoxfile .xox=Xoxfile

Then we specify which program is used to handle the Xoxfile type of file. The ftype command sets up an association between a file type name, and a string to be used to execute it. In this example, we specify the Java JVM to be used, the classpath to load the Head.class plus the parameter (the selected .xox file). >ftype Xoxfile=C:\Program Files\Java\jre1.5.0\bin\java −cp c:\dev\work Head %1 Xoxfile=C:\Program Files\Java\jre1.5.0\bin\java −cp c:\dev\work Head %1

Now, if you double−click on a file with .xox extension, a Dos shell is opened, the Head class is launched with the clicked filename as a parameter and the first 10 line are displayed. To make the file association works from a command line, you define the environment variable PATHEXT to include the .xox extension. >set pathext=.xox;%pathext% PATHEXT=.XOX;.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH

then you will be able, from a Dos shell, to type only the name of .xox file and the associated program will be launched with that file as a parameter. See also this HowTo.

6.32 Execute a Windows Shortcut (.lnk)

6.34 Capture the output from a VBS Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0576.html This HowTo query the Windows Registry for a specific key. The VBS prints the result and from Java, we capture this output. Since we need the output, we must use the VBS interpreter for the console mode (CSCRIPT.EXE). import import import import

java.io.BufferedReader; java.io.File; java.io.FileWriter; java.io.InputStreamReader;

public class VBSUtils { private VBSUtils() { } public static String readWindowRegistry(String key) { String result = ""; try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = "Dim WSHShell \n" + "Set WSHShell = WScript.CreateObject(\"WScript.Shell\") \n" + "WScript.Echo _ \n" + "WSHShell.RegRead(\"" + key + "\") \n" + "Set WSHShell = Nothing \n"; fw.write(vbs); fw.close(); Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath()); BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream())); String line; while ((line = input.readLine()) != null) { result += line; } input.close(); } catch(Exception e){ e.printStackTrace(); } return result.trim(); }

public static void main(String[] args){ // // DEMO // String result = ""; msgBox("Get the path of Acrobat reader from the registry"); result = readWindowRegistry ("HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\AcroRd32.exe\\");

6.34 Capture the output from a VBS

msgBox("Acrobat Reader is located in " + result); } public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } }

6.35 Get a return code from a VBS Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0575.html You can't detect directly if Windows service is running or not in Java. However, it's easy to do from a VBS. You execute the script from Java, wait for its completion and capture the return code. Obviously, this is useful only on the Windows plateform. import java.io.File; import java.io.FileWriter; public class VBSUtils { private VBSUtils() { } public static boolean isServiceRunning(String serviceName) { try { File file = File.createTempFile("realhowto",".vbs"); file.deleteOnExit(); FileWriter fw = new java.io.FileWriter(file); String vbs = "Set sh = CreateObject(\"Shell.Application\") \n" + "If sh.IsServiceRunning(\""+ serviceName +"\") Then \n" + " wscript.Quit(1) \n" + "End If \n" + "wscript.Quit(0) \n"; fw.write(vbs); fw.close(); Process p = Runtime.getRuntime().exec("wscript " + file.getPath()); p.waitFor(); return (p.exitValue() == 1); } catch(Exception e){ e.printStackTrace(); } return false; }

public static void main(String[] args){ // // DEMO // String result = ""; msgBox("Check if service 'Themes' is running (should be yes)"); result = isServiceRunning("Themes") ? "" : " NOT "; msgBox("service 'Themes' is " + result + " running ");

6.35 Get a return code from a VBS

msgBox("Check if service 'foo' is running (should be no)"); result = isServiceRunning("foo") ? "" : " NOT "; msgBox("service 'foo' is " + result + " running "); } public static void msgBox(String msg) { javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION); } }

6.36 Execute a CMD file stored in a JAR Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0600.html In this example, a CMD file is stored a JAR file. The Java code extracts the file as a ressource, launch a Windows CMD Shell and write the content to the stdin without any temporary file. In this How−to, the CMD included is used to trigger the default Windows screen saver. scrnsave.scr /s import java.io.*; public class StartScreenSaver { public static void main(String args[]) throws IOException { new StartScreenSaver().doit(); } public void doit() throws IOException{ String line; OutputStream stdin = null; InputStream stderr = null; InputStream stdout = null; try { // that our CMD file in our JAR InputStream is = getClass().getResource("/screensaver.cmd").openStream(); BufferedReader brCmdLine = new BufferedReader(new InputStreamReader(is)); // launch CMD and grab stdin/stdout and stderr Process process = Runtime.getRuntime ().exec ("cmd"); stdin = process.getOutputStream (); stderr = process.getErrorStream (); stdout = process.getInputStream (); // "write" the CMD file into stdin while ((line = brCmdLine.readLine()) != null) { line += "\n"; stdin.write(line.getBytes() ); } stdin.flush(); stdin.close(); // clean up if any output in stdout

6.36 Execute a CMD file stored in a JAR

BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout)); while ((line = brCleanUp.readLine ()) != null) { //System.out.println ("[Stdout] " + line); } brCleanUp.close(); // clean up if any output in stderr brCleanUp = new BufferedReader (new InputStreamReader (stderr)); while ((line = brCleanUp.readLine ()) != null) { //System.out.println ("[Stderr] " + line); } brCleanUp.close(); } catch (IOException e) { e.printStackTrace(); } finally { stdout.close(); stderr.close(); } } }

Get the JAR here.

6.37 Read the content of a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0052.html This following example is for an application. On the command line, give the filename to be displayed. import java.io.*; public class Cat { public static void main (String args[]) { String thisLine; for (int i=0; i < args.length; i++) { try { FileInputStream fin = new FileInputStream(args[i]); // JDK1.1+ BufferedReader myInput = new BufferedReader (new InputStreamReader(fin)); while ((thisLine = myInput.readLine()) != null) { System.out.println(thisLine); } } catch (Exception e) { e.printStackTrace(); } } } }

6.37 Read the content of a file

With an Applet, we can only open file on the same server that the Applet is coming from.

import java.applet.*; import java.net.*; import java.io.*; public class MyApplet extends Applet { public void init() { readFile("mydatafile.txt"); } public void readFile(String f) { try { String aLine = ""; URL source = new URL(getCodeBase(), f); BufferedReader br = new BufferedReader (new InputStreamReader(source.openStream())); while(null != (aLine = br.readLine())) { System.out.println(aLine); } br.close(); } catch(Exception e) { e.printStackTrace(); } } }

The next Applet reads a data file and inserts the data in a Choice component.

import import import import

java.applet.*; java.awt.*; java.net.*; java.io.*;

public class ReadDataInChoice extends Applet { Choice myChoice; public void init() { myChoice = new java.awt.Choice(); add(myChoice); readFile("dataforchoice.txt"); } public void readFile(String f) { try { String anItem = ""; URL source = new URL(getCodeBase(), f); BufferedReader in = new BufferedReader(new InputStreamReader(source.openStream())); while(null != (anItem = in.readLine())) { myChoice.add(anItem); } in.close(); } catch(Exception e) { e.printStackTrace(); } } }

6.37 Read the content of a file

[dataforchoice.txt] item item item item item ITEM

1 2 3 4 5 6

Try it here.

The following method read a data file and return the content as a String. We use a StringBuffer to optimize string concatenation operations. private static String readFile(String filename) throws IOException { String lineSep = System.getProperty("line.separator"); BufferedReader br = new BufferedReader(new FileReader(filename)); String nextLine = ""; StringBuffer sb = new StringBuffer(); while ((nextLine = br.readLine()) != null) { sb.append(nextLine); // // note: // BufferedReader strips the EOL character // so we add a new one! // sb.append(lineSep); } return sb.toString(); }

See this HowTo to read a File which is inside a JAR.

6.38 Read a text file from a jar Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0077.html import java.io.*; import java.util.*; public class FileUtils{ public static List<String> readTextFromJar(String s) { InputStream is = null; BufferedReader br = null; String line; ArrayList<String> list = new ArrayList<String>(); try { is = FileUtils.class.getResourceAsStream(s); br = new BufferedReader(new InputStreamReader(is)); while (null != (line = br.readLine())) { list.add(line); } } catch (Exception e) { e.printStackTrace();

6.38 Read a text file from a jar

} finally { try { if (br != null) br.close(); if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } } return list; } public static void main(String args[]) throws IOException{ List<String> list = FileUtils.readTextFromJar("/datafile1.txt"); Iterator<String> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } list = FileUtils.readTextFromJar("/test/datafile2.txt"); it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }

Create 2 datafiles. datafile1.txt in the same directory as FileUtils.class (in the root) and datafile2.txt in a subdirectory called test [datafile1.txt] datafile1 datafile1 datafile1 datafile1 datafile1

line line line line line

1 2 3 4 5

[/test/datafile2.txt] datafile2 datafile2 datafile2 datafile2 datafile2

line line line line line

1 2 3 4 5

Create the jar with >"C:\Program Files\Java\jdk1.5.0\bin\jar" −cf MyJar.jar FileUtils.class datafile.txt test/datafile.txt

Try it : C> java −cp MyJar.jar FileUtils

The output should be like : 6.38 Read a text file from a jar

datafile1 datafile1 datafile1 datafile1 datafile1 datafile2 datafile2 datafile2 datafile2 datafile2

line line line line line line line line line line

1 2 3 4 5 1 2 3 4 5

Get the JAR here With an Applet, it's the same technique import java.applet.*; import java.io.*; public class ReadFromJar extends Applet{ public void init(){ readTextFromJar("datafile1.txt"); readTextFromJar("test/datafile2.txt"); } public void readTextFromJar(String s) { String thisLine; try { InputStream is = getClass().getResourceAsStream(s); BufferedReader br = new BufferedReader (new InputStreamReader(is)); while ((thisLine = br.readLine()) != null) { System.out.println(thisLine); } } catch (Exception e) { e.printStackTrace(); } } }

Create the JAR >"C:\Program Files\Java\jdk1.5.0\bin\jar" −cf MyJarApplet.jar ReadFromJar.class datafile1.txt test/datafile2.txt

The html <APPLET CODE=ReadFromJar.class width=1 height=1 archive=MyJarApplet.jar> See java console for output

Try it here

6.38 Read a text file from a jar

6.39 Extract a file from a Jar Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0429.html The following snippet extract a file (mydb.mdb) from a jar. import java.io.*; import java.util.jar.*; import java.util.zip.*;

public class ExtractFromJAR { public void extractMyMDBromJAR(String dest){ try { String home = getClass().getProtectionDomain(). getCodeSource().getLocation().toString(). substring(6); JarFile jar = new JarFile(home); ZipEntry entry = jar.getEntry("mydb.mdb"); File efile = new File(dest, entry.getName()); InputStream in = new BufferedInputStream(jar.getInputStream(entry)); OutputStream out = new BufferedOutputStream(new FileOutputStream(efile)); byte[] buffer = new byte[2048]; for (;;) { int nBytes = in.read(buffer); if (nBytes <= 0) break; out.write(buffer, 0, nBytes); } out.flush(); out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args []){ new ExtractFromJAR().extractMyMDBFromJAR("."); } }

Grab this auto−run Jar if you want to try it. To create an auto−run JAR, first create a manifest.mft Manifest−Version: 1.0 Classpath: .\mydb.jar Main−Class: ExtractFromJAR

Create the JAR C:\jdk141\bin\jar cvfm mydb.jar manifest.mft ExtractFromJAR.class mydb.mdb

6.39 Extract a file from a Jar

Run it ... and the mydb.mdb file should appear in the current directory. java −jar mydb.jar

(A tip from Fred Hommersom) Your code reads: String home = getClass().getProtectionDomain(). getCodeSource().getLocation().toString().substring(6);

I got a problem when the jar file was located in C:\Program Files\xyz due to the embedded space. So I modified the code to String home = getClass().getProtectionDomain() .getCodeSource().getLocation() .getPath().replaceAll("%20", " "); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.40 Read a data file with floats Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0078.html [ReadingFloat.java] public class ReadingFloat { public static float[] readFile(String file, String delimiter) throws Exception { return(readValues(new java.io.FileInputStream(file), delimiter)); } public static float[] readURL(String url, String delimiter) throws Exception { java.net.URL addr = new java.net.URL(url); return(readValues(addr.openStream(), delimiter)); } public static float[] readValues(java.io.InputStream in, String delimiter) throws java.io.FileNotFoundException, java.io.IOException, java.lang.NumberFormatException { String thisLine; java.io.BufferedInputStream s = new java.io.BufferedInputStream(in); java.io.BufferedReader myInput = new java.io.BufferedReader (new java.io.InputStreamReader(s)); int j = 0; float[] values = new float[10]; while ((thisLine = myInput.readLine()) != null) { // scan it line by line java.util.StringTokenizer st = new java.util.StringTokenizer(thisLine, delimiter); while(st.hasMoreElements()) values[j++] = Float.valueOf(st.nextToken()).floatValue();

6.40 Read a data file with floats

} return(values); } public static void main(String arg[]) { new ReadingFloat().demo(); } public void demo() { try { // we assume 10 floats (max)to be read float results [] = readFile("floatwithdelimitercolon.dat", ","); for(int i = 0; i < results.length; i++ ) { System.out.println(results[i]); } System.out.println(); results = readFile("floatwithdelimiterspace.dat", " "); for(int i = 0; i lt; results.length; i++ ) { System.out.println(results[i]); } } catch (Exception e) { e.printStackTrace(); } } }

[floatwithdelimitercolon.dat] 1.2,1.3,1.6,1.78,1.2345 2.2,2.3,2.6,2.78,2.2345

[floatwithdelimiterspace.dat] 1.2 1.3 1.6 1.78 1.2345 2.2 2.3 2.6 2.78 2.2345

6.41 Write to the end of a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0054.html [JDK1.0.2] import java.io.*; public class appendtext { public static void main(String args[]){ try { PrintStream out = new PrintStream(new AppendFileStream("myfile")); out.print("A new line of text"); out.close(); } catch(Exception e) { System.out.println(e.toString()); } } }

6.41 Write to the end of a file

class AppendFileStream extends OutputStream { RandomAccessFile fd; public AppendFileStream(String file) throws IOException { fd = new RandomAccessFile(file,"rw"); fd.seek(fd.length()); } public void close() throws IOException { fd.close(); } public void write(byte[] b) throws IOException { fd.write(b); } public void write(byte[] b,int off,int len) throws IOException { fd.write(b,off,len); } public void write(int b) throws IOException { fd.write(b); } }

[JDK1.1] FileOutputStream fos = new FileOutputStream("myfile", true);

to open in Append mode

6.42 Write "real" ascii file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0058.html Java uses Unicode character encoding internally. To pass information to outside world, it may be necessary to use different encoding. For example, DOS application may use MS ISO−Latin 1(or Codepage 850) to represent french characters like é or à. Before writting to a file or in a database record it is necessary to change the default String encoding. This done via the InputStreamReader class for input and OutputStreamWriter for output. InputStreamReader converts from the specified input encoding to Unicode while the OutputStreamWriter converts from Unicode to the specified output encoding. import java.io.*; import java.awt.*; public class DosString { public static void main(String args[]){ String javaString = "é \u00e9"; // Unicode for "é" try { // output : Unicode to Cp850 (MS−DOS Latin−1) FileOutputStream fos = new FileOutputStream("out.dat"); Writer w = new BufferedWriter(new OutputStreamWriter(fos, "Cp850")); w.write(JavaString);

6.42 Write "real" ascii file

w.flush(); w.close(); // input`: Cp850 to Unicode FileInputStream fis = new FileInputStream("out.dat"); BufferedReader r = new BufferedReader(new InputStreamReader(fis, "Cp850")); String dosString = r.readLine(); r.close(); Frame f = new Frame(); f.setSize(100,100); f.add(new Label(dosString)); f.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } } NOTE: When the character encoding is not specified, the default encoding is used. You can find out the current default encoding by looking at file.encoding property with System.getProperty("file.encoding"); .

6.43 Copy a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0064.html [Old technique (pre JDK1.4)] import java.io.*; public class FileUtils{ public static void copyFile(File in, File out) throws Exception { FileInputStream fis = new FileInputStream(in); FileOutputStream fos = new FileOutputStream(out); try { byte[] buf = new byte[1024]; int i = 0; while ((i = fis.read(buf)) != −1) { fos.write(buf, 0, i); } } catch (Exception e) { throw e; } finally { if (fis != null) fis.close(); if (fos != null) fos.close(); } } public static void main(String args[]) throws Exception{ FileUtils.copyFile(new File(args[0]),new File(args[1])); } }

[JDK1.4 using the java.nio package (faster)]

6.43 Copy a file

import java.io.*; import java.nio.channels.*; public class FileUtils{ public static void copyFile(File in, File out) throws IOException { FileChannel inChannel = new FileInputStream(in).getChannel(); FileChannel outChannel = new FileOutputStream(out).getChannel(); try { inChannel.transferTo(0, inChannel.size(), outChannel); } catch (IOException e) { throw e; } finally { if (inChannel != null) inChannel.close(); if (outChannel != null) outChannel.close(); } } public static void main(String args[]) throws IOException{ FileUtils.copyFile(new File(args[0]),new File(args[1])); } } NOTE: In win2000 , the transferTo() does not transfer files > than 2^31−1 bytes. it throws an exception of "java.io.IOException: The parameter is incorrect" In solaris8 , Bytes transfered to Target channel are 2^31−1 even if the source channel file is greater than 2^31−1 In LinuxRH7.1 , it gives an error of java.io.IOException: Input/output error

ref : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4643189 On the Windows plateform, you can't copy a file bigger than 64Mb, an Exception in thread "main" java.io.IOException: Insufficient system resources exist to complete the requested service is thrown. For a discussion about this see : http://forum.java.sun.com/thread.jspa?threadID=4396950 The workaround is to copy in a loop 64Mb each time until there is no more data. Replace ... try { inChannel.transferTo(0, inChannel.size(), outChannel); } ...

by ... try { // magic number for Windows, 64Mb − 32Kb) int maxCount = (64 * 1024 * 1024) − (32 * 1024); long size = inChannel.size(); long position = 0;

6.43 Copy a file

while (position < size) { position += inChannel.transferTo(position, maxCount, outChannel); } ...

6.44 Use a "log file" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0063.html /** * Utilities log */ import java.io.*; import java.text.*; import java.util.*; public class SimpleLog { private static String logFile = "/msglog.txt"; private final static DateFormat df = new SimpleDateFormat ("yyyy.mm.dd private SimpleLog() { } public static void setLogFilename(String filename) { logFile = filename; new File(filename).delete(); try { write("LOG file : " + filename); } catch (Exception e) { System.out.println(stack2string(e)); } } public static void write(String msg) { write(logFile, msg); } public static void write(Exception e) { write(logFile, stack2string(e)); } public static void write(String file, String msg) { try { Date now = new Date(); String currentTime = SimpleLog.df.format(now); FileWriter aWriter = new FileWriter(file, true); aWriter.write(currentTime + " " + msg + System.getProperty("line.separator")); System.out.println(currentTime + " " + msg); aWriter.flush(); aWriter.close(); } catch (Exception e) { System.out.println(stack2string(e)); }

6.44 Use a "log file"

hh:mm:ss ");

} private static String stack2string(Exception e) { try { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); return "−−−−−−\r\n" + sw.toString() + "−−−−−−\r\n"; } catch(Exception e2) { return "bad stack2string"; } } }

and then to use it SimpleLog.write("i am here");

See also this HowTo and this one

6.45 Delete files with a certain extension Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0072.html Define a special FilenameFilter : import java.io.*; public class ExtensionFilter implements FilenameFilter { private String extension; public ExtensionFilter( String extension ) { this.extension = extension; } public boolean accept(File dir, String name) { return (name.endsWith(extension)); } }

and then import java.io.*; public class FileUtils{ public static void main(String args[]) throws Exception { FileUtils.deleteFiles("c:/test/", ".gif"); } public static void deleteFiles( String directory, String extension ) { ExtensionFilter filter = new ExtensionFilter(extension); File dir = new File(directory); String[] list = dir.list(filter); File file;

6.45 Delete files with a certain extension

if (list.length == 0) return; for (int i = 0; i < list.length; i++) { //file = new File(directory + list[i]); file = new File(directory, list[i]); System.out.print(file + " deleted : " + file.delete()); } } } }

6.46 Insert a line in a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0073.html The only way to insert a line in a text file is to read the original file and write the content in a temporary file with the new line inserted. Then we erase the original file and rename the temporary file to the original name. In this example, you need to supply 3 arguments : the filename, a line number and the string to be inserted at the line number specified. java JInsert test.out 9 "HELLO WORLD"

will insert the string "HELLO WORLD" at line number 9 in the file "test.out". of course you need more error checking...

[JDK1.1] import java.io.*; public class JInsert { public static void main(String args[]){ try { JInsert j = new JInsert(); j.insertStringInFile (new File(args[0]),Integer.parseInt(args[1]), args[2]); } catch (Exception e) { e.printStackTrace(); } } public void insertStringInFile (File inFile, int lineno, String lineToBeInserted) throws Exception { // temp file File outFile = new File("$$$$$$$$.tmp"); // input FileInputStream fis = new FileInputStream(inFile); BufferedReader in = new BufferedReader (new InputStreamReader(fis)); // output FileOutputStream fos = new FileOutputStream(outFile);

6.46 Insert a line in a file

PrintWriter out = new PrintWriter(fos); String thisLine = ""; int i =1; while ((thisLine = in.readLine()) != null) { if(i == lineno) out.println(lineToBeInserted); out.println(thisLine); i++; } out.flush(); out.close(); in.close(); inFile.delete(); outFile.renameTo(inFile); } }

6.47 Read a file into a variable in one shot Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0074.html import java.io.*; public class ReadFullyIntoVar { public static void main(String argv[]){ try { FileInputStream file = new FileInputStream (argv[0]); DataInputStream in = new DataInputStream (file); byte[] b = new byte[in.available ()]; in.readFully (b); in.close (); String result = new String (b, 0, b.length, "Cp850"); /* */ System.out.println(result); } catch (Exception e) { e.printStackTrace(); } } }

6.48 Serialize an object to a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0075.html Suppose we have a class called Queue.class. We want to save the state of the Queue in a file. Since our Queue extends the Vector class, the methods needed to serialize the object are already done. All we need is an input or output stream. First the Queue class import java.util.Vector; import java.io.*;

6.47 Read a file into a variable in one shot

public class Queue extends Vector { /* ** FIFO, first in first out */ Queue() { super(); } void put(Object o) { addElement(o); } Object get() { if (isEmpty()) return null; Object o = firstElement(); removeElement(o); return o; } Object peek() { if (isEmpty()) return null; return firstElement(); } }

To serialize (save the Queue state to a file) : public static void main(String args[]) { Queue theQueue; theQueue = new Queue(); theQueue.put("element 1"); theQueue.put("element 2"); theQueue.put("element 3"); theQueue.put("element 4"); System.out.println(theQueue.toString()); // serialize the Queue System.out.println("serializing theQueue"); try { FileOutputStream fout = new FileOutputStream("thequeue.dat"); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(theQueue); oos.close(); } catch (Exception e) { e.printStackTrace(); } }

To unserialize (to load a previously saved Queue) : public static void main(String args[]) { Queue theQueue; theQueue = new Queue(); // unserialize the Queue System.out.println("unserializing theQueue"); try { FileInputStream fin = new FileInputStream("thequeue.dat"); ObjectInputStream ois = new ObjectInputStream(fin); theQueue = (Queue) ois.readObject();

6.47 Read a file into a variable in one shot

ois.close(); } catch (Exception e) { e.printStackTrace(); } System.out.println(theQueue.toString()); }

6.49 Redirect stdout to a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0061.html [JDK1.1] application only System.setOut( new PrintStream( new BufferedOutputStream( new FileOutputStream("OUTPUT.DAT")))); You may want to look at this How−to to redirect exception output to a Frame.

6.50 Get the "last modified" date from a file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0068.html Simply use the lastModified() method from a file object. but the return value is system dependent and should only be used to compare with other values returned by last modified. It should not be interpreted as an absolute time. String s1 = "file1.dat"; String s2 = "file2.dat"; File f1 = new File(s1); File f2 = new File(s2); if (f1.lastModified() < f2.lastModified()) System.out.println((s1 + " IS OLDER THAN " + S2);

6.51 Check if a file exists Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0070.html import java.io.*; public class FileTest { public static void main(String args[]) { File f = new File(args[0]); System.out.println (f + (f.exists()? " is found " : " is missing ")); } }

6.49 Redirect stdout to a file

6.52 Detect file modification Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0490.html For a single file, a thread is launched to check the lastModified value and compare it with the previous value. import java.util.*; import java.io.*; public abstract class FileWatcher extends TimerTask { private long timeStamp; private File file; public FileWatcher( File file ) { this.file = file; this.timeStamp = file.lastModified(); } public final void run() { long timeStamp = file.lastModified(); if( this.timeStamp != timeStamp ) { this.timeStamp = timeStamp; onChange(file); } } protected abstract void onChange( File file ); }

import java.util.*; import java.io.*; class FileWatcherTest { public static void main(String args[]) { // monitor a single file TimerTask task = new FileWatcher( new File("c:/temp/text.txt") ) { protected void onChange( File file ) { // here we code the action on a change System.out.println( "File "+ file.getName() +" have change !" ); } }; Timer timer = new Timer(); // repeat the check every second timer.schedule( task , new Date(), 1000 ); } }

For a directory, a thread is launched where we keep the Files in a Map, we check the current lastModifed value of a given file and compare it with the value stored in the Map. Also a special check is made to detect if a File is deleted.

6.52 Detect file modification

import java.util.*; import java.io.*; public abstract class DirWatcher extends TimerTask { private String path; private File filesArray []; private HashMap dir = new HashMap(); private DirFilterWatcher dfw; public DirWatcher(String path) { this(path, ""); } public DirWatcher(String path, String filter) { this.path = path; dfw = new DirFilterWatcher(filter); filesArray = new File(path).listFiles(dfw); // transfer to the hashmap be used a reference and keep the // lastModfied value for(int i = 0; i
6.52 Detect file modification

this.filter = ""; } public DirFilterWatcher(String filter) { this.filter = filter; } public boolean accept(File file) { if ("".equals(filter)) { return true; } return (file.getName().endsWith(filter)); } }

import java.util.*; import java.io.*; class DirWatcherTest { public static void main(String args[]) { TimerTask task = new DirWatcher("c:/temp", "txt" ) { protected void onChange( File file, String action ) { // here we code the action on a change System.out.println ( "File "+ file.getName() +" action: " + action ); } }; Timer timer = new Timer(); timer.schedule( task , new Date(), 1000 ); } }

See also this related howto and this one too.

6.53 File/directory polling to detect change Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0617.html

6.54 jpoller (directory poller) http://jpoller.sourceforge.net/ A general purpose Java component to enable polling on directories and aysnchronously notify client code of incoming files. It's instrumented via JMX and controllable (also) via a JMX agent, like JBoss' JMX console.

6.55 JNotify http://jnotify.sourceforge.net/

6.53 File/directory polling to detect change

JNotify is a java library that allow java application to listen to file system events. JNotify works on both Windows (Windows 2000, XP, Vista) and Linux with INotify support (Kernel 2.6.14 and above).

6.56 Java Native Access (JNA) https://jna.dev.java.net/ The goal of the JNA project is to let you access native code from Java while avoiding C and the Java Native Interface. One example provides notification of file system changes using the mechanism provided by the OS. FileMonitor.java Javaworld article about JNA

6.57 Call native methods in a DLL from Java (NativeCall)

http://johannburkard.de/blog/programming/java/Call−native−methods−in−a−DLL−from−Java−without−JNI.ht In this blog entry, the package NativeCall is used to call the Windows API to get notification about modification in given folder.

6.58 Java 7 http://www.artima.com/lejava/articles/more_new_io.html Java 7 is supposed to provides a mechanism to get notificaton on file change without polling (JSR 203).

6.59 The simple (and naive!) approach Detect file modification Using Threads and file lookup at regular interval.

6.60 Get the current directory Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0076.html import java.io.File; public class CurrentDir { public static void main (String args[]) { File dir1 = new File ("."); File dir2 = new File (".."); try { System.out.println ("Current dir : " + dir1.getCanonicalPath()); System.out.println ("Parent dir : " + dir2.getCanonicalPath()); } catch(Exception e) {

6.56 Java Native Access (JNA)

e.printStackTrace(); } } }

6.61 Get the "root" of an application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0581.html By root, we mean the starting directory. import import import import import

java.io.File; java.io.IOException; java.net.URI; java.net.URISyntaxException; java.net.URL;

public class DummyApp { public static void main(String args[]) throws Exception{ DummyApp s = new DummyApp(); s.getRoot(); } public void getRoot() throws IOException, URISyntaxException{ URL u = getClass().getProtectionDomain().getCodeSource().getLocation(); File f = new File(u.toURI()); System.out.println(f.getParent()); } }

Running from a regular class C:\Applications\dev\HowTo>java −cp . DummyApp C:\Applications\dev

Running from a jar C:\Applications\dev\HowTo>jar cf DummyApp.jar DummyApp.* C:\Applications\dev\HowTo>java −cp DummyApp.jar DummyApp C:\Applications\dev\HowTo

See these related HowTo's : 1 2

6.62 Get the content of a directory with a Filter Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0055.html First you create a class that implements java.io.FilenameFilter and then code the accept() method, then call File.list() with the filter as a parameter. The returned array of strings has all the names that passed through the accept()filter.

6.61 Get the "root" of an application

import java.io.File; import java.io.FilenameFilter; public class Filter implements FilenameFilter { protected String pattern; public Filter (String str) { pattern = str; } public boolean accept (File dir, String name) { return name.toLowerCase().endsWith(pattern.toLowerCase()); } public static void main (String args[]) { if (args.length != 1) { System.err.println ("usage: java Filter <pattern list> return; }

ex. java Filter java");

Filter nf = new Filter (args[0]); // current directory File dir = new File ("."); String[] strs = dir.list(nf); for (int i = 0; i < strs.length; i++) { System.out.println (strs[i]); } } }

Here a version to support multiple filters. import import import import import

java.io.File; java.io.FilenameFilter; java.util.Arrays; java.util.Iterator; java.util.TreeSet;

/** * * GenericFileFilter xml = new GenericFileFilter ("xml"); * // GenericFileFilter xmlandpdf = new GenericFileFilter (new String [] { "xml", "pdf" }); * File dir = new File ("."); * String[] strs = dir.list(xml); * for (int i = 0; i < strs.length; i++) { * // strs[i] * } * */ public class GenericFileFilter implements FilenameFilter { private TreeSet<String> exts = new TreeSet<String>() ; public GenericFileFilter(String ext) { exts.add("." + ext.toLowerCase().trim()); }

public GenericFileFilter(String[] extensions) { Iterator<String> extList = Arrays.asList(extensions).iterator(); while (extList.hasNext()) { exts.add("." + extList.next().toLowerCase().trim()); }

6.61 Get the "root" of an application

exts.remove(""); } public boolean accept(File dir, String name) { final Iterator<String> extList = exts.iterator(); while (extList.hasNext()) { if (name.toLowerCase().endsWith(extList.next())) { return true; } } return false; } }

If multiple extensions are to be checked then a regular expression can be used. import java.io.File; import java.io.FilenameFilter; import java.util.regex.*; public class Filter implements FilenameFilter { public boolean accept (File dir, String name) { return Pattern.matches(".*\\.(jpg|jpeg|gif|png|bmp)", name); // if only one extension to check : "\\.jpg" } public static void main (String args[]) { if (args.length < 1) { System.err.println ("usage: java Filter ex. java Filter c:\\temp"); return; } Filter nf = new Filter(); // current directory File dir = new File (args[0]); String[] strs = dir.list(nf); for (int i = 0; i < strs.length; i++) { System.out.println (strs[i]); } } }

6.63 Get the content of a directory with subdirectories Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0056.html import java.io.*; import java.util.*; public class DirUtils { public static List recurseDir(String dir) { String result, _result[]; result = recurseInDirFrom(dir); _result = result.split("\\|"); return Arrays.asList(_result); }

6.63 Get the content of a directory with subdirectories

private static String recurseInDirFrom(String dirItem) { File file; String list[], result; result = dirItem; file = new File(dirItem); if (file.isDirectory()) { list = file.list(); for (int i = 0; i < list.length; i++) result = result + "|" + recurseInDirFrom(dirItem + File.separatorChar + list[i]); } return result; } public static void main(String arg[]) { if (arg.length > 0) { System.out.println("recursive Dirs from " + arg[0]); System.out.println(DirUtils.recurseDir(arg[0])); } else { System.out.println("Usage :"); System.out.println(" java DirUtils c:\temp"); } /* output: C:\Applications>java DirUtils c:\zip recursive Dir from c:\zip [c:\zip, c:\zip\AutoIt.exe, c:\zip\cc32d48.exe, c:\zip\CODE_UPLOAD 148812122001.zip, c:\zip\groups2.txt, c:\zip\httrack−3.23.exe, c:\ zip\mass20.zip, c:\zip\mp3,c:\zip\mp3\BonkEnc−1.0−beta1.exe, c:\zi p\mp3\cdex_150b10_enu.exe, c:\zip\mp3\hh_install.exe, c:\zip\mp3\T PlayerSetup.exe, c:\zip\mp3\Tunchy1017full.zip, c:\zip\mp3\TWMP3en coder.exe, c:\zip\ok, c:\zip\ok\CmdHerePowertoySetup.exe, c:\zip\o k\htmldoc−1.8.23−winfree.exe, c:\zip\ok\j2sdk−1_4_1_02−windows−i58 6.exe, c:\zip\ok\jdk141−hh.zip, c:\zip\ok\jsref13.zip, c:\zip\ok\T weakUiPowertoySetup.exe, c:\zip\quickmail−2_1.zip, c:\zip\RealOneP layerV2GOLD.exe, c:\zip\RESTorefile2514.EXE,c:\zip\Shockwave_Insta ller_Full.exe, c:\zip\Water.exe, c:\zip\winamp50_full.exe,c:\zip\w olf, c:\zip\wolf\ok, c:\zip\wolf\ok\kf_box.zip, c:\zip\wolf\sp_off lag_levels_1−4_final.zip, c:\zip\xpAntiSpy.zip] */ } }

6.64 Make a directory Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0057.html For application only, not Applet! File td = new File("NewDirName"); td.mkDir();

6.64 Make a directory

6.65 Create a fixed−length file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0461.html // // usage : java CreateAFile 2048 twokbytes.dat // import java.io.FileOutputStream; import java.io.IOException; public class CreateAFile { public static void main(String[] args) throws IOException { byte[] buf = new byte[8192]; long n = Long.parseLong(args[0]); FileOutputStream fos = new FileOutputStream(args[1]); long m = n / buf.length; for (long i = 0; i < m; i++) { fos.write(buf, 0, buf.length); } fos.write(buf, 0, (int)(n % buf.length)); fos.close(); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.66 Delete a non−empty directory Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0483.html Use the following recursive method. import java.io.File; class DeleteDir { public static void main(String args[]) { deleteDirectory(new File(args[0])); } static public boolean deleteDirectory(File path) { if( path.exists() ) { File[] files = path.listFiles(); for(int i=0; i
6.65 Create a fixed−length file

} If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.67 Create a temporary file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0484.html import java.io.File; ... File temp = File.createTempFile("real",".howto"); temp.deleteOnExit();

Creates an empty file in the default temporary−file directory, using the given prefix ("real") and suffix (".howto"). Plus, the temporary file will be deleted when the virtual machine terminates. Deletion will be attempted only for normal termination of the virtual machine. (Javadoc) The prefix argument must be at least three characters long. It is recommended that the prefix be a short, meaningful string such as "hjb" or "mail". The suffix argument may be null, in which case the suffix ".tmp" will be used. To create the new file, the prefix and the suffix may first be adjusted to fit the limitations of the underlying platform.

If the prefix is too long then it will be truncated, but its first three characters will always be preserved. If the suffix is too long then it too will be truncated, but if it begins with a period character ('.') then the period and the first three characters following it will always be preserved. Once these adjustments have been made the name of the new file will be generated by concatenating the prefix, five or more internally−generated characters, and the suffix. The location of the directory used to hold temporary files is defined by the property java.io.tmpdir. The default value can be changed with the command line used to launch the JVM : java −Djava.io.tmpdir=C:\mydir

myClass

or , on Windows, you can set the environment variable TMP to a different value. On some plateform, the temporary directory returned by java.io.tmpdir do not include a trailing slash. That is, Win NT Win XP Solaris Linux

−−> −−> −−> −−>

C:\TEMP\ C:\TEMP /var/tmp/ /var/tmp

It's not a bad idea to check if there is a trailing slash or not. String tempdir = System.getProperty("java.io.tmpdir"); if ( !(tempdir.endsWith("/") || tempdir.endsWith("\\")) ) tempdir = tempdir + System.getProperty("file.separator");

6.67 Create a temporary file

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.68 Get the default character set of the JVM Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0505.html public class Hello { public static void main(String args[]) throws Exception{ // not crossplateform safe System.out.println(System.getProperty("file.encoding")); // jdk1.4 System.out.println( new java.io.OutputStreamWriter( new java.io.ByteArrayOutputStream()).getEncoding() ); // jdk1.5 System.out.println(java.nio.charset.Charset.defaultCharset().name()); } }

Output example (winXP) >java Hello Cp1252 Cp1252 windows−1252

See also java encoding table for the encoding sets supported. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.69 Parse a pathname Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0514.html import java.io.File; public class ParsePathname { public ParsePathname() { } public static void main(String[] args) throws Exception { File f = new File ("c:/program files/adobe/Acrobat 5.0/Reader/acrord32.exe"); System.out.println("dir : " + f.getParent()); System.out.println("file : " + f.getName()); System.out.println("ext : " + getFileExtension(f.getName()));

6.68 Get the default character set of the JVM

System.out.println("url : " + f.toURL()); System.out.println("uri : " + f.toURI()); /* output : dir : c:\program files\adobe\Acrobat 5.0\Reader file : acrord32.exe ext : exe url : file:/c:/program files/adobe/Acrobat 5.0/Reader/acrord32.exe uri : file:/c:/program%20files/adobe/Acrobat%205.0/Reader/acrord32.exe */ } public static String getFileExtension(String f) { String ext = ""; int i = f.lastIndexOf('.'); if (i > 0 & i < f.length() − 1) { ext = f.substring(i+1).toLowerCase(); } return ext; } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.70 Handle Excel files Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0516.html There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about OpenSource (and free) solutions.

6.71 JDBC−ODBC Excel driver This solution lets you access your Excel worksheet with SQL SELECT statement. The required ODBC driver is included in a regular Windows installation and the JDBC−ODBC bridge is used to access the Excel DSN. See this HowTo for an example.

6.72 JExcel Java Excel API is a java API enabling developers to read, write, and modify Excel spreadsheets dynamically. Any operating system which can run a Java virtual machine can both process and deliver Excel spreadsheets. One nice thing about JExcelApi is that it has no dependencies on any third party libraries. Example : output an Excel file from a Servlet import java.io.IOException; import java.io.OutputStream;

6.70 Handle Excel files

import import import import

javax.servlet.ServletException; javax.servlet.http.HttpServlet; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse;

import import import import

jxl.Workbook; jxl.write.Label; jxl.write.WritableSheet; jxl.write.WritableWorkbook;

public class Sample extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { OutputStream out = null; try { response.setContentType("application/vnd.ms−excel"); response.setHeader ("Content−Disposition", "attachment; filename=sampleName.xls"); WritableWorkbook w = Workbook.createWorkbook(response.getOutputStream()); WritableSheet s = w.createSheet("Demo", 0); s.addCell(new Label(0, 0, "Hello World")); w.write(); w.close(); } catch (Exception e){ throw new ServletException("Exception in Excel Sample Servlet", e); } finally{ if (out != null) out.close(); } } }

See http://jexcelapi.sourceforge.net/

6.73 POI The POI project consists of APIs for manipulating various file formats based upon Microsoft's OLE 2 Compound Document format using pure Java. POI is your Java Excel solution as well as your Java Word solution. HSSF is the POI Project's pure Java implementation of the Excel '97(−2002) file format and it provides a way to read spreadsheets create, modify, read and write XLS spreadsheets. Since it's Jakarta project, POI has a dependencies with other JARs (commons,log4j,etc...). Example : create an Excel file HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet"); HSSFRow row = sheet.createRow((short)0); row.createCell((short)0).setCellValue("HelloWorld"); FileOutputStream fileOut = new FileOutputStream("workbook.xls"); wb.write(fileOut);

6.73 POI

fileOut.close();

The name was originally an acronym for "Poor Obfuscation Implementation" (ref: Wikipedia). See http://jakarta.apache.org/poi/

6.74 JXLS jXLS is a project that allows creation of extremely complex Excel reports just in several lines of code. It is based on Jakarta POI. With jXLS, all you need is to create XLS template file with all required formatting, formulas etc using specific notation to indicate placement of data and then write a couple lines of code to invoke jXLS engine passing XLS template and the exported data as parameters. Example : The XLS Template Employees Name ${employee.name}

Age Payment Bonus ${employee.age} ${employee.payment} ${employee.bonus} $[SUM(@employee.payment@)]

with the code Collection staff = new HashSet(); staff.add(new Employee("Derek", 35, 3000, 0.30)); staff.add(new Employee("Elsa", 28, 1500, 0.15)); Map beans = new HashMap(); beans.put("employee", staff); XLSTransformer transformer = new XLSTransformer(); transformer.transformXLS(templateFileName, beans, destFileName);

gives the result Employees Name Age Derek 35 Else 28

Payment Bonus 3000 30,00% 1500 15,00% 4500

See http://jxls.sourceforge.net/

6.75 xlSQL xlSQL is a JDBC Driver for Excel and CSV data sources. Documents can be read and written with SQL as if they were tables in a database. You can export XLS to XML or SQL INSERT statements. xlSQL includes its own "zero−admin" mySQL database. The documentation is minimal at this time. See http://xlsql.sourceforge.net/

6.74 JXLS

6.76 JCOM JCOM is a Java to COM bridge library. With JCOM you can call a COM object from Java as if it were a Java object without having to deal with the internals of JNI. The documentation is minimal (in Japanese!). Example : import import import import

jp.ne.so_net.ga2.no_ji.jcom.excel8.*; jp.ne.so_net.ga2.no_ji.jcom.*; java.io.File; java.util.Date;

class TestExcel { public static void main(String[] args) throws Exception { ReleaseManager rm = new ReleaseManager(); try { System.out.println("EXCEL startup..."); // if already started, open new window ExcelApplication excel = new ExcelApplication(rm); excel.Visible(true); // display any information System.out.println("Version="+excel.Version()); System.out.println("UserName="+excel.UserName()); System.out.println("Caption="+excel.Caption()); System.out.println("Value="+excel.Value()); ExcelWorkbooks xlBooks = excel.Workbooks(); ExcelWorkbook xlBook = xlBooks.Add(); // create new book // enumurate all files System.out.println ("set infomation of files in current directory to cell ..."); ExcelWorksheets xlSheets = xlBook.Worksheets(); ExcelWorksheet xlSheet = xlSheets.Item(1); ExcelRange xlRange = xlSheet.Cells(); xlRange.Item(1,1).Value("filename" ); xlRange.Item(2,1).Value("size" ); xlRange.Item(3,1).Value("last modified time"); xlRange.Item(4,1).Value("is directory"); xlRange.Item(5,1).Value("is file"); xlRange.Item(6,1).Value("can read"); xlRange.Item(7,1).Value("can write"); File path = new File("./"); String[] filenames = path.list(); for(int i=0; i
6.76 JCOM

xlRange.Item(1,filenames.length+2).Value("sum"); xlRange.Item(2,filenames.length+2).Formula(expression); xlRange.Columns().AutoFit(); // fit columns // comment out, if print out. // output default printer. // System.out.println("print out..."); // xlSheet.PrintOut(); // // // // //

comment out, if book save to file. if no path, save to(My Documents) System.out.println ("save to file... (My Documents)\\testExcel.xls"); xlBook.SaveAs("testExcel.xls");

xlBook.Close(false,null,false); excel.Quit(); System.out.println("thank you ."); } catch(Exception e) { e.printStackTrace(); } finally { rm.release(); } } }

See http://sourceforge.net/projects/jcom See also this HowTo for an alternative package to access a COM package from Java.

6.77 OpenXLS Java Spreadsheet SDK OpenXLS claims that it has the best compatibility with complex Excel files and able to handle any kind of Excel file out there without corrupting it. This open source effort is the result of over 6 years of development into it. See http://www.extentech.com/estore/product_detail.jsp?product_group_id=228 Example (extract 3 images from a workbook, create a new workbook with them) : doit("testImages.xls","Sheet1"); ... void doit(String finpath, String sheetname){ System.out.println("Begin parsing: " + workingdir + finpath); WorkBookHandle tbo = new WorkBookHandle(workingdir + finpath); try{ sheet = tbo.getWorkSheet(sheetname); // read images from sheet 1 −− .gif, .png, .jpg ImageHandle[] extracted = sheet.getImages(); // extract and output images for(int t=0;t<extracted.length;t++) { System.out.println("Successfully extracted: " + workingdir + "testImageOut_" + extracted[t].getName()+"." +extracted[t].getType()); FileOutputStream outimg = new FileOutputStream (workingdir + extracted[t].getName()+"." +extracted[t].getType());

6.77 OpenXLS Java Spreadsheet SDK

extracted[t].write(outimg); outimg.flush(); outimg.close(); } tbo = new WorkBookHandle(); sheet = tbo.getWorkSheet("Sheet1"); CellHandle a1 = sheet.add ("New workbook with 3 images: a gif, a jpg, and a png", "A1"); // get gif image input stream FileInputStream fin = new FileInputStream (workingdir + "testImages.gif"); // add to sheet ImageHandle giffy = new ImageHandle(fin, sheet); // set picture size and location in sheet giffy.setBounds(100, 100, 400, 200); giffy.setName("giffy"); sheet.insertImage(giffy); // add to sheet for(int x=0;x<100;x++) { fin = new FileInputStream(workingdir + "testImages.png"); ImageHandle jpgy = new ImageHandle(fin, sheet); jpgy.setName("heart" + x); // set the random x/y coords of picture int ix = Math.round((float)((x * (Math.random()*10)))); jpgy.setX(100 + ix); ix = Math.round((float)((x * (Math.random()*10)))); jpgy.setY(100 + ix); sheet.insertImage(jpgy); } // get png image input stream fin = new FileInputStream(workingdir + "testImages.jpg"); // add to sheet ImageHandle pngy = new ImageHandle(fin, sheet); // set just the x/y coords of picture pngy.setX(10); pngy.setY(200); sheet.insertImage(pngy); } catch(Exception e){ System.err.println("testImages failed: " + e.toString()); } testWrite(tbo, workingdir + "testImagesOut.xls"); WorkBookHandle newbook = new WorkBookHandle (workingdir + "testImagesOut.xls",0); System.out.println("Successfully read: " + newbook); } public void testWrite(WorkBookHandle b, String fout){ try{ java.io.File f = new java.io.File(fout); FileOutputStream fos = new FileOutputStream(f); BufferedOutputStream bbout = new BufferedOutputStream(fos); bbout.write(b.getBytes()); bbout.flush(); fos.close(); } catch (java.io.IOException e){ System.err.println("IOException in Tester. "+e);

6.77 OpenXLS Java Spreadsheet SDK

} }

See also this HowTo for a way to create a simple XLS without any additional library.

6.78 Handle CSV file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0591.html

6.79 com.Ostermiller.util CSV Utils CSVPrinter/CSVParser/ExcelCSVPrinter/ExcelCSVParser http://ostermiller.org/utils/CSV.html

6.80 opencsv A simple csv parser library for Java http://opencsv.sourceforge.net/

6.81 ServingXML Framework for flat/XML data transformations. Supported transformations : flat−XML, XML−flat, flat−flat, and XML−XML http://servingxml.sourceforge.net/

6.82 Super CSV This CSV reader/writer makes it easy to read/write objects/maps/string lists with automatic type conversion and constraint checking. http://supercsv.sourceforge.net/

6.83 csvreader Library for reading and writing CSV and plain delimited text files. All kinds of CSV files can be handled, text qualified, Excel formatted, etc. http://www.csvreader.com/java_csv.php

6.84 CSVFile A simple set of Java classes used to handle CSV http://sourceforge.net/projects/csvfile

6.85 FlatPack Flat file parser that handles CSV, fixed length and custom delimiters. Export a DataSet to a fixed length or delimited format. FlatPack provides a sorting mechanism for your flat files. 6.78 Handle CSV file

http://flatpack.sourceforge.net/

6.86 Create an Excel file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0586.html While you can use specialized packages to create native Excel file, an easy way to import data into Excel is to create an HTML file and embed the date into a TABLE tag. You give to the file the XLS extension and Excel will do the translation for you! With a text editor or from a program, create a file named test.xls with this content

Just testing

123
446
789
=SUM(A3:A5)=SUM(B3:B5)=SUM(C3:C5)


Now you can double click on the saved file to load it into Excel and the translation will be done. This trick works with OpenOffice too. From a server, remember to send the appropriate MIME TYPE : application/excel to the client. See also this HowTo

6.87 Create or process a PDF file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0523.html A nice OpenSource is http://www.lowagie.com/iText/ [ITEXT] . iText can deal with RTF and HTML file too. Nicely documented with many examples. • Create a PDF import java.io.FileOutputStream; import java.io.IOException; import com.lowagie.text.*; import com.lowagie.text.pdf.PdfWriter; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); Document document = new Document(); try { PdfWriter.getInstance(document, new FileOutputStream("HelloWorld.pdf")); document.open();

6.86 Create an Excel file

document.add(new Paragraph("Hello World")); } catch (DocumentException de) { System.err.println(de.getMessage()); } catch (IOException ioe) { System.err.println(ioe.getMessage()); } document.close(); } }

• Add a watermark to an existing document. import java.io.FileOutputStream; import java.util.HashMap; import import import import import import import

com.lowagie.text.Element; com.lowagie.text.Image; com.lowagie.text.PageSize; com.lowagie.text.pdf.BaseFont; com.lowagie.text.pdf.PdfContentByte; com.lowagie.text.pdf.PdfReader; com.lowagie.text.pdf.PdfStamper;

public class AddWatermarkPageNumbers { public static void main(String[] args) { System.out.println("Add watermarks and pagenumbers"); try { PdfReader reader = new PdfReader("ChapterSection.pdf"); int n = reader.getNumberOfPages(); // create a stamper that will copy the document to a new file PdfStamper stamp = new PdfStamper(reader, new FileOutputStream("watermark_pagenumbers.pdf")); // adding some metadata HashMap moreInfo = new HashMap(); moreInfo.put("Author", "Bruno Lowagie"); stamp.setMoreInfo(moreInfo); // adding content to each page int i = 0; PdfContentByte under; PdfContentByte over; Image img = Image.getInstance("watermark.jpg"); BaseFont bf = BaseFont.createFont (BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED); img.setAbsolutePosition(200, 400); while (i < n) { i++; // watermark under the existing page under = stamp.getUnderContent(i); under.addImage(img); // text over the existing page over = stamp.getOverContent(i); over.beginText(); over.setFontAndSize(bf, 18); over.setTextMatrix(30, 30); over.showText("page " + i); over.setFontAndSize(bf, 32); over.showTextAligned (Element.ALIGN_LEFT, "DUPLICATE", 230, 430, 45); over.endText(); } // adding an extra page stamp.insertPage(1, PageSize.A4);

6.86 Create an Excel file

over = stamp.getOverContent(1); over.beginText(); over.setFontAndSize(bf, 18); over.showTextAligned(Element.ALIGN_LEFT, "DUPLICATE OF AN EXISTING PDF DOCUMENT", 30, 600, 0); over.endText(); // adding a page from another document PdfReader reader2 = new PdfReader("SimpleAnnotations1.pdf"); under = stamp.getUnderContent(1); under.addTemplate (stamp.getImportedPage(reader2, 3), 1, 0, 0, 1, 0, 0); // closing PdfStamper will generate the new PDF file stamp.close(); } catch (Exception de) { de.printStackTrace(); } } }

See also this HowTo

6.88 Create a PDF Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0618.html

6.89 iText http://www.lowagie.com/iText/ iText is a very simple to use package to create and manipulate PDF file. For the simple need, only 1 jar is required (ex. itext−2.1.3.jar, download at http://www.lowagie.com/iText/download.html) In this example, you pass on the command line a filename (plain text file − args[0]) to convert to a PDF file (args[1]). import java.io.*; import com.lowagie.text.*; import com.lowagie.text.pdf.*; public class TextFileToPDF { /* ex. java TextFileToPDF c:\temp\text.txt c:\temp\text.pdf */ public static void main (String [] args){ BufferedReader input = null; Document output = null; System.out.println("Convert text file to pdf"); System.out.println("input : " + args[0]); System.out.println("output : " + args[1]);

6.88 Create a PDF

try { // text file to convert to pdf as args[0] input = new BufferedReader (new FileReader(args[0])); // letter 8.5x11 // see com.lowagie.text.PageSize for a complete list of page−size constants. output = new Document(PageSize.LETTER, 40, 40, 40, 40); // pdf file as args[1] PdfWriter.getInstance(output, new FileOutputStream (args[1])); output.open(); output.addAuthor("RealHowTo"); output.addSubject(args[0]); output.addTitle(args[0]); String line = ""; while(null != (line = input.readLine())) { System.out.println(line); Paragraph p = new Paragraph(line); p.setAlignment(Element.ALIGN_JUSTIFIED); output.add(p); } System.out.println("Done."); output.close(); input.close(); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } }

See also this HowTo A good introduction to iText : http://www.informit.com/articles/printerfriendly.aspx?p=420686

6.90 Convert OEM (DOS) file to Ansi (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0524.html We are using an InputStreamReader which convert the specified input encoding to Unicode and an OutputStreamWriter which from Unicode to the specified output encoding. This can be useful when migrating data from a legacy database (ex. Clipper, dBase) to newer DBMS (ex. mySQL, Sybase). import java.io.*; public class OemToAnsi { public static void main(String args[]) throws Exception{ if (args.length != 2) { System.out.println( "Usage : java OemToAnsi inputdosfile outputansifile"

6.90 Convert OEM (DOS) file to Ansi (Windows)

); System.out.println( " note : codepage input Cp850 ); System.exit(1);

codepage output Cp1252"

} // input FileInputStream fis = new FileInputStream(args[0]); BufferedReader r = new BufferedReader(new InputStreamReader(fis, "Cp850")); // output FileOutputStream fos = new FileOutputStream(args[1]); Writer w = new BufferedWriter(new OutputStreamWriter(fos, "Cp1252")); String oemString = ""; while ( (oemString= r.readLine()) != null) { w.write(oemString); w.flush(); } w.close(); r.close(); System.exit(0); } }

See also this related HowTo If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2006 [ home ]

6.91 Close a stream in a try/catch block Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0539.html You close them in the finally clause using a special method. public static boolean compareFile(File file1, File file2) { BufferedInputStream in1 = null; BufferedInputStream in2 = null; try { in1 = new BufferedInputStream(new FileInputStream(file1)); in2 = new BufferedInputStream(new FileInputStream(file2)); boolean result = true; int i; do { i = in1.read(); result = (i == in2.read()); } while ( result && i != −1 ); return result; } catch (FileNotFoundException ex) { ex.printStackTrace(); }

6.91 Close a stream in a try/catch block

catch (IOException ex) { ex.printStackTrace(); } finally { close(in1); close(in2); } return false; } private static void close( InputStream is ) { if ( is != null ) { try { is.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); } } }

6.92 Rename a file extension Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0541.html public static boolean renameFileExtension (String source, String newExtension) { String target; String currentExtension = getFileExtension(source); if (currentExtension.equals("")){ target = source + "." + newExtension; } else { target = source.replaceAll("." + currentExtension, newExtension); } return new File(source).renameTo(new File(target)); } public static String getFileExtension(String f) { String ext = ""; int i = f.lastIndexOf('.'); if (i > 0 && i < f.length() − 1) { ext = f.substring(i + 1).toLowerCase(); } return ext; }

6.93 Remove HTML tags from a file to extract only the TEXT Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0424.html

6.92 Rename a file extension

6.94 Using regular expression A special regular expression is used to strip out anything between a < and > . import java.io.*; public class Html2TextWithRegExp { private Html2TextWithRegExp() {} public static void main (String[] args) { try { StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader (new FileReader ("java−new.html")); String line; while ( (line=br.readLine()) != null) { sb.append(line); } String nohtml = sb.toString().replaceAll("\\<.*?>",""); System.out.println(nohtml); } catch (Exception e) { e.printStackTrace(); } } }

However if any Javascript is present, the script will be seen as text. Also you may need to add some logic during the reading to take into account only what is inside the tag.

6.95 Using javax.swing.text.html.HTMLEditorKit In most cases, the HTMLEditorKit is used with a JEditorPane text component but it can be also used directly to extract text from an HTML page. import java.io.*; import javax.swing.text.html.*; import javax.swing.text.html.parser.*; public class Html2Text extends HTMLEditorKit.ParserCallback { StringBuffer s; public Html2Text() {} public void parse(Reader in) throws IOException { s = new StringBuffer(); ParserDelegator delegator = new ParserDelegator(); // the third parameter is TRUE to ignore charset directive delegator.parse(in, this, Boolean.TRUE); } public void handleText(char[] text, int pos) { s.append(text); } public String getText() { return s.toString(); }

6.94 Using regular expression

public static void main (String[] args) { try { // the HTML to convert FileReader in = new FileReader("java−new.html"); Html2Text parser = new Html2Text(); parser.parse(in); in.close(); System.out.println(parser.getText()); } catch (Exception e) { e.printStackTrace(); } } }

6.96 Get the Mime Type from a File Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0487.html

6.96.1 Using javax.activation.MimetypesFileTypeMap activation.jar is required, it can be downloaded from http://java.sun.com/products/javabeans/glasgow/jaf.html. The MimetypesFileMap class is used to map a File to a Mime Type. Mime types supported are defined in a ressource file inside the activation.jar. import javax.activation.MimetypesFileTypeMap; import java.io.File; class GetMimeType { public static void main(String args[]) { File f = new File("gumby.gif"); System.out.println("Mime Type of " + f.getName() + " is " + new MimetypesFileTypeMap().getContentType(f)); // expected output : // "Mime Type of gumby.gif is image/gif" } }

The built−in mime−type list is very limited but a mechanism is available to add very easily more Mime Types/extensions. The MimetypesFileTypeMap looks in various places in the user's system for MIME types file entries. When requests are made to search for MIME types in the MimetypesFileTypeMap, it searches MIME types files in the following order: 1. Programmatically added entries to the MimetypesFileTypeMap instance. 2. The file .mime.types in the user's home directory. 3. The file <java.home>/lib/mime.types. 4. The file or resources named META−INF/mime.types.

6.96 Get the Mime Type from a File

5. The file or resource named META−INF/mimetypes.default (usually found only in the activation.jar file). This method is interesting when you need to deal with incoming files with the filenames normalized. The result is very fast because only the extension is used to guess the nature of a given file.

6.96.2 Using java.net.URL Warning : this method is very slow!. Like the above method a match is done with the extension. The mapping between the extension and the mime−type is defined in the file [jre_home]\lib\content−types.properties import java.net.*; public class FileUtils{ public static String getMimeType(String fileUrl) throws java.io.IOException, MalformedURLException { String type = null; URL u = new URL(fileUrl); URLConnection uc = null; uc = u.openConnection(); type = uc.getContentType(); return type; } public static void main(String args[]) throws Exception { System.out.println(FileUtils.getMimeType("file://c:/temp/test.TXT")); // output : text/plain } }

6.96.3 Using JMimeMagic Checking the file extension is not a very strong way to determine the file type. A more robust solution is possible with the JMimeMagic library. JMimeMagic is a Java library (LGLP licence) that retrieves file and stream mime types by checking magic headers. // snippet for JMimeMagic lib // http://sourceforge.net/projects/jmimemagic/ Magic parser = new Magic() ; // getMagicMatch accepts Files or byte[], // which is nice if you want to test streams MagicMatch match = parser.getMagicMatch(new File("gumby.gif")); System.out.println(match.getMimeType()) ; Thanks to Jean−Marc Autexier and sygsix for the tip!

6.96.4 Using mime−util Another tool is mime−util. This tool can detect using the file extension or the magic header technique. // snippet for mime−util lib // http://sourceforge.net/projects/mime−util

6.96.2 Using java.net.URL

public static final String UNKNOWN_MIME_TYPE="application/x−unknown−mime−type"; ... String mimeType = MimeUtil.getMagicMimeType(file); if(mimeType == null) mimeType = UNKNOWN_MIME_TYPE;

The nice thing about mime−util is that there is no dependency (with others Apache packages) so it is very lightweight.

6.96.5 Using Droid DROID (Digital Record Object Identification) is a software tool to perform automated batch identification of file formats. DROID uses internal and external signatures to identify and report the specific file format versions of digital files. These signatures are stored in an XML signature file, generated from information recorded in the PRONOM technical registry. New and updated signatures are regularly added to PRONOM, and DROID can be configured to automatically download updated signature files from the PRONOM website via web services. It can be invoked from two interfaces, a Java Swing GUI or a command line interface. http://droid.sourceforge.net/wiki/index.php/Introduction

6.96.6 Aperture framework Aperture is an open source library and framework for crawling and indexing information sources such as file systems, websites and mail boxes. The Aperture code consists of a number of related but independently usable parts: • Crawling of information sources: file systems, websites, mail boxes • MIME type identification • Full−text and metadata extraction of various file formats • Opening of crawled resources For each of these parts, a set of APIs has been developed and a number of implementations is provided. http://aperture.wiki.sourceforge.net/Overview

6.97 Sort a directory listing Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0606.html This HowTo sorts a directory listing in ascending or descending order. import import import import

java.io.*; java.util.Arrays; java.util.Comparator; java.util.Date;

6.96.5 Using Droid

public class FileUtils{ public static void main(String args[]) throws Exception { File files[] = FileUtils.dirListByAscendingDate (new File("C:/Applications/folder")); for (File file : files) { System.out.println(file.getName() + " " + new Date(file.lastModified())); } System.out.println("*********"); files = FileUtils.dirListByDescendingDate (new File("C:/Applications/folder")); for (File file : files) { System.out.println(file.getName() + " " + new Date(file.lastModified())); } } @SuppressWarnings("unchecked") public static File[] dirListByAscendingDate(File folder) { if (!folder.isDirectory()) { return null; } File files[] = folder.listFiles(); Arrays.sort( files, new Comparator() { public int compare(final Object o1, final Object o2) { return new Long(((File)o1).lastModified()).compareTo (new Long(((File) o2).lastModified())); } }); return files; } @SuppressWarnings("unchecked") public static File[] dirListByDescendingDate(File folder) { if (!folder.isDirectory()) { return null; } File files[] = folder.listFiles(); Arrays.sort( files, new Comparator() { public int compare(final Object o1, final Object o2) { return new Long(((File)o2).lastModified()).compareTo (new Long(((File) o1).lastModified())); } }); return files; } }

Take a look at this HowTo to filter by a date interval.

6.98 Filter a directory listing by date Current version of this HowTo : 6.98 Filter a directory listing by date

http://www.rgagnon.com/javadetails/../javadetails/java−0607.html This HowTo filters a directory listing based on a date interval. import java.io.*; import java.text.*; import java.util.*; public class FileFilterDateIntervalUtils implements FilenameFilter { String dateStart; String dateEnd; SimpleDateFormat sdf; public FileFilterDateIntervalUtils(String dateStart, String dateEnd) { this.dateStart = dateStart; this.dateEnd = dateEnd; sdf = new SimpleDateFormat("yyyy−MM−dd"); } public boolean accept(File dir, String name) { Date d = new Date(new File(dir, name).lastModified()); String current = sdf.format(d); return ((dateStart.compareTo(current) < 0 && (dateEnd.compareTo(current) >= 0))); } }

Then import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; public class Test { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy−MM−dd"); FileFilterDateIntervalUtils filter = new FileFilterDateIntervalUtils("2004−01−01", "2004−12−31"); File folder = new File("C:/temp"); File files[] = folder.listFiles(filter); for (File f : files) { System.out.println(f.getName() + " " + sdf.format(new Date(f.lastModified()))); } } }

Take a look at this HowTo to sort the filenames in ascending/descending order.

6.99 Display a comment in a Javadoc Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0615.html Use the numerical identity to represent the / in the javadoc section to avoid any conflict with a real comment. 6.99 Display a comment in a Javadoc

import java.awt.*; public class Example { /** * Simple Frame * <pre> * /* create a frame */ * Frame f = new Frame() * * @param args */ public static void main(String args[]){ Frame f = new Frame(); f.setSize(200,200); f.setVisible(true); } }

and the javadoc output is :

You can represent any character with a numerical identity, the syntax is &#nnn; where nnn is the Unicode code (decimal value) of the character.

6.100 Create a compressed (ZIP) file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0065.html /* ** a simple ZIP tool ** ** ex. java Zip file.1 file.2 > file.zip ** */ import java.io.*; import java.util.zip.*; class Zip { public static void main(String args[]) throws IOException { byte b[] = new byte[512]; ZipOutputStream zout = new ZipOutputStream(System.out); for(int i = 0; i < args.length; i ++) { InputStream in = new FileInputStream(args[i]); ZipEntry e = new ZipEntry(args[i].replace(File.separatorChar,'/')); zout.putNextEntry(e); int len=0; while((len=in.read(b)) != −1) { zout.write(b,0,len); } zout.closeEntry(); print(e); } zout.close(); } public static void print(ZipEntry e){ PrintStream err = System.err;

6.100 Create a compressed (ZIP) file

err.print("added " + e.getName()); if (e.getMethod() == ZipEntry.DEFLATED) { long size = e.getSize(); if (size > 0) { long csize = e.getCompressedSize(); long ratio = ((size−csize)*100) / size; err.println(" (deflated " + ratio + "%)"); } else { err.println(" (deflated 0%)"); } } else { err.println(" (stored 0%)"); } } } NOTE: There no way to directly add or modify an entry to a ZIP file after its creation. To do so, rename the old ZIP to a temporary filename. Expand the contents of the old ZIP, create the new ZIP, add the original contents plus the new files and delete the old ZIP when done.

6.101 Display compressed (ZIP) file content Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0066.html /* ** a simple viewZIP tool ** ** ex. java ViewZip file.zip ** */ import java.io.*; import java.util.*; import java.util.zip.*; import java.text.*; class ViewZip { public static void main(String args[]) throws IOException { InputStream in = new BufferedInputStream(new FileInputStream(args[0])); ZipInputStream zin = new ZipInputStream(in); ZipEntry e; System.err.println("Size\t Date Time Method Ratio Name"); System.err.println("−−−−\t −−−− −−−− −−−−−− −−−−− −−−−"); while((e=zin.getNextEntry())!= null) { zin.closeEntry(); print(e); } zin.close(); } public static void print(ZipEntry e) { PrintStream err = System.err; err.print(e.getSize() + "\t"); DateFormat df = new SimpleDateFormat ("yyyy.mm.dd Date d = new Date(e.getTime()); err.print(df.format(d) + " "); if (e.getMethod() == ZipEntry.DEFLATED) {

6.101 Display compressed (ZIP) file content

hh:mm:ss");

err.print("deflated "); long size = e.getSize(); if (size > 0) { long csize = e.getCompressedSize(); long ratio = ((size−csize)*100) / size; if (ratio < 10) { err.write(' '); } err.print(ratio + "% "); } else { err.print(" 0% "); } } else { err.println(" (stored }

0 %");

err.println(e.getName()); } }

6.102 Expand the compressed (ZIP) file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0067.html /* ** a simple unZIP tool ** ** ex. java UnZip file.zip file1 ** java UnZip file.zip ** */ import java.io.*; import java.util.*; import java.util.zip.*; import java.text.*;

to unzip file 1 from file.zip to unzip file.zip

class UnZip { public static void main(String args[]) throws IOException { InputStream in = new BufferedInputStream(new FileInputStream(args[0])); ZipInputStream zin = new ZipInputStream(in); ZipEntry e; while((e=zin.getNextEntry())!= null) { if (args.length > 1) { if (e.getName().equals(args[1])) { unzip(zin, args[1]); break; } } unzip(zin, e.getName()); } zin.close(); } public static void unzip(ZipInputStream zin, String s) throws IOException {

6.102 Expand the compressed (ZIP) file

System.out.println("unzipping " + s); FileOutputStream out = new FileOutputStream(s); byte [] b = new byte[512]; int len = 0; while ( (len=zin.read(b))!= −1 ) { out.write(b,0,len); } out.close(); } }

6.103 Emit a beep Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0001.html There are three ways to emit a beep in Java. • Use an AU audio file For Java, AU files need to be created at a sample rate of 8000. Any sample rate beyound that will not work. See also this How−to.

• Print the ASCII Bell character to the console public class TestBeep { public static main(String args[]) { // ASCII bell System.out.print("\007"); System.out.flush(); } }

The buzzer on the motherboard is used. • Starting with JDK 1.1, use the beep method in the Toolkit import java.awt.*; public class Beep { public static void main(String args[]) { Toolkit.getDefaultToolkit().beep(); } }

(Windows) The sound used is determined from the setting found in Control Panel/Sounds and Devices/Sounds/Sound Scheme/"Default Beep". If no sound file is selected then the beep() will be a silence.

6.104 Emit a Tone Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0499.html import javax.sound.sampled.*; //jdk1.3 public class Tone { public static float SAMPLE_RATE = 8000f; public static void sound(int hz, int msecs) throws LineUnavailableException { byte[] buf = new byte[1];

6.103 Emit a beep

AudioFormat af = new AudioFormat(SAMPLE_RATE,8,1,true,false); SourceDataLine sdl = AudioSystem.getSourceDataLine(af); sdl.open(af); sdl.start(); for (int i=0; i<msecs*8; i++) { double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; buf[0] = (byte)(Math.sin(angle) * 110.0); sdl.write(buf,0,1); } sdl.drain(); sdl.stop(); sdl.close(); } public static void main(String[] args) { try { Tone.sound(1000,100); Tone.sound(100,1000); Tone.sound(5000,100); } catch (LineUnavailableException lue) { System.out.println(lue); } } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

6.105 Play an audio file from an application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0006.html With Applet, the getAudioClip method() from the Applet package is used to play sound file. Starting with JDK1.2, getAudioClip() is now a static method. So it may be possible to use it without an Applet (i.e. in a regular Java application) with java.applet.Applet.getAudioClip(URLofMySound);

Note: Since JDK1.2, Java can play WAV directly, see http://java.sun.com/docs/books/tutorial/sound/playing.html. Another way is to use the undocumented sun.audio package. import sun.audio.*; ... ... AudioPlayer p=AudioPlayer.player; try{ AudioStream as = new AudioStream(new FileInputStream("aSound.au")); p.start(as); } catch(IOException err){ err.printStackTrace();

6.105 Play an audio file from an application

}

To play a sound from a JAR file (the .AU file in the JAR must be accessible via the CLASSPATH of course!) : import java.io.*; import java.net.*; import sun.audio.*; public class AppAudio { public static void main(String args[]) throws Throwable { InputStream in = AppAudio.class.getResourceAsStream(args[0]); AudioStream as = new AudioStream(in); AudioPlayer.player.start(as); Thread.sleep(5000); } }

Since JDK1.3, you have also the javax.sound package, see this HowTo.

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

6.105 Play an audio file from an application

7 JDBC 7.1 java−jdbc

7.2 Connect to a database via JDBC−ODBC Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0107.html You have to keep in mind that the bridge JDBC−ODBC is only useful in an Application, you can't use it with JAVA Applet because ODBC requires some DLL on the client machine (forbidden for security reason). import java.net.URL; import java.sql.*; class JDBCapp

{

static Connection theConn; public static void main (String args[]) { try { // connection to an ACCESS MDB theConn = MyConnection.getConnection(); ResultSet rs; Statement stmt; String sql; sql = "select objet from Email"; stmt = theConn.createStatement(); rs = stmt.executeQuery(sql); while (rs.next()) { System.out.println(rs.getString("objet")); } rs.close(); stmt.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (theConn != null) theConn.close(); } catch (Exception e) { } } } } class MyConnection { public static Connection getConnection() throws Exception { Driver d = (Driver)Class.forName

7 JDBC

("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); Connection c = DriverManager.getConnection( "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:/tech97.mdb" ); return c; /* To use an already defined ODBC Datasource : String URL = "jdbc:odbc:myDSN"; Connection c = DriverManager.getConnection(URL, "user", "pwd"); */ } }

7.3 SELECT data from a table Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0108.html Note:the MyConnection class was used to connect to the DB

With a Prepared Statement (only 1 row) String id = cust_id.getText(); try { PreparedStatement prepstmt; boolean found = false; prepstmt = theConn.prepareStatement ("select custName, CustAddr from tCust where custId = ?"); prepstmt.setString(1, id); ResultSet rs; rs = prepstmt.executeQuery(); found = rs.next(); if (found) System.out.println(rs.getString(1)); else System.out.println("Customer " + id + " not found!"); prepstmt.close(); } catch (Exception e) { e.printStackTrace(); }

With a Statement (many rows) String name = cust_name.getText(); try { Statement stmt; String sql; sql = "select custName from tCust where custName = " += "'" + name + "'"; stmt = theConn.createStatement(); ResultSet rs; rs = stmt.executeQuery();

7.3 SELECT data from a table

while (rs.next()) { System.out.println(rs.getString("custName")); } rs.close(); stmt.close(); } catch (Exception e) { e.printStackTrace(); } You need to be aware to the snippet above contains a SQL Injection vulnerability. String concatentation of this form can only be used if you first validate the fields to include only alphanumeric characters. Even, then it is generally considered bad practice when prepared statements solve this problem more cleanly. This is especially when you in a Web application environnement.

Thanks to Lawrence Angrave for the warning.

7.4 INSERT data into a table Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0109.html Note:the MyConnection class was used to connect to the DB

Statement stmt; String sql; int rows; sql = + + + + +

"INSERT INTO tCust " "(custId, custName, custAddr) " "VALUES " "('" + custId + "'," "('" + custName + "'," "('" + custAddr + "')";

stmt = theConn.createStatement(); rows = stmt.executeUpdate(sql); theConn.dbConn.commit(); stmt.close(); You need to be aware to the snippet above contains a SQL Injection vulnerability. String concatentation of this form can only be used if you first validate the fields to include only alphanumeric characters. Even, then it is generally considered bad practice when prepared statements solve this problem more cleanly. This is especially when you in a Web application environnement.

Thanks to Lawrence Angrave for the warning. Before inserting data containing quotes, you may need to double them (so "Real's HowTo" −> "Real''s HowTo"). You can use the following function to "prepare" your string. public static String convertString(String source) { StringBuffer sb = new StringBuffer(); for(int i = 0; i < source.length(); i++){ sb.append(source.charAt(i)); if(source.charAt(i)=='\'') sb.append('\'') } return sb.toString();

7.4 INSERT data into a table

}

Or you can use a PreparedStatement to insert data containing QUOTES PreparedStatement stmt = null; String sql; int rows; try { sql = "INSERT INTO tCust" + "(custName) " + "VALUES " + "(?)"; stmt = theConn.prepareStatement(sql); stmt.setString(1, "Name with \" are permitted!"); rows = stmt.executeUpdate(); theConn.commit(); stmt.close(); System.out.println(sql); } catch (Exception e){ e.printStackTrace(); }

The character "\" can be difficult to use in an INSERT statement since "\" is considered as an escape character in Java (and probably by the database also). stmt.executeUpdate("INSERT INTO mytable VALUES('\\')");

may generate a SQL Exception even if the "\" is escaped for Java because you need to escape it again for the database. At the end, you need to use "\\\\" to INSERT a simple "\". stmt.executeUpdate("INSERT INTO mytable VALUES('\\\\')");

7.5 MODIFY data in a table Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0110.html Note:the MyConnection class was used to connect to the DB

PreparedStatement prepstmt; try { prepstmt = theConn.prepareStatement ("UPDATE tCust SET custName = ? "+ " WHERE custId = ?"); prepstmt.setString(1,"Smith"); prepstmt.setString(2, cust_id.getText()); prepstmt.executeUpdate(); theConn.commit(); prepstmt.close(); } catch (Exception e) { e.printStackTrace(); }

7.5 MODIFY data in a table

7.6 DELETE data in a table Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0111.html Note:the MyConnection class was used to connect to the DB

PreparedStatement prepstmt; try { prepstmt = theConn.prepareStatement ("DELETE FROM tCust "+ " WHERE custId = ?"); prepstmt.setString(1,cust_id.getText()); prepstmt.executeUpdate(); theConn.commit(); prepstmt.close(); } catch (Exception e) { e.printStackTrace(); }

7.7 Test for an empty ResultSet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0116.html boolean found; ResultSet rs; ... // execute the query and then found = rs.next(); if (found) System.out.println("Record found"); else System.out.println("RECORD NOT FOUND");

A nicer way to do the same would be ResultSet rs; ... if (rs.next()) { do { System.out.println("Record found"); } while (rs.next()); } else { System.out.println("Record not found"); }

7.6 DELETE data in a table

7.8 Store and retrieve an object from a table Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0117.html Assume that we have a table called "Employee", with only one field called "emp" and "long binary" or "blob" as data type. We want to insert an instance of the class "Employee" into the table "Employee". The object "Employee" will be serialized into the table "Employee" ( ideally the table "Employee" should have an index key, something like emp_id, but for the example there is none). import java.net.URL; import java.sql.*; import java.io.*; class JDBCapp { static MyConnection theConn; public static void main (String args[]) { JDBCapp j = new JDBCapp(); j.connectToDB(); j.insertIntoEmp(); j.selectFromEmp(); } public void connectToDB() { theConn = new MyConnection(); theConn.connect("your_db_profile", "username", "password"); } public void insertIntoEmp() { Employee employee = new Employee(42,"Real Gagnon", 98000); try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(employee); // serialize the employee object into a byte array byte[] employeeAsBytes = baos.toByteArray(); PreparedStatement pstmt = theConn.dbConn.prepareStatement ("INSERT INTO EMPLOYEE (emp) VALUES(?)"); ByteArrayInputStream bais = new ByteArrayInputStream(employeeAsBytes); // bind our byte array to the emp column pstmt.setBinaryStream(1,bais, employeeAsBytes.length); pstmt.executeUpdate(); theConn.dbConn.commit(); pstmt.close(); } catch(Exception e) { e.printStackTrace(); } } public void selectFromEmp() { boolean found; try { Statement stmt = theConn.dbConn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT emp FROM Employe"); // loop through the result set while (rs.next()) {

7.8 Store and retrieve an object from a table

// fetch the serialized object to a byte array byte[] st = (byte[])rs.getObject(1); // or byte[] st = rs.getBytes(1); // or Blob aBlob = rs.getBlob(1); // byte[] st = aBlob.getBytes(0, (int) aBlob.length()); ByteArrayInputStream baip = new ByteArrayInputStream(st); ObjectInputStream ois = new ObjectInputStream(baip); // re−create the object Employee emp = (Employee)ois.readObject(); // display the result for demonstration System.out.println(emp.name); } stmt.close(); rs.close(); } catch(Exception e) { e.printStackTrace(); } } } class Employee implements Serializable { int ID; String name; double salary; public Employee(int ID, String name, double salary) { this.ID = ID; this.name = name; this.salary = salary; } } class MyConnection { Connection dbConn = null; void connect(String db, String user, String passw) { try { Driver d = (Driver)Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); String URL = "jdbc:odbc:" + db; dbConn = DriverManager.getConnection(URL, user, passw); } catch (Exception e) { e.printStackTrace(); } } void disconnect() { try { dbConn.close(); } catch (Exception e) { e.printStackTrace(); } } }

7.8 Store and retrieve an object from a table

7.9 Retrieve an Image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0118.html // column is column index in ResultSet containing the image, // we assume that the type is LONGVARBINARY Image myImage = null; InputStream stream = rset.getBinaryStream(column); ByteArrayOutputStream output = new ByteArrayOutputStream(); try { int a1 = stream.read(); while (a1 >= 0) { output.write((char)a1); a1 = stream.read(); } myImage = Toolkit.getDefaultToolkit().createImage(output.toByteArray()); output.close(); } catch(Exception e){}

7.10 Insert an Image Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0119.html File file = new File("myimage.gif"); FileInputStream fis = new FileInputStream(file); PreparedStatement ps = conn.prepareStatement("insert into images values (?,?)"); ps.setString(1,file.getName()); ps.setBinaryStream(2,fis,(int)file.length()); ps.executeUpdate(); ps.close(); fis.close();

7.11 Connect to an Oracle database with JDBC Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0112.html Oracle Corporation has released a free 100% JAVA driver. It is available at their Web site. All you need is to include the required jar in the classpath. import java.sql.*; public class TestDBOracle { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("oracle.jdbc.driver.OracleDriver"); // // or

7.9 Retrieve an Image

// DriverManager.registerDriver // (new oracle.jdbc.driver.OracleDriver()); String url = "jdbc:oracle:thin:@//server.local:1521/prod"; // jdbc:oracle:thin:@//host:port/service // or // String url = "jdbc:oracle:thin:@server.local:1521:prodsid"; // jdbc:oracle:thin:@host:port:SID Connection conn = DriverManager.getConnection(url,"scott", "tiger"); conn.setAutoCommit(false); Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery("select BANNER from SYS.V_$VERSION"); while (rset.next()) { System.out.println (rset.getString(1)); } stmt.close(); System.out.println ("Ok."); } }

See also this HowTo to connect using the Oracle Connection Pool.

7.12 Connect to Oracle using a connection pool Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0545.html The Oracle thin jdbc driver (v9.2) makes it very easy to use a connection pool, it's all built in the OracleDataSource with the implicit connection cache mechanism. An application turns the implicit connection cache on by invoking OracleDataSource.setConnectionCachingEnabled(true). After implicit caching is turned on, the first connection request to the OracleDataSource transparently creates a connection cache. After you have turned connection caching on, whenever you retrieve a connection through an OracleDataSource.getConnection(), the JDBC drivers check to see if a connection is available in the cache.The getConnection() method checks if there are any free physical connections in the cache that match the specified criteria. If a match is found, a logical connection is returned wrapping the physical connection. If no physical connection match is found, a new physical connection is created, wrapped in a logical connection, and returned. A Connection Pool is a cache of database connections maintained in memory so that the connections can be reused when the database receives future requests for data. Connection pools are used to enhance the performance of executing commands on a database. Various parameters such as number of minimum connections, maximum connections and idle connections can be set to make sure the connection pool works well according to the environment it is deployed to work in. In this example, we have a program with several threads. Each thread makes a connection but the login process is done only once. First a static class to manage the connection pool. 7.12 Connect to Oracle using a connection pool

import oracle.jdbc.pool.OracleDataSource; import oracle.jdbc.pool.OracleConnectionCacheManager; import java.util.Properties; import java.sql.*; public class JDBCUtils { private final static String CACHE_NAME = "MYCACHE"; private static OracleDataSource ods = null; static { logger.info("Initialisation du OracleDataSource"); try { ods = new OracleDataSource(); ods.setURL("jdbc:oracle:thin:@//server.local:1521/prod"); ods.setUser("scott"); ods.setPassword("tiger"); // caching parms ods.setConnectionCachingEnabled(true); ods.setConnectionCacheName(CACHE_NAME); Properties cacheProps = new Properties(); cacheProps.setProperty("MinLimit", "1"); cacheProps.setProperty("MaxLimit", "4"); cacheProps.setProperty("InitialLimit", "1"); cacheProps.setProperty("ConnectionWaitTimeout", "5"); cacheProps.setProperty("ValidateConnection", "true"); ods.setConnectionCacheProperties(cacheProps); } catch (SQLException e) { e.printStackTrace(); } } /** * private constructor for static class */ private JDBCUtils() { } public static Connection getConnection() throws SQLException { return getConnection("env. unspecified"); }

public static Connection getConnection(String env) throws SQLException { System.out.println("Request connection for " + env); if (ods == null) { throw new SQLException("OracleDataSource is null."); } return ods.getConnection(); } public static void closePooledConnections() throws SQLException{ if (ods != null ) { ods.close(); } } public static void listCacheInfos() throws SQLException{ OracleConnectionCacheManager occm =

7.12 Connect to Oracle using a connection pool

OracleConnectionCacheManager.getConnectionCacheManagerInstance(); System.out.println (occm.getNumberOfAvailableConnections(CACHE_NAME) + " connections are available in cache " + CACHE_NAME); System.out.println (occm.getNumberOfActiveConnections(CACHE_NAME) + " connections are active"); } }

then the working thread import java.sql.*; public class TestDBOraclePool3Thread implements Runnable { private int noThread = 0; TestDBOraclePool3Thread(int n) { noThread = n; } public void run() { System.out.println("Starting Thread " + noThread); while (true) { try { Connection conn = JDBCUtils.getConnection("env " + noThread); conn.setAutoCommit(false); Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery("select BANNER from SYS.V_$VERSION"); while (rset.next()) System.out.println (rset.getString(1)); stmt.close(); System.out.println ("Ok."); JDBCUtils.listCacheInfos(); conn.close(); } catch (SQLException e) { e.printStatckTrace() } finally { System.out.println ("Sleep... " + noThread); try { Thread.sleep(1000); } catch(Exception e) { } } } } }

and finally, the main class import java.net.URL; import java.sql.*;

7.12 Connect to Oracle using a connection pool

public class TestDBOraclePool3 { public static void main(String[] args) throws SQLException { new Thread( new TestDBOraclePool3Thread(1)).start(); new Thread( new TestDBOraclePool3Thread(2)).start(); new Thread( new TestDBOraclePool3Thread(3)).start(); new Thread( new TestDBOraclePool3Thread(4)).start(); new Thread( new TestDBOraclePool3Thread(5)).start(); new Thread( new TestDBOraclePool3Thread(6)).start(); new Thread( new TestDBOraclePool3Thread(7)).start(); } }

7.13 Get JDBC driver for major database vendors Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0113.html JDBC vendors list Intersolv plugin to access ODBC database through a browser

7.14 Handle dates Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0114.html To get the current date in SQL format. java.util.Date today = new java.util.Date(); java.sql.Date sqlToday = new java.sql.Date(today.getTime());

For Timestamp, it's the same idea java.util.Date today = new java.util.Date(); java.sql.Timestamp now = new java.sql.Timestamp(today.getTime());

To use a Date, Time or Timestamp in a query, you can use JDBC escape codes. Date {d 'yyyy−mm−dd'} Time {t {'hh:mm:ss'} Timestamp {ts `yyyy−mm−dd hh:mm:ss.f . . .'} note: the .f .... is optional

For example, a Statement with a Date will look like this java.util.Date today = new java.util.Date(); java.sql.Date sqlToday = new java.sql.Date(today.getTime());

7.13 Get JDBC driver for major database vendors

String query = "select * from cust where purchase_date <{ d '" + sqlDate.toString() + "' }");

With a PreparedStatement, you don't need JDBC escape codes, the JDBC driver will do the job for you. java.util.Date today = new java.util.Date(); java.sql.Date sqlToday = new java.sql.Date(today.getTime()); PreparedStatement p = theConn.prepareStatement ("select * from cust where purchase_date
To INSERT PreparedStatement p = theConn.prepareStatement ("insert into TableWithADateColumn values(?)"); p.setDate(1, sqlToday); p.executeUpdate();

or p.executeUpdate ("insert into TableWithADateColumn values( { d '1999−12−31' } )");

One thing to remember when using java.sql.date is (according to the javadoc) : To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.

7.15 Call a stored procedure Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0115.html We assume that the Connection is known as : Connection conn;

then String query = "begin thePackage.theProcedure(?,?,?); CallableStatement cs = conn.prepareCall(query); cs.setString(1, "string parameter"); // #1 is cs.setInt(2, 1); // #2 is cs.registerOutParameter(2, Types.INTEGER); // and cs.registerOutParameter(3, Types.INTEGER); // #3 is cs.execute(); int output_parm2 = cs.getInt(2);

7.15 Call a stored procedure

end;"; INPUT INPUT OUTPUT OUTPUT

// get the result from OUTPUT #2

int output_parm3 = cs.getInt(3);

// get the result from OUTPUT #3

7.16 Stored procedure with Input/Output parms and a ResultSet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0120.html Thanks to T. Guirado for the tips.

public static int storedProcWithResultSet (String parms) throws Exception // Stored procedure to be called. CallableStatement cs = conn.prepareCall ("{? = call mypackage.p_astoreproc (?,?,?,?,?,?,?)}"); // register input parameters cs.setString(2, ""); cs.setString(3, ""); cs.setString(4, parms); // regsiter ouput parameters cs.registerOutParameter(5, java.sql.Types.CHAR); cs.registerOutParameter(6, java.sql.Types.CHAR); cs.registerOutParameter(7, java.sql.Types.CHAR); // Procedure execution ResultSet rs = cs.executeQuery(); // Note that you need to retrieve the ResultSet _before_ retrieving // OUTPUT parameters. if ( rs == null) System.out.println( "No resultSet!"); else { // To retrieve columns info. ResultSetMetaData rsmd = rs.getMetaData(); int nbCol = rsmd.getColumnCount(); int i = 0; int j = 1; Vector vResSet = new Vector(); while (rs.next ()) { System.out.println( "Record " + (i+1)); // putting the ResultSet columns in a vector for ( j = 1; j <= nbCol ; j++){ vResSet.insertElementAt(rs.getString(j), 0); vResSet.addElement(rs.getString(j)); } // Reading vector to print ResultSet data for ( int k = 0 ; k < nbColonnes ; k++ ) { if ( vResSet.elementAt(k) != null) System.out.println( vResSet.elementAt(k).toString()); else System.out.println( "Column " + (k+1) + " Null"); } i++; } } // Retrieving Strored Procedure OUTPUT parameters System.out.println( "return code of Stored procedure = : "

7.16 Stored procedure with Input/Output parms and a ResultSet

+ cs.getInt(1)); // Retrieving OUTPUT parameters for ( int i = 5 ; i <= 7; i ++) System.out.println( "parameter " + i + " : " + cs.getString(i)); return cs.getInt(1); }

7.17 Fix incomplete field returned by the ResultSet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0121.html Some JDBC driver have limit about how big returned records can be. First use the getMaxRowSize() and doesMaxRowSizeIncludeBlobs() from the DatabaseMetaData class to see what the maximum supported by the driver. Then getMaxFieldSize() and setMaxFieldSize() from the Statement class to adjust if necessary the current maximum value.

7.18 Get a record count with a SQL Statement Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0292.html Statement s = conn.createStatement(); ResultSet r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM MyTable"); r.next(); int count = r.getInt("rowcount") ; r.close() ; System.out.println("MyTable has " + count + " row(s).");

JDBC 2.0 provides a way to retrieve a rowcount from a ResultSet without having to scan through all the rows or issue a separate SELECT COUNT(*). Statement s = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet r = s.executeQuery ("SELECT * FROM employee WHERE id_emp LIKE '1%'"); r.last(); int count = r.getRow(); r.beforeFirst(); ...

NOTE : Your JDBC driver may not support this feature.

7.17 Fix incomplete field returned by the ResultSet

7.19 Transfer a ResultSet to a JTable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0309.html // TableModel definition String[] tableColumnsName = {"col 1","col 2","col 3"}; DefaultTableModel aModel = (DefaultTableModel) aTable.getModel(); aModel.setColumnIdentifiers(tableColumnsName); // the query ResultSet rs = statement.executeQuery("select col1,col2,col3 from mytable"); // Loop through the ResultSet and transfer in the Model java.sql.ResultSetMetaData rsmd = rs.getMetaData(); int colNo = rsmd.getColumnCount(); while(rs.next()){ Object[] objects = new Object[colNo]; // tanks to umit ozkan for the bug fix! for(int i=0;i
7.20 List tables in a database Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0317.html import java.net.URL; import java.sql.*; class JDBCapp { static MyConnection theConn; public static void main (String args[]) { new JDBCapp().doit(); } public void doit() { theConn = new MyConnection(); theConn.connect("myDSN", "user", "password"); try { ResultSet rs1; ResultSet rs2; String ss, tblnames = ""; DatabaseMetaData dmd = theConn.dbConn.getMetaData(); rs1 = dmd.getSchemas(); while(rs1.next()) { ss = rs1.getString(1); rs2 = dmd.getTables(null,ss, "%",null); while(rs2.next()) tblnames += rs2.getString(3) + " " + rs2.getString(4) + "\n\r"; } System.out.println("Tables :");

7.19 Transfer a ResultSet to a JTable

System.out.println(tblnames); } catch (Exception e) { e.printStackTrace(); } } } class MyConnection { Connection dbConn = null; void connect(String db, String user, String passw) { try { Driver d = (Driver)Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); // URL corresponding to the ODBC DSN String URL = "jdbc:odbc:" + db; // DB logon dbConn = DriverManager.getConnection(URL, user, passw); } catch (Exception e) { e.printStackTrace(); } } void disconnect() { try { dbConn.close(); } catch (Exception e) { e.printStackTrace(); } } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

7.21 Display ResultSet data in an HTML Table in Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0378.html private int dumpData(java.sql.ResultSet rs, java.io.PrintWriter out) throws Exception { int rowCount = 0; out.println("

"); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); // table header out.println(""); for (int i = 0; i < columnCount; i++) { out.println(""); } out.println(""); // the data while (rs.next()) { rowCount++;

7.21 Display ResultSet data in an HTML Table in Servlet

out.println(""); for (int i = 0; i < columnCount; i++) { out.println(""); } out.println(""); } out.println("
" + rsmd.getColumnLabel(i + 1) + "
" + rs.getString(i + 1) + "

"); return rowCount; }

7.22 Detect SQL errors or warnings Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0331.html Warning When the database server executes an SQL statement successfully, but encounters a warning condition, it sets the SQLSTATE class field to "01". The subclass code then indicates the cause of the warning. This warning can be an ANSI or X/Open warning message (if supported by the driver) the subclass code in the range "000" to "006". Also the driver can provide is own warning codes in the "01" class. Class Subclass 01 000

Success with warning

01

002

Disconnect error−transaction rolled back

01

003

Null value eliminated in set function

01

004

String data, right truncation

01

005

Insufficient item descriptor areas

01

006

Privilege not revoked

01

007

PRIVILEGE NOT GRANTED

The JDK API doc reveals that "The SQLWarning class provides information on a database access warnings. Warnings are silently chained to the object whose method caused it to be reported". So after DB operation, you ask the Connection object if there are any warnings. Depending on the vendor driver, informations (not only Warnings) can be found in the SQLWarning object. dbConn = DriverManager.getConnection ("jdbc:odbc:YourDatabaseName","username","password"); SQLWarning w = dbConn.getWarnings(); // If a SQLWarning object was returned by the // Connection object, the warning messages are displayed. // You may have multiple warnings chained together if (w != null) { System.out.println ("\n *** SQL Warning ***\n"); while (w != null) { System.out.println ("Message: " + w.getMessage ()); System.out.println ("SQLState: " + w.getSQLState ()); System.out.println ("VendorCode: " + w.getErrorCode ()); System.out.println (""); w = w.getNextWarning ();

7.22 Detect SQL errors or warnings

} } }

Error When an error occurs, a SQLException is thrown. You can interrogate the SQLException object to know more details about the actual error. Note that SQLException can be chained. The SQLException object contains : 1. A string describing the error. This is used as the Java Exception message, available via the getMessage method. 2. A "SQLState" string, which follows the XOPEN SQLState conventions. 3. An integer error code that is specific to each vendor. try { // ... some SQL operations } catch (SQLException ex) { // SQLException occured. // There could be multiple error objects chained together System.out.out.println ("*** SQLException caught ***"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState () + ""); System.out.println ("Message: " + ex.getMessage() + ""); System.out.println ("Vendor ErrorCode: " + ex.getErrorCode() + ""); ex = ex.getNextException(); System.out.println(""); } } catch (java.lang.Exception ex) { // Some other type of exception occurred System.out.println("*** Exception caught ***"); System.out.println(ex.getMessage()+ ""); } finally { // Close the database connection. try { if (con != null) con.close(); } catch (SQLException ignored) { //do nothing } }

Check your DBMS manual for a full list of supported SQLState.

7.23 Using DSN−less connection Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0345.html This HowTo seems broken, if anyone know what is problem, let me know!, Thanks (works on some Windows installation while on other it does not!)

7.23 Using DSN−less connection

It is possible to connect to a database without a User or System DSN. This is useful if you don't have easy access to a client registry to define the required DSN. Not all JDBC driver support this feature. // For Access Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String myDB = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/data/month.MDB"; DBConn = DriverManager.getConnection(myDB,"",""); // For Excel Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String myDB = "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=c:/data/month.xls;" + "DriverID=22;READONLY=false"; DriverManager.getConnection(myDB,"",""); Thanks to R. Hibberd for the tip.

7.24 Read data from Excel worksheet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0362.html Let's assume we have a worksheet like this LASTNAME Reiser Ricci Gugliuzza

FIRSTNAME Beth Dylan Brian

ID 102 111 116

To access this data, we can use the JDBC−ODBC bridge. Microsoft provides an ODBC driver to Excel worksheet. Define an ODBC datasource (system DSN) named "employee_xls" that points to that worksheet. example 1 import import import import

java.io.*; java.net.*; java.sql.*; java.util.*;

public class EmployeeReader{ public static final String DRIVER_NAME = "sun.jdbc.odbc.JdbcOdbcDriver"; public static final String DATABASE_URL = "jdbc:odbc:employee_xls"; public static void main(String[] args) throws ClassNotFoundException, SQLException{ Class.forName(DRIVER_NAME); Connection con = null; try { con = DriverManager.getConnection(DATABASE_URL); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery ("select lastname, firstname, id from [Sheet1$]");

7.24 Read data from Excel worksheet

while (rs.next()) { String lname = rs.getString(1); String fname = rs.getString(2); int id = rs.getInt(3); System.out.println(fname + " " + lname + " } rs.close(); stmt.close();

id : " + id);

} finally { if (con != null) con.close(); } } }

example 2 import java.io.*; import java.sql.*; public class EmployeeReader{ public static void main(String[] args){ Connection connection = null; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con = DriverManager.getConnection( "jdbc:odbc:employee_xls" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "Select * from [Sheet1$]" ); ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); System.out.println ( "No of cols "+numberOfColumns

);

while (rs.next()) { for (int i = 1; i <= numberOfColumns; i++) { if (i > 1) System.out.print(", "); String columnValue = rs.getString(i); System.out.print(columnValue); } System.out.println(""); } rs.close(); st.close(); } catch(Exception ex) { System.err.print("Exception: "); System.err.println(ex.getMessage()); } finally { con.close(); } } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

7.24 Read data from Excel worksheet

7.25 Handle Excel files Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0516.html There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about OpenSource (and free) solutions.

7.26 JDBC−ODBC Excel driver This solution lets you access your Excel worksheet with SQL SELECT statement. The required ODBC driver is included in a regular Windows installation and the JDBC−ODBC bridge is used to access the Excel DSN. See this HowTo for an example.

7.27 JExcel Java Excel API is a java API enabling developers to read, write, and modify Excel spreadsheets dynamically. Any operating system which can run a Java virtual machine can both process and deliver Excel spreadsheets. One nice thing about JExcelApi is that it has no dependencies on any third party libraries. Example : output an Excel file from a Servlet import java.io.IOException; import java.io.OutputStream; import import import import

javax.servlet.ServletException; javax.servlet.http.HttpServlet; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse;

import import import import

jxl.Workbook; jxl.write.Label; jxl.write.WritableSheet; jxl.write.WritableWorkbook;

public class Sample extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { OutputStream out = null; try { response.setContentType("application/vnd.ms−excel"); response.setHeader ("Content−Disposition", "attachment; filename=sampleName.xls"); WritableWorkbook w = Workbook.createWorkbook(response.getOutputStream()); WritableSheet s = w.createSheet("Demo", 0); s.addCell(new Label(0, 0, "Hello World")); w.write(); w.close(); } catch (Exception e){ throw new ServletException("Exception in Excel Sample Servlet", e); }

7.25 Handle Excel files

finally{ if (out != null) out.close(); } } }

See http://jexcelapi.sourceforge.net/

7.28 POI The POI project consists of APIs for manipulating various file formats based upon Microsoft's OLE 2 Compound Document format using pure Java. POI is your Java Excel solution as well as your Java Word solution. HSSF is the POI Project's pure Java implementation of the Excel '97(−2002) file format and it provides a way to read spreadsheets create, modify, read and write XLS spreadsheets. Since it's Jakarta project, POI has a dependencies with other JARs (commons,log4j,etc...). Example : create an Excel file HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet"); HSSFRow row = sheet.createRow((short)0); row.createCell((short)0).setCellValue("HelloWorld"); FileOutputStream fileOut = new FileOutputStream("workbook.xls"); wb.write(fileOut); fileOut.close();

The name was originally an acronym for "Poor Obfuscation Implementation" (ref: Wikipedia). See http://jakarta.apache.org/poi/

7.29 JXLS jXLS is a project that allows creation of extremely complex Excel reports just in several lines of code. It is based on Jakarta POI. With jXLS, all you need is to create XLS template file with all required formatting, formulas etc using specific notation to indicate placement of data and then write a couple lines of code to invoke jXLS engine passing XLS template and the exported data as parameters. Example : The XLS Template Employees Name ${employee.name}

with the code

7.28 POI

Age Payment Bonus ${employee.age} ${employee.payment} ${employee.bonus} $[SUM(@employee.payment@)]

Collection staff = new HashSet(); staff.add(new Employee("Derek", 35, 3000, 0.30)); staff.add(new Employee("Elsa", 28, 1500, 0.15)); Map beans = new HashMap(); beans.put("employee", staff); XLSTransformer transformer = new XLSTransformer(); transformer.transformXLS(templateFileName, beans, destFileName);

gives the result Employees Name Age Derek 35 Else 28

Payment Bonus 3000 30,00% 1500 15,00% 4500

See http://jxls.sourceforge.net/

7.30 xlSQL xlSQL is a JDBC Driver for Excel and CSV data sources. Documents can be read and written with SQL as if they were tables in a database. You can export XLS to XML or SQL INSERT statements. xlSQL includes its own "zero−admin" mySQL database. The documentation is minimal at this time. See http://xlsql.sourceforge.net/

7.31 JCOM JCOM is a Java to COM bridge library. With JCOM you can call a COM object from Java as if it were a Java object without having to deal with the internals of JNI. The documentation is minimal (in Japanese!). Example : import import import import

jp.ne.so_net.ga2.no_ji.jcom.excel8.*; jp.ne.so_net.ga2.no_ji.jcom.*; java.io.File; java.util.Date;

class TestExcel { public static void main(String[] args) throws Exception { ReleaseManager rm = new ReleaseManager(); try { System.out.println("EXCEL startup..."); // if already started, open new window ExcelApplication excel = new ExcelApplication(rm); excel.Visible(true); // display any information System.out.println("Version="+excel.Version()); System.out.println("UserName="+excel.UserName()); System.out.println("Caption="+excel.Caption()); System.out.println("Value="+excel.Value()); ExcelWorkbooks xlBooks = excel.Workbooks(); ExcelWorkbook xlBook = xlBooks.Add(); // create new book

7.30 xlSQL

// enumurate all files System.out.println ("set infomation of files in current directory to cell ..."); ExcelWorksheets xlSheets = xlBook.Worksheets(); ExcelWorksheet xlSheet = xlSheets.Item(1); ExcelRange xlRange = xlSheet.Cells(); xlRange.Item(1,1).Value("filename" ); xlRange.Item(2,1).Value("size" ); xlRange.Item(3,1).Value("last modified time"); xlRange.Item(4,1).Value("is directory"); xlRange.Item(5,1).Value("is file"); xlRange.Item(6,1).Value("can read"); xlRange.Item(7,1).Value("can write"); File path = new File("./"); String[] filenames = path.list(); for(int i=0; i
comment out, if book save to file. if no path, save to(My Documents) System.out.println ("save to file... (My Documents)\\testExcel.xls"); xlBook.SaveAs("testExcel.xls");

xlBook.Close(false,null,false); excel.Quit(); System.out.println("thank you ."); } catch(Exception e) { e.printStackTrace(); } finally { rm.release(); } } }

See http://sourceforge.net/projects/jcom See also this HowTo for an alternative package to access a COM package from Java.

7.30 xlSQL

7.32 OpenXLS Java Spreadsheet SDK OpenXLS claims that it has the best compatibility with complex Excel files and able to handle any kind of Excel file out there without corrupting it. This open source effort is the result of over 6 years of development into it. See http://www.extentech.com/estore/product_detail.jsp?product_group_id=228 Example (extract 3 images from a workbook, create a new workbook with them) : doit("testImages.xls","Sheet1"); ... void doit(String finpath, String sheetname){ System.out.println("Begin parsing: " + workingdir + finpath); WorkBookHandle tbo = new WorkBookHandle(workingdir + finpath); try{ sheet = tbo.getWorkSheet(sheetname); // read images from sheet 1 −− .gif, .png, .jpg ImageHandle[] extracted = sheet.getImages(); // extract and output images for(int t=0;t<extracted.length;t++) { System.out.println("Successfully extracted: " + workingdir + "testImageOut_" + extracted[t].getName()+"." +extracted[t].getType()); FileOutputStream outimg = new FileOutputStream (workingdir + extracted[t].getName()+"." +extracted[t].getType()); extracted[t].write(outimg); outimg.flush(); outimg.close(); } tbo = new WorkBookHandle(); sheet = tbo.getWorkSheet("Sheet1"); CellHandle a1 = sheet.add ("New workbook with 3 images: a gif, a jpg, and a png", "A1"); // get gif image input stream FileInputStream fin = new FileInputStream (workingdir + "testImages.gif"); // add to sheet ImageHandle giffy = new ImageHandle(fin, sheet); // set picture size and location in sheet giffy.setBounds(100, 100, 400, 200); giffy.setName("giffy"); sheet.insertImage(giffy); // add to sheet for(int x=0;x<100;x++) { fin = new FileInputStream(workingdir + "testImages.png"); ImageHandle jpgy = new ImageHandle(fin, sheet); jpgy.setName("heart" + x); // set the random x/y coords of picture int ix = Math.round((float)((x * (Math.random()*10)))); jpgy.setX(100 + ix);

7.32 OpenXLS Java Spreadsheet SDK

ix = Math.round((float)((x * (Math.random()*10)))); jpgy.setY(100 + ix); sheet.insertImage(jpgy); } // get png image input stream fin = new FileInputStream(workingdir + "testImages.jpg"); // add to sheet ImageHandle pngy = new ImageHandle(fin, sheet); // set just the x/y coords of picture pngy.setX(10); pngy.setY(200); sheet.insertImage(pngy); } catch(Exception e){ System.err.println("testImages failed: " + e.toString()); } testWrite(tbo, workingdir + "testImagesOut.xls"); WorkBookHandle newbook = new WorkBookHandle (workingdir + "testImagesOut.xls",0); System.out.println("Successfully read: " + newbook); } public void testWrite(WorkBookHandle b, String fout){ try{ java.io.File f = new java.io.File(fout); FileOutputStream fos = new FileOutputStream(f); BufferedOutputStream bbout = new BufferedOutputStream(fos); bbout.write(b.getBytes()); bbout.flush(); fos.close(); } catch (java.io.IOException e){ System.err.println("IOException in Tester. "+e); } }

See also this HowTo for a way to create a simple XLS without any additional library.

7.33 Specify a CharSet when connecting to a DBMS Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0371.html Class.forName(sun.jdbc.odbc.JdbcOdbcDriver) ; // setup the properties java.util.Properties prop = new java.util.Properties(); prop.put("charSet", "iso−8859−7"); // for example... prop.put("user", username); prop.put("password", password); // Connect to the database con = DriverManager.getConnection(url, prop);

7.33 Specify a CharSet when connecting to a DBMS

7.34 Get current date using JDBC Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0383.html With most DBMS, JDBC function escape sequence can be used : SELECT {fn curdate() } SELECT {fn curtime() } SELECT {fn now() }

for current date for current hour for current date and hour

for Oracle, you add the from dual SELECT {fn curdate() } FROM dual SELECT {fn curtime() } FROM dual SELECT {fn now() } FROM dual

for current date for current hour for current date and hour

Example : // for Oracle String sql = "select {fn " " " "

dayname ({fn now()})}," + {d '1997−05−24'}, " + {t '10:30:29' }, " + {ts '1997−05−24 10:30:29.123'}" + from dual" ;

ResultSet rs = stmt.executeQuery(sql); while (rs.next()) System.out.println("results: "\n " + rs.getString(2) "\n " + rs.getString(3) "\n " + rs.getString(4)

" + rs.getString(1) + + + );

7.35 Enable JDBC logging Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0411.html [JDK1.2] Take the following program. import java.net.URL; import java.sql.*; class JDBCapp { static MyConnection theConn; public static void main (String args[]) { new JDBCapp().doit(); } public void doit() { theConn = new MyConnection();

7.34 Get current date using JDBC

theConn.connect("EAS Demo DB V3", "dba", "sql"); PreparedStatement prepstmt; try { prepstmt = theConn.dbConn.prepareStatement ("SELECT emp_id FROM employee" ); prepstmt.execute(); prepstmt.close(); } catch (Exception e) { e.printStackTrace(); } theConn.disconnect(); } }

class MyConnection { Connection dbConn = null; void connect(String db, String user, String passw) { try { Driver d = (Driver)Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); String URL = "jdbc:odbc:" + db; dbConn = DriverManager.getConnection(URL, user, passw); java.io.PrintWriter w = new java.io.PrintWriter (new java.io.OutputStreamWriter(System.out)); DriverManager.setLogWriter(w); } catch (Exception e) { e.printStackTrace(); } } void disconnect() { try { dbConn.close(); } catch (Exception e) { e.printStackTrace(); } } }

And the output at the console will look like this : *Connection.prepareStatement (SELECT emp_id FROM employee) Allocating Statement Handle (SQLAllocStmt), hDbc=185334988 hStmt=184290392 Setting statement option (SQLSetStmtOption), hStmt=184290392, Setting statement option (SQLSetStmtOption), hStmt=184290392, Preparing (SQLPrepare), szSqlStr=SELECT emp_id FROM employee Number of parameter markers (SQLNumParams), hStmt=184290392 value=0 Registering Statement sun.jdbc.odbc.JdbcOdbcPreparedStatement@19ee1ac *PreparedStatement.execute Free statement (SQLFreeStmt), hStmt=184290392, fOption=0 Executing (SQLExecute), hStmt=184290392 Number of result columns (SQLNumResultCols), hStmt=184290392 value=1 *PreparedStatement.close Free statement (SQLFreeStmt), hStmt=184290392, fOption=1 deregistering Statement sun.jdbc.odbc.JdbcOdbcPreparedStatement@19ee1ac *Connection.close

7.34 Get current date using JDBC

0 Statement(s) to close Disconnecting (SQLDisconnect), hDbc=185334988 Closing connection (SQLFreeConnect), hDbc=185334988 Closing environment (SQLFreeEnv), hEnv=185334828

7.36 Detect if a table exists Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0485.html Connection c = ... DatabaseMetaData dbm = c.getMetaData(); // check if "employee" table is there ResultSet tables = dbm.getTables(null, null, "employee", null); if (rs.next()) { // Table exists } else { // Table does not exist } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

7.37 Convert a ResultSet to XML Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0511.html import import import import import import

java.sql.Connection; java.sql.Statement; java.sql.Driver; java.sql.DriverManager; java.sql.ResultSet; java.sql.ResultSetMetaData;

import import import import import import import

javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.transform.*; javax.xml.transform.stream.*; javax.xml.transform.dom.*; org.w3c.dom.Document; org.w3c.dom.Element;

class JDBCapp

{

static Connection con; public static void main (String args[]) { ResultSet rs = null; Statement stmt = null; String sql; try {

7.36 Detect if a table exists

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder =factory.newDocumentBuilder(); Document doc = builder.newDocument(); Element results = doc.createElement("Results"); doc.appendChild(results); // connection to an ACCESS MDB con = AccessCon.getConnection(); sql = "select objet from Email"; stmt = con.createStatement(); rs = stmt.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); while (rs.next()) { Element row = doc.createElement("Row"); results.appendChild(row); for (int ii = 1; ii <= colCount; ii++) { String columnName = rsmd.getColumnName(ii); Object value = rs.getObject(ii); Element node = doc.createElement(columnName); node.appendChild(doc.createTextNode(value.toString())); row.appendChild(node); } } System.out.println(getDocumentAsXml(doc)); } catch (Exception e) { e.printStackTrace(); } finally { try { if (con != null) con.close(); if (stmt != null) stmt.close(); if (rs != null) rs.close(); } catch (Exception e) { } } } public static String getDocumentAsXml(Document doc) throws TransformerConfigurationException, TransformerException { DOMSource domSource = new DOMSource(doc); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); //transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes"); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING,"ISO−8859−1"); // we want to pretty format the XML output // note : this is broken in jdk1.5 beta! transformer.setOutputProperty ("{http://xml.apache.org/xslt}indent−amount", "4"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // java.io.StringWriter sw = new java.io.StringWriter(); StreamResult sr = new StreamResult(sw); transformer.transform(domSource, sr);

7.36 Detect if a table exists

return sw.toString(); } } class AccessCon { public static Connection getConnection() throws Exception { Driver d = (Driver)Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); Connection c = DriverManager.getConnection ("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:/tech97.mdb"); return c; /* To use an already defined ODBC Datasource : String URL = "jdbc:odbc:myDSN"; Connection c = DriverManager.getConnection(URL, "user", "pwd"); */ } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

7.38 Escape special character in a LIKE clause Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0554.html Your JDBC driver may support the {escape 'escape character'} syntax for using LIKE clause wildcards as literals. The escape sequence must be at the end of the SQL statement. Searching for "one_word" st = con.createStatement(); rs = st.executeQuery ("SELECT value FROM vendors WHERE value LIKE 'one/_word' {escape '/'}");

Searching for strings ending with "one%word" st = con.createStatement(); rs = st.executeQuery ("SELECT value FROM vendors WHERE value LIKE '%one/%word' {escape '/'} ");

Find all rows in which a begins with the character "%" st = con.createStatement(); rs = st.executeQuery ("SELECT value FROM vendors WHERE value LIKE '$%%' {escape '$'}");

Find all rows in which a ends with the character "_" st = con.createStatement(); rs = st.executeQuery ("SELECT value FROM vendors WHERE value LIKE '%=_' {escape '='}");

7.38 Escape special character in a LIKE clause

If you don't want to use JDBC escape sequence then it's possible to use native SQL based on the target DBMS. For Oracle, it will look like this : SELECT value FROM vendors WHERE value LIKE '%=_%' ESCAPE '=';

ref : Labo−Oracle.com.

7.39 Insert the current date Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0567.html It's good idea to use the JDBC escape function instead of using a specific DBMS function. This way, your code will be portable. sql = + + +

"INSERT INTO CUSTOMERS VALUES(" "'" + custName + "'" + "," "'" + custPhone + "'" + "," " {fn now() } )";

7.40 Log the SQL Statements Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0602.html

7.41 Plain JDBC Logging See this HowTo.

7.42 P6Spy P6Spy is an open source framework for applications that intercept and optionally modify database statements. The log file format is current time|execution time|category|statement SQL String|effective SQL string

P6Spy is especially useful with an application server. Download at http://p6spy.com/

7.39 Insert the current date

7.43 Proxool Proxool is a Java connection pool. It provides really nice logging facilities with the SQL statement and the running time. Download at http://proxool.sourceforge.net/

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

7.43 Proxool

8 JNI 8.1 java−jni

8.2 Use native code through JNI Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0283.html • With MSVC6, create a new Win32 DLL project (simple) and call it javahowto. • In the same directory create a java source called JavaHowTo.java class JavaHowTo { public native String sayHello(); static { System.loadLibrary("javahowto"); } }

• Compile the Java program and use javah utility to generate the JavaHowTo.h header file. javah −jni JavaHowTo

• In MSVC6, add the JavaHowTo.h in your project header files • In the Tools − Options menu, set the include directories to include the Java JNI headers files. They are located in [jdk dir]\include and [jdk dir]\include\win32 directories • In the javahowto.cpp source, add #include "JavaHowTo.h" JNIEXPORT jstring JNICALL Java_JavaHowTo_sayHello (JNIEnv *env, jobject obj) { return env−>NewStringUTF("Hello world"); }

• Select the Release configuration and build the project. • Copy the javahowto.dll in the same directory as the java program. • Create this new java program public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo(); System.out.println(jht.sayHello()); } }

• Compile and execute.

8.3 Pass a string to/from Java to/from C Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0284.html To Java from C (as seen from the previous How−to) : #include "JavaHowTo.h" JNIEXPORT jstring JNICALL Java_JavaHowTo_sayHello (JNIEnv *env, jobject obj) {

8 JNI

return

env−>NewStringUTF("Hello world");

}

From Java to C : Suppose we have a Java Class public class MyClass { public String sayHello(){ return "Hello world From Java"; } }

then from C, we want to call the Java sayHello() method which returns a String : JNIEXPORT void JNICALL Java_JavaHowTo_sayHello (JNIEnv *env, jobject obj) { const char *str; jclass myclass_class =(jclass) env−>NewGlobalRef (env−>FindClass ("MyClass")); // we need the MyClass constructor jmethodID constructorID = env−>GetMethodID (myclass_class, "", "()V"); // and the sayHello() method jmethodID methodID = env−>GetMethodID (myclass_class, "sayHello", "()Ljava/lang/String;"); // instanciate a MyClass object jobject myclass_object = env−>NewObject (myclass_class, constructorID); // call the sayHello() method jstring s = (jstring) env−>CallObjectMethod (myclass_object, methodID); // convert the Java String to use it in C str = env−>GetStringUTFChars(s, 0); printf("%s" , str); env−>ReleaseStringUTFChars(s, str); }

The Java JNI wrapper would be class JavaHowTo { public native void sayHello(); static { System.loadLibrary("javahowto"); } }

And finally, to use it public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo(); jht.sayHello(); } }

8 JNI

8.4 Set the computer clock Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0285.html Define the following prototype in the header file JNIEXPORT void JNICALL Java_JavaHowTo_setSystemTime (JNIEnv *, jobject, jshort, jshort);

the JNI function JNIEXPORT void JNICALL Java_JavaHowTo_setSystemTime (JNIEnv *env, jobject obj, jshort hour, jshort minutes) { SYSTEMTIME st; GetLocalTime( st.wHour = hour; st.wMinute = minutes; SetLocalTime( }

The Java JNI wrapper would be class JavaHowTo { public native void setSystemTime( short hour, short minutes); static { System.loadLibrary("javahowto"); } }

And finally, to use it public class JNIJavaHowTo { public static void main(String[] args) { short hour = 10; short minutes = 21; // this example will set the system at 10h21 using the Windows API // SetLocalTime. JavaHowTo jht = new JavaHowTo(); // set the time at 10h21 jht.setSystemTime(hour, minutes); } }

8.5 Determine the signature of a method Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0286.html Before calling a Java object's method from JNI, we need its signature. For example, the method long myMethod (int n, String s, int[] arr);

8.4 Set the computer clock

is seen from JNI with the signature (ILJAVA/LANG/STRING;[I)J

There are two parts to the signature. The first part is enclosed within the parentheses and represents the method's arguments. The second portion follows the closing parenthesis and represents the return type. The mapping between the Java type and C type is Type boolean byte char double float int long object short void array

Chararacter Z B C D F I J L S V [

Note that to specify an object, the "L" is followed by the object's class name and ends with a semi−colon, ';' . The javap utility (included with the JDK) is very useful to show the signature to be used in JNI. X:\>javap −s java.awt.Label Compiled from Label.java public class java.awt.Label extends java.awt.Component { public static final int LEFT; /* I */ public static final int CENTER; /* I */ public static final int RIGHT; /* I */ java.lang.String text; /* Ljava/lang/String; */ int alignment; /* I */ static {}; /* ()V */ public java.awt.Label(); /* ()V */ public java.awt.Label(java.lang.String); /* (Ljava/lang/String;)V */ public java.awt.Label(java.lang.String,int); /* (Ljava/lang/String;I)V */ public void addNotify(); /* ()V */ java.lang.String constructComponentName(); /* ()Ljava/lang/String; */ public int getAlignment(); /* ()I */ public java.lang.String getText(); /* ()Ljava/lang/String; */ protected java.lang.String paramString(); /* ()Ljava/lang/String; */ public synchronized void setAlignment(int); /* (I)V */ public void setText(java.lang.String); /* (Ljava/lang/String;)V */

8.4 Set the computer clock

The javap utility can be used on the java.* or your own classes.

8.6 Use arrays Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0287.html JNI provides special functions (relative to the type) to access Java arrays. This example returns the maximum of an int array. JNIEXPORT jint JNICALL Java_JavaHowTo_max (JNIEnv * env, jclass obj, jintArray arr) { int i; jsize len = env−>GetArrayLength(arr, max = −1; jint *body = env−>GetIntArrayElements(arr, 0); for (max = body[0], i=1; i ReleaseIntArrayElements(arr, body, 0); return max; }

The Java wrapper class JavaHowTo { public static native int max(int [] t); static { System.loadLibrary("javahowto"); } }

The test program class JNIJavaHowTo { public static void main(String[] args) { int [] myArray = {4, 7, 5, 9, 2, 0, 1}; System.out.println(JavaHowTo.max(myArray)); } }

This following how−to is currently broken... Without passing the array directly to the JNI function, it's possible to fetch directly from the class the array. JNIEXPORT jint JNICALL Java_JavaHowTo_printArray (JNIEnv * env, jclass obj) { jfieldID fid; jobject jtab; jsize len; int i; jclass cls = env−>GetObjectClass(obj); fid = env−>GetFieldID(cls, "myArray", "[I"); if (fid == 0) return; jtab = env−>GetObjectField(obj, fid); tab = env−>GetIntArrayElements(jtab, 0); len = env−>GetArrayLength(jtab);

8.6 Use arrays

printf("int [] : ["); for (i = 0; i
", tab[i]);

}

8.7 Load a DLL Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0318.html [pre JDK1.2] System.loadLibrary("d:\\directoryX\\subDirY\\MyDll.dll")

In JDK1.2 (or better), if the DLL is in the CLASSPATH then you don't need to specify a PATH. If the DLL is not in the CLASSPATH then you need to specify the PATH. Do something like this instead. Runtime.getRuntime().load("d:/directoryX/subDirY/MyDll.dll");

or specify through the JVM command line the location where to find the JNI DLL to be loaded java −Djava.library.path=c:/temp JNIJavaHowTo

8.8 Use the MouseWheel Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0314.html Current JDK don't support scrolling via the MouseWheel. Next version (JDK1.4) may provide this functionality but for now, you need some JNI functions. See this link http://www.codeproject.com/java/mousewheel.asp .

8.9 Throw an Exception (from JNI code) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0323.html Define the following prototype in the header file JNIEXPORT jdouble JNICALL Java_JavaHowTo_divide (JNIEnv *, jobject, jdouble, jdouble);

the JNI function JNIEXPORT jdouble JNICALL Java_JavaHowTo_divide

8.7 Load a DLL

(JNIEnv *env, jobject obj, jdouble d1, jdouble d2) { if (d2 == 0.0) { jclass Exception = env−>FindClass("java/lang/Exception"); env−>ThrowNew(Exception,"Can't divide by zero."); } return d1/d2; }

The Java JNI wrapper would be class JavaHowTo { public native double divide(double d1, double d2); static { System.loadLibrary("javahowto"); } }

And finally, to use it public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo(); System.out.println("division 1 : " + jht.divide(9.0, 3.0)); System.out.println("division 2 : " + jht.divide(9.0, 0.0)); } }

8.10 Throw my own Exception (from JNI code) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0322.html The MyOwnException class public class MyOwnException extends Exception { public MyOwnException(){} public MyOwnException(String txt) { super(txt); } }

the prototype in the header file JNIEXPORT void JNICALL Java_JavaHowTo_triggerException (JNIEnv *, jobject);

the JNI function JNIEXPORT void JNICALL Java_JavaHowTo_triggerException (JNIEnv *env, jobject obj) { jclass MyOwnException = env−>FindClass("MyOwnException"); env−>ThrowNew(MyOwnException,"Exception triggered from JNI routine."); }

The Java JNI wrapper would be class JavaHowTo {

8.10 Throw my own Exception (from JNI code)

public native void triggerException(); static { System.loadLibrary("javahowto"); } }

And finally, to use it public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo(); jht.triggerException(); } }

8.11 JNI from a package Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0348.html JNI requires that the function names follow a specific format. If you have a Java native method in a class called MyClass like this: public native void myMethod();

the native function must look like this: JNIEXPORT void JNICALL Java_MyClass_myMethod(JNIEnv *, jobject);

When you put the class into a package (say com.rgagnon), you need to include the package information in the native function name like this: JNIEXPORT void JNICALL Java_com_rgagnon_MyClass_myMethod(JNIEnv *, jobject);

To generated the proper header, compile the JNI class in the package then, using the javah utility (from the root of the package) : javah com.rgagnon.MyClass If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

8.12 Make a Window "stay on top" Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0353.html First you need the handle of the Window. Call this JNI function with Window Title. JNIEXPORT jint JNICALL Java_JavaHowTo_getHwnd (JNIEnv *env, jclass obj, jstring title){

8.11 JNI from a package

HWND hwnd = NULL; const char *str = NULL; str = (*env)−>GetStringUTFChars(env, title, 0); hwnd = FindWindow(NULL,str); (*env)−>ReleaseStringUTFChars(env, title, str); return (jint) hwnd; }

Then you pass the handle to this function JNIEXPORT void JNICALL Java_JavaHowTo_setWindowAlwaysOnTop (JNIEnv *env, jclass obj, jint hwnd, jboolean flag){ if (flag) SetWindowPos((HWND) hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); else SetWindowPos((HWND) hwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); return; }

8.13 Start a JVM from C Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0354.html #include <jni.h> #include <stdio.h> int main() { JavaVM *vm; JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption options[1]; options[0].optionString = "−Djava.class.path=c:/myclasses"; vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.nOptions = 1; vm_args.ignoreUnrecognized = 1; jstring jstr; jobjectArray args; jint res = JNI_CreateJavaVM((void **) if (res < 0) { printf("Can't create Java VM\n"); exit(1); } jclass cls = env−>FindClass("HelloWorld"); // in c:/myclasses if (cls == 0) { printf("HelloWorld class not found\n"); exit(1); } jmethodID mid = env−>GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); if (mid == 0) { printf("main() method not found\n"); exit(1); } jstring argString = env−>NewStringUTF(""); //empty arg list jobjectArray args = env−>NewObjectArray(1, env−>FindClass("java/lang/String"), jstr);

8.13 Start a JVM from C

if (args == 0) { printf("Out of memory\n"); exit(1); } env−>CallStaticVoidMethod(cls, mid, args); return 0; }

8.14 Retrieve environment variable (JNI) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0460.html For some odd reasons, the getenv() method was removed from the JDK. Rumors is that a mechanism to retrieve an environment will be back in JDK1.5 (see this HowTo). But for now, you can use −D switch to retrieve named environment variable and pass them to the JVM (see this HowTo) or use this JNI routine : JNIEXPORT jstring JNICALL JavaHowTo_getenv (JNIEnv *env, jclass c, jstring jname){ if ( jname == NULL ) { return NULL ; } const char *name = (*env)−>GetStringUTFChars(env, jname, (jboolean *)NULL) ; const char *value = getenv(name) ; (*env)−>ReleaseStringUTFChars(env, jname, name) ; return value ? (*env)−>NewStringUTF(env, value) : NULL ; }

NOTE : This is fine if the environment variable contains only regular 7−bit ASCII characters. See also this HowTo. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

8.15 Get the PID Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0467.html class JavaHowTo { public native long getCurrentProcessId(); static { System.loadLibrary("jni2"); } } public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo();

8.14 Retrieve environment variable (JNI)

System.out.println("Press Any key..."); java.io.BufferedReader input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); try { input.readLine();} catch (Exception e) { e.printStackTrace();} System.out.println(jht.getCurrentProcessId()); } } // jni2.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include <process.h> #include "JavaHowTo.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }

JNIEXPORT jlong JNICALL Java_JavaHowTo_getCurrentProcessId (JNIEnv *, jobject) { // return GetCurrentProcessId(); return getpid(); }

You can download the whole thing here. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

8.16 Clear the console, set color and cursor position (JNI) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0469.html [Windows only] First you need this Java stub (JavaHowTo.java) to provide an interface to the JNI DLL (jni3.dll). class JavaHowTo { public public public public public public

static static static static static static

final final final final final final

short short short short short short

FOREGROUND_BLACK = 0x0; FOREGROUND_BLUE = 0x1; FOREGROUND_GREEN = 0x2; FOREGROUND_RED = 0x4; FOREGROUND_WHITE = 0x7; FOREGROUND_INTENSITY = 0x8;

public static final short BACKGROUND_BLUE = 0x10; public static final short BACKGROUND_GREEN = 0x20;

8.16 Clear the console, set color and cursor position (JNI)

public static final short BACKGROUND_RED = 0x40; public static final short BACKGROUND_INTENSITY = 0x80; // and so on...the definition for the other colors is // left as an exercise :−)

public native void cls(); public native void setCursorPosition( short x, short y); public native void keepColors(); public native void restoreColors(); public native void setColor( short foreground, short background); static { System.loadLibrary("jni3"); } }

Compile and generate an header with javah JavaHowto, the result is a file called JavaHowTo.h. Next we built a DLL, I'm using VisualStudio v6. Don't forget to include the folders %JAVAHOME%\include and %JAVAHOME%\include\win32 to have access to the JNI header files. // jni3.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include <stdlib.h> #include "JavaHowTo.h"

int originalColors; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }

JNIEXPORT void JNICALL Java_JavaHowTo_cls (JNIEnv *env, jobject obj) { HANDLE hConsole; unsigned long * hWrittenChars = 0; CONSOLE_SCREEN_BUFFER_INFO strConsoleInfo; COORD Home; static unsigned char EMPTY = 32; Home.X = 0; Home.Y = 0; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsole, FillConsoleOutputCharacter(hConsole, EMPTY, strConsoleInfo.dwSize.X * strConsoleInfo.dwSize.X, Home, hWrittenChars); SetConsoleCursorPosition(hConsole, Home); // system("cls"); will do the same as the above! } JNIEXPORT void JNICALL Java_JavaHowTo_setCursorPosition (JNIEnv *env, jobject obj, jshort x, jshort y) {

8.16 Clear the console, set color and cursor position (JNI)

HANDLE hConsole; COORD coordScreen; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); coordScreen.X = x; coordScreen.Y = y; SetConsoleCursorPosition( hConsole, coordScreen ); } JNIEXPORT void JNICALL Java_JavaHowTo_setColor (JNIEnv *env, jobject obj, jshort foreground, jshort background) { HANDLE hConsole; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, foreground + background); } JNIEXPORT void JNICALL Java_JavaHowTo_keepColors (JNIEnv *env, jobject obj) { HANDLE hConsole; CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsole, originalColors = ConsoleInfo.wAttributes; } JNIEXPORT void JNICALL Java_JavaHowTo_restoreColors (JNIEnv *env, jobject obj) { HANDLE hConsole; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, originalColors); }

Build the DLL (target Release), the result is jni3.dll. Here an example how to use the DLL. public class JNIJavaHowTo { public static void main(String[] args) { JavaHowTo jht = new JavaHowTo(); // clear the screen jht.cls(); // set the cursor at line 10 column 20 jht.setCursorPosition((short)20,(short)10); System.out.print("Real's HowTo"); // set the cursor at line 15 column 20 jht.setCursorPosition((short)20,(short)15); // keep the current colors jht.keepColors(); // set the color as WHITE on BLUE jht.setColor(jht.FOREGROUND_WHITE,jht.BACKGROUND_BLUE); System.out.print("http://www.rgagnon.com");

8.16 Clear the console, set color and cursor position (JNI)

// restore the orginal colors jht.restoreColors(); // set the cursor at line 20 column 0 jht.setCursorPosition((short)0,(short)20); } }

You can download a zip with everything here. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

8.17 Call Windows API (Open source solution) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0497.html NativeCall NativeCall is a Java toolkit that lets you call operating system methods from whithin Java without JNI code. // copying a file to a new one using the Windows API import com.eaio.nativecall.*; NativeCall.init(); IntCall ic = new IntCall("CopyFileA"); ic.executeCall(new Object[] { "test.txt", "test_copy.txt", Boolean.FALSE }); ic.destroy();

See http://johannburkard.de/software/nativecall/ If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

8.17 Call Windows API (Open source solution)

9 Javascript interaction 9.1 java−js

9.2 * Read me * Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0168.html

The examples in these How−to's are tested with Netscape 7 (or better) on Windows. The LiveConnect package is included with IE4/5 (Win version). The LiveConnect package is included with the Java plugin too. The official documentation for the various versions can be found at http://java.sun.com/products/plugin/reference/docs/index.html. Unix/Linux But it seems that there is a LiveConnect−SDK for Unix. It's based on N3 but works on N4 (at least on Solaris and Linux, thanks to A. Zisowsky for the tip). The JSObject package is included with Netscape 6 preview but it is broken but should be fixed for the release version! Mac To use the LiveConnect packages on the Mac you will need to install the latest MRJ available from the Apple website and then goto the Mozilla website and download the MRJ Plugin. The only other thing then is to change the tags to <embed> tag (more info on this is on the Mozilla site). Thanks to Neil English for the tip

9.3 Wake−up a Java applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0169.html When moving the mouse over an image, we want to start an applet (here a simple chronometer), and when the mouse leave the image, the Applet should stop. [JAVA APPLET] import java.applet.*; import java.awt.*; public class JavaChrono extends Applet { String previousTime = "0" ; String currentTime = "0"; long j,k, l; boolean okToChrono = false;

9 Javascript interaction

Color b, f; public void init() { b = getBackground(); f = getForeground(); MyThread tm = new MyThread(this); tm.start(); } public void startChrono() { j = System.currentTimeMillis(); okToChrono = true; } public void stopChrono() { okToChrono = false; } public void paint(Graphics g) { if (okToChrono) { g.setColor(b); g.drawString(previousTime,10,30); g.setColor(f); k = System.currentTimeMillis(); l = k−j; currentTime = Long.toString(l/1000); g.drawString(currentTime,10,30); previousTime = currentTime; } } } class MyThread extends Thread { JavaChrono theApplet; public MyThread(JavaChrono a) { theApplet = a; } public void run() { while (true) { try { theApplet.repaint(); this.sleep(1000); } catch(InterruptedException e) { } } } }

[HTML] <APPLET CODE=JavaChrono.class WIDTH=150 HEIGHT=150>
/BODY/HTML

9 Javascript interaction

Try it here.

In the next example, when we click on a FORM's button, we tell the applet to open or close a frame. [HTML] <APPLET NAME="myApplet" CODE="MyApplet.class" HEIGHT=1 WIDTH=1>
/FORM/BODY/HTML

[JAVA APPLET] import java.applet.*; import java.awt.*; public class MyApplet extends Applet { Frame f = null; public void init() { } public void showFrame() { if (f == null) { f = new Frame(); f.setSize(100,100); f.add(new Label("Hello World")); f.setVisible(true); } } public void disposeFrame() { if (f != null) { f.dispose(); f = null; } } } Try it here.

9.4 Call a Java method from Javascript Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0170.html You call a Java method by giving its fully qualified name. In the following snippet, the first example calls the method in the Toolkit to retrieve the screen resolution. The second example, calls a method in our Applet. 9.4 Call a Java method from Javascript

NOTE: On IE4 or better, you can't call java.* methods directly from Javascript or Jscript. IE javascript can only access the public methods of an applet (a class derived from java.applet.Applet) but don't have a general access to other java classes . So the solution is simple, wrap the java.* call in a public method of a "dummy" Applet. [Java applet] import java.awt.*; import java.applet.*; public class InJava extends Applet{ public void sayHello() { Graphics g = getGraphics(); g.drawString("Hello from JAVA!", 10, 10); } }

[Javascript and HTML (Netscape)] <SCRIPT> function getScreenDimension() { alert("Screen Dimension\n" + " width:" + java.awt.Toolkit.getDefaultToolkit().getScreenSize().width + " height:" + java.awt.Toolkit.getDefaultToolkit().getScreenSize().height); }
<APPLET CODE="InJava.class" NAME="myApplet" HEIGHT=100 WIDTH=100> /BODY/HTML Try it here

import java.awt.*; import java.applet.*; // (IE and Netscape ok) public class InJava2 extends Applet{ public int getScreenWidth() { return Toolkit.getDefaultToolkit().getScreenSize().width; } public int getScreenHeight() { return Toolkit.getDefaultToolkit().getScreenSize().height; } }

[Javascript and HTML (IE and Netscape)]

9.4 Call a Java method from Javascript

<SCRIPT> function getScreenDimension() { alert("Screen Dimension\r\n width:" + document.myApplet.getScreenWidth() + " height:" + document.myApplet.getScreenHeight() ); }
<APPLET CODE="InJava2.class" NAME="myApplet" HEIGHT=100 WIDTH=100> /BODY/HTML Try it here NOTE: This for demonstration only. On N4 or IE4, it's better to use screen.height and screen.width properties directly. There is no need for a Java Applet! NOTE: The first time, there is a delay because the Applet need to load and initialize.

9.5 Calling Java applets methods using DOM and JavaScript Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0346.html [IE4 or better] ... ... [in your script] document.all.myApplet.myMethod()

You use the scriptable parameter if you call Java method from Javascript. You use the mayscript parameter if you call Javascript function from Java. This Sun's document describes how Java to Javascript communication works when using the Java Plug−in.

9.6 Access Java variables from Javascript Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0171.html Java variables can be used by giving the fully qualified name. In Java, the variable must be declared as "public". To be compatible Netscape AND MSIEv4, the preferred way is to use special "access method" to read Java variables (only String or integer). 9.5 Calling Java applets methods using DOM and JavaScript

[Java applet] import java.awt.*; import java.applet.*; public class InJava3 extends Applet{ public int iJava = 123; public String sJava = "String from JAVA"; public int getIntJava() { return iJava; } public String getStringJava() { return sJava; } }

[Javascript and HTML] <SCRIPT> function JavaSays() { alert("Java says\n the value of iJava is :" + document.myApplet.getIntJava() + "\n" + "and sJava is :" + document.myApplet.getStringJava()); }
<APPLET CODE="InJava3.class" NAME="myApplet" HEIGHT=0 WIDTH=0> /APPLET/BODY/HTML Try it here Remember that IE4 can access only attributes and methods from a class derived from java.applet.Applet. If you want to call a method or use an attribute in another class, you have to create a method in your applet class that calls the other class's method.

9.7 Call Javascript from a Java applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0172.html Netscape only, using the javascript: protocol A Javascript function is called from Java by using the showDocument method. A URL is needed with "javascript:" as the protocol. [Java applet] import java.applet.*; import java.net.*; public class InJava4 extends Applet{ public void init(){ String msg = "Hello from Java (using javascript alert)";

9.7 Call Javascript from a Java applet

try { getAppletContext().showDocument (new URL("javascript:doAlert(\"" + msg +"\")")); } catch (MalformedURLException me) { } } }

[Javascript and HTML] <SCRIPT> function doAlert(s) { alert(s); } <APPLET CODE="InJava4.class" NAME="myApplet" MAYSCRIPT HEIGHT=10 WIDTH=10> /HTML Try it here

Netscape and IE ok, using the netscape.javascript.JSObject package How to compile when using the netscape.javascript.JSObject package ? For Java 1.4.2 and later: add plugin.jar to your classpath. It can be found in the lib directory of your JRE installation, e.g. C:\Program Files\Java\jre1.5.0\lib\plugin.jar For Java 1.4.0/1.4.1: use jaws.jar (same directory). In the following example, you type in the TextField a Javascript function and press the button to execute the function. For example, try alert('Hello from JAVA'). Or you can execute function defined on the same page as the Applet. The Applet must contains the MAYSCRIPT parameter to be able to use JSObject. Netscape and IE Ok. import import import import

java.applet.*; java.awt.*; java.awt.event.*; netscape.javascript.*;

public class InJava5 extends Applet implements ActionListener { Button b; TextField t; public void init() { t = new TextField(20); add(t); b = new Button("execute Javascript"); add(b); b.addActionListener(this); }

9.7 Call Javascript from a Java applet

public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) { JSObject win = (JSObject) JSObject.getWindow(this); win.eval(t.getText()); } } } Try it here

Another way is to use the Reflection API. That way you don't need to modify your CLASSPATH for compilation or even import the netscape.jsobject package. // posted by C Werner on the realhowto list import java.lang.reflect.*; ... // Somewhere in the applet class ... ... String jscmd = "window.close()"; /* JavaScript command */ String jsresult = null; boolean success = false; try { Method getw = null, eval = null; Object jswin = null; Class c = Class.forName("netscape.javascript.JSObject"); /* does it in IE too */ Method ms[] = c.getMethods(); for (int i = 0; i < ms.length; i++) { if (ms[i].getName().compareTo("getWindow") == 0) getw = ms[i]; else if (ms[i].getName().compareTo("eval") == 0) eval = ms[i]; } } Object a[] = new Object[1]; a[0] = this; /* this is the applet */ jswin = getw.invoke(c, a); /* this yields the JSObject */ a[0] = jscmd; Object result = eval.invoke(jswin, a); if (result instanceof String) jsresult = (String) result; else jsresult = result.toString(); success = true; } catch (InvocationTargetException ite) { jsresult = "" + ite.getTargetException(); } catch (Exception e) { jsresult = "" + e; } if (success) System.out.println("eval succeeded, result is " + jsresult); else System.out.println("eval failed with error " + jsresult);

9.7 Call Javascript from a Java applet

9.8 Create dynamic HTML from a Java applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0173.html We can use the netscape.javascript.* included with Netscape browser and IE4 (Win version). See also this HowTo to learn how to compile with this package. [Java applet JDK1.1 Netscape/IE4 (win) OK] import import import import

java.applet.*; java.awt.*; java.awt.event.*; netscape.javascript.*;

public class HtmlFromJava extends Applet implements ActionListener { Button aButton; public void init(){ setLayout(new FlowLayout()); aButton = new Button("create HTML"); add(aButton); aButton.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == aButton){ String HTML = ""; HTML += "
Hello world
"; HTML += ""; JSObject win = (JSObject)JSObject.getWindow(this); win.eval("createHTML(\"" + HTML +"\");"); } } }

[Javascript and HTML] <SCRIPT> function createHTML(s) { win = window.open("about:"); win.document.write(s); win.document.close(); } <APPLET CODE=HtmlFromJava.class MAYSCRIPT WIDTH=150 HEIGHT=150> /APPLET/BODY/HTML Try it here

9.8 Create dynamic HTML from a Java applet

9.9 Have Applets on different frames communicates with each other Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0174.html You can use a Javascript function as a bridge between the 2 frames. [main HTML (interframe0.html)]

[frame 1 HTML (interframe1.html)] <SCRIPT> function toOtherFrame(a, target) { if (target == "f1") parent.f1.document.app1.fromOtherFrame(a); else parent.f2.document.app2.fromOtherFrame(a); } <APPLET CODE="InterFrameDemo.class" NAME="app1" MAYSCRIPT HEIGHT=200 WIDTH=200>

[frame 2 HTML (interframe2.html)] <APPLET CODE="InterFrameDemo.class" NAME="app2" MAYSCRIPT HEIGHT=200 WIDTH=200> WIDTH=200>

[Java applet (InterFrameDemo.java)] import java.applet.*; import java.awt.*; import java.awt.event.*;

9.9 Have Applets on different frames communicates with each other

import java.net.URL; import netscape.javascript.*; public class InterFrameDemo extends Applet implements ActionListener { TextField tf; Button b; String target; public void init() { target = getParameter("target"); setLayout(new BorderLayout()); tf = new TextField(20); add("South", tf); b = new Button("To other frame"); add("North",b); b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) { String js = "parent.f1.toOtherFrame(\"" + tf.getText() + "\",\"" + target + "\")"; System.out.println("to Javascript:" + js); JSObject win = (JSObject) JSObject.getWindow(this); win.eval(js); } } public void fromOtherFrame(String s) { tf.setText(s); } } Try it here For a JAVA−only solution check this Java How−to

9.10 Send a message from an Applet to another Applet on a different page Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0181.html FirstApplet encodes the message for SecondApplet in the search (or query) section of SecondApplet.html URL. A simple script in SecondApplet.html decodes the search section and dynamically creates a new page containing the APPLET tag for SecondApplet and a PARAM with the message coming from FirstApplet. FirstApplet.html <APPLET CODE="FirstApplet.class" HEIGHT=100 WIDTH=300> /APPLET/BODY/HTML

9.10 Send a message from an Applet to another Applet on a different page

FirstApplet.java import import import import

java.applet.*; java.awt.*; java.awt.event.*; java.net.*;

public class FirstApplet extends Applet implements ActionListener { Button b; TextField t; public void init() { add(new Label("Message to 2nd applet :")); add(t= new TextField(20)); add(b = new Button("Load 2nd applet")); b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b) { try { getAppletContext().showDocument (new URL(getCodeBase(), "SecondApplet.html?" + "message=" + URLEncoder.encode(t.getText()))); } catch (Exception e) { e.printStackTrace(); } } } }

SecondApplet.html <SCRIPT> // from Javascript How−to general part 3, // replace all occurrence of token by another // in a string. function replace(s, t, u) { i = s.indexOf(t); r = ""; if (i == −1) return s; r += s.substring(0,i) + u; if ( i + t.length <s.length) r += replace(s.substring(i + t.length, s.length), t, u); return r; } strlen = document.location.search.length if (strlen > 0) { theMessage = document.location.search // strip the "message header" theMessage = theMessage.substring(1 + 'message='.length,strlen) // replace all '+" by space theMessage = replace(theMessage, '+', ' ') // replace encoded chars by decoded chars if any theMessage = unescape(theMessage) html = '<APPLET CODE="SecondApplet.class"' html += ' HEIGHT=100' html += ' WIDTH=400> '

9.10 Send a message from an Applet to another Applet on a different page

html += ' ' html += '' document.close() document.open() document.write(html) document.close() } /BODY/HTML

SecondApplet.java import java.applet.*; import java.awt.*; public class SecondApplet extends Applet { public void init() { Label l = new Label("Message from 1st Applet"); add (l); TextField tf = new TextField( 50 ); add(tf); String s = getParameter("Message"); tf.setText(s); } } You can try it here!

This method is useful when you need to pass the message to the SecondApplet via PARAM tag. But if you don't need the PARAM tag, take a look at this Java How−to.

9.11 Retrieve values from a Java applet for HTML form (CGI) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0175.html Retrieve the value with a Javascript function called via the onSubmit event of the form. [InitHTMLForm.java] public class InitHTMLForm extends java.applet.Applet { public String getFirstName() { // in real life, you have TextField in your Applet and // you want to transert its content to the HTML FORM // return myTextField.getText(); return "Real's HowTo"; } }

[HTML and Javascript] <SCRIPT> function getValueFromApplet(){ document.myForm.q.value = document.myApplet.getFirstName(); return true; }

9.11 Retrieve values from a Java applet for HTML form (CGI)

<APPLET CODE="InitHTMLForm.class" NAME="myApplet" HEIGHT=0 WIDTH=0>
/BODY/HTML Try it here

9.12 Detect if an Applet is ready Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0176.html <SCRIPT> function isAppletReady(a) { return a.isActive(); }
/FORM An Applet is ready when it's loaded and its init() method is done.

To execute a Javascript only when an Applet is ready : <SCRIPT> function waituntilok() { if (document.myApplet.isActive()) { doit(); } else { settimeout(waituntilok(),5000) } } function doit() { .... } ... .... /BODY

9.12 Detect if an Applet is ready

By calling the javascript function from the BODY onLoad handler, we can assume that the Applet is loaded, initiated and started. Here a "browser friendly" solution from N. Witteman to check if an Applet can be loaded (or found). <SCRIPT LANGUAGE="JavaScript"> onError = errHandler; // Without he parentheses, because we don't want IE // to do this. Like this, only NS does. function appLoaded() { if (!document.applets[0].isActive) // in IE: isActive returns an error if the applet IS loaded, // false if not loaded // in NS: isActive returns true if loaded, an error if not loaded, // so never reaches the next statement alert("IE: Applet could not be loaded"); } function errHandler() { alert("NS: Applet could not be loaded"); consume(); // stops further processing of the error } <APPLET code=someClass.class codeBase=someURL height=50 width=300> /HTML

9.13 Read/Write HTML field values from JAVA Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0177.html [Netscape AND IE4 compatible] The netscape.javascript.* (LiveConnect) package provides facilities to directly manipulate HTML FORM components. JSObject win = (JSObject)JSObject.getWindow(this); JSObject inputText = (JSObject) win.eval("document.forms[0].elements[0]"); String value = (String)inputText.getMember("value"); // read form value inputText.setMember("value" , value + " new stuff"); // write form value

But this action requires a signed applet. in Netscape, you must PrivilegeManager.enablePrivilege("UniversalBrowserRead"); PrivilegeManager.enablePrivilege("UniversalBrowserWrite");

9.13 Read/Write HTML field values from JAVA

before using an JSObject related to an HTML document. But there is a workaround, simply pass the informations through Javascript functions! [JSjava.java] import import import import

java.applet.*; java.awt.event.*; java.awt.*; netscape.javascript.*;

public class JSjava extends Applet implements ActionListener { Button b1,b2; TextField tf; JSObject win; public void init(){ setLayout(new FlowLayout()); tf = new TextField(10); b1 = new Button("to FORM"); b2 = new Button("from FORM"); b1.addActionListener(this); b2.addActionListener(this); add(tf);add(b1);add(b2); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b1) { // send TO FORM JSObject win = (JSObject)JSObject.getWindow(this); win.eval("setHTMLInputText('"+tf.getText()+"');"); } if (ae.getSource() == b2) { // receive FROM FORM JSObject win = (JSObject)JSObject.getWindow(this); tf.setText((String)win.eval("getHTMLInputText();")); } } }

[JSjava.html] <SCRIPT> function getHTMLInputText(){ return document.forms[0].elements[0].value; } function setHTMLInputText(s){ document.forms[0].elements[0].value = s; }
<APPLET NAME="JS" CODE=JSjava.class MAYSCRIPT WIDTH=200 HEIGTH=200> /APPLET/BODY/HTML

9.13 Read/Write HTML field values from JAVA

For best result, never use LiveConnect JSObject in Applet's init() method.

9.14 Detect if Java is enabled Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0178.html from Javascript : function isJavaAvailable(){ return ( navigator.javaEnabled &navigator.javaEnabled() ); } For an HTML solution, check this How−to

9.15 Detect if Java 1.1 (with event delegation) is available Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0179.html On some version of Netscape (eg.4.03), even if the JDK1.1 is reported as the Java version, you need to apply a special patch to upgrade to the event delegation model. Here how you can detect if the patch has been applied. function isJava11Available() { if (java.awt.event.MouseEvent) return true; else return false; }

Someone at Netscape suggests a better way to check : function isJava11Available(){ if (java.awt.event.MouseEvent == "[JavaClass java/awt/event/MouseEvent]") return true; return false; }

because Unknown Java classes are reflected as JavaPackages, for reasons related to the fact that there's no way to tell if something is a valid package.

9.16 Access Cookies from a Java Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0180.html This Applet uses the package netscape.javascript.JSObject. To compile such program, you have to include in the CLASSPATH a special jar included in the JRE 9.14 Detect if Java is enabled

installation. For Java 1.4.2 and later: add plugin.jar to your classpath when compiling. It can be found in the lib directory of your JRE installation, ex. C:\Program Files\Java\jre1.5.0\lib\plugin.jar NOTE : For Java 1.4.0/1.4.1: use jaws.jar (same directory). [HTML file (testCookie.html)] <APPLET CODE=TestCookie.class MAYSCRIPT HEIGHT=150 WIDTH=200> /APPLET/BODY/HTML

[Java applet (TestCookie.java)] import import import import

netscape.javascript.*; java.awt.*; java.awt.event.*; java.applet.*;

public class TestCookie extends Applet implements ActionListener { TextField tf1, tf2; Button b1, b2, b3;

public void init() { tf1 = new TextField(20); tf2 = new TextField(20); b1 = new Button("Write Cookie"); b2 = new Button("Read Cookie"); b3 = new Button("Delete Coookie"); setLayout(new FlowLayout()); add(tf1); add(tf2); add(b1); add(b2); add(b3); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == b1) { /* ** write a cookie ** computes the expiration date, good for 1 month */ java.util.Calendar c = java.util.Calendar.getInstance(); c.add(java.util.Calendar.MONTH, 1); String expires = "; expires=" + c.getTime().toString(); String s1 = tf1.getText() + expires; System.out.println(s1);

9.14 Detect if Java is enabled

JSObject myBrowser = JSObject.getWindow(this); JSObject myDocument = (JSObject) myBrowser.getMember("document"); myDocument.setMember("cookie", s1); } if (ae.getSource() == b2) { /* ** read a cookie */ tf2.setText(getCookie()); } if (ae.getSource() == b3) { /* ** delete a cookie, set the expiration in the past */ java.util.Calendar c = java.util.Calendar.getInstance(); c.add(java.util.Calendar.MONTH, −1); String expires = "; expires=" + c.getTime().toString(); String s1 = tf1.getText() + expires; JSObject myBrowser = JSObject.getWindow(this); JSObject myDocument = (JSObject) myBrowser.getMember("document"); myDocument.setMember("cookie", s1); } } public String getCookie() { /* ** get all cookies for a document */ try { JSObject myBrowser = (JSObject) JSObject.getWindow(this); JSObject myDocument = (JSObject) myBrowser.getMember("document"); String myCookie = (String)myDocument.getMember("cookie"); if (myCookie.length() > 0) return myCookie; } catch (Exception e){ e.printStackTrace(); } return "?"; } public String getCookie(String name) { /* ** get a specific cookie by its name, parse the cookie. ** not used in this Applet but can be useful */ String myCookie = getCookie(); String search = name + "="; if (myCookie.length() > 0) { int offset = myCookie.indexOf(search); if (offset != −1) { offset += search.length(); int end = myCookie.indexOf(";", offset); if (end == −1) end = myCookie.length(); return myCookie.substring(offset,end); } else System.out.println("Did not find cookie: "+name);

9.14 Detect if Java is enabled

} return ""; } } You can try it here.

See this text file with some useful Javascript functions for cookies handling. Check this How−to to detect if Cookies are enabled or not.

9.17 Set Applet PARAM VALUE from javascript Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0182.html PARAM VALUE can't be changed ar run−time but during layout time, javascript "entities" can be used to set calculated VALUES. In this How−to, VALUES are coming from a javascript variable, a javascript function and a javascript expression. <SCRIPT> var jsVar = "Hello World from jsVar"; function jsFnct() { return "Hello World from jsFnct"; } <<APPLET CODE ="MyApplet.class" HEIGHT=100 WIDTH=400> <param name="second" value="&{jsFnct()};"> <param name="third" value="&{'hello world'.toUpperCase() + ' from js Expression'};"> /BODY/HTML

For demonstration purpose, the MyApplet class import java.applet.*; import java.awt.*; public class MyApplet extends Applet

{

public void init() { add(new Label(getParameter("first"))); add(new Label(getParameter("second"))); add(new Label(getParameter("third"))); } } NOTE: Javascript entities are not supported in IE. The workaround is to use the document.write() method to customize the APPLET PARAM during layout time. See this How−to for an example.

9.17 Set Applet PARAM VALUE from javascript

9.18 Pass an Array between Java and Javascript Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0183.html Javascript can read directly a Java Array but the other way don't seem be true. NOTE : Reading a Java array from Javascript may crash your browser for some unknown reason. So it's safer to use the next technique! A safe and simple way is to transform the Array as a big String with a known character used a separator. From there, it's trivial to do some manipulations to retrieve the array. In the following example, the first button is used to read directly the Java array. The second button call a Java method which to transform the array as a string, then the Javascript function split() is used to retrieve the array. The third button will modify the Java array. A Javascript array is transformed with the function join() and on the Java−side, a StringTokenizer will do the rest. [Java applet] import java.awt.*; import java.applet.*; import java.util.*; public class TestJavaArray extends Applet{ public String javaArray [] = { "array 1", "array 2" , "array 3" }; public String [] getJavaArray() { return javaArray; } public String getJavaArrayAsAString() { // you need more error checking here, of course... int k; String s = ""; k = javaArray.length; s = javaArray[0]; for (int i= 1 ; i < k; i++) { s += "|" + javaArray[i] ; } return s; } public void putJavaArray(String arrayAsAString) { int i = 0; String s; StringTokenizer st = new StringTokenizer(arrayAsAString, "|"); while(st.hasMoreTokens()){ javaArray[i++] = st.nextToken(); } } }

[HTML and Javascript]

9.18 Pass an Array between Java and Javascript

<SCRIPT> function getJavaArray() { arrayFromJava = document.myApplet.getJavaArray(); alert("Java Array length = " + arrayFromJava.length + "\r\n" + "element 2 is " + arrayFromJava[1]); } function getJavaArrayAsAString() { var arrayAsAString = document.myApplet.getJavaArrayAsAString(); realJsString = arrayAsAString + ""; arrayFromJava = realJsString.split("|"); alert("Java Array length = " + arrayFromJava.length + "\r\n" + "element 2 is " + arrayFromJava[1]); } function putJavaArray() { arrayFromJs = new Array("ARRAY 1", "ARRAY 2", "ARRAY 3"); arrayAsAString = arrayFromJs.join("|"); document.myApplet.putJavaArray(arrayAsAString); }
<APPLET CODE="TestJavaArray.class" NAME="myApplet" HEIGHT=0 WIDTH=0> /APPLET/BODY/HTML

Try it here. Here an interesting piece of code submitted by M. Caetano which does basically the same thing. Note the use of regular expressions to keep the code short and compact. Since java classes are called directly by javascript, these functions won't work with IE (only with Netscape). /* COPYJAVA

(by Mike Caetano)

Array prototype method to transfer array elements between javascript and java java array arg fills this empty js array with elements from java array empty js array assigns its elements to string cast java array Use: // fill empty jsArray with the elements from the java array as strings var jsArray = []; jsArray.copyJava(javaArray) // fill a javaArray with the elements from jsArray cast as java.lang.String var javaArray2 = jsArray.copyJava()

9.18 Pass an Array between Java and Javascript

Note: doesn't include cast for netscape.javascript.JSObject − that requires a more stringent type checking ie. typeof( [object Layer] ) => netscape.javascript.JSObject − for now just don't call copyJava on an array of objects −−−−−−−−−−−−−−−−−−−−−−−−−−−− */ function copyJava(arg_) { if ( /^\bnull\b$|^\bundefined\b$|^\s?$/i.test(arg_) ) { if ( this.length > 0 ) { var temp = makeJavaArray('String',this.length); var i=0; while ( i < this.length ) { temp[i] = ''+this[i++]; } return temp; } else { return null; } } else { if ( /^\bobject\b$/i.test(typeof(arg_)) ) { if ( this.length == 0 ) { var len = java.lang.reflect.Array.getLength(arg_); var i=0; while ( i < len ) { this[i] = ''+arg_[i++]; } } } } } function makeJavaArray(type_,size_) { if ( !/^\bnull\b$|^\bundefined\b$|^\s?$/i.test(type_) ) { if ( /boolean|byte|int|long|short|double |float|char|void|String|Object|Class|Thread/.test(type_) ) { var type = type_.charCodeAt(0)<91 ? 'java.lang.' + type_: type_; var size = !isNaN(Number(size_)) ? Number(size_) : 1; return ( new java.lang.reflect.Array.newInstance (java.lang.Class.forName(type),size) ); } // else invalid cast } // else invalid args }

9.19 Interaction without LiveConnect Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0184.html Java−Javascript interaction is not possible on many browsers or platforms. On Mac, for example, the LiveConnect package is not available, even with the latest Netscape version. On IE3, the interaction is very limited too. Java to Javascript One way to pass information from Java to Javascript, without LiveConnect or scripting support, is to have an hidden frame acting as a bridge. From Java you do a showDocument() with a particuliar page passing the message as parameter to the hidden frame, something like showDocument("mypage.html?HelloJavascriptFromJava", "hiddenframe"). The mypage.html page contains a javascript script to extract the parameter received in the URL (using the 9.19 Interaction without LiveConnect

document.search property). And then the parameter extracted is send to another javascript function in the visible frame. First, define the frameset with an invisible frame. [SimpleJ2JS.HTML]

visiblepage.html contains the Applet and a javascript function. The idea is to type something in a TextField, press a Button to send a string to a javascript to do an alert() with the TextField content. [visiblepage.html] <SCRIPT> function showMessage(s) { alert(s) }

Simple Java to Javascript interaction

<APPLET CODE=SimpleApplet.class WIDTH=150 HEIGHT=150>

invisiblepage.html contains the function to extract the parameter and call the showMessage() function in the visible frame. <SCRIPT> function replace(s, t, u) { i = s.indexOf(t); r = ""; if (i == −1) return s; r += s.substring(0,i) + u; if ( i + t.length < s.length) r += replace(s.substring(i + t.length, s.length), t, u); return r; } function getAndSendMessage() { theMessage = document.location.search.substring(1,255) if (theMessage.length > 0) { // replace all '+" by space theMessage = replace(theMessage, '+', ' ') window.parent.mainFrame.showMessage(unescape(theMessage)) } }

and finally the Applet (a JDK102 style, since we want to be friendly to older browsers). [SimpleApplet.java] import java.applet.Applet; import java.awt.*;

9.19 Interaction without LiveConnect

public class SimpleApplet extends Applet { TextField aMessage; Button sendButton; public void init() { aMessage = new TextField(20); add(aMessage); sendButton = new Button("Send to Javascript"); add(sendButton); } public boolean action(Event e, Object o) { if (e.target.equals(sendButton)) { try { getAppletContext().showDocument (new java.net.URL (getCodeBase(), "invisiblepage.html?"+ java.net.URLEncoder.encode(aMessage.getText())), "scriptFrame"); } catch (Exception ex) { ex.printStackTrace(); } } return true; } } Try it here.

Javascript to Java The idea here is to have an invisible Applet in an invisible frame that will receive a message (from Javascript in the visible frame) through the search part of its URL. Then via a static pointer to the visible Applet, the invisible Applet pass the message to the visible Applet by calling the appropriate function. Frames definition [SimpleJS2J.html]

The visible page [visiblepage2.html] <SCRIPT> function send2Java() { // you may need to encode the value with the escape() function parent.invisibleFrame.location = "invisiblepage2.html?" + document.forms[0].FromJs.value }

Simple Javascript to Java interaction



9.19 Interaction without LiveConnect

<APPLET CODE=SimpleApplet2.class WIDTH=300 HEIGHT=150>

The class to hold a static pointer to SimpleApplet2. This pointer will be used by the InvisibleApplet. [SimpleAppletRegistered.java] public class SimpleAppletRegistered { static SimpleApplet2 sa; }

The SimpleApplet2 is TextField which will be used to display the message type in the HTML FORM. [SimpleApplet2.java] import java.applet.Applet; import java.awt.*; public class SimpleApplet2 extends Applet { TextField aMessage; public void init() { add(new Label("Message from Javascript ")); aMessage = new TextField(20); add(aMessage); // put a pointer to this Applet in a static // variable which can be shared with the InvisibleApplet SimpleAppletRegistered.sa = this; } public void setMessage(String msg) { aMessage.setText(msg); } }

And finally the invisible page and InvisibleApplet [invisiblepage2.html] <APPLET CODE=InvisibleApplet.class WIDTH=1 HEIGHT=1> [InvisibleApplet.java] import java.applet.Applet; public class InvisibleApplet extends Applet { public void init() { String completeURL = getDocumentBase().toString(); System.out.println("URL received : " + completeURL); int i = completeURL.indexOf("?");

9.19 Interaction without LiveConnect

if (i > −1) { String msg = completeURL.substring(completeURL.indexOf("?") + 1); // call SimpleApplet via the static pointer // you may to decode the string here with // java.net.URLDecoder.decode() method. SimpleAppletRegistered.sa.setMessage(msg); } } } Try it here. NOTE: To send a message containing spaces and other special characters like &or ?, you will need to encode the message from Javascript (with the escape function) and decode the message in Java.

With IE, you need to run this sample through a Web server.

9.20 Directory listing on the Web server in a Java Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0185.html There is no way for an Applet to retrieve a directory contents without the help of server side process(servlet/CGI). But here a way to do it with some help from Javascript. In a browser, loading a URL with no file specified will return a directory listing under the following conditions : 1. The directory doesn't contain a default page like index.html, default.htm or default.html. 2. The web server allows directory exploration. For example, the URL http://www.tactika.com/realhome/images shows a directory listing of the files in the images directory. The listing is actually a real HTML page build on the fly. Our applet will extract the links in this page and present them in a List. Links in a page are listed in the document property called links. This property can be easily transform into a String array by a Javascript function. Then the array is passed to a Java method. The Applet is very simple and can be customized to display more useful descriptions or filter some entries. We have 3 frames, 2 visibles and 1 invisible. The invisible one will contains the directory listing. Frame visible #1 is for the Applet, by doubleclicking on a line in the List, the corresponding images will be displayed in frame visble #2. Frames definitions Note that the 2 visibles frames are initially loaded with a "blank.html" to allow the third frame (the invisible one) to be loaded with the directory content (here "../images"). browse.html <SCRIPT> function reload_master() { window.master.location.href = "./selector.html";

9.20 Directory listing on the Web server in a Java Applet

} /HTML

blank.html <TITLE

When all pages are loaded, the selector.html page is loaded into the first visible frame. That page contains the Applet. During layout time, Javascript extracts links to the an Array. Via the BODY onLoad event handler, we trigger a Javascript function to transfer the Array to the Applet. selector.html <SCRIPT> var LinksLength = parent.contents.window.document.links.length var AllTheLinksAsArray = new Array() // start at the second link because // we dont want the root directory for (var i = 1; i < LinksLength ; i++) { s = parent.contents.window.document.links[i]; AllTheLinksAsArray[i] = s; } function putLinksIntoApplet() { AllTheLinksAsString = AllTheLinksAsArray.join("|"); document.Selector.insertData(AllTheLinksAsString); }

Doubleclick to view <APPLET CODE=Selector.class HEIGHT=100 WIDTH=400 NAME=Selector> /HTML

Selector.java import import import import import

java.awt.*; java.awt.event.*; java.applet.*; java.util.*; java.net.*;

public class Selector extends Applet implements ActionListener { java.awt.List l;

9.20 Directory listing on the Web server in a Java Applet

boolean okToDisplay = false; String targetFrame = ""; public void init() { setLayout(new BorderLayout()); add(l = new java.awt.List(5), "Center"); l.addActionListener(this); targetFrame = getParameter("targetFrame"); } public void actionPerformed(ActionEvent ae) { if (okToDisplay) { try { URL urlToDisplay = new URL(ae.getActionCommand()); getAppletContext().showDocument(urlToDisplay, targetFrame); } catch (Exception e) { e.printStackTrace(); } } } public void insertData(String arrayAsAString) { int i = 0; String s; StringTokenizer st = new StringTokenizer(arrayAsAString, "|"); while(st.hasMoreTokens()){ s = st.nextToken(); l.add(s); // or l.addItem(s); System.out.println(s); } okToDisplay = true; } } You can try it here. NOTE: This How−to is inspired by an article by Martin Webb on http://www.irt.org

9.21 Have a Java button close the browser window Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0282.html import import import import

java.applet.*; java.awt.*; java.awt.event.*; netscape.javascript.*;

public class WinClose extends Applet implements ActionListener{ Button wc = new Button("Close me"); public void init() { wc.setActionCommand("CLOSE"); wc.addActionListener(this); add(wc); }

9.21 Have a Java button close the browser window

public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command.equals("CLOSE")) { JSObject win = (JSObject) JSObject.getWindow(this); win.eval("self.close();"); } } }

Try it here

9.22 Detect if cookies are enabled Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0303.html The detection is made by trying to write a cookie and reading it back. The value is passed to a Java Applet by create dynamically the APPLET tag. [testcookie.html] <SCRIPT> document.write("<APPLET CODE='MyApplet.class' HEIGHT=100 WIDTH=400>"); // check if cookie are enabled cookieBackup = document.cookie document.cookie = "cookie=yep" cookieOk = document.cookie.indexOf("cookie=yep") > −1 document.cookie = cookieBackup document.write(" ");

VALUE=" + cookieOk + ">");

[MyApplet.java] import java.applet.*; import java.awt.*; public class MyApplet extends Applet

{

public void init() { add(new Label("Cookie enabled :")); add(new Label(getParameter("okToCookie"))); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

9.22 Detect if cookies are enabled

9.23 Display a page after all applets are loaded Current version of this HowTo : http://www.rgagnon.com/javadetails/../jsdetails/js−0071.html Place your page completely in a DIV tag. Initially the visible attribute is false. When the page is completely loaded, the DIV visibility attribute is set to true. <SCRIPT> function doIt() { if (document.all) mypage.style.visibility="visible" else document.mypage.visibility="visible" }

...


Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

9.23 Display a page after all applets are loaded

10 Servlet/JSP 10.1 java−jsp

10.2 Read me Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0379.html You may to take a look to these related How−to's in the EAServer/Jaguar section.

10.3 Get parameters passed to a servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0357.html
value :
import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) { // note : if "someValue" is missing a null is returned String valuePassed = req.getParameter("someValue"); res.setContentType("text/html"); java.io.PrintWriter out = res.getWriter(); out.println(""); out.println("the value is : " + valuePassed); out.println(""); } public void doGet(HttpServletRequest req, HttpServletResponse res) { doPost(req, res); } }

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10 Servlet/JSP

10.4 Detect no argument condition in a Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0341.html Servlet 2.3 int i = req.getParameterMap().size(); if (i = 0) { // no arguments } else { Enumeration paramNames = req.getParameterNames(); while(paramNames.hasMoreElements()) { String parm = (String)paramNames.nextElement(); // do something with this parm } }

Previous version of the Servlet API protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); response.setContentType( "text/html" ); out.println(""); if (!request.getParameterNames().hasMoreElements()) { // no arguments out.println("<TITLE>MyServlet (no args)"); out.println(""); out.println("

MyServlet

"); out.println("
"); out.println(" Subject"); out.println(" Recipients"); out.println(" Message"); out.println(" "); out.println("
"); } else { out.println("<TITLE>MyServlet (with args)"); out.println(""); out.println("

Servlet

"); java.util.Enumeration paramNames = request.getParameterNames(); while(paramNames.hasMoreElements()) { String parm = (String)paramNames.nextElement(); out.println(parm + " = " + request.getParameter(parm) + "
"); } out.println(""); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.4 Detect no argument condition in a Servlet

10.5 Set a Cookie from a servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0358.html import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) { res.addCookie(new Cookie("mycookie_name", "mycookie_value")); } public void doGet(HttpServletRequest req, HttpServletResponse res) { doPost(req, res); } }

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.6 Read a Cookie from a servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0359.html import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doPost (HttpServletRequest req, HttpServletResponse res) { Cookie[] theCookies = request.getCookies(); if (theCookies != null) { java.io.PrintWriter out = res.getWriter(); for (int i =0; i
If you find this article useful, consider making a small donation to show your support for this Web site and its content.

10.5 Set a Cookie from a servlet

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.7 Delete (or expire) a Cookie from a servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0360.html import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) { Cookie cookie = new Cookie ("myCookie", "theCookieValue"); // Expire in five minutes (5 * 60) cookie.setMaxAge( 300 ); // Expire after the browser is closed // cookie.setMaxAge( −1 ); // Expire right now // cookie.setMaxAge( 0 ); } public void doGet(HttpServletRequest req, HttpServletResponse res) { doPost(req, res); } }

10.8 Ask for a password from a Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0342.html public void askPassword(HttpServletResponse response) { response.setStatus(response.SC_UNAUTHORIZED); response.setHeader("WWW−Authenticate", "BASIC realm=\"protected−area\""); }

then the browser will popup a dialog for username/password

10.9 Talk to a CGI/Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0082.html 10.7 Delete (or expire) a Cookie from a servlet

From the client point of view, there is no difference talking to CGI or Servlet. There is two ways to send a request to a CGI. The GET method contains encoded parameters in the URL. A typical URL talking to CGI using the GET method would be: new URL("http://www.server.com/cgi−bin/acgi.pl?name=real);

Here we calling a script called aCGI.pl (a PERL script) passing the parameters name and site. Parameters are encoded, spaces are changed to "+" and special character to hexadecimal using a 3−letter escape sequence. Each parameter is delimited by the character "Habitually the encoding is done through the static method encode of the java.net.URLencoder class. String theCGI = "http://www.server.com/cgi−bin/aCGI.pl?"; String encoded = "name=" + URLencoder.encode("Real Gagnon"); URL cgiurl = new URL(thecgi + encoded);

Once the URL is constructed, you call the CGI using the showDocument method (Applet). getAppletContext().showDocument(cgiurl);

The CGI will process the result and produce a page to be displayed. The POST method allows the programmer to manipulate the data received from the CGI. First a connection is made to the CGI, an OutputStream is open to send the parameters (if any). Then InputStream is created to receive the result. String theCGI = "http://www.server.com/cgi−bin/aCGI.pl"; String encoded = "name=" + URLencoder.encode("Real Gagnon"); URL CGIurl = new URL(theCGI); URLConnection c = CGIurl.openConnection(); c.setDoOutput(true); c.setUseCaches(false); c.setRequestProperty("content−type","application/x−www−form−urlencoded"); DataOutputStream out = new DataOutputStream(c.getOutputStream()); out.writeBytes(encoded); out.flush(); out.close(); BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()); String aLine; while ((aLine = in.readLine()) != null) { // data from the CGI System.out.println(aLine); }

You can't do some output then some input and do again some output. You must do all the output and then the input. There is no "dialog" between the client and the server. The client make a request and the server send back the result and close the connection.

10.10 Test for Cookies Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0374.html

10.10 Test for Cookies

import javax.servlet.*; import javax.servlet.http.*; public class Test4Cookies extends HttpServlet { private private private private

static static static static

final final final final

Cookie String String String

cookie = new Cookie( "hello" , "world" ); paramName = "foo"; successURI = "/success.htm"; failureURI = "/failure.htm";

public void doPost(HttpServletRequest req, HttpServletResponse res) { if ( req.getParameter( paramName ) == null ) { res.addCookie( cookie ); res.sendRedirect(req.getRequestURI() +"?"+ paramName +"=bar" ); } else { res.sendRedirect (( req.getCookies().length == 0 ) ? failureURI : successURI ) } public void doGet(HttpServletRequest req, HttpServletResponse res) { doPost(req, res); } }

10.11 Display ResultSet data in an HTML Table in Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0378.html private int dumpData(java.sql.ResultSet rs, java.io.PrintWriter out) throws Exception { int rowCount = 0; out.println("

"); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); // table header out.println(""); for (int i = 0; i < columnCount; i++) { out.println(""); } out.println(""); // the data while (rs.next()) { rowCount++; out.println(""); for (int i = 0; i < columnCount; i++) { out.println(""); } out.println(""); } out.println("
" + rsmd.getColumnLabel(i + 1) + "
" + rs.getString(i + 1) + "

"); return rowCount; }

10.11 Display ResultSet data in an HTML Table in Servlet

10.12 Specify the filename to be used for a file sent by a Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0387.html Say that your servlet called ""/servlet/GetFile" send back a file to a client request. That file needs to be saved by the client. If you do nothing, the browser will suggest "GetFile" as the filename. To specify the correct filename String filename = "abc.dat" ; File textFile = new File(filename); response.setHeader("Content−length",Integer.toString(textFile.length())); response.setHeader("Content−type","application/octetstream"); response.setHeader("Content−disposition","inline; filename=" + filename ); // open the file and write it in the OutputStream NOTE: For PDF output, see this HowTo If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.13 Pass information to another servlet/jsp Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0401.html You set attributes on your request object and then forward the request object to the other servlet/jsp. For a simple string request.setAttribute("foo", "Real's HowTo");

A parameter received by the first servlet to the second one String requestVar = request.getParameter("sitename"); request.setAttribute("foo", requestVar);

A Bean MyBean myBean = new MyBean(); myBean.setFooProperty("Real's HowTo"); request.setAttribute("foo", myBean);

Then you forward the request RequestDispatcher dispatch = request.getRequestDispatcher("next.jsp"); dispatch.forward(request, response);

10.12 Specify the filename to be used for a file sent by a Servlet

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.14 Handle PDF output Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0404.html • Set the content−type of the response to "application/pdf", ex. response.setContentType("application/pdf"); • Add a dummy parameter on the end of the url, like: http://x.y.z/DoGenCompStmt?filename=dummy.pdf because IE ignores content−types, so you need to give it a hint, and the ".pdf" extension is an easy way. • Set the "content−length" on the response, otherwise the Acrobat Reader plugin may not work properly, ex. response.setContentLength(bos.size()); • An additional thing that seems to help some IE browsers is to also have : response.setHeader("Content−Disposition", "inline;filename=somepdf.pdf"); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.15 Detect if the connection is via a secure channel Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0415.html Use the servlet request's isSecure() or getAuthType() methods. Or you look at these HTTP headers : CERT_KEYSIZE , CERT_KEYSIZE, HTTPS_KEYSIZE Note: for a javascript solution see this HowTo If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.16 In a Servlet, check if Form Field is present Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0443.html public isDefined(HttpServletRequest req, String fieldNameToSearchFor) { return req.getParameterMap().containsKey(fieldNameToSearchFor); }

10.14 Handle PDF output

If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.17 Get the root dir of a web app Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0519.html In a JSP String path = application.getRealPath("/");

In a Servlet String path = getServletContext.getRealPath("/"); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.18 Get client IP address from JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0363.html <% out.print( request.getRemoteAddr() ); out.print( request.getRemoteHost() ); %>

You may not get the real client IP if a the client is behind a proxy, you will get the IP of the proxy and not the client. However, the proxy may include the requesting client IP in a special HTTP header. <% out.print( request.getHeader("x−forwarded−for") ); %>

10.19 Output a binary stream from a JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0366.html You can't. From JSP, only character stream should be used. 10.17 Get the root dir of a web app

JSP pages were designed for *text* output. The "out" object is a Writer, which means it will play games with text encoding. For binary output, like PDF or dynamically generated GIF, it's a better idea to use a servlet. Having said that, since a JSP will be converted to a servlet, it's possible to modifed the output stream. [image.jsp] <%@ page import="java.io.*" %> <%@ page import="java.net.*" %> <%@page contentType="image/gif" %><% OutputStream o = response.getOutputStream(); InputStream is = new URL("http://myserver/myimage.gif").getInputStream(); byte[] buf = new byte[32 * 1024]; // 32k buffer int nRead = 0; while( (nRead=is.read(buf)) != −1 ) { o.write(buf, 0, nRead); } o.flush(); o.close();// *important* to ensure no more jsp output return; % Thanks to Benjamin Grant for the bug fix.

10.20 Use a connection cache from JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0380.html Jaguar provides a very useful cache mechanism to speed up database requests. You can have ODBC, JDBC or Oracle cached connections. NOTE: Java component can't use cached ODBC connection, you need to use a cached JDBC connection. If there is no JDBC driver available, it's still possible to use the ODBC−JDBC provided by Sun. But performance of such a bridge is poor and the reliability is not good in a multi−threaded environment.

To define a cache using ODBC−JDBC (bridge) connection, follow these steps: 1. Define a regular System DSN (through the ODBC Administration panel) 2. In jaguar, you define the cache : 1. General Tab : Server name = jdbc:odbc:YourSystemDSNName with user/pwd 2. Driver Tab : DLL or class name = sun.jdbc.odbc.JdbcOdbcDriver with JDBC radio button selected 3. Cache Tab : checkbox cache−by−name checked <%@page contentType="text/html"%> JSP Page <%@ page import="java.sql.*" %> <% com.sybase.jaguar.jcm.JCMCache jcmCache= null;

10.20 Use a connection cache from JSP

java.sql.Connection dbConn = null; String jcmCacheString = "mycachename"; String msg = ""; try { jcmCache = com.sybase.jaguar.jcm.JCM.getCacheByName(jcmCacheString); dbConn = jcmCache.getConnection(com.sybase.jaguar.jcm.JCMCache.JCM_WAIT); Statement stmt = dbConn.createStatement(); ResultSet rs = stmt.executeQuery ("select msg from messages where msgid='00001'"); if(rs != null) { while(rs.next()) { msg = rs.getString("msg"); } } rs.close(); dbConn.close(); } catch (Exception e) { out.println("OUPS " + e.getMessage() + "
"); } %> msgtext = <%= msg %>

Instead of hard−coding the cache name into your java component, make the name available through a Property (of the Environment) of the Web application. This way your components are more flexible and you are using the "J2EE way" to make a connection. In this example, myconnection contains the cache name to be used. javax.naming.InitialContext ctx = new javax.naming.InitialContext(); javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("java:comp/env/jdbc/myconnection"); java.sql.Connection con = ds.getConnection(); java.sql.PreparedStatement stmt = con.prepareStatement(sql); java.sql.ResultSet rs = stmt.executeQuery(); while (rs.next()) { //do something } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998−2005 [ home ]

10.21 Read a Web Application property Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0381.html

10.21 Read a Web Application property

Web Application properties are defined in the WEB−INF/web.xml deployment descriptor (in between the <webapp> tag) <env−entry> <env−entry−name>docPath <env−entry−value>c:/doc/doc1 <env−entry−type>java.lang.String <env−entry> <env−entry−name>docUser <env−entry−value>net1 <env−entry−type>java.lang.String

Then from your JSP or Servlet, Context env = (Context) new InitialContext().lookup("java:comp/env"); String docBase = (String) env.lookup("docPath"); String docBaseUser = (String) env.lookup("docUser");

10.22 Use EJB from JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0396.html EJB with constructor with no parameter <jsp:useBean id="myBean" scope="session" class="com.company.MyBean"/>

EJB with constructor with parameters <% com.company.MyBean bean=new com.company.MyBean(1, 2, 3, 4); session.putAttribute("myBean", bean); %>

10.23 Define a method in a JSP page Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0410.html <%! public String sayHello(){ return "Hello"; } %>

<%= sayHello() %>

10.22 Use EJB from JSP

10.24 Precompile JSP pages Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0414.html Some JSP containers (as per section 8.4.2 of the JSP 1.2 specification) support the capability of precompiling a JSP page. To precompile a JSP page, access the page with a query string of ?jsp_precompile http://hostname.com/mywebapp/mypage.jsp?jsp_precompile

The JSP page will not be executed. If the container supports precompilation, the JSP page will be compiled if necessary. Here a JSP page that will scan the current directory (and subdirectories) to precompile all JSP found. <%@ <%@ <%@ <%@

page page page page

contentType="text/html;charset=UTF−8" language="java" %> import="javax.servlet.*"%> import="javax.servlet.http.*,javax.servlet.jsp.*"%> import="java.util.Set,java.util.Iterator,java.io.IOException"%>

<%! private void compileAllJsps (PageContext pageContext, JspWriter out, HttpServletRequest request,HttpServletResponse response, String uripath) throws IOException, ServletException { Set set = pageContext.getServletContext().getResourcePaths(uripath); for (Iterator iter = set.iterator(); iter.hasNext();) { String uri = (String) iter.next(); if (uri.endsWith(".jsp")) { out.write("
  • "+ uri +"
  • "); out.flush(); RequestDispatcher rd = getServletContext().getRequestDispatcher(uri); if (rd == null) { throw new Error(uri +" − not found"); } rd.include(request, response); } else if (uri.endsWith("/")) { compileAllJsps(pageContext, out, request, response, uri); } } } %> Precompiling *.JSPs

    Precompiling *.JSPs:

      <% HttpServletRequest req = new HttpServletRequestWrapper(request) { public String getQueryString() { // can be "jsp_precompile=true" return "jsp_precompile"; }; };

      10.24 Precompile JSP pages

      compileAllJsps(pageContext, out, req, response, "/"); %>

    Done.

    NOTE: Many Application servers provide an utility to precompile JSP pages (ex. EAServer, BEAWLS). Check for a JSPC command file.

    10.25 Get a list of directories for JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0417.html

    Directories

      <% String root="c:/Repository/WebApplication/mydocs/javadoc/"; java.io.File file; java.io.File dir = new java.io.File(root); String[] list = dir.list(); if (list.length > 0) { for (int i = 0; i < list.length; i++) { file = new java.io.File(root + list[i]); if (file.isDirectory()) { %>
    • " target="_top"><%=list[i]%>
      <% } } } %>
    If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.26 Use and share a class in JSP pages Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0508.html I have a class public class Hello { public String say() { return "Hello"; } }

    and I need to use it in many JSP pages using 10.25 Get a list of directories for JSP

    <%= say() %>

    They are many to achieve that goal : • Create a Java class with the method in it, compile it, and deploy the resulting .class file(s) in your webapp's WEB−INF/class directory. <% Hello h = new Hello(); out.print(h.say()); %>

    • Create a JAR file containing the .class file(s) and deploy the resulting JAR file via your webapp's WEB−INF/lib directory. <% Hello h = new Hello(); out.print(h.say()); %>

    • Create a tag library for it, deploy it via the webapp's WEB−INF/tld directory. TAG source code TAG source code : package test; import java.io.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class HelloTag extends TagSupport { public int doStartTag() throws JspException { try { pageContext.getOut().println("Hello"); } catch (IOException e) { } return SKIP_BODY; } }

    the resulting class should go in the WEB−INF/class directory. TLD configuration (in the WEB−INF/tlds as hello.tld) hello test.HelloTag

    and to use the tag <%@ taglib prefix="ht" uri="WEB−INF/tlds/hello.tld" %> ...

    • Create the desired method at the top of the page and copy it from page to page <%! public static String say() {

    10.25 Get a list of directories for JSP

    return "Hello"; } %>

    • Create an "include file" (say hello.inc), place the method noted above in it, and include it at the top of each JSP page <%@ include file="hello.inc" %> If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.27 Get the root dir of a web app Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0519.html In a JSP String path = application.getRealPath("/");

    In a Servlet String path = getServletContext.getRealPath("/"); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.28 Launch an applet from a JSP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0534.html The jsp:plugin tag will generate the right html code to load your Applet. <jsp:plugin type="applet" code="TestApplet.class" width="500" height="300"> <jsp:params> <jsp:param name="message" value="Hello, world"/> <jsp:param name="action" value="<%=AppletAction%>"/> <jsp:fallback>

    unable to start plugin

    If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    10.27 Get the root dir of a web app

    Written and compiled by Réal Gagnon ©1998−2006 [ home ]

    10.29 Prevent caching of a JSP output Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0590.html You will need to set the appropriate HTTP header attributes. <% response.setHeader("Cache−Control","no−cache"); response.setHeader("Pragma","no−cache"); response.setDateHeader ("Expires", −1); %>

    However, cache handling is tricky with IE brower. See http://support.microsoft.com/kb/q222064/. By adding a second HEAD is supposed to solve the problem! <% response.setHeader("Cache−Control","no−cache"); response.setHeader("Pragma","no−cache"); response.setDateHeader ("Expires", −1); %> my page body <META HTTP−EQUIV="PRAGMA" CONTENT="NO−CACHE"> <META HTTP−EQUIV="Expires" CONTENT="−1">

    NOTE: Pragma: no−cache prevents caching only when used over a secure connection, Expires: −1 should do the job over unsecure conection. See also this HowTo and this one.

    10.30 Call another EJB Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0384.html InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("MyPackage/MyEJB"); MyEJBHome home = (MyEJBHome) PortableRemoteObject.narrow(objref, MyEJBHome.class);

    10.29 Prevent caching of a JSP output

    return (MyEJB) home.create();

    10.31 Keep java files generated from JSP (BEA WLS) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0446.html Set the 'keepgenerated' parameter in weblogic.xml to 'true' <jsp−descriptor> <jsp−param> <param−name> keepgenerated <param−value> true

    or, with weblogic.jar in the classpath, java weblogic.jspc −keepgenerated Your.jsp If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.32 Get the server version (BEA WLS) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0447.html <%@page import = "weblogic.common.internal.VersionInfo"%> ... <%VersionInfo serverVersion = VersionInfo.theOne();%> ... %=serverVersion.getImplementationVersion()%

    or from the command line java −cp weblogic.jar weblogic.version Thanks to Frederic Close for the tip! If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.31 Keep java files generated from JSP (BEA WLS)

    10.33 Quickly create a Web application with BEA WLS Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0449.html To create a web application without an EAR or WAR, follow these steps : 1. Open a Shell window in %BEA%\user_projects\domains\[mydomain]\applications 2. Run this script : ..\setenv.cmd 3. Type this command : md testapp 4. Type this command : md testapp\WEB−INF 5. Run this program : java weblogic.marathon.ddinit.WebInit testapp and that's all. To configure your new application, run this program java weblogic.marathon.Main testapp If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.34 Nicely display WEB.XML informations Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0451.html A web.xml file contains informations about a web application hosted by a application server. While it's possible to consult the data using a regular text editor, it maybe easier to use a special stylesheet to nicely format the data for easy browsing. I found a nice generic stylesheet on the Web and adapted it a little bit for that purpose. Here the modified xsl file, the css file, a sample web.xml. See the sample output if your browser supports XML/XSL transformation. Attach the xsl to the xml by adding this line to the xml file : ...

    or do the transformation in Java, for a hint see this How−to. Here an ASP page (yeah I know...) which accepts as a parameter an XML filename and transforms the passed filename using the XSL. As an added bonus, the original XML filename is displayed (you will need this XSL). <META http−equiv="Content−Type" content="text/html; charset=ISO8859−1"> <%@ LANGUAGE="JScript" %> <% Response.buffer = true; var xmlfile;

    10.33 Quickly create a Web application with BEA WLS

    var var var var var var

    oXML; oXSL; oXSLTemplate; oXSLProcessor; SrcXSL; SrcXML;

    // get the PARAM=??? (assumes you have used GET request method!)... // assume something like http://.../docxml.asp?xmlfile=myxml.xml xmlfile = '' + Request.QueryString('xmlfile'); // get the source file (XML and XSL) paths SrcXML = Server.MapPath(xmlfile); SrcXSL = Server.MapPath('xmldoc/tree−view2.xsl'); // create documents for the XML and XSL... oXML = Server.CreateObject('Msxml2.DOMDocument'); oXSL = Server.CreateObject('Msxml2.FreeThreadedDOMDocument'); // load the XML and XSL into your documents... // we don't want to waste time validating the file oXSL.load(SrcXSL); oXML.validateOnParse = false ; oXML.async = false ; oXML.resolveExternals = false ; oXML.load(SrcXML); // create the XSL template and processor... oXSLTemplate = Server.CreateObject('Msxml2.XSLTemplate'); oXSLTemplate.stylesheet = oXSL; oXSLProcessor = oXSLTemplate.createProcessor; // place the ?xmlfile=xxx value into the XSL processor... oXSLProcessor.addParameter('xmlfile',xmlfile,''); // tell the XSL processor of the XML you want to have transformed... oXSLProcessor.input = oXML; try { oXSLProcessor.transform ; Response.write(oXSLProcessor.output); } catch (e) { Response.write ('The file ' +e.url + ' is not valid. Reason: ' + e.reason ); } % If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    10.35 Reverse the CLASSLOADER order (BEA) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0551.html 10.35 Reverse the CLASSLOADER order (BEA)

    By default, Weblogic loads a class by asking the parent classloader to load the required class. This can be a problem, if you have a JAR version in the server LIB directory and your web app requires an another version. ref : WebLogic Server Application Classloader Overview To make sure that your web app will use the JAR located in its WEB−INF\LIB, create a file called weblogic.xml in the WEB−INF directory with the content : <weblogic−web−app> <prefer−web−inf−classes>true

    10.36 Detect change in JSP and recompile (BEA) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0562.html By default, if you deployed an application in exploded mode, BEA WLS doesn't recompile a modified JSP. You change this behaviour by adding this directive in a weblogic.xml configuration file. <jsp−descriptor> <jsp−param> <param−name>page−check−seconds <param−value>60

    page−check−seconds sets the interval, in seconds, at which WLS checks to see if JSP files have changed and need recompiling. Dependencies are also checked and recursively reloaded if changed. If set to 0, pages are checked on every request. If set to −1, page checking and recompiling is disabled.

    Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

    10.36 Detect change in JSP and recompile (BEA)

    11 Language 11.1 java−language

    11.2 * Read me * Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0290.html If you have difficulty to find what you are your are looking for, try do use search on this site using Google. Enter your search terms www.rgagnon.com

    Web

    Submit search form If you can't find then you may want to look at these other sites : Java Glossary Many subjects covered in depth. The Java Developers Almanac 1.4 (exampledepot.com) Contains many code examples. Sun Developers Online Community You need to register first (free). Be sure to search the forums first before asking a question because regular posters can be a little bit rude if you don't! Stack Overflow A site where you can ask question (not restricted to Java), really innovative in the way it works. Participants are really cool. Also check out my Java links page. Usenet's newgroups are very useful too. Check out the comp.lang.java.* groups on your favorite Usenet newserver. Specialized server from vendors can be accessed to obtain support : • forums.sybase.com Easerver and Powerbuilder • news.gmane.org Netbeans, look for the hierarchy gmane.comp.java.netbeans.* • news.eclipse.org

    11 Language

    Eclipse, need to ask for username first at http://www.eclipse.org/newsgroups/register.php. • news.mozilla.org Mozilla • msnews.microsoft.com Microsoft • news.software.ibm.com IBM (WebSphere) • newsgroups.bea.com BEA WebLogic

    11.3 Obtain from where a Class is loaded Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0300.html public class LoadingFromWhere { public static void main(String args[]){ LoadingFromWhere s = new LoadingFromWhere(); s.doit(); } public void doit() { System.out.println(this.getClass().getName() + " is loaded from " + getClass().getProtectionDomain().getCodeSource().getLocation()); MyClass s = new MyClass(); } } class MyClass { MyClass() { System.out.println (this.getClass().getName() + " is loaded from " + this.getClass().getProtectionDomain().getCodeSource().getLocation()); } }

    The output >java LoadingFromWhere LoadingFromWhere is loaded from file:/C:/temp/ MyClass is loaded from file:/C:/temp/

    Other technique (doesn't work with jar) public class FromWhere { public static void main(String args[]){ Class theClass = FromWhere.class; java.net.URL u = theClass.getResource(""); System.out.println("This class (FromWhere) is located at : " + u); }

    11.3 Obtain from where a Class is loaded

    }

    The output > java FromWhere This class (FromWhere) is located at : file:/C:/temp/

    See these related HowTo's : 1 2

    11.4 Get the class name in a static method Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0402.html public class ClassFromStatic { public static void main(java.lang.String[] args) { someStaticMethod(); } public static void someStaticMethod() { System.out.println ("I'm in " + new CurrentClassGetter().getClassName() + " class"); } public static class CurrentClassGetter extends SecurityManager { public String getClassName() { return getClassContext()[1].getName(); } } }

    11.5 Get the current method name Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0420.html JDK1.4 public class MyTest { public static void main(String args[]) { new MyTest().doit(); } public void doit() { System.out.println (new Exception().getStackTrace()[0].getMethodName()); } }

    The output doit

    JDK1.5 11.4 Get the class name in a static method

    While the above snippet is not bad, it is expensive since we need to create an Exception. With JDK1.5, a new technique is available. public class Test { public static void main(String args[]) { trace(Thread.currentThread().getStackTrace()); new Test().doit(); trace(Thread.currentThread().getStackTrace()); } public void doit() { trace(Thread.currentThread().getStackTrace()); doitagain(); } public void doitagain() { trace(Thread.currentThread().getStackTrace()); } public static void trace(StackTraceElement e[]) { boolean doNext = false; for (StackTraceElement s : e) { if (doNext) { System.out.println(s.getMethodName()); return; } doNext = s.getMethodName().equals("getStackTrace"); } } } main doit doitagain main

    To get the calling method public class Test { public static void main(String args[]) { new Test().doit(); } public void doit() { System.out.println( Thread.currentThread().getStackTrace()[3].getMethodName()); } }

    See also this HowTo. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.6 Call a method dynamically (Reflection) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0031.html 11.6 Call a method dynamically (Reflection)

    import java.lang.reflect.*; import java.io.*; public class TestReflect { public static void main(String s[]) throws Exception{ String aClass; String aMethod; // we assume that called methods have no argument Class params[] = {}; Object paramsObj[] = {}; while (true) { aClass = lineInput("\nClass : "); aMethod = lineInput("Method: "); // get the Class Class thisClass = Class.forName(aClass); // get an instance Object iClass = thisClass.newInstance(); // get the method Method thisMethod = thisClass.getDeclaredMethod(aMethod, params); // call the method System.out.println (thisMethod.invoke(iClass, paramsObj).toString()); } /* Output examples: Class : Class1 Method: class1Method2 ### Class 1, Method2 ### Class : java.util.Date Method: toString Sat Aug 11 13:18:39 EDT 2007 Class : java.util.Date Method: getTime 1186852732140 */ }

    public static String lineInput (String prompt) throws IOException { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); System.out.print(prompt); return input.readLine(); } } class Class1 { public String class1Method1() { return "*** Class 1, Method1 ***"; } public String class1Method2() { return "### Class 1, Method2 ###"; } }

    The next example calls a class method with 2 arguments : import java.lang.reflect.*;

    11.6 Call a method dynamically (Reflection)

    public class TestReflect { public static void main(String[] args) throws Exception { TestReflect.invoke("Class1", "say", new Class[] {String.class, String.class}, new Object[] {new String("Hello"), new String("World")}); /* output : Hello World */ } public static void invoke (String aClass, String aMethod, Class[] params, Object[] args) throws Exception { Class c = Class.forName(aClass); Method m = c.getDeclaredMethod(aMethod, params); Object i = c.newInstance(); Object r = m.invoke(i, args); } } class Class1 { public void say( String s1, String s2) { System.out.println(s1 + " " + s2); } }

    11.7 Detect if a package is available Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0422.html public class ClassUtils { public static void main(String args[]) { System.out.println ("Swing " + (ClassUtils.isAvailable("javax.swing.JComponent")?"present":"absent")); System.out.println ("JAI " + (ClassUtils.isAvailable("javax.media.jai.ImageJAI")?"present":"absent")); System.out.println ("SAX " + (ClassUtils.isAvailable("org.xml.sax.XMLReader")?"present":"absent")); System.out.println ("ImaginaryClass " + (ClassUtils.isAvailable("imaginary.ImaginaryClass")?"present":"absent")); System.out.println ("Java3d " + (ClassUtils.isJava3dAvailable()?"present":"absent")); /* output : Swing present JAI absent SAX present ImaginaryClass absent Java3d absent */ } public static boolean isAvailable(String className) { boolean isFound = false; try {

    11.7 Detect if a package is available

    Class.forName(className, false, null); isFound = true; } catch (ClassNotFoundException e) { isFound = false; } return isFound; } public static boolean isJava3dAvailable() { return isAvailable("javax.media.j3d.View"); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.8 Create an object from a string Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0351.html import java.lang.reflect.*; Class [] classParm = null; Object [] objectParm = null; try { String name = "com.rgagnon.MyClass"; Class cl = Class.forName(name); java.lang.reflect.Constructor co = cl.getConstructor(classParm); return co.newInstance(objectParm); } catch (Exception e) { e.printStackTrace(); return null; }

    Another example, but this time we are passing a parameter to the constructor and calling a method dynamically. public class Test { public static void main(String args[]) { try { String name = "java.lang.String"; String methodName = "toLowerCase"; // get String Class Class cl = Class.forName(name); // get the constructor with one parameter java.lang.reflect.Constructor constructor = cl.getConstructor (new Class[] {String.class}); // create an instance

    11.8 Create an object from a string

    Object invoker = constructor.newInstance (new Object[]{"REAL'S HOWTO"}); // the method has no argument Class arguments[] = new Class[] { }; // get the method java.lang.reflect.Method objMethod = cl.getMethod(methodName, arguments); // convert "REAL'S HOWTO" to "real's howto" Object result = objMethod.invoke (invoker, (Object[])arguments); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } } }

    11.9 Get a variable value from the variable name Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0038.html import java.lang.reflect.*; public class ReflectUtils {

    public static void main(String[] args) throws Exception{ TestClass test = new TestClass(); System.out.println (ReflectUtils.getValueOf(test,"firstValue")); System.out.println (ReflectUtils.getValueOf(test,"secondValue")); System.out.println (ReflectUtils.getValueOf(test,"thirdValue")); /* output : 3.1416 42 Hello world */ } public static Object getValueOf(Object clazz, String lookingForValue) throws Exception { Field field = clazz.getClass().getField(lookingForValue); Class clazzType = field.getType(); if (clazzType.toString().equals("double")) return field.getDouble(clazz); else if (clazzType.toString().equals("int")) return field.getInt(clazz); // else other type ... // and finally return field.get(clazz);

    11.9 Get a variable value from the variable name

    } } class TestClass public double public int public String }

    { firstValue = 3.1416; secondValue = 42; thirdValue = "Hello world";

    11.10 Make methods that have unspecified number of parameters Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0289.html You pass an array of Objects. public class Howto { public static void main(String args[]) { Howto howto = new Howto(); howto.myMethod ( new Object[] {"value 1", new Integer(2), "value n"} ); } public void myMethod(Object parms[]) { for (int i=0; i < parms.length; i++) System.out.println(parms[i]); } }

    NOTE : In JDK1.5, we have VARARGS parameters so this not needed anymore! public class TestIt { public static void main(String args[]) { TestIt.doit ( "value 1", new Integer(2), "value n" ); /* output : value 1 2 value n */ } public static void doit(Object ... parms) { for(Object parm:parms) { System.out.println(parm); } } } public class TestIt { public static void main(String ... args) { for(String arg:args) { System.out.println(arg); }

    11.10 Make methods that have unspecified number of parameters

    } /* output : >java TestIt 1 2 3 how−to 1 2 3 how−to */ }

    11.11 Create a java source dynamically, compile and call Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0039.html import java.io.*; import java.util.*; import java.lang.reflect.*; public class MakeTodayClass { Date today = new Date(); String todayMillis = Long.toString(today.getTime()); String todayClass = "z_" + todayMillis; String todaySource = todayClass + ".java"; public static void main (String args[]){ MakeTodayClass mtc = new MakeTodayClass(); mtc.createIt(); if (mtc.compileIt()) { System.out.println("Running " + mtc.todayClass + ":\n\n"); mtc.runIt(); } else System.out.println(mtc.todaySource + " is bad."); } public void createIt() { try { FileWriter aWriter = new FileWriter(todaySource, true); aWriter.write("public class "+ todayClass + "{"); aWriter.write(" public void doit() {"); aWriter.write(" System.out.println(\""+todayMillis+"\");"); aWriter.write(" }}\n"); aWriter.flush(); aWriter.close(); } catch(Exception e){ e.printStackTrace(); } } public boolean compileIt() { String [] source = { new String(todaySource)}; ByteArrayOutputStream baos= new ByteArrayOutputStream(); new sun.tools.javac.Main(baos,source[0]).compile(source); // if using JDK >= 1.3 then use // public static int com.sun.tools.javac.Main.compile(source); return (baos.toString().indexOf("error")==−1);

    11.11 Create a java source dynamically, compile and call

    } public void runIt() { try { Class params[] = {}; Object paramsObj[] = {}; Class thisClass = Class.forName(todayClass); Object iClass = thisClass.newInstance(); Method thisMethod = thisClass.getDeclaredMethod("doit", params); thisMethod.invoke(iClass, paramsObj); } catch (Exception e) { e.printStackTrace(); } } }

    11.12 Launch an application from another application Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0394.html While you can exec("java myaotherapp"), it is more appropriate to instanciate and called the main method of the other application. For example, take this simple application : public class Program2 { public static void main(String arg[]) { System.out.println("Hello from Program2"); } }

    To call the above application from another public class Program1a { public static void main(String arg[]) { System.out.println("Hello from Program1a"); new Thread(){ public void run() { Program2.main(new String[]{});} }.start(); } }

    The above example is used when the class is hard−coded. The dynamic version is little more tricky. public class Program1b { public static void main(String arg[]) { System.out.println("Hello from Program1b"); new Program1b().execute("Program2"); } public void execute(String name) {

    11.12 Launch an application from another application

    Class params[] = {String[].class}; // if you need parameters // String[] args = new String[] { "Hello", "world" }; // Class params[] = new Class[] { args.getClass() }); try { Class.forName(name). getDeclaredMethod("main", params). invoke(null, new Object[] {new String[] {}}); } catch(Exception e){ e.printStackTrace();} } }

    Launch many programs using Thread and use join() to wait for the completion. [Program2.java] public class Program2 { public static void main(String arg[]) { System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); System.out.println("Hello from Program2"); } } [Program1a.java] public class Program1a { public static void main(String arg[]) throws Exception{ System.out.println("Hello from Program1a"); Thread t1 = new Thread(){ public void run() { Program2.main(new String[]{});} }; t1.start(); t1.join(); System.out.println("Hello from Program1a"); } }

    The output : C:\>java Program1a Hello from Program1a Hello from Program2 Hello from Program2 Hello from Program2 Hello from Program2 Hello from Program1a

    11.13 Access the enclosing class from an inner class Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0037.html public class TestIt { public static void main(String a[]){ new TestIt().doit(); /* output :

    11.13 Access the enclosing class from an inner class

    Hello world! */ } public void doit() { new InnerClass().sayHello(); } public void enclosingClassMethod(){ System.out.println("Hello world!"); }

    class InnerClass { public void sayHello() { TestIt.this.enclosingClassMethod(); } } }

    or public class TestIt { TestIt testItClass = this; public static void main(String a[]){ new TestIt().doit(); /* output : Hello world! */ } public void doit() { new InnerClass().sayHello(); } public void enclosingClassMethod(){ System.out.println("Hello world!"); } class InnerClass { public void sayHello() { testItClass.enclosingClassMethod(); } } }

    11.14 Access inner class from outside Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0425.html public class TestIt { public static void main(String[] args) { Outer outer = new Outer(); outer.new Inner().hello(); /* output : Hello from Inner() */

    11.14 Access inner class from outside

    } } class Outer { public class Inner { public void hello(){ System.out.println("Hello from Inner()"); } } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.15 Use globally defined constants Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0040.html Via a class This technique is useful for constants defined on a corporate level. They are very generic by nature. The CONSTANT class is included in the classpath. public class CONSTANT public static final public static final public static final }

    { integer SUCCESS = 1; integer FAILURE = −1; integer NOTFOUND = 0;

    Since the members of the class are defined as "static", there is no need to instantiate the class. To use a constant, simply use CONSTANT.[constant name] if (myMethod()==CONSTANT.SUCCESS) { ...; } else { ...; }

    Via an interface This technique can be used if the constants are not really global but especially designed to be used in a specific application for example. An application−level class needs to implement the interface to be able to see the constant definitions. public interface APPCONSTANT public static final String public static final String public static final String }

    { APPNAME = "The Super APP"; APPVERSION = "version 1.0"; DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    then to use a constant, simply implement the interface public class TheAppFrame extends Frame implements APPCONSTANT {

    11.15 Use globally defined constants

    TheAppFrame { ... setTitle(APPNAME); ... } ... }

    NOTE : This is not considered as good practice (depending on who you are talking to!) to use an interface this way. NOTE: By convention, constant name are always in CAPITALS. JDK1.5 JDK1.5 import statement can be used to import only static member from a class. import static java.lang.Math.*; public class DemoImport { public static void main(String[] args) { double x = 16.0; System.out.println(abs(x)); System.out.println(PI); // instead of System.out.println(Math.abs(x)); // System.out.println(Math.PI); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.16 Serialize an Object Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0042.html To serialize an object, it must implements the Serializable interface. The object needs 2 functions with these signatures private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

    Many standard Java objects already implements the Serializable interface so there is almost nothing to do. In the following snippet, we use a Vector to simulate a Queue. First the Queue state is saved to a file.

    11.16 Serialize an Object

    Then rename main to main_serialize and main_reload to main and compile. Now the snippet read the file to reload the Queue from the data previously saved. import java.util.Vector; import java.io.*; public class Queue extends Vector { /* ** FIFO */ Queue() { super(); } void put(Object o) { addElement(o); } Object get() { if (isEmpty()) return null; Object o = firstElement(); removeElement(o); return o; } Object peek() { if (isEmpty()) return null; return firstElement(); } public static void main(String args[]) { Queue theQueue; theQueue = new Queue(); theQueue.put("element 1"); theQueue.put("element 2"); theQueue.put("element 3"); theQueue.put("element 4"); System.out.println(theQueue.toString()); // serialize the Queue System.out.println("serializing theQueue"); try { FileOutputStream fout = new FileOutputStream("thequeue.dat"); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(theQueue); oos.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main_load(String args[]) { Queue theQueue; theQueue = new Queue(); // unserialize the Queue System.out.println("unserializing theQueue"); try { FileInputStream fin = new FileInputStream("thequeue.dat"); ObjectInputStream ois = new ObjectInputStream(fin); theQueue = (Queue) ois.readObject(); ois.close();

    11.16 Serialize an Object

    } catch (Exception e) { e.printStackTrace(); } System.out.println(theQueue.toString()); } }

    Note : See this How−to to serialize using XML format. If you need to serialize and manipulate huge objects, take a look at this open−source project. joafip( java data object persistence in file ) at http://joafip.sourceforge.net.

    11.17 Serialize an Object over a socket Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0043.html From the client side, you open a Socket and then oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(someObject);

    On the server side, you use the ObjectInputStream.readObject method. NOTE: If the OutputStream is kept open and you modify your object and resend it, you will not see a change on the server side. That's because Java keeps objects sent in an internal cache and the old version will be taken in account instead of the new one. The fix is to do an ObjectOutputStream.reset() before re−sending the object or open a new connection each time.

    11.18 Easily remove my debugging code Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0130.html Unlike a C/C++ compiler, there is no JAVA compiler directive to exclude certain source code parts from compilation. By making the release version of a class smaller, the loading process will faster. Without editing the source to remove the debugging codes, you can rely on the simple optimization that the JAVA compiler always do. If a if expression is always false, the code in the if statement will not be included in the compilation. Not only the resulting class will be smaller, but the execution time will be a little faster too by not making unnecessary test. The technique is simple. In the development environment, you have a class called Debug. public class Debug { public static final boolean RELEASE = true; }

    In your source, when you need some debugging codes, you included them in a if statement like 11.17 Serialize an Object over a socket

    if (Debug.RELEASE) { System.out.println("The value of i is " + i); }

    During compilation, since Debug.RELEASE is always true, the code will be present. In the production environment, the Debug class looks like this: public class Debug { public static final boolean RELEASE = false; }

    When compiling in that environment, the debugging code will be absent from the class file since Debug.release is always false. Another way is to simply close the out stream. (System.out.println() will be present in your class but the output is disabled).

    public class TestOut { public TestOut() { } public static void main(String s[]) { System.out.close(); // may want System.err.close() too for (int i=0; i <100000; i++){ System.out.print(".");} } }

    11.19 Have a singleton Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0355.html A singleton is a class that can be instantiated only one time in a JVM. Repeated calls always return the same instance. public class OnlyOne{ private static OnlyOne one = new OnlyOne(); private OnlyOne(){} public static OnlyOne getInstance() { return one; } }

    To use it OnlyOne myOne = OnlyOne.getInstance(); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.19 Have a singleton

    11.20 Multiple expressions in for loops Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0316.html You do it "à la C". public class MultipleFor{ public static void main (String [] args){ for (int i=0, j=0; i < 10; i++, j−−) System.out.println ("i = " + i + " j= " + j); } }

    11.21 Handle the List conflict Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0372.html The List interface is declared in the java.util package and the List class is in the java.awt package. So if both import are defined in your source you won't be able to compile properly because this will cause a name conflict. The solution is to fully qualify the name used when you reference the List class or interface. import java.util.*; import java.awt.*; ... java.awt.List myAwtList = new java.awt.List(); ... If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.22 Use a generic toString() Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0432.html A nice idea is to put this toString() into a base class so all the descendents inherit from it. public class generictostring { String hello = "world"; int i = 42; public static void main(String args []) { System.out.println(new generictostring().toString()); // generictostring{i=42, hello=world} }

    11.20 Multiple expressions in for loops

    public String toString() { java.util.Hashtable h = new java.util.Hashtable(); Class cls = getClass(); java.lang.reflect.Field[] f = cls.getDeclaredFields(); java.lang.reflect.AccessibleObject.setAccessible(f, true); //jdk1.2 for (int i = 0; i < f.length; i++) { try { h.put(f[i].getName(),f[i].get(this)); } catch (IllegalAccessException e) { e.printStackTrace(); } } if (cls.getSuperclass().getSuperclass() != null) { h.put("super", super.toString()); } return cls.getName() + h; } }

    Christian Ullenboom wrote: Hi, your solution is fine, but has some drawbacks: − it based on inheritance − an attribute of a subclass cannot overlap an attribute of a superclass (because of hashtable) So I changed your solution a bit: // @author Christian Ullenboom // @url http://java−tutor.com import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.util.ArrayList; class ToStringHelper { public static String toString( Object o ) { ArrayList list = new ArrayList(); toString( o, o.getClass(), list ); return o.getClass().getName().concat( list.toString() ); } private static void toString( Object o, Class clazz, ArrayList list ) { Field f[] = clazz.getDeclaredFields(); AccessibleObject.setAccessible( f, true ); for ( int i = 0; i < f.length; i++ ) { try { list.add( f[i].getName() + "=" + f[i].get(o) ); } catch ( IllegalAccessException e ) { e.printStackTrace(); } } if ( clazz.getSuperclass().getSuperclass() != null ) toString( o, clazz.getSuperclass(), list ); } } class Ober { int i = 123; private double d = 3.1415; } public class ToStringHelperTest extends Ober {

    11.20 Multiple expressions in for loops

    String hello = "world"; int i = 42; public static void main(String args[]) { Ober t = new ToStringHelperTest(); System.out.println( ToStringHelper.toString(t) ); // ToStringHelperTest[hello=world, i=42, i=123, d=3.1415] } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.23 Use Object.clone() Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0433.html Consider the following example. import java.util.Date; class MyData { private Date aDate; MyData() { aDate = new Date(); } public Date getDate() { return aDate; } public void setdate(Date d) { aDate = d; } } public class DemoClone { public static void main(String args[]) { MyData mydata = new MyData(); Date d = mydata.getDate(); System.out.println(d); d.setTime(1000); System.out.println(d); System.out.println(mydata.getDate()); // Sat Apr 19 23:17:43 EDT 2003 // Wed Dec 31 19:00:01 EST 1969 // Wed Dec 31 19:00:01 EST 1969 which is no good } }

    Even if aDate is declared as private, it is possible to modify because a Date object is mutable and we have a reference to it. The solution is to return a copy of aDate, so even if you have reference to 11.23 Use Object.clone()

    it, any modification will be done on the copy, not the original. import java.util.Date; class MyData { private Date aDate; MyData() { aDate = new Date(); } public Date getDate() { return (Date)aDate.clone(); } public void setdate(Date d) { aDate = d; } } public class DemoClone { public static void main(String args[]) { MyData mydata = new MyData(); Date d = mydata.getDate(); System.out.println(d); d.setTime(1000); System.out.println(d); System.out.println(mydata.getDate()); // Sat Apr 19 23:17:43 EDT 2003 // Wed Dec 31 19:00:01 EST 1969 // Sat Apr 19 23:17:43 EDT 2003 which is good } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.24 Static field, constructor and exception Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0444.html Consider the following class public class Foo { private static Bar b = new Bar(); ... } class Bar { public Bar ( ) throws Exception { } }

    11.24 Static field, constructor and exception

    it will not compile because Bar() is declared to throw an exception. To solve this situation, use a static block. public class Foo { static Bar bar ; static { try { bar = new Bar() ; } catch ( Exception e ) { e.printStackTrace() ; } } } class Bar { public Bar ( ) throws Exception { } }

    If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.25 Use a Label break Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0500.html Labelled breaks allow breaking out of several levels of nested loops inside a pair of curly braces. This way, you can almost simulate a GOTO! class JavaGoto { public static void main(String args[]) { int max = 10; int limit = 5; int j = 0; out: { for( int row=0; row< max; row++ ) { for( int col=0; col< max; col++ ) if( row == limit) break out; j += 1; } } System.out.println(j); // output 5 } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.25 Use a Label break

    11.26 Put printStackTrace() into a String Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0537.html public class TestException { public static void main(String args[]) { try { throw new Exception("for no reason!"); } catch (Exception e) { e.printStackTrace(); } }2 // output : // java.lang.Exception: for no reason! // at TestException.main(TestException.java:8) }

    You redirect the StackTrace to a String with a StringWriter/PrintWriter : import java.io.PrintWriter; import java.io.StringWriter; public class TestException { public static void main(String args[]) { try { throw new Exception("for no reason!"); } catch (Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); System.out.println(sw.toString().toUpperCase()); } } // output : // JAVA.LANG.EXCEPTION: FOR NO REASON! // AT TESTEXCEPTION.MAIN(TESTEXCEPTION.JAVA:7) }

    This can be useful if you want to format the StackTrace before showing it to the user. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2006 [ home ]

    11.27 Use a Hashtable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0027.html Hashtables are very useful for maintaining a 1−to−1 relationship between Objects. With an arbitary key, you can retrieve easily an Object. In the following example, we retrieve a String array with a String. 11.26 Put printStackTrace() into a String

    String[] array1 = {"A","B","C"}; String[] array2 = {"X","Y","Z"}; String[] array3 = {"1","2","3"}; Hashtable arrays = new Hashtable(); arrays.put("Array1", array1); arrays.put("Array2", array2); arrays.put("Array3", array3); String[] resultArray = (String[])(arrays.get("Array2")); System.out.println (resultArray[0] + ", " + resultArray[1] + ", " + resultArray[2]);

    11.28 Scan the content of a hashtable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0032.html Enumeration keys = hash.keys(); while( keys.hasMoreElements() ) { Object key = keys.nextElement(); Object value = hash.get(key); }

    11.29 Sort an array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0008.html [ArraySorter.java] JDK1.1 public class ArraySorter { /* ** Sort in the same array */ public static void sort(Object[] a, Comparer comparer) { sort(a, null, 0, a.length − 1, true, comparer); } /* ** Sort a and b, using a as the reference */ public static void sort(Object[] a, Object[] b, int from, int to, boolean ascending, Comparer comparer) { // No sort if (a == null || a.length < 2) return; // sort using Quicksort int i = from, j = to; Object center = a[ (from + to) / 2 ]; do { if (ascending) { while( (i < to) &(comparer.compare( center, a[i]) > 0) ) i++; while( (j > from) &(comparer.compare(center, a[j]) < 0) ) j−−; }

    11.28 Scan the content of a hashtable

    else { // Decending sort while( (i < to) &(comparer.compare( center, a[i]) < 0) ) i++; while( (j > from) &(comparer.compare(center, a[j]) > 0) ) j−−; } if (i < j) { // Swap elements Object temp = a[i]; a[i] = a[j]; a[j] = temp; // Swap in b array if needed if (b != null) { temp = b[i]; b[i] = b[j]; b[j] = temp; } } if (i <= j) { i++; j−−; } } while(i <= j); // Sort the rest if (from < j) sort(a, b, from, j, ascending, comparer); if (i < to) sort(a, b, i, to, ascending, comparer); } public static interface Comparer { /** * The interface implementation should compare the two * objects and return an int using these rules: * if (a > b) return > 0; * if (a == b) return 0; * if (a < b) return < 0; */ public int compare(Object a, Object b); } }

    [testArraySorter.java] public class testArraySorter { public static final ASCIIComparer asciiComparer = new ASCIIComparer(); public static void main(String args[]) { if (args.length == 0) System.out.println("give me some args to sort"); else { ArraySorter.sort(args, asciiComparer); for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } } public static class ASCIIComparer implements ArraySorter.Comparer { public int compare(Object a, Object b) { return ((String)a).compareTo((String)b); } } }

    JDK1.4 case−sensitive String[] myArray = new String[] {"foo","bar","baz"}; java.util.Arrays.sort(myArray);

    11.28 Scan the content of a hashtable

    case−insensitive String[] myArray = new String[] {"foo","Bar","baz"}; java.util.Arrays.sort(myArray, java.text.Collator.getInstance());

    11.30 Initialize multidimensional array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0036.html Simply use braces... static double[][] Rates = { {0.50, 0.70, 0.40, 0.60}, {0.50, 1.10, 0.50, 0.80}, {0.80, 1.60, 0.70, 1.20}, {1.50, 2.90, 1.20, 2.10}, {2.50, 4.90, 2.00, 3.30}, {4.60, 8.50, 3.20, 5.00}, {6.40,11.00, 4.10, 6.00} };

    11.31 Get array upperbound Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0280.html class ArrayLength { public static void main(String args[]) { String[][] data = new String[3][4]; System.out.println("Dimension 1: " + data.length); System.out.println("Dimension 2: " + data[0].length); } }

    To get the number of dimensions : class ArrayDim { public static void main(String args[]) { String[][] data = new String[3][4]; System.out.println("This array has " + getDim(data) + " dimensions"); // expected output : // "This array has 2 dimensions" } public static int getDim(Object array ) { int dim=0; Class c = array.getClass(); while( c.isArray() ) { c = c.getComponentType(); dim++; } return( dim ); } }

    11.30 Initialize multidimensional array

    If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.32 Convert a String to an array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0368.html NOTE: This HowTo was designed for JDK 1.0.2. Starting with version 1.4, the String class offers a better way to split a String into an Array. It's the String.split(regexp) method. See this HowTo. Thanks to T. GUIRADO

    public String[] stringtoArray( String s, String sep ) { // convert a String s to an Array, the elements // are delimited by sep StringBuffer buf = new StringBuffer(s); int arraysize = 1; for ( int i = 0; i < buf.length(); i++ ) { if ( sep.indexOf(buf.charAt(i) ) != −1 ) arraysize++; } String [] elements = new String [arraysize]; int y,z = 0; if ( buf.toString().indexOf(sep) != −1 ) { while ( buf.length() > 0 ) { if ( buf.toString().indexOf(sep) != −1 ) { y = buf.toString().indexOf(sep); if ( y != buf.toString().lastIndexOf(sep) ) { elements[z] = buf.toString().substring(0, y ); z++; buf.delete(0, y + 1); } else if ( buf.toString().lastIndexOf(sep) == y ) { elements[z] = buf.toString().substring (0, buf.toString().indexOf(sep)); z++; buf.delete(0, buf.toString().indexOf(sep) + 1); elements[z] = buf.toString();z++; buf.delete(0, buf.length() ); } } } } else { elements[0] = buf.toString(); } buf = null; return elements; }

    To transform back to String public String arrayToString(String s[], String sep) { int k;

    11.32 Convert a String to an array

    String result = ""; k = s.length; if (k > 0) { result = s[0]; for (int i= 1 ; i < k; i++) { result += sep + s[i] ; } } return result; }

    11.33 Sort in reverse order Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0428.html Arrays.sort (myArray, Collections.reverseOrder()); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.34 Resize an array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0431.html Arrays cannot be resized dynamically. If you want a dynamic data structure with random access, you use a Collection (Map, ArrayList,...). If you need to expand, you can use System.arraycopy() method to copy the content of an array to another one. import java.lang.reflect.Array; public class ArrayUtils { public static void main (String arg[]) { String s[] = new String[20]; System.out.println("The s array length is " + s.length); // 20 s = (String[])ArrayUtils.expand(s); System.out.println("The s array length is " + s.length); // 30 int i[] = {1 ,2 ,3, 4}; System.out.println("The i array length is " + i.length); // 4 i = (int[])ArrayUtils.expand(i); System.out.println("The i array length is " + i.length); // 6 } public static Object expand(Object a) { Class cl = a.getClass(); if (!cl.isArray()) return null; int length = Array.getLength(a);

    11.33 Sort in reverse order

    int newLength = length + (length / 2); // 50% more Class componentType = a.getClass().getComponentType(); Object newArray = Array.newInstance(componentType, newLength); System.arraycopy(a, 0, newArray, 0, length); return newArray; } }

    But a better way is to use a Vector or an ArrayList. ArrayList is roughly equivalent to Vector, except that it is unsynchronized. import java.util.ArrayList; public class ArrayListDemo { public static void main (String arg[]) { ArrayListDemo x = new ArrayListDemo(); x.doit1(); x.doit2(); } public void doit1() { // single dimension ArrayList list = new ArrayList(); list.add("a"); list.add("b"); int size = list.size(); // 2 System.out.println("Array 1 " +list.get(0); }

    // a

    public void doit2() { // multi dimensions ArrayList list = new ArrayList(); ArrayList l1 = new ArrayList(); l1.add("a"); ArrayList l2 = new ArrayList(); l2.add("b"); ArrayList l3 = new ArrayList(); l3.add("c"); list.add(l1); list.add(l2); list.add(l3); int size1 = list.size(); // 3 int size2 = ((ArrayList)list.get(0)).size(); System.out.println("Array 2 " + ((ArrayList)list.get(1)).get(0)); // b }

    // 1

    } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.35 Dump array content Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0465.html 11.35 Dump array content

    Convert the array to a List and then convert to String. This technique works only with classes and not with primitives like int or double. public class Test { public static void main(String args[]) { String s[] = {"a", "b", "c", "d"}; System.out.println(java.util.Arrays.asList(s).toString()); // output // [a, b, c, d] } }

    JDK1.5 java.utils.Arrays provides new ways to dump the content of an array. It's even possible to dump muti−dimensional arrays. public class Test { public static void main(String args[]) { String s[] = {"a", "b", "c", "d"}; double d [][]= { {0.50, 0.70, 0.40, 0.60}, {0.50, 1.10, 0.50, 0.80} }; System.out.println(java.util.Arrays.toString(s)); System.out.println(java.util.Arrays.deepToString(d)); // output // [a, b, c, d] // [[0.5, 0.7, 0.4, 0.6], [0.5, 1.1, 0.5, 0.8]] } }

    You can also use the new shorthand notation to iterate through an array : public class Test { public static void main(String args[]) { String s[] = {"a", "b", "c", "d"}; for (String element : s) System.out.println(element); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.36 Initialize a static array Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0475.html import java.util.*; import java.io.*; class InitStaticArray {

    11.36 Initialize a static array

    static Integer[] integerArray; static { integerArray= new Integer[] { new Integer(1), new Integer(2), new Integer(3), new Integer(4), }; } public static void main(String args[]) { for (int i=0; i
    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.37 Sort an Hashtable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0478.html Data in hashtable are not sorted. We extract the keys and sort them. import java.util.*; public class HashtableTest { static String[] array1 = {"C","B","A"}; static String[] array2 = {"1","2","3"}; public static void main(String args[]) { Hashtable h = new Hashtable(); h.put(array1[0], array2[0]); h.put(array1[1], array2[1]); h.put(array1[2], array2[2]); // unsorted keys output Iterator it = h.keySet().iterator(); while (it.hasNext()) { String element = (String)it.next(); System.out.println(element + " " + (String)h.get(element)); } System.out.println("============"); // sorted keys output thanks to T. GUIRADO for the tip! Vector v = new Vector(h.keySet()); Collections.sort(v); it = v.iterator(); while (it.hasNext()) { String element = (String)it.next();

    11.37 Sort an Hashtable

    System.out.println( element + " " + (String)h.get(element)); } /* output : A 3 C 1 B 2 ============ A 3 B 2 C 1 */ } }

    NOTE : When possible always use an HashMap instead of an Hashtable. Since Hashtable methods are synchronized they are slower than those in HashMap. See this Howto. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    11.38 Eliminate "[unchecked] unchecked call ..." compiler warning Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0521.html import java.util.*; public class ArrayListGeneric { public static void main(String[] args) { ArrayList data = new ArrayList(); data.add("hello"); data.add("world");

    Iterator<String> it = data.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }

    When compiling the above class, the compiler (jdk1.5) emits the following warnings : C:\ArrayListGeneric.java:21: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList data.add("hello"); ^ C:\ArrayListGeneric.java:22: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList data.add("world"); ^

    11.38 Eliminate "[unchecked] unchecked call ..." compiler warning

    C:\ArrayListGeneric.java:25: warning: [unchecked] unchecked conversion found : java.util.Iterator required: java.util.Iterator Iterator it = data.iterator(); ^ 3 WARNINGS

    Since there are only warnings, your class is ready to run but ... it's not bad idea to eliminate the warnings in production code. Simply add the expected type (between < and >) after the class. import java.util.*; public class ArrayListGeneric { public static void main(String[] args) { ArrayList<String> data = new ArrayList<String>(); data.add("hello"); data.add("world");

    Iterator<String> it = data.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }

    In JDK 1.6, it will be possible to insert a special annotation to suppress this kind of warning, something like : import java.util.*; public class ArrayListGeneric { @SuppressWarnings("unchecked") public static void main(String[] args) { ArrayList data = new ArrayList(); data.add("hello"); data.add("world");

    Iterator it = data.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }

    A complete list of possible @SuppressWarnings parameters can be found at http://mindprod.com/jgloss/annotations.html.

    11.38 Eliminate "[unchecked] unchecked call ..." compiler warning

    12 ANT When compiling with ANT, you see the following output : [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with −Xlint:unchecked for details.

    but it's not easy to see the details of those unsafe operations. To add the −Xlint, you need to use the compilerarg tag in the javac task definition. Something like <mkdir dir="${bin}"/> <mkdir dir="${lib}"/> <javac srcdir="${src}" destdir="${bin}" includeAntRuntime="no" classpathref="lib.path" debug="${compile.debug}">

    12.1 Sort on many fields Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0520.html We want to sort a Collection of Person objects based on their LastName and Firstname. First the Person class class Person implements Comparable { String firstName, lastName; public Person(String f, String l) { this.firstName = f; this.lastName = l; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String toString() { return "[ firstname=" + firstName + ",lastname=" + lastName + "]"; } public int compareTo(Object obj) { Person emp = (Person) obj; int deptComp = firstName.compareTo(emp.getFirstName());

    12 ANT

    return ((deptComp == 0) ? lastName.compareTo(emp.getLastName()) : deptComp); } public boolean equals(Object obj) { if (!(obj instanceof Person)) { return false; } Person emp = (Person) obj; return firstName.equals(emp.getFirstName()) &lastName.equals(emp.getLastName()); } }

    then we need a class to implement the Comparable interface. It's in there where we put the logic behind the sorting. import java.util.Comparator; class PersonComparator implements Comparator{ public int compare(Object obj1, Object obj2) { Person emp1 = (Person) obj1; Person emp2 = (Person) obj2; int nameComp = emp1.getLastName().compareTo(emp2.getLastName()); return ((nameComp == 0) ? emp1.getFirstName().compareTo(emp2.getFirstName()) : nameComp); } }

    To test it : import import import import import

    java.util.ArrayList; java.util.Arrays; java.util.Collections; java.util.List; java.util.Iterator;

    public class TestSort { public static void main(String args[]) { String Smith[] = { "Real", "Vincent", "Nathalie", "Christine" }; String Simpsons[] = { "Bart", "Lisa", "Marge", "Homer", "Maggie" }; ArrayList names = new ArrayList(); // do the smith for(int i = 0 ; i < Smith.length ; i ++) { Person one = new Person(Smith[i],"Smith"); names.add(one); } // do the simpsons for(int i = 0 ; i < Simpsons.length ; i ++) { Person one = new Person(Simpsons[i],"Simpsons"); names.add(one); } System.out.println("BEFORE:"); Iterator iter1 = names.iterator(); while (iter1.hasNext()) {

    12 ANT

    System.out.println(iter1.next()); } // now sort everything Collections.sort(names, new PersonComparator()); System.out.println("AFTER:"); Iterator iter2 = names.iterator(); while (iter2.hasNext()) { System.out.println(iter2.next()); } /* output : BEFORE: [ firstname=Real,lastname=Smith] [ firstname=Vincent,lastname=Smith] [ firstname=Nathalie,lastname=Smith] [ firstname=Christine,lastname=Smith] [ firstname=Bart,lastname=Simpsons] [ firstname=Lisa,lastname=Simpsons] [ firstname=Marge,lastname=Simpsons] [ firstname=Homer,lastname=Simpsons] [ firstname=Maggie,lastname=Simpsons] AFTER: [ firstname=Bart,lastname=Simpsons] [ firstname=Homer,lastname=Simpsons] [ firstname=Lisa,lastname=Simpsons] [ firstname=Maggie,lastname=Simpsons] [ firstname=Marge,lastname=Simpsons] [ firstname=Christine,lastname=Smith] [ firstname=Nathalie,lastname=Smith] [ firstname=Real,lastname=Smith] [ firstname=Vincent,lastname=Smith] */ } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.2 Optimize Collection usage Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0553.html From Usenet, (a post by ""Ed") a post to demonstrate that depending on your need, choosing the right Collection implementation can be really important. In the demonstration, we read a huge text file war−and−peace.txt and then count the duplicated words. as you can see depending on the Collection used, the execution time is very different! import java.util.*; import java.io.*; class TestCollectionPerformance {

    12.2 Optimize Collection usage

    private static String TEXT_BOOK_NAME = "war−and−peace.txt"; public static void main(String[] args) { try { String text = readText(); // Read text into RAM countDuplicateWords(text, new HashSet<String>()); countDuplicateWords(text, new TreeSet<String>()); countDuplicateWords(text, new ArrayList<String>()); countDuplicateWords(text, new LinkedList<String>()); } catch (Throwable t) { System.out.println(t.toString()); } } private static String readText() throws Throwable { BufferedReader reader = new BufferedReader(new FileReader(TEXT_BOOK_NAME)); String line = null; StringBuffer text = new StringBuffer(); while ((line = reader.readLine()) != null) { text.append(line + " "); } return text.toString(); } private static void countDuplicateWords(String text, Collection<String> listOfWords) { int numDuplicatedWords = 0; long startTime = System.currentTimeMillis(); for (StringTokenizer i = new StringTokenizer(text); i.hasMoreElements();) { String word = i.nextToken(); if (listOfWords.contains(word)) { numDuplicatedWords++; } else { listOfWords.add(word); } } long endTime = System.currentTimeMillis(); System.out.println(numDuplicatedWords + " duplicated words. " + "Using " + listOfWords.getClass().getName() + ", time = " + (endTime − startTime) + "ms."); } }

    Result : 522396 522396 522396 522396

    duplicated duplicated duplicated duplicated

    words. words. words. words.

    Using Using Using Using

    java.util.HashSet, time = 453ms. java.util.TreeSet, time = 1031ms. java.util.ArrayList, time = 100937ms. java.util.LinkedList, time = 129375ms.

    • A Set offers a collection of unique elements. • An HashSet maintains its collection in an unordered manner. • A TreeSet keeps the elements in the collection in sorted order. • A List provides ordered access (by index), but it doesn't guarantee uniqueness. • The ArrayList provides a collection backed by an array. It provides quick indexed access to its elements, and works best when elements are only added and removed at the end. To make this happen, ArrayList performs an internal move operation when an element is added or removed. 12.2 Optimize Collection usage

    The LinkedList is best when add and remove operations happen anywhere, not only at the end. LinkList doesn't do an internal move operation for an element insert or remove, it just manipulates reference pointers. But LinkedList's added flexibility comes at an added cost −− it results in much slower indexed operations. ref : Sun's Java tech Tips Feb2003

    12.3 Sort an HashMap Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0561.html Sort based on the keys Map yourMap= new HashMap(); // put some tuples in yourMap ... Map sortedMap = new TreeMap(yourMap);

    Sort based on the values HashMap yourMap = new HashMap(); // put some tuples in yourMap ... // to hold the result HashMap map = new LinkedHashMap();

    List yourMapKeys = new ArrayList(yourMap.keySet()); List yourMapValues = new ArrayList(yourMap.values()); TreeSet sortedSet = new TreeSet(yourMapValues); Object[] sortedArray = sortedSet.toArray(); int size = sortedArray.length; for (int i=0; i<size; i++) { map.put (yourMapKeys.get(yourMapValues.indexOf(sortedArray[i])), sortedArray[i]); }

    To iterate your new Sorted Map Set ref = map.keySet(); Iterator it = ref.iterator(); while (it.hasNext()) { String file = (String)it.next(); }

    12.4 Get a key from value with an HashMap Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0564.html [Java 5] 12.3 Sort an HashMap

    public static Object getKeyFromValue(HashMap hm,Object value){ for(Object o:hm.keySet()){ if(hm.get(o).equals(value)) { return o; } } return null; }

    [Java 1.4] public static Object getKeyFromValue(HashMap hm,Object value){ Set ref = hm.keySet(); Iterator it = ref.iterator(); while (it.hasNext()) { Object o = it.next(); if(o.equals(value)) { return o; } } return null; }

    12.5 Iterate a Collection and remove an item Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0619.html You get an exception if while scanning a Collection, you decide to remove an item. import java.util.ArrayList; public class Simple { public static void main(String args[]) { ArrayList<String> list = new ArrayList<String>(); list.add("Bart"); list.add("Lisa"); list.add("Marge"); list.add("Barney"); list.add("Homer"); list.add("Maggie"); for(String s: list) { if (s.equals("Barney")) { list.remove("Barney"); } System.out.println(s); } } /* output : Bart Lisa Marge Barney

    12.5 Iterate a Collection and remove an item

    Exception in thread "main" java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(Unknown Source) at java.util.AbstractList$Itr.next(Unknown Source) at com.rgagnon.howto.Simple.main(Simple.java:20) */ }

    The trick is to use an Iterator and remove the item with Iterator.remove() import java.util.ArrayList; import java.util.Iterator; public class Simple { public static void main(String args[]) { ArrayList<String> list = new ArrayList<String>(); list.add("Bart"); list.add("Lisa"); list.add("Marge"); list.add("Barney"); list.add("Homer"); list.add("Maggie"); for (Iterator<String> iter = list.iterator(); iter.hasNext();) { String s = iter.next(); if (s.equals("Barney")) { iter.remove(); } else { System.out.println(s); } } for(String s: list) { System.out.println(s); } } /* output : Bart Lisa Marge Homer Maggie Bart Lisa Marge Homer Maggie */ }

    12.6 Count distinct elements in a Vector Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0377.html 12.6 Count distinct elements in a Vector

    • Submitted by T GUIRADO /** ** This method counts distinct elements from a given position in vector ** containing series of element. ** Arguments : source = vector containing the vectors of elements ** position = which element to search, first position = 0 ** count = serie length ** ** ex : ** source = A,B,C D,E,F D,F,G ** length is 3 ** from position 0 in each series we have A,D,D ** this method returns 2 because there are 2 distinct elements (A and D) ** from position 2 in each series we have C,F,G ** this method returns 2 because there are 3 distinct elements (C,FandG) **/ protected synchronized int countDistinctElements (Vector source,int position,int count){ Vector v = null; for (int i = 0 ; i < source.size() ; i++) { boolean isFound = false; if ( i % count == position ) { if ( null != v ) { for (int j = 0 ; j < v.size() ; j++) { if ( source.elementAt(i).equals(v.elementAt(j) ) ) { isFound = true; j = v.size(); } } } if ( !isFound ) { if ( null == v ) v = new Vector(1, 1); v.addElement( (String)source.elementAt(i) ); } i += count − position; } } try { return v.size(); } catch ( Exception e ) {return 0;} }

    Submitted by bdobby2000 protected static int countDistinctElements ( Vector source, int position, int count ) throws IllegalArgumentException , IndexOutOfBoundsException { List list = source.subList(position, position+count); Set set = new HashSet(); set.addAll(list); return set.size(); } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.6 Count distinct elements in a Vector

    12.7 Dump the content of a Collection (JDK 1.5) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0628.html public class DumpCollection { public static void main(String[] args) { java.util.ArrayList theSimpsons = new java.util.ArrayList(); theSimpsons.add("Bart"); theSimpsons.add("Lisa"); theSimpsons.add("Marge"); theSimpsons.add("Barney"); theSimpsons.add("Homer"); theSimpsons.add("Maggie"); for (String character: theSimpsons) { System.out.println(character); } } }

    12.8 Use an INI file (properties) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0024.html In Java, configuration file are stored in properties file. By convention, the filename extension is props or properties. The structure is very similar to Windows INI file with except that there is no [...] section. [Props file : user.props] # this a comment ! this a comment too DBuser=anonymous DBpassword=DBlocation=bigone

    [JAVA code] import java.util.*; import java.io.*; class ReadProps { public static void main(String args[]) { ReadProps props = new ReadProps(); props.doit(); } public void doit() { try{ Properties p = new Properties(); p.load(new FileInputStream("user.props"));

    12.7 Dump the content of a Collection (JDK 1.5)

    System.out.println("user = " + p.getProperty("DBuser")); System.out.println("password = " + p.getProperty("DBpassword")); System.out.println("location = " + p.getProperty("DBlocation")); p.list(System.out); } catch (Exception e) { System.out.println(e); } } }

    Since the Properties class extends the Hashtable, we can manipulate the Properties through the get and put methods. The modified data can be saved back to a file with the save method. This can be useful to store user preferences for example. Note that the order is not preserved. import java.util.*; import java.io.*; class WriteProps { public static void main(String args[]) { WriteProps props = new WriteProps(); props.doit(); } public void doit() { try{ Properties p = new Properties(); p.load(new FileInputStream("user.props")); p.list(System.out); // new Property p.put("today", new Date().toString()); // modify a Property p.put("DBpassword","foo"); FileOutputStream out = new FileOutputStream("user.props"); p.save(out, "/* properties updated */"); } catch (Exception e) { System.out.println(e); } } }

    This ok with an application but you can't do it from an Applet since you can't write directly on the server without some kind of a server−side process. To read a Properties file via an Applet, load the Properties files this way : p.load((new URL(getCodeBase(), "user.props")).openStream());

    A Properties file stored in a JAR can be loaded this way : URL url = ClassLoader.getSystemResource("/com/rgagnon/config/system.props"); if (url != null) props.load(url.openStream());

    See also this HowTo, this one and finally this one too!

    12.7 Dump the content of a Collection (JDK 1.5)

    12.9 Load a properties file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0434.html public class LoadProps { public static void main(String args[]) throws Exception{ h.doit(); h.doitagain(); } public void doit() throws Exception{ // properties in the classpath java.util.Properties props = new java.util.Properties(); java.net.URL url = ClassLoader.getSystemResource("myprops.props"); props.load(url.openStream()); System.out.println(props); } public void doitagain() throws Exception{ // properties in the startup directory java.util.Properties props = new java.util.Properties(); String path = getClass().getProtectionDomain().getCodeSource(). getLocation().toString().substring(6); java.io.FileInputStream fis = new java.io.FileInputStream (new java.io.File( path + "\\myprops.props")); props.load(fis); System.out.println(props); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.10 Accentuated characters in Properties/ResourceBundle file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0492.html The rules are • Only use ISO Latin 1 characters in the Properties/ResourceBundle files • For other characters use the \u.... notation • To avoid having to type all the \u... notation manually, use the native2ascii tool (included with the SDK). If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.9 Load a properties file

    12.11 Have a multi−line value in a properties file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0503.html You add a slash ("\") to continue the value on the next line. Take the following properties file : [props.properties] prop1=first line of prop1 \ second line of prop1\ third line of prop1 prop2=first line of prop2 \n \ second line of prop2 \n \ third line of prop2

    A program to read the properties file : [Hello.java] public class Hello { public static void main(String args[]) throws Exception{ Hello h = new Hello(); h.doit(); } public void doit() throws Exception{ // properties in the classpath java.util.Properties props = new java.util.Properties(); java.net.URL url = ClassLoader.getSystemResource("props.properties"); props.load(url.openStream()); System.out.println("prop1 :\n " + props.get("prop1")); System.out.println("prop2 :\n " + props.get("prop2")); } }

    The output >java Hello prop1 : first line of prop1 second line of prop1third line of prop1 prop2 : first line of prop2 second line of prop2 third line of prop2 If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.12 Use XML with Properties Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0578.html import java.util.*;

    12.11 Have a multi−line value in a properties file

    import java.io.*; class XMLProps { public static void main(String args[]) { new XMLProps().doit(); } public void doit() { try{ Properties p = new Properties(); p.put("today", new Date().toString()); p.put("user", "Bob"); FileOutputStream out = new FileOutputStream("user.props"); p.storeToXML(out,"props updated"); FileInputStream in = new FileInputStream("user.props"); p.loadFromXML(in); p.list(System.out); /* output : −− listing properties −− today=Thu Aug 09 22:45:11 EDT 2007 user=Bob */ } catch (Exception e) { e.printStackTrace(); } } }

    The XML looks like <properties> props updated <entry key="user">Bob <entry key="today">Thu Aug 09 22:45:11 EDT 2007

    12.13 Use the Registry to store informations (Preferences API) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0421.html With JDK1.4, the Preferences class can use the Windows registry (on Unix, a file is used) : import java.util.prefs.Preferences; public class UsingReg { public static final String REALKEY= "com.rgagnon.foo"; public static void main(String[] args){ new UsingReg().doit();

    12.13 Use the Registry to store informations (Preferences API)

    } public void doit() { // write into HKCU\Software\Javasoft\Prefs\com.rgagnon.foo Preferences p = Preferences.userRoot(); p.put(REALKEY, "bar"); // read back from HKEY_CURRENT_USER System.out.println(p); System.out.println(p.get(REALKEY, "HKCU houston we have a problem")); // write into HKLM\Software\Javasoft\Prefs\com.rgagnon.foo p = Preferences.systemRoot(); p.put(REALKEY, "barbar"); // read back from HKEY_LOCAL_MACHINE System.out.println(p); System.out.println(p.get(REALKEY, "HKLM houston we have a problem")); } }

    See also this How−to to access the Windows registry. With Unix (or Linux), a file is used and you may run into problems if you don't have write access in the default location for the Preferences storage. See this interesting article and these 2 bugs : 1 2 If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    12.14 Sort Properties when saving Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0614.html Create a SortedProperties class which extend the regular Properties. Then override the keys() method to return the sorted keys instead.

    import import import import

    java.util.Collections; java.util.Enumeration; java.util.Properties; java.util.Vector;

    public class SortedProperties extends Properties { /** * Overrides, called by the store method. */ @SuppressWarnings("unchecked") public synchronized Enumeration keys() { Enumeration keysEnum = super.keys(); Vector keyList = new Vector(); while(keysEnum.hasMoreElements()){ keyList.add(keysEnum.nextElement()); } Collections.sort(keyList);

    12.14 Sort Properties when saving

    return keyList.elements(); } /** * Demo */ public static void main(String[] args) throws Exception { // regular Properties Properties p = new Properties(); p.put("B", "value B"); p.put("C", "value C"); p.put("A", "value A"); p.put("D", "value D"); java.io.FileOutputStream fos = new java.io.FileOutputStream("/temp/p.props"); p.store(fos, "regular props"); /* #regular props #Thu Jul 31 22:21:51 EDT 2008 A=value A D=value D C=value C B=value B */ // same data but with sorted Properties SortedProperties sp = new SortedProperties(); sp.put("B", "value B"); sp.put("C", "value C"); sp.put("A", "value A"); sp.put("D", "value D"); fos = new java.io.FileOutputStream("/temp/sp.props"); sp.store(fos, "sorted props"); /* #sorted props #Thu Jul 31 22:34:06 EDT 2008 A=value A B=value B C=value C D=value D */ } }

    Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

    12.14 Sort Properties when saving

    13 Networking 13.1 java−net

    13.2 Extract network card address Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0369.html JDK1.6 java.net.NetworkInterface import java.io.*; import java.net.*; import java.util.*; public class ListNetsEx { public static void main(String args[]) throws SocketException { Enumeration nets = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface netint : Collections.list(nets)) displayInterfaceInformation(netint); } static void displayInterfaceInformation(NetworkInterface netint) throws SocketException { System.out.println("Display name: " + netint.getDisplayName()); System.out.println("Hardware address: " + Arrays.toString(netint.getHardwareAddress())); } }

    JDK1.5 or less One way, without using JNI, is to launch an external utility and interpret the output. In Windows, "arp −a" will return the MAC addresses of all adapters that have TCP/IP bound to them and have recently (default < 5 mins) resolved an IP address. Otherwise, in NT/2K/XP, "ipconfig /all" will return all relevant network info for IP−bound adapters, including the MAC address (displayed as "physical address"). In Linux, "ifconfig" does something similar. Example for Windows import import import import

    java.net.InetAddress; java.io.InputStream; java.io.BufferedInputStream; java.io.IOException;

    13 Networking

    import java.text.ParseException; import java.util.StringTokenizer; // // inspired by // http://forum.java.sun.com/thread.jspa?messageID=902023 // public final class NetworkUtils { private final static int MACADDR_LENGTH = 17; private final static String WIN_OSNAME = "Windows"; private final static String WIN_MACADDR_REG_EXP = "^[0−9A−F]{2}−[0−9A−F]{2}−[0−9A−F]{2}−[0−9A−F]{2}−[0−9A−F]{2}−[0−9A−F]{2}$"; private final static String WIN_MACADDR_EXEC = "ipconfig /all";

    public final static String getMacAddress() throws IOException { String os = System.getProperty("os.name"); try { if (os.startsWith(WIN_OSNAME)) { return winMacAddress(winIpConfigCommand()); } // other OS left as an exercise ! // LINUX −−> else if (os.startsWith("Linux")) { ... // ... // Process p = Runtime.getRuntime().exec("ifconfig"); // MAC OSX −−> else if(os.startsWith("Mac OS X")) { ... // ... // Process p = Runtime.getRuntime().exec("ifconfig"); else { throw new IOException("OS not supported : " + os); } } catch(ParseException e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } private final static String winMacAddress(String ipConfigOutput) throws ParseException { String localHost = null; try { localHost = InetAddress.getLocalHost().getHostAddress(); } catch(java.net.UnknownHostException ex) { ex.printStackTrace(); throw new ParseException(ex.getMessage(), 0); } StringTokenizer tokenizer = new StringTokenizer(ipConfigOutput, "\n"); String lastMacAddress = null; while(tokenizer.hasMoreTokens()) { String line = tokenizer.nextToken().trim(); // see if line contains IP address if (line.endsWith(localHost) && lastMacAddress != null) { return lastMacAddress; }

    13 Networking

    // see if line contains MAC address int macAddressPosition = line.indexOf(":"); if(macAddressPosition <= 0) continue; String macAddressCandidate = line.substring(macAddressPosition + 1).trim(); if (winIsMacAddress(macAddressCandidate)) { lastMacAddress = macAddressCandidate; continue; } } ParseException ex = new ParseException ("cannot read MAC address from [" + ipConfigOutput + "]", 0); ex.printStackTrace(); throw ex; }

    private final static boolean winIsMacAddress(String macAddressCandidate) { if (macAddressCandidate.length() != MACADDR_LENGTH) return false; if (!macAddressCandidate.matches(WIN_MACADDR_REG_EXP)) return false; return true; }

    private final static String winIpConfigCommand() throws IOException { Process p = Runtime.getRuntime().exec(WIN_MACADDR_EXEC); InputStream stdoutStream = new BufferedInputStream(p.getInputStream()); StringBuffer buffer= new StringBuffer(); for (;;) { int c = stdoutStream.read(); if (c == −1) break; buffer.append((char)c); } String outputText = buffer.toString(); stdoutStream.close(); return outputText; }

    public final static void main(String[] args) { try { System.out.println("MAC ADDRESS"); System.out.println(" OS : " + System.getProperty("os.name")); System.out.println(" IP/Localhost: " + InetAddress.getLocalHost().getHostAddress()); System.out.println(" MAC Address : " + getMacAddress()); } catch(Throwable t) { t.printStackTrace(); } } }

    13.3 Get the workstation name/ip

    13.3 Get the workstation name/ip

    Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0390.html public class NetInfo { public static void main(String[] args) { new NetInfo().say(); } public void say() { try { java.net.InetAddress i = java.net.InetAddress.getLocalHost(); System.out.println(i); // name and IP address System.out.println(i.getHostName()); // name System.out.println(i.getHostAddress()); // IP address only } catch(Exception e){e.printStackTrace();} } }

    The output > java NetInfo realone/209.142.72.112 realone 209.142.72.112

    To list all the interfaces available on a workstation : [JDK1.4] import import import import

    java.net.*; java.util.*; java.io.*; java.nio.*;

    public class IPAdress { public void getInterfaces (){ try { Enumeration e = NetworkInterface.getNetworkInterfaces(); while(e.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) e.nextElement(); System.out.println("Net interface: "+ni.getName()); Enumeration e2 = ni.getInetAddresses(); while (e2.hasMoreElements()){ InetAddress ip = (InetAddress) e2.nextElement(); System.out.println("IP address: "+ ip.toString()); } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { IPAdress ip = new IPAdress(); ip.getInterfaces(); } }

    13.3 Get the workstation name/ip

    The output > java IPAdress Net interface: lo IP address: /127.0.0.1 Net interface: eth0 IP address: /194.168.0.1 Net interface: eth1 IP address: /164.254.147.20 Net interface: ppp0 IP address: /64.68.115.69

    Windows A "low−tech" way to get the computer name (can be useful if there is no network card) is to use the environment variable COMPUTERNAME (at least on modern Windows installation). [JDK1.4 or less] Pass it to your JVM as java −Dcomputername="%COMPUTERNAME%" ... and then get the value with System.getProperty("computername") [JDK1.5 or more] You can extract environment variable directly with System.getenv("COMPUTERNAME") To get the IP of a client from the server side, see this HowTo.

    13.4 Find port number not in use Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0412.html On Windows, "netstat −an" list the ports currently in use. Take a look at http://www.iana.org/assignments/port−numbers for a list of assigned numbers.

    13.5 Disable DNS caching Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0445.html JDK1.4 Once an application has performed network access (i.e. urlconnection, parsing of xml document with external references, etc), the DNS settings get cached so any subsequent operation will use the old settings even if the real settings have changed. To reset everything, you have to restart the server since the the default setting JVM setting is to cache forever. There are 4 properties that can be used to override the default behaviour. networkaddress.cache.ttl (default: −1) Specified in java.security to indicate the caching policy for successful

    13.4 Find port number not in use

    name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the successful lookup. A value of −1 indicates "cache forever". networkaddress.cache.negative.ttl (default: 10) Specified in java.security to indicate the caching policy for un−successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the failure for un−successful lookups. A value of 0 indicates "never cache". A value of −1 indicates "cache forever". sun.net.inetaddr.ttl This is a sun private system property which corresponds to networkaddress.cache.ttl. It takes the same value and has the same meaning, but can be set as a command−line option. However, the preferred way is to use the security property mentioned above.

    sun.net.inetaddr.negative.ttl This is a sun private system property which corresponds to networkaddress.cache.negative.tt It takes the same value and has the same meaning, but can be set as a command−line option. However, the preferred way is to use the security property mentioned above.

    So you can disable caching by adding −Dsun.net.inetaddr.ttl=0 on the command line starting the JVM. But you can't set the value of networkaddress.cache.ttl on the command line. You can set the required value in the java.security file located in %JRE%\lib\security networkaddress.cache.ttl=60 networkaddress.cache.negative.ttl=10

    or set the value in your code with java.security.Security.setProperty("networkaddress.cache.ttl" , "0");

    ref : J2SE 1.4 Net properties JDK1.6 The default value has changed for networkaddress.cache.ttl, check the documentation at http://java.sun.com/javase/6/docs/technotes/guides/net/properties.html#nct If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2006 [ home ]

    13.6 Encode/Decode to/from Base64 Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0598.html As seen in this HowTo, the sun.misc.BASE64Encoder/Decoder or creating your own Base64 handling are the best way to deal with Base64 encoding/decoding.

    13.6 Encode/Decode to/from Base64

    13.7 Using javax.mail.internet.MimeUtility import javax.mail.internet.MimeUtility; import java.io.*; public class Base64Utils { public static byte[] encode(byte[] b) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream b64os = MimeUtility.encode(baos, "base64"); b64os.write(b); b64os.close(); return baos.toByteArray(); } public static byte[] decode(byte[] b) throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(b); InputStream b64is = MimeUtility.decode(bais, "Base64"); byte[] tmp = new byte[b.length]; int n = b64is.read(tmp); byte[] res = new byte[n]; System.arraycopy(tmp, 0, res, 0, n); return res; } public static void main(String[] args) throws Exception { String test = "realhowto"; byte res1[] = Base64Utils.encode(test.getBytes()); System.out.println(test + " base64 −> " + java.util.Arrays.toString(res1)); System.out.println(new String(res1)); byte res2[] = Base64Utils.decode(res1); System.out.println(""); System.out.println( java.util.Arrays.toString(res1) + " string −−> " + new String(res2)); /* * output * realhowto base64 −> * [99, 109, 86, 104, 98, 71, 104, 118, 100, 51, 82, 118] * cmVhbGhvd3Rv * [99, 109, 86, 104, 98, 71, 104, 118, 100, 51, 82, 118] * string −−> realhowto */ } }

    13.8 Using Apache Commons Codec Apache Commons Codec provides implementations of common encoders and decoders such as Base64, Hex, Phonetic and URLs. Download at http://commons.apache.org/codec/ import org.apache.commons.codec.binary.Base64; public class Codec { public static void main(String[] args) { try { String clearText = "Hello world"; String encodedText;

    13.7 Using javax.mail.internet.MimeUtility

    // Base64 encodedText = new String(Base64.encodeBase64(clearText.getBytes())); System.out.println("Encoded: " + encodedText); System.out.println("Decoded:" + new String(Base64.decodeBase64(encodedText.getBytes()))); // // output : // Encoded: SGVsbG8gd29ybGQ= // Decoded:Hello world // } catch (Exception e) { e.printStackTrace(); } } }

    13.9 MiGBase64 • MiGBase64 is a very fast Base64 Codec written in Java. http://migbase64.sourceforge.net/.

    13.10 Lookup using MX record to validate mail server Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0452.html The best you can do to verify if an email address is real is to verify if there is a mail server registered to the domain name. import import import

    java.util.Hashtable; javax.naming.*; javax.naming.directory.*;

    public class MXLookup { public static void main( String args[] ) { if( args.length == 0 ) { System.err.println( "Usage: MXLookup host [...]" ); System.exit( 99 ); } for( int i = 0; i < args.length; i++ ) { try { System.out.println( args[i] + " has " + doLookup( args[i] ) + " mail servers" ); } catch( Exception e ) { System.out.println(args[i] + " : " + e.getMessage()); } } } static int doLookup( String hostName ) throws NamingException { Hashtable env = new Hashtable(); env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); DirContext ictx = new InitialDirContext( env ); Attributes attrs = ictx.getAttributes( hostName, new String[] { "MX" });

    13.9 MiGBase64

    Attribute attr = attrs.get( "MX" ); if( attr == null ) return( 0 ); return( attr.size() ); } }

    The output is >java MXLookup rgagnon.com realhowto.com rgagnon.com has 1 mail servers realhowto.com : DNS name not found [response code 3]

    From T. Orbaker, more infos on that subject (thanks to him). There are other methods by which to validate an email address to a higher degree of than just the mail server. One: Use the VRFY command (see RFCs 821/2821). Because this was abused by spammers, it have typically been disabled on most mail servers. Some recent servers don't even support this command as they are so frequently shut off. When it works, connect to the server, issue the HELO command and then send 'VRFY '. If it is enabled, and the address is valid, you should get a 250 if the address is valid and a 550 if it isn't. Note that some servers (qmail) return 252 as a means of pleading the fifth. Others will return a failure even if the address exists but the command has been disables (although this is typically a 450 error). Two (better method): Connect to the servers determined by your code snippet. BUT (and the code below doesn't do this) they must be tried from lowest preference to highest to be absolutely correct. Once you have connected, you create the SMTP envelope, but you don't put anything in it. This is the point at which most servers will give up the dirt on whether or not an address is valid. If an envelope cannot be built, we know that the address is invalid. The reason for connecting in order of preference: Imagine ABC company has an Internet conneciton and runs their own mail server for abc.com. To prevent bounces and other mail errors if their connection or server should be down, their provider isp.com agrees to set up a 'store and forward' scheme for their mail. If abc.com is not available, then isp.com gets the message and when abc.com is again available, the message gets forwarded. The MX records would look something like: MX 1 abc.com MX 5 isp.com

    Now, imagine that you connect to isp.com and try to send a message. The mail server at isp.com doesn't have the actual user list to know which addresses are valid, it just accepts everything and relies on abc.com to sort out the bounces. If these are not checked in the proper order, there will be no errors for invalid addresses.

    13.9 MiGBase64

    Yahoo appears to use a store and forward mechanism to its own internal servers, thus conclusively verifying a yahoo address is not possible. I suspect that hotmail is the same. It is not possible to verify an address on a domain that uses a catch−all account as the catch account will receive the mail (it does, however, mean that someone will at least SEE the message). import import import import import

    java.io.*; java.net.*; java.util.*; javax.naming.*; javax.naming.directory.*;

    public class SMTP { private static int hear( BufferedReader in ) throws IOException { String line = null; int res = 0; while ( (line = in.readLine()) != null ) { String pfx = line.substring( 0, 3 ); try { res = Integer.parseInt( pfx ); } catch (Exception ex) { res = −1; } if ( line.charAt( 3 ) != '−' ) break; } return res; } private static void say( BufferedWriter wr, String text ) throws IOException { wr.write( text + "\r\n" ); wr.flush(); return; } private static ArrayList getMX( String hostName ) throws NamingException { // Perform a DNS lookup for MX records in the domain Hashtable env = new Hashtable(); env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); DirContext ictx = new InitialDirContext( env ); Attributes attrs = ictx.getAttributes ( hostName, new String[] { "MX" }); Attribute attr = attrs.get( "MX" ); // if we don't have an MX record, try the machine itself if (( attr == null ) || ( attr.size() == 0 )) { attrs = ictx.getAttributes( hostName, new String[] { "A" }); attr = attrs.get( "A" ); if( attr == null ) throw new NamingException ( "No match for name '" + hostName + "'" ); } // Huzzah! we have machines to try. Return them as an array list // NOTE: We SHOULD take the preference into account to be absolutely

    13.9 MiGBase64

    // correct. This is left as an exercise for anyone who cares. ArrayList res = new ArrayList(); NamingEnumeration en = attr.getAll(); while ( en.hasMore() ) { String x = (String) en.next(); String f[] = x.split( " " ); if ( f[1].endsWith( "." ) ) f[1] = f[1].substring( 0, (f[1].length() − 1)); res.add( f[1] ); } return res; } public static boolean isAddressValid( String address ) { // Find the separator for the domain name int pos = address.indexOf( '@' ); // If the address does not contain an '@', it's not valid if ( pos == −1 ) return false; // Isolate the domain/machine name and get a list of mail exchangers String domain = address.substring( ++pos ); ArrayList mxList = null; try { mxList = getMX( domain ); } catch (NamingException ex) { return false; } // Just because we can send mail to the domain, doesn't mean that the // address is valid, but if we can't, it's a sure sign that it isn't if ( mxList.size() == 0 ) return false; // Now, do the SMTP validation, try each mail exchanger until we get // a positive acceptance. It *MAY* be possible for one MX to allow // a message [store and forwarder for example] and another [like // the actual mail server] to reject it. This is why we REALLY ought // to take the preference into account. for ( int mx = 0 ; mx < mxList.size() ; mx++ ) { boolean valid = false; try { int res; Socket skt = new Socket( (String) mxList.get( mx ), 25 ); BufferedReader rdr = new BufferedReader ( new InputStreamReader( skt.getInputStream() ) ); BufferedWriter wtr = new BufferedWriter ( new OutputStreamWriter( skt.getOutputStream() ) ); res = hear( rdr ); if ( res != 220 ) throw new Exception( "Invalid header" ); say( wtr, "EHLO orbaker.com" ); res = hear( rdr ); if ( res != 250 ) throw new Exception( "Not ESMTP" ); // validate the say( wtr, "MAIL res = hear( rdr if ( res != 250

    sender address FROM: " ); ); ) throw new Exception( "Sender rejected" );

    say( wtr, "RCPT TO: <" + address + ">" );

    13.9 MiGBase64

    res = hear( rdr ); // be polite say( wtr, "RSET" ); hear( rdr ); say( wtr, "QUIT" ); hear( rdr ); if ( res != 250 ) throw new Exception( "Address is not valid!" ); valid = true; rdr.close(); wtr.close(); skt.close(); } catch (Exception ex) { // Do nothing but try next host } finally { if ( valid ) return true; } } return false; } public static void main( String args[] ) { String testData[] = { "[email protected]", // Valid address "[email protected]", // Invalid domain name "[email protected]", // Invalid address "[email protected]" // Failure of this method }; for ( int ctr = 0 ; ctr < testData.length ; ctr++ ) { System.out.println( testData[ ctr ] + " is valid? " + isAddressValid( testData[ ctr ] ) ); } return; } }

    S.Boerner has this comments about this HowTo : The method SMTP::getMX() in the second example throws an ArrayIndexOutOfBoundsException while getting the mailhost via the "A" attribute at: while ( en.hasMore() ) { String x = (String) en.next(); String f[] = x.split( " " ); if ( f[1].endsWith( "." ) )

    The "A" attribute returns only an address list, so f.length is always 1. I used something like: boolean hasMX = "MX".equals(attr.getID());

    and later if (hasMX) { mailhost = f[1]; } else {

    13.9 MiGBase64

    mailhost = f[0]; }

    Here my proposed fix : import import import import import

    java.io.*; java.net.*; java.util.*; javax.naming.*; javax.naming.directory.*;

    public class SMTPMXLookup { private static int hear( BufferedReader in ) throws IOException { String line = null; int res = 0; while ( (line = in.readLine()) != null ) { String pfx = line.substring( 0, 3 ); try { res = Integer.parseInt( pfx ); } catch (Exception ex) { res = −1; } if ( line.charAt( 3 ) != '−' ) break; } return res; } private static void say( BufferedWriter wr, String text ) throws IOException { wr.write( text + "\r\n" ); wr.flush(); return; } private static ArrayList getMX( String hostName ) throws NamingException { // Perform a DNS lookup for MX records in the domain Hashtable env = new Hashtable(); env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); DirContext ictx = new InitialDirContext( env ); Attributes attrs = ictx.getAttributes ( hostName, new String[] { "MX" }); Attribute attr = attrs.get( "MX" ); // if we don't have an MX record, try the machine itself if (( attr == null ) || ( attr.size() == 0 )) { attrs = ictx.getAttributes( hostName, new String[] { "A" }); attr = attrs.get( "A" ); if( attr == null ) throw new NamingException ( "No match for name '" + hostName + "'" ); } // Huzzah! we have machines to try. Return them as an array list // NOTE: We SHOULD take the preference into account to be absolutely // correct. This is left as an exercise for anyone who cares. ArrayList res = new ArrayList(); NamingEnumeration en = attr.getAll(); while ( en.hasMore() ) {

    13.9 MiGBase64

    String mailhost; String x = (String) en.next(); String f[] = x.split( " " ); // THE fix ************* if (f.length == 1) mailhost = f[0]; else if ( f[1].endsWith( "." ) ) mailhost = f[1].substring( 0, (f[1].length() − 1)); else mailhost = f[1]; // THE fix ************* res.add( mailhost ); } return res; } public static boolean isAddressValid( String address ) { // Find the separator for the domain name int pos = address.indexOf( '@' ); // If the address does not contain an '@', it's not valid if ( pos == −1 ) return false; // Isolate the domain/machine name and get a list of mail exchangers String domain = address.substring( ++pos ); ArrayList mxList = null; try { mxList = getMX( domain ); } catch (NamingException ex) { return false; } // Just because we can send mail to the domain, doesn't mean that the // address is valid, but if we can't, it's a sure sign that it isn't if ( mxList.size() == 0 ) return false; // Now, do the SMTP validation, try each mail exchanger until we get // a positive acceptance. It *MAY* be possible for one MX to allow // a message [store and forwarder for example] and another [like // the actual mail server] to reject it. This is why we REALLY ought // to take the preference into account. for ( int mx = 0 ; mx < mxList.size() ; mx++ ) { boolean valid = false; try { int res; // Socket skt = new Socket( (String) mxList.get( mx ), 25 ); BufferedReader rdr = new BufferedReader ( new InputStreamReader( skt.getInputStream() ) ); BufferedWriter wtr = new BufferedWriter ( new OutputStreamWriter( skt.getOutputStream() ) ); res = hear( rdr ); if ( res != 220 ) throw new Exception( "Invalid header" ); say( wtr, "EHLO rgagnon.com" ); res = hear( rdr ); if ( res != 250 ) throw new Exception( "Not ESMTP" ); // validate the sender address say( wtr, "MAIL FROM: " ); res = hear( rdr );

    13.9 MiGBase64

    if ( res != 250 ) throw new Exception( "Sender rejected" ); say( wtr, "RCPT TO: <" + address + ">" ); res = hear( rdr ); // be polite say( wtr, "RSET" ); hear( rdr ); say( wtr, "QUIT" ); hear( rdr ); if ( res != 250 ) throw new Exception( "Address is not valid!" ); valid = true; rdr.close(); wtr.close(); skt.close(); } catch (Exception ex) { // Do nothing but try next host ex.printStackTrace(); } finally { if ( valid ) return true; } } return false; } public static void main( String args[] ) { String testData[] = { "[email protected]", "[email protected]", "[email protected]", // Invalid domain name "[email protected]", // Invalid address "[email protected]" // Failure of this method }; for ( int ctr = 0 ; ctr < testData.length ; ctr++ ) { System.out.println( testData[ ctr ] + " is valid? " + isAddressValid( testData[ ctr ] ) ); } return; } }

    A note sent by M. Donders. While using the code I noticed a problem with greylisting. Greylisting, is an anti spam attempt which denies service for the first time the triple of client, sender and address reaches the smtp server. Greylisting will send back a temporary error (450) and therefore the address will be denied. In this case it probably is better to accept the address as verified, because there is no better information available at that moment.

    A list a possible SMTP Reply Codes: Code 211 214 220

    Description System status, or system help reply. Help message. Domain service ready. Ready to start TLS.

    13.9 MiGBase64

    221 250 251 252

    253 354 355 421 432 450 451 452 453 454 458 459 500 501 502 503 504 521 530 534 538 550 551 552 553 554

    Domain service closing transmission channel. OK, queuing for node node started. Requested mail action okay, completed. OK, no messages waiting for node node. User not local, will forward to forwardpath. OK, pending messages for node node started. Cannot VRFY user (e.g., info is not local), but will take message for this user and attempt delivery. OK, messages pending messages for node node started. Start mail input; end with .. Octet−offset is the transaction offset. Domain service not available, closing transmission channel. A password transition is needed. Requested mail action not taken: mailbox unavailable. (ex. mailbox busy) Requested action aborted: local error in processing. Unable to process ATRN request now Requested action not taken: insufficient system storage. You have no mail. TLS not available due to temporary reason. Encryption required for requested authentication mechanism. Unable to queue messages for node node. Node node not allowed: reason. Command not recognized: command. Syntax error. Syntax error, no parameters allowed. Command not implemented. Bad sequence of commands. Command parameter not implemented. Machine does not accept mail. Must issue a STARTTLS command first. Encryption required for requested authentication mechanism. Authentication mechanism is too weak. Encryption required for requested authentication mechanism. Requested action not taken: mailbox unavailable. User not local; please try forwardpath. Requested mail action aborted: exceeded storage allocation. Requested action not taken: mailbox name not allowed. Transaction failed.

    RFC0821

    13.11 Send an email using the SMTP protocol Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0079.html SMTP is the protocol used to send an email. Article on how SMTP works. Unless you have a good reason, try to use the JavaMail API (see section Mail(Javamail)). import java.net.*; import java.io.*; public class SendElvisMail {

    13.11 Send an email using the SMTP protocol

    public static void main(String s[]) { // // Send fake mail from Elvis Presley // // SendElvisMail [mail server] [recipient address] // mail server can be hostname or IP address // // ex. SendElvisMail mail.company.com [email protected] // SendElvisMail t = new SendElvisMail(); t.sendMail(s[0], s[1]); } public void sendMail(String mailServer, String recipient) { try { Socket s = new Socket(mailServer, 25); BufferedReader in = new BufferedReader (new InputStreamReader(s.getInputStream(), "8859_1")); BufferedWriter out = new BufferedWriter (new OutputStreamWriter(s.getOutputStream(), "8859_1")); send(in, out, "HELO theWorld"); // warning : some mail server validate the sender address // in the MAIL FROm command, put your real address here send(in, out, "MAIL FROM: <[email protected]>"); send(in, out, "RCPT TO: " + recipient); send(in, out, "DATA"); send(out, "Subject: In the ghetto"); send(out, "From: Elvis Presley <[email protected]>"); send (out, "\n"); // message body send(out, "I'm alive. Help me!"); send(out, "\n.\n"); send(in, out, "QUIT"); s.close(); } catch (Exception e) { e.printStackTrace(); } } public void send(BufferedReader in, BufferedWriter out, String s) { try { out.write(s + "\n"); out.flush(); System.out.println(s); s = in.readLine(); System.out.println(s); } catch (Exception e) { e.printStackTrace(); } } public void send(BufferedWriter out, String s) { try { out.write(s + "\n"); out.flush(); System.out.println(s); } catch (Exception e) { e.printStackTrace(); }

    13.11 Send an email using the SMTP protocol

    } }

    13.12 Check if there is mail waiting Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0080.html import java.net.*; import java.io.*; public class CheckMail { public static void main(String s[]) { // // CheckMail [mailServer] [user] [password] // try { CheckMail t = new CheckMail(); int i = t.checkMyMail(s[0], s[1], s[2]); if (i==0) { System.out.println("No mail waiting."); } else { System.out.println ("There " + (i==1?"is " :"are ") + i + " message" +(i==1?"":"s")+ " waiting."); } } catch (Exception e) { e.printStackTrace(); } } private void send(BufferedWriter out, String s) throws IOException { out.write(s+"\n"); out.flush(); } private String receive(BufferedReader in) throws IOException { return in.readLine(); } private int checkMyMail (String server, String user, String pass) throws IOException { Socket s = new Socket(server, 110); BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream())); BufferedWriter out = new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); receive(in); send(out, "USER " + user); receive(in); send(out, "PASS " + pass); receive(in); return getNumberOfMessages(in, out); }

    13.12 Check if there is mail waiting

    public int getNumberOfMessages (BufferedReader in, BufferedWriter out) throws IOException { int i = 0; String s; send(out, "LIST"); receive(in); while((s = receive(in)) != null) { if (!(s.equals("."))) { i++; } else return i; } return 0; } }

    13.13 Receive email Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0081.html import java.net.*; import java.io.*; public class DisplayMail { public static void main(String arg[]) { // // usage : // DisplayMail [mailServer] [user] [password] // (will not delete mail on the server) // try { // connect on port 110 (POP3) System.out.println("Connect to " + arg[0] + ":110"); Socket s = new Socket(arg[0], 110); BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream())); BufferedWriter out = new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); DisplayMail mail = new DisplayMail(); mail.login(in, out, arg[1], arg[2]); int i = mail.check(in,out); if (i==0) { System.out.println("No mail waiting."); } else { for (int j=1; j <= i; j++) { String msg = mail.get(in, out, j); System.out.println("*****"); System.out.println(msg); System.out.println("*****"); } // // If the mail was removed from the server // (see getMail()) then we must COMMIT with // the "QUIT" command : // send(out, "QUIT");

    13.13 Receive email

    // } } catch (Exception e) { e.printStackTrace(); } } public String get (BufferedReader in, BufferedWriter out, int i) throws IOException { String s = ""; String t = ""; send(out, "RETR "+i); while (((s = in.readLine()) != null) )))) { t += s + "\n"; } // // To remove the mail on the server : // send(out, "DELE "+i); // receive(in); // return t; }

    private void send(BufferedWriter out, String s) throws IOException { System.out.println(s); out.write(s+"\n"); out.flush(); } private String receive(BufferedReader in) throws IOException { String s = in.readLine(); System.out.println(s); return s; } private void login (BufferedReader in, BufferedWriter out, String user, String pass) throws IOException { receive(in); send(out, "HELO theWorld"); receive(in); send(out, "USER " + user); receive(in); send(out, "PASS " + pass); receive(in); } private int check (BufferedReader in, BufferedWriter out) throws IOException { return getNumberOfMessages(in, out); } public int getNumberOfMessages (BufferedReader in, BufferedWriter out) throws IOException { int i = 0;

    13.13 Receive email

    String s; send(out, "LIST"); receive(in); while((s = receive(in)) != null) { if (!(s.equals("."))) { i++; } else { return i; } } return 0; } }

    13.14 Send email with an attachment Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0083.html In this example, Elvis is sending a GIF of his old Gumby friend. The attachment is encodded using the BASE64 algorithm. In this example, we are sending as attachment this image :

    import java.io.*; import java.net.*; public class TestMailMIME { static int SMTPport = 25; static Socket socket; static DataInputStream in; static DataOutputStream out; static PrintStream prout; /* Name of file to be sent. */ String FileName = "gumby.gif"; public static void main(String s[]) { /* ** TestMailMIME [server] [recipient] */ TestMailMIME t = new TestMailMIME(); t.sendMail(s[0], s[1]); } public void sendMail(String mailServer, String recipient) { System.out.println("Send mail with attached file "); try { Socket s = new Socket(mailServer, 25); BufferedReader in = new BufferedReader (new InputStreamReader(s.getInputStream(), "8859_1")); BufferedWriter out = new BufferedWriter (new OutputStreamWriter(s.getOutputStream(), "8859_1")); String boundary = "DataSeparatorString";

    13.14 Send email with an attachment

    // here you are supposed to send your username sendln(in, out, "HELO theWorld"); // warning : some mail server validate the sender address // in the MAIL FROM command, put your real address here sendln(in, out, "MAIL FROM: "); sendln(in, out, "RCPT TO: <" + recipient + ">" ); // to have more than one recipient, repeat // sendln(in, out, "RCPT TO: <" + recipient2 + ">" ); // sendln(in, out, "RCPT TO: <" + recipient3 + ">" ); // etc... // thanks to P−Y Colle for the tip! sendln(in, out, "DATA"); sendln(out, "MIME−Version: 1.0"); sendln(out, "Subject: remember me"); sendln(out, "From: Elvis Presley <[email protected]>"); sendln (out, "Content−Type: multipart/mixed; boundary=\"" + boundary +"\""); sendln(out, "\r\n−−" + boundary); // Send the sendln(out, sendln(out, sendln(out,

    body "Content−Type: text/plain; charset=\"us−ascii\"\r\n"); "I'm alive. Help me!\r\n\r\n"); "\r\n−−" + boundary );

    // send the GIF sendln(out, "Content−Type:image/gif; name="+FileName); sendln (out, "Content−Disposition: attachment;filename=\""+FileName+"\""); sendln(out, "Content−transfer−encoding: base64\r\n"); MIMEBase64.encode(FileName, out); sendln(out, "\r\n−−" + boundary); sendln(out, "\r\n\r\n−−" + boundary + "−−\r\n"); sendln(in, out,"."); sendln(in, out, "QUIT"); s.close(); } catch (Exception e) { e.printStackTrace(); } } public void sendln(BufferedReader in, BufferedWriter out, String s) { try { out.write(s + "\r\n"); out.flush(); // System.out.println(s); s = in.readLine(); // System.out.println(s); } catch (Exception e) { e.printStackTrace(); } } public void sendln(BufferedWriter out, String s) { try { out.write(s + "\r\n"); out.flush(); System.out.println(s); } catch (Exception e) {

    13.14 Send email with an attachment

    e.printStackTrace(); } } }

    And the MIMEBase64 class import java.io.*; public class MIMEBase64 { /* Base64 uses a 65 character subset of US−ASCII, allowing 6 bits for each character so the character "m" with a Base64 value of 38, when represented in binary form, is 100110. With a text string, let's say "men" is encoded this is what happens : The text string is converted into its US−ASCII value. The character "m" has the decimal value of 109 The character "e" has the decimal value of 101 The character "n" has the decimal value of 110 When converted to binary the string looks like this : m e n

    01101101 01100101 01101110

    These three "8−bits" are concatenated to make a 24 bit stream 011011010110010101101110 This 24 bit stream is then split up into 4 6−bit sections 011011 010110 010101 101110 We now have 4 values. These binary values are converted to decimal form 27 22 21 46 And the corresponding Base64 character are : b W V u The encoding is always on a three characters basis (to have a set of 4 Base64 characters). To encode one or two then, we use the special character "=" to pad until 4 base64 characters is reached. ex. encode "me" 01101101 01100101 0110110101100101 011011 010110 0101 111111 011011 010110 010100 b W U b W U so "bWU="

    (AND to fill the missing bits)

    =

    ("=" is the padding character)

    is the base64 equivalent.

    13.14 Send email with an attachment

    encode "m" 01101101 011011 01 111111 011011 010000 b Q

    (AND to fill the missing bits) =

    =

    (two paddings are added)

    Finally, MIME specifies that lines are 76 characters wide maximum. */ static String BaseTable[] = { "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f", "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v", "w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/" }; public static void encode(String filename, BufferedWriter out) { try { File f = new File(filename); FileInputStream fin = new FileInputStream(filename); // read the entire file into the byte array byte bytes[] = new byte[(int)(f.length())]; int n = fin.read(bytes); if (n < 1) return;

    // no bytes to encode!?!

    byte buf[] = new byte[4];

    // array of base64 characters

    int int int int int

    n3byt nrest k linelength i

    = = = = =

    n / 3; // how 3 bytes groups? n % 3; // the remaining bytes from the grouping n3byt * 3; // we are doing 3 bytes at a time 0; // current linelength 0; // index

    // do the 3−bytes groups ... while ( i < k ) { buf[0] = (byte)(( bytes[i] &0xFC) >> 2); buf[1] = (byte)(((bytes[i] &0x03) << 4) | ((bytes[i+1] &0xF0) >> 4)); buf[2] = (byte)(((bytes[i+1] &0x0F) << 2) | ((bytes[i+2] &0xC0) >> 6)); buf[3] = (byte)( bytes[i+2] &0x3F); send(out, BaseTable[buf[0]]); send(out, BaseTable[buf[1]]); send(out, BaseTable[buf[2]]); send(out, BaseTable[buf[3]]); /* The above code can be written in more "optimized" way. Harder to understand but more compact. Thanks to J. Tordera for the tip! buf[0]= (byte)(b[i] >> 2); buf[1]= (byte)(((b[i] &0x03) << 4)|(b[i+1]>> 4)); buf[2]= (byte)(((b[i+1] &0x0F)<< 2)|(b[i+2]>> 6)); buf[3]= (byte)(b[i+2] &0x3F); send(out,BaseTable[buf[0]]+BaseTable[buf[1]]+ BaseTable[buf[2]]+BaseTable[buf[3]]); */ if ((linelength += 4) >= 76) {

    13.14 Send email with an attachment

    send(out, "\r\n"); linelength = 0; } i += 3; } // deals with with the padding ... if (nrest==2) { // 2 bytes left buf[0] = (byte)(( bytes[k] &0xFC) >> 2); buf[1] = (byte)(((bytes[k] &0x03) << 4) | ((bytes[k+1] &0xF0) >> 4)); buf[2] = (byte)(( bytes[k+1] &0x0F) << 2); } else if (nrest==1) { // 1 byte left buf[0] = (byte)((bytes[k] &0xFC) >> 2); buf[1] = (byte)((bytes[k] &0x03) << 4); } if (nrest > 0) { // send the padding if ((linelength += 4) >= 76) send(out, "\r\n"); send(out, BaseTable[buf[0]]); send(out, BaseTable[buf[1]]); // Thanks to R. Claerman for the bug fix here! if (nrest==2) { send(out, BaseTable[buf[2]]); } else { send(out, "="); } send(out, "="); } out.flush(); } catch (Exception e) { e.printStackTrace(); } } public static void send(BufferedWriter out, String s) { try { out.write(s); System.out.print(s); } catch (Exception e) { e.printStackTrace(); } } }

    If Elvis want to send a GIF and a text file about his Gumby old friend then he would change his sendMail() for something like this ... /* Name of files to be sent. */ String FileName1 = "gumby.gif"; String FileName2 = "gumby.txt"; ...

    13.14 Send email with an attachment

    public void sendMail(String mailServer, String recipient) { System.out.println("Send mail with attached file"); try { Socket s = new Socket(mailServer, 25); BufferedReader in = new BufferedReader (new InputStreamReader(s.getInputStream(), "8859_1")); BufferedWriter out = new BufferedWriter (new OutputStreamWriter(s.getOutputStream(), "8859_1")); String boundary = "DataSeparatorString"; // here you are supposed to send your username sendln(in, out, "HELO world"); sendln(in, out, "MAIL FROM: "); sendln(in, out, "RCPT TO: <" + recipient + ">" ); sendln(in, out, "DATA"); sendln(out, "MIME−Version: 1.0"); sendln(out, "Subject: remember me"); sendln(out, "From: Elvis Presley <[email protected]<"); sendln (out,"Content−Type: multipart/mixed; boundary=\"" + boundary +"\""); sendln(out, "\r\n−−" + boundary); // send the GIF sendln(out, "Content−Type: text/plain; charset=\"us−ascii\"\r\n"); sendln(out, "I'm alive. Help me!\n\n"); sendln(out, "\r\n" + "−−" + boundary ); sendln(out, "Content−Type:image/gif; name="+FileName1); sendln (out, "Content−Disposition: attachment;filename=\""+FileName1+"\""); sendln(out, "Content−transfer−encoding: base64\r\n"); MIMEBase64.encode(FileName1, out); sendln(out, "\r\n−−" + boundary); // the text file sendln(out, "Content−Type: text/plain; name="+FileName2); sendln(out, "Content−Disposition: inline;filename=\""+FileName2+"\""); // to send the file as an attachment instead of "inline" use : // sendln // (out, "Content−Type: text/plain; name="+FileName2); // sendln // (out,"Content−Disposition: attachment;filename=\""+FileName2+"\""); sendln(out, "Content−Transfer−Encoding: base64\r\n"); MIMEBase64.encode(FileName2, out); sendln(out, "\r\n\r\n−−" + boundary + "−−\r\n"); // done sendln(in, out,"."); sendln(in, out, "QUIT"); s.close(); } catch (Exception e) { e.printStackTrace(); } } ... NOTE: A compact algorithm to encode string as Base64 can be found here. Check out the Javascript, it is very short! NOTE: Check this related HowTo.

    13.14 Send email with an attachment

    13.15 Send email with JavaMail Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0321.html The JavaMail API can found here. You need 2 jars : mail.jar and activation.jar. It's a good idea to read the JavaMail FAQ. Simple email import javax.mail.*; import javax.mail.internet.*; import java.util.Properties; class SimpleMail { public static void main(String[] args) throws Exception{ Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "mymail.server.org"); props.setProperty("mail.user", "emailuser"); props.setProperty("mail.password", ""); Session mailSession = Session.getDefaultInstance(props, null); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setSubject("Testing javamail plain"); message.setContent("This is a test", "text/plain"); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    HTML Email import javax.mail.*; import javax.mail.internet.*; import java.util.Properties; class SimpleHTMLMail { public static void main(String[] args) throws Exception{ Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "mymail.server.org"); props.setProperty("mail.user", "emailuser"); props.setProperty("mail.password", ""); Session mailSession = Session.getDefaultInstance(props, null); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession);

    13.15 Send email with JavaMail

    message.setSubject("Testing javamail html"); message.setContent ("This is a test HOWTO", "text/html; charset=ISO−8859−1"); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    Email with attachment import import import import

    javax.mail.*; javax.mail.internet.*; javax.activation.FileDataSource; javax.activation.DataHandler;

    import java.util.Properties; class SimpleMailWithAttachment { public static void main(String[] args) throws Exception{ boolean debug = false; Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "mymail.server.org"); props.setProperty("mail.user", "emailuser"); props.setProperty("mail.password", ""); Session mailSession = Session.getDefaultInstance(props, null); mailSession.setDebug(debug); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setSubject("Testing javamail with attachment"); MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent("

    Check attachment

    ", "text/html"); MimeBodyPart attachFilePart = new MimeBodyPart(); FileDataSource fds = new FileDataSource("SimpleMailWithAttachment.java"); attachFilePart.setDataHandler(new DataHandler(fds)); attachFilePart.setFileName(fds.getName()); Multipart mp = new MimeMultipart(); mp.addBodyPart(textPart); mp.addBodyPart(attachFilePart); message.setContent(mp); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    13.15 Send email with JavaMail

    13.16 Send email with authentication Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0538.html import import import import

    javax.mail.*; javax.mail.internet.*; javax.mail.Authenticator; javax.mail.PasswordAuthentication;

    import java.util.Properties;

    public class SimpleMail { private static final String SMTP_HOST_NAME = "smtp.myserver.com"; private static final String SMTP_AUTH_USER = "myusername"; private static final String SMTP_AUTH_PWD = "mypwd"; public static void main(String[] args) throws Exception{ new SimpleMail().test(); } public void test() throws Exception{ Properties props = new Properties(); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.host", SMTP_HOST_NAME); props.put("mail.smtp.auth", "true"); Authenticator auth = new SMTPAuthenticator(); Session mailSession = Session.getDefaultInstance(props, auth); // uncomment for debugging infos to stdout // mailSession.setDebug(true); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setContent("This is a test", "text/plain"); message.setFrom(new InternetAddress("[email protected]")); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } private class SMTPAuthenticator extends javax.mail.Authenticator { public PasswordAuthentication getPasswordAuthentication() { String username = SMTP_AUTH_USER; String password = SMTP_AUTH_PWD; return new PasswordAuthentication(username, password); } } } NOTE : The JavaMail Authenticator is found in the javax.mail package and is different from the java.net class of the same name. The two don't share the same Authenticator as the JavaMail API works with Java 1.1, which didn't have the java.net variety.

    13.16 Send email with authentication

    13.17 Send HTML mail with images (Javamail) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0504.html It's easy to send HTML mail with JavaMail. Simply set the content type to "text/html". import javax.mail.*; import javax.mail.internet.*; import java.util.Properties; class SimpleMail { public static void main(String[] args) throws Exception{ System.out.println("Sending mail..."); Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "smtp.mymailserver.com"); props.setProperty("mail.user", "myuser"); props.setProperty("mail.password", "mypwd"); Session mailSession = Session.getDefaultInstance(props, null); mailSession.setDebug(true); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setSubject("HTML mail with images"); message.setFrom(new InternetAddress("[email protected]")); message.setContent("

    Hello world

    ", "text/html"); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    One approach to include images in the mail body is to use the IMG tag and make the images available on a server. import javax.mail.*; import javax.mail.internet.*; import java.util.Properties; class SimpleMail1 { public static void main(String[] args) throws Exception{ System.out.println("Sending mail..."); Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "smtp.mymailserver.com"); props.setProperty("mail.user", "myuser"); props.setProperty("mail.password", "mypwd"); Session mailSession = Session.getDefaultInstance(props, null); mailSession.setDebug(true); Transport transport = mailSession.getTransport();

    13.17 Send HTML mail with images (Javamail)

    MimeMessage message = new MimeMessage(mailSession); message.setSubject("HTML mail with images"); message.setFrom(new InternetAddress("[email protected]")); message.setContent ("

    This is a test

    " + "", "text/html"); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    The browser accesses these images just as if it were displaying an image in a Web page. Unfortunately, spammers have used this mechanism as a sneaky way to record who visits their site (and mark your email as valid). To protect your privacy, many Web−based (and other) email clients don't display images in HTML emails. An alternative to placing absolute URLs to images in your HTML is to include the images as attachments to the email. The HTML can reference the image in an attachment by using the protocol prefix cid: plus the content−id of the attachment. import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; import java.util.Properties; class SimpleMail2 { public static void main(String[] args) throws Exception{ System.out.println("Sending mail..."); Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", "smtp.mymailserver.com"); props.setProperty("mail.user", "myuser"); props.setProperty("mail.password", "mypwd"); Session mailSession = Session.getDefaultInstance(props, null); mailSession.setDebug(true); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setSubject("HTML mail with images"); message.setFrom(new InternetAddress("[email protected]")); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); // // This HTML mail have to 2 part, the BODY and the embedded image // MimeMultipart multipart = new MimeMultipart("related"); // first part (the html) BodyPart messageBodyPart = new MimeBodyPart(); String htmlText = "

    Hello

    "; messageBodyPart.setContent(htmlText, "text/html");

    13.17 Send HTML mail with images (Javamail)

    // add it multipart.addBodyPart(messageBodyPart); // second part (the image) messageBodyPart = new MimeBodyPart(); DataSource fds = new FileDataSource ("C:\\images\\jht.gif"); messageBodyPart.setDataHandler(new DataHandler(fds)); messageBodyPart.setHeader("Content−ID",""); // add it multipart.addBodyPart(messageBodyPart); // put everything together message.setContent(multipart); transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    13.18 Debug a Javamail Program Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0552.html Set the Javamail DEBUG mode "on" : Session mailSession = Session.getDefaultInstance(props, null); mailSession.setDebug(true);

    This setting puts the Javamail classes in verbose mode to System.out. Verify connectivity to the MailServer with Telnet : telnet mymailserver 25

    for example, you can detect if your firewall is blocking your connection. Use a Javamail server mock−up to act as "in−memory" mail server : See https://mock−javamail.dev.java.net/ and http://quintanasoft.com/dumbster/. These mock−ups are designed to act a mail server but the actual email is not delivered to the mail recipient which can be useful in a testing stage.

    13.18 Debug a Javamail Program

    13.19 Send email with SMTPS (eg. Google GMail) (Javamail) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0570.html It's not uncommon that the outgoing mail needs to be encrypted using the SMTPS protocol. It's the case for GMAIL for example. You need Javamail 1.4 to use the SMTPS protocol. import javax.mail.*; import javax.mail.internet.*; import java.util.Properties;

    public class SimpleSSLMail { private private private private

    static static static static

    final final final final

    String SMTP_HOST_NAME = "smtp.gmail.com"; int SMTP_HOST_PORT = 465; String SMTP_AUTH_USER = "[email protected]"; String SMTP_AUTH_PWD = "mypwd";

    public static void main(String[] args) throws Exception{ new SimpleSSLMail().test(); } public void test() throws Exception{ Properties props = new Properties(); props.put("mail.transport.protocol", "smtps"); props.put("mail.smtps.host", SMTP_HOST_NAME); props.put("mail.smtps.auth", "true"); // props.put("mail.smtps.quitwait", "false"); Session mailSession = Session.getDefaultInstance(props); mailSession.setDebug(true); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setSubject("Testing SMTP−SSL"); message.setContent("This is a test", "text/plain"); message.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); transport.connect (SMTP_HOST_NAME, SMTP_HOST_PORT, SMTP_AUTH_USER, SMTP_AUTH_PWD); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); } }

    The property props.put("mail.smtps.quitwait", "false");

    13.19 Send email with SMTPS (eg. Google GMail) (Javamail)

    is required to get rid of a strange SSL exception : javax.mail.MessagingException: Exception reading response; nested exception is: javax.net.ssl.SSLException: Unsupported record version Unknown−50.49 ...

    The mail is sent but the exception is unwanted... The property quitwait means If set to false, the QUIT command is sent and the connection is immediately closed. If set to true (the default), causes the transport to wait for the response to the QUIT command.

    ref : http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package−summary.html This setting, mail.smtps.quitwait, is not required anymore! (july2007)

    13.19.1 Settings for well known mail providers Yahoo Incoming Mail Server − pop.mail.yahoo.com (POP3 − port 110) Outgoing Mail Server − smtp.mail.yahoo.com (SMPTP − port 25) Google GMail Incoming Mail Server − pop.gmail.com (POP3S SSL enabled, port 995) Outgoing Mail Server − gmail.com (SMPTS SSL enabled, port 465)

    13.20 Mix plain text and HTML content in a mail Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0471.html Properties props = new Properties(); props.put("mail.smtp.host", "MYMAILSERVER"); Session session = Session.getInstance(props,null); MimeMessage message = new MimeMessage(session); InternetAddress from = new InternetAddress("[email protected]"); InternetAddress to = new InternetAddress("[email protected]"); message.setSubject("I am a multipart text/html email" ); message.setFrom(from); message.addRecipient(Message.RecipientType.TO, to); Multipart multipart = new MimeMultipart(); // PLAIN TEXT BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("Here is your plain text message"); multipart.addBodyPart(messageBodyPart); // HTML TEXT messageBodyPart = new MimeBodyPart(); String htmlText = "

    I am the html part

    "; messageBodyPart.setContent(htmlText, "text/html");

    13.19.1 Settings for well known mail providers

    multipart.addBodyPart(messageBodyPart); message.setContent(multipart); Transport.send(message); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    13.21 Read an Outlook MSG file Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0613.html When Outlook Express saves an email, it uses the EML format which is a good thing because the format is a standard. You read them with Javamail easily, see this HowTo. But Outlook (not the Express but the one with Office) can only save an email with the MSG format which is Microsoft specific.

    13.22 msgparser http://auxilii.com/msgparser/ msgparser is a small open source Java library that parses Outlook .msg files and provides their content using Java objects. msgparser uses the Apache POI − POIFS library to parse the message files which use the OLE 2 Compound Document format. import java.util.List; import com.auxilii.msgparser.*; import com.auxilii.msgparser.attachment.*; public class SimpleMsgParser { public static void main(String[] args) throws Exception{ MsgParser msgp = new MsgParser(); Message msg = msgp.parseMsg("c:/temp/test2.msg"); String String String String

    fromEmail = msg.getFromEmail(); fromName = msg.getFromName(); subject = msg.getSubject(); body = msg.getBodyText();

    System.out.println("From :" + fromName + " <" + fromEmail + ">"); System.out.println("Subject :" + subject); System.out.println(""); System.out.println(body); System.out.println(""); List atts = msg.getAttachments(); for (Attachment att : atts) { if (att instanceof FileAttachment) { FileAttachment file = (FileAttachment) att; System.out.println("Attachment : " + file.getFilename());

    13.21 Read an Outlook MSG file

    // you get the actual attachment with // byte date[] = file.getData(); } } } }

    13.23 Apache POI HSMF http://poi.apache.org/hsmf/ HSMF is the POI Project's pure Java implementation of the Outlook MSG format.

    13.24 jmbox https://jmbox.dev.java.net/ The jmbox project (read jambox) is a Local Store Provider for JavaMail, enabling developers to use JavaMail api to manage the mail stored in local repositories like Outlook Express, Mozilla, Netscape etc. At the moment are supported navigation and reading from Outlook Express 5/6 mail (dbx format).

    13.25 Handle EML file with JavaMail Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0458.html When saving an email to a file, the resulting file has an eml extension (email files−−which are in RFC 822 format). This kind of file can be read and parsed by JavaMail. import import import import

    java.util.*; java.io.*; javax.mail.*; javax.mail.internet.*;

    public class ReadEmail { public static void main(String args[]) throws Exception{ display(new File("C:\\temp\\message.eml")); } public static void display(File emlFile) throws Exception{ Properties props = System.getProperties(); props.put("mail.host", "smtp.dummydomain.com"); props.put("mail.transport.protocol", "smtp"); Session mailSession = Session.getDefaultInstance(props, null); InputStream source = new FileInputStream(emlFile); MimeMessage message = new MimeMessage(mailSession, source);

    System.out.println("Subject : " + message.getSubject());

    13.23 Apache POI HSMF

    System.out.println("From : " + message.getFrom()[0]); System.out.println("−−−−−−−−−−−−−−"); System.out.println("Body : " + message.getContent()); } }

    A typical eml looks like this : X−Mozilla−Status: 0001 X−Mozilla−Status2: 00000000 Received: from tomts25−srv.bellnexxia.net (tomts25.bellnexxia.net [209.226.175.188]) by tactika.com (8.9.3/8.9.3) with ESMTP id NAA07621 for ; Sun, 1 Feb 2004 13:25:33 −0500 (EST) Date: Sun, 01 Feb 2004 13:31:40 −0500 From: real gagnon Reply−To: [email protected] User−Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en−US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X−Accept−Language: en−us, en MIME−Version: 1.0 To: [email protected] Subject: Example for HowTo Content−Type: text/plain; charset=us−ascii; format=flowed Content−Transfer−Encoding: 7bit X−UIDL: oP#!!c]^!!1;−!!T@1"!

    This is an example for HowTo

    Running the above HowTo gives this output : Subject : Example for HowTo From : real gagnon −−−−−−−−−−−−−− Body : This is an example for HowTo If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    13.26 Check if a file was modified on the server Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0069.html URL u =null; long timestamp = 0; try { u = new URL(getDocumentBase(), "test.gif"); URLConnection uc = u.openConnection(); uc.setUseCaches(false);

    13.26 Check if a file was modified on the server

    /* ** use timestamp has a reference, re−open an URLConnection ** to the same file to check if the timestamp is different ** with the getLastModified() method. */ timestamp = uc.getLastModified(); } catch (Exception e) { e.printStackTrace(); } }

    13.27 Check if a page exists Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0059.html [JDK1.1] import java.net.*; import java.io.*; public class URLUtils { public static void main(String s[]) { System.out.println(URLUtils.exists("http://www.rgagnon.com/howto.html")); System.out.println(URLUtils.exists("http://www.rgagnon.com/pagenotfound.html")); /* output : true false */ } public static boolean exists(String URLName){ try { HttpURLConnection.setFollowRedirects(false); // note : you may also need // HttpURLConnection.setInstanceFollowRedirects(false) HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection(); con.setRequestMethod("HEAD"); return (con.getResponseCode() == HttpURLConnection.HTTP_OK); } catch (Exception e) { e.printStackTrace(); return false; } } } Thanks to Steve B. for the bug fix!

    The following is doing the same thing but this time we identify ourself to a proxy. See also this HowTo. import java.net.*; import java.io.*; import java.util.Properties;

    13.27 Check if a page exists

    public class URLUtils { public static void main(String s[]) { System.out.println(exists("http://www.rgagnon.com")); System.out.println(exists("http://www.yahoo.com")); }

    public static boolean exists(String URLName){ try { Properties systemSettings = System.getProperties(); systemSettings.put("proxySet", "true"); systemSettings.put("http.proxyHost","proxy.mycompany.local") ; systemSettings.put("http.proxyPort", "80") ; URL u = new URL(URLName); HttpURLConnection con = (HttpURLConnection) u.openConnection(); // // it's not the greatest idea to use a sun.misc.* class // Sun strongly advises not to use them since they can // change or go away in a future release so beware. // sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder(); String encodedUserPwd = encoder.encode("domain\\username:password".getBytes()); con.setRequestProperty ("Proxy−Authorization", "Basic " + encodedUserPwd); con.setRequestMethod("HEAD"); System.out.println (con.getResponseCode() + " : " + con.getResponseMessage()); return (con.getResponseCode() == HttpURLConnection.HTTP_OK); } catch (Exception e) { e.printStackTrace(); return false; } } }

    13.28 Connect through a Proxy Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0085.html You have to set the following properties : http.proxyHost (default: <none>) http.proxyPort (default: 80 if http.proxyHost specified) http.nonProxyHosts (default: <none>)

    NOTE: proxyHost, proxyPort are deprecated. you have to prefix them with "http.". NOTE: Those properties are documented here : http://java.sun.com/j2se/1.4/docs/guide/net/properties.html. You can set the required properties when starting the JVM for a JAVA application from the command line:

    13.28 Connect through a Proxy

    java

    −Dhttp.proxyHost=myproxyserver.com

    −Dhttp.proxyPort=80 MyJavaApp

    Or in your source : import java.util.Properties; ... Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost", "myProxyServer.com"); systemSettings.put("http.proxyPort", "80"); System.setProperties(systemSettings);

    You might need to identify yourself to the proxy server. One way is to use the HTTP property "Proxy−Authorization" with a username:password base64 encoded. Properties systemSettings = System.getProperties(); ... System.setProperties(systemSettings); URL url=new URL("http://someserver/somepage"); URLConnection uc = url.openConnection (); String encoded = new String (Base64.base64Encode(new String("username:password").getBytes())); uc.setRequestProperty("Proxy−Authorization", "Basic " + encoded); uc.connect(); NOTE: For a base64 function, see this How−to.

    The following example dumps the content of a URL but before we identify ourself to the proxy import java.net.*; import java.io.*; import java.util.Properties; public class URLUtils { public static void main(String s[]) { URLUtils.dump("http://www.yahoo.com"); System.out.println("**************"); URLUtils.dump("https://www.paypal.com"); System.out.println("**************"); } public static void dump(String URLName){ try { DataInputStream di = null; FileOutputStream fo = null; byte [] b = new byte[1]; // PROXY Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost","proxy.mydomain.local") ; systemSettings.put("http.proxyPort", "80") ; URL u = new URL(URLName); HttpURLConnection con = (HttpURLConnection) u.openConnection(); // // it's not the greatest idea to use a sun.misc.* class // Sun strongly advises not to use them since they can // change or go away in a future release so beware. // sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();

    13.28 Connect through a Proxy

    String encodedUserPwd = encoder.encode("mydomain\\MYUSER:MYPASSWORD".getBytes()); con.setRequestProperty ("Proxy−Authorization", "Basic " + encodedUserPwd); // PROXY −−−−−−−−−− di = new DataInputStream(con.getInputStream()); while(−1 != di.read(b,0,1)) { System.out.print(new String(b)); } } catch (Exception e) { e.printStackTrace(); } } }

    With JDK1.2, the java.net.Authenticator can be used to send the credentials when needed. When no username/password are provided then popup is shown to ask for the credentials. public static void dump(String URLName){ try { DataInputStream di = null; FileOutputStream fo = null; byte [] b = new byte[1]; // PROXY Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost","proxy.mydomain.local") ; systemSettings.put("http.proxyPort", "80") ; Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("mydomain\\username","password".toCharArray()); }}); URL u = new URL(URLName); HttpURLConnection con = (HttpURLConnection) u.openConnection(); di = new DataInputStream(con.getInputStream()); while(−1 != di.read(b,0,1)) { System.out.print(new String(b)); } } catch (Exception e) { e.printStackTrace(); } }

    In intranet environment, you may need to bypass the proxy server and go directly to the http server. The http.nonProxyHosts property indicates the hosts which should be connected too directly and not through the proxy server. The value can be a list of hosts, each seperated by a |, and in addition a wildcard character (*) can be used for matching. java.exe −Dhttp.nonProxyHosts="*.mycompany.com|*.mycompany.local|localhost" MyClass

    13.28 Connect through a Proxy

    13.29 Identify yourself using HTTP Authentification Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0084.html import java.net.*; import java.io.*; public class TestAuth { public static void main (String args[]){ /* ** args[0] is the URL protected ** args[1] is the username ** args[2] is the password */ try { BufferedReader in = new BufferedReader( new InputStreamReader (openURLForInput(new URL(args[0]), args[1], args[2]))); String line; while ((line = in.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } public static InputStream openURLForInput (URL url, String uname, String pword) throws IOException { URLConnection conn = url.openConnection(); conn.setDoInput (true); conn.setRequestProperty ("Authorization", userNamePasswordBase64(uname,pword)); conn.connect (); return conn.getInputStream(); } public static String userNamePasswordBase64 (String username, String password) { return "Basic " + base64Encode (username + ":" + password); } private final 'A', 'B', 'I', 'J', 'Q', 'R', 'Y', 'Z', 'g', 'h', 'o', 'p', 'w', 'x', '4', '5', };

    static char base64Array [] = { 'C', 'D', 'E', 'F', 'G', 'H', 'K', 'L', 'M', 'N', 'O', 'P', 'S', 'T', 'U', 'V', 'W', 'X', 'a', 'b', 'c', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'q', 'r', 's', 't', 'u', 'v', 'y', 'z', '0', '1', '2', '3', '6', '7', '8', '9', '+', '/'

    13.29 Identify yourself using HTTP Authentification

    private static String base64Encode (String string) String encodedString = ""; byte bytes [] = string.getBytes (); int i = 0; int pad = 0; while (i < bytes.length) { byte b1 = bytes [i++]; byte b2; byte b3; if (i >= bytes.length) { b2 = 0; b3 = 0; pad = 2; } else { b2 = bytes [i++]; if (i >= bytes.length) { b3 = 0; pad = 1; } else b3 = bytes [i++]; } byte c1 = (byte)(b1 >> 2); byte c2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4)); byte c3 = (byte)(((b2 & 0xf) << 2) | (b3 >> 6)); byte c4 = (byte)(b3 & 0x3f); encodedString += base64Array [c1]; encodedString += base64Array [c2]; switch (pad) { case 0: encodedString += base64Array [c3]; encodedString += base64Array [c4]; break; case 1: encodedString += base64Array [c3]; encodedString += "="; break; case 2: encodedString += "=="; break; } } return encodedString; }

    {

    }

    A better alternative is the Authenticator class, see this HowTo. NOTE: a simple explanation about the base64 encoding principle is shown in this How−to. An alternative way to Base64 encoding is to use the Base64 class in the sun.misc.* package. sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder(); String encodedUserPwd = encoder.encode("domain\\username:password".getBytes()); con.setRequestProperty("Proxy−Authorization", "Basic " + encodedUserPwd);

    13.29 Identify yourself using HTTP Authentification

    Use of the sun.* package is "discouraged" by sun and not formally supported. Those classes can be missing in your JDK release. Check this HowTo for a more official way to encode/decode to/from Base64.

    13.30 Talk to a CGI/Servlet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0082.html From the client point of view, there is no difference talking to CGI or Servlet. There is two ways to send a request to a CGI. The GET method contains encoded parameters in the URL. A typical URL talking to CGI using the GET method would be: new URL("http://www.server.com/cgi−bin/acgi.pl?name=real);

    Here we calling a script called aCGI.pl (a PERL script) passing the parameters name and site. Parameters are encoded, spaces are changed to "+" and special character to hexadecimal using a 3−letter escape sequence. Each parameter is delimited by the character "Habitually the encoding is done through the static method encode of the java.net.URLencoder class. String theCGI = "http://www.server.com/cgi−bin/aCGI.pl?"; String encoded = "name=" + URLencoder.encode("Real Gagnon"); URL cgiurl = new URL(thecgi + encoded);

    Once the URL is constructed, you call the CGI using the showDocument method (Applet). getAppletContext().showDocument(cgiurl);

    The CGI will process the result and produce a page to be displayed. The POST method allows the programmer to manipulate the data received from the CGI. First a connection is made to the CGI, an OutputStream is open to send the parameters (if any). Then InputStream is created to receive the result. String theCGI = "http://www.server.com/cgi−bin/aCGI.pl"; String encoded = "name=" + URLencoder.encode("Real Gagnon"); URL CGIurl = new URL(theCGI); URLConnection c = CGIurl.openConnection(); c.setDoOutput(true); c.setUseCaches(false); c.setRequestProperty("content−type","application/x−www−form−urlencoded"); DataOutputStream out = new DataOutputStream(c.getOutputStream()); out.writeBytes(encoded); out.flush(); out.close(); BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()); String aLine; while ((aLine = in.readLine()) != null) { // data from the CGI System.out.println(aLine); }

    13.30 Talk to a CGI/Servlet

    You can't do some output then some input and do again some output. You must do all the output and then the input. There is no "dialog" between the client and the server. The client make a request and the server send back the result and close the connection.

    13.31 Write/Read cookies using HTTP Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0092.html For a Java−Javascript solution, check this How−to.

    import java.net.*; import java.io.*; import java.util.*; class CookiesInJava { static Hashtable theCookies = new Hashtable(); /** * Send the Hashtable (theCookies) as cookies, and write them to * the specified URLconnection * * @param urlConn The connection to write the cookies to. * @param printCookies Print or not the action taken. * * @return The urlConn with the all the cookies in it. */ public URLConnection writeCookies (URLConnection urlConn, boolean printCookies){ String cookieString = ""; Enumeration keys = theCookies.keys(); while (keys.hasMoreElements()) { String key = (String)keys.nextElement(); cookieString += key + "=" + theCookies.get(key); if (keys.hasMoreElements()) cookieString += "; "; } urlConn.setRequestProperty("Cookie", cookieString); if (printCookies) System.out.println("Wrote cookies:\n " + cookieString); return urlConn; } /** * Read cookies from a specified URLConnection, and insert them * to the Hashtable * The hashtable represents the Cookies. * * @param urlConn the connection to read from * @param printCookies Print the cookies or not, for debugging * @param reset Clean the Hashtable or not */ public void readCookies(URLConnection urlConn, boolean printCookies, boolean reset){ if (reset) theCookies.clear(); int i=1; String hdrKey; String hdrString; String aCookie;

    13.31 Write/Read cookies using HTTP

    while ((hdrKey = urlConn.getHeaderFieldKey(i)) != null) { if (hdrKey.equals("Set−Cookie")) { hdrString = urlConn.getHeaderField(i); StringTokenizer st = new StringTokenizer(hdrString,","); while (st.hasMoreTokens()) { String s = st.nextToken(); aCookie = s.substring(0, s.indexOf(";")); // aCookie = hdrString.substring(0, s.indexOf(";")); int j = aCookie.indexOf("="); if (j != −1) { if (!theCookies.containsKey(aCookie.substring(0, j))){ // if the Cookie do not already exist then when keep it, // you may want to add some logic to update // the stored Cookie instead. thanks to rwhelan theCookies.put (aCookie.substring(0, j),aCookie.substring(j + 1)); if (printCookies){ System.out.println("Reading Key: " + aCookie.substring(0, j)); System.out.println(" Val: " + aCookie.substring(j + 1)); } } } } } i++; } } /** * Display all the cookies currently in the HashTable * */ public void viewAllCookies() { System.out.println("All Cookies are:"); Enumeration keys = theCookies.keys(); String key; while (keys.hasMoreElements()){ key = (String)keys.nextElement(); System.out.println(" " + key + "=" + theCookies.get(key)); } } /** * Display the current cookies in the URLConnection, * searching for the: "Cookie" header * * This is Valid only after a writeCookies operation. * * @param urlConn The URL to print the associates cookies in. */ public void viewURLCookies(URLConnection urlConn) { System.out.print("Cookies in this URLConnection are:\n "); System.out.println(urlConn.getRequestProperty("Cookie")); } /** * Add a specific cookie, by hand, to the HastTable of the Cookies * * @param _key The Key/Name of the Cookie * @param _val The Calue of the Cookie

    13.31 Write/Read cookies using HTTP

    * @param printCookies Print or not the result */ public void addCookie(String _key, String _val, boolean printCookies){ if (!theCookies.containsKey(_key)){ theCookies.put(_key,_val); if (printCookies){ System.out.println("Adding Cookie: "); System.out.println(" " + _key + " = " + _val); } } } } Thanks to Saar Machtiner for the bug fix

    13.32 Read a GIF or CLASS from an URL save it locally Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0060.html import java.io.*; import java.net.*; public class SuckURL { String aFile; String aURL; public static void main(String args[]) { // GIF JAVA How−to at Real's Home String url = "http://www.rgagnon.com/images/"; SuckURL b = new SuckURL(url, "jht.gif"); b.doit(); } SuckURL(String u, String s){ aURL = u; aFile = s; } public void doit() { DataInputStream di = null; FileOutputStream fo = null; byte [] b = new byte[1]; try { System.out.println("Sucking " + aFile); System.out.println(" at " + aURL ); // input URL url = new URL(aURL + aFile); URLConnection urlConnection = url.openConnection(); urlConnection.connect(); di = new DataInputStream(urlConnection.getInputStream()); // output fo = new FileOutputStream(aFile); // copy the actual file // (it would better to use a buffer bigger than this) while(−1 != di.read(b,0,1))

    13.32 Read a GIF or CLASS from an URL save it locally

    fo.write(b,0,1); di.close(); fo.close(); } catch (Exception ex) { System.out.println("Oups!!!"); ex.printStackTrace(); System.exit(1); } System.out.println("done."); } }

    This example dumps a page using the HTTPS protocol : import java.io.*; import java.net.*; public class URLReader { public static void main(String[] args) throws Exception { // no longer necessary since JSSE is now included in // recent jdk release... // Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); // System.setProperty("java.protocol.handler.pkgs", // "com.sun.net.ssl.internal.www.protocol"); URL url = new URL("https://www.thawte.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader( con.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } }

    There is an issue with root certificate from Verisign (jdk142 or less, you have exception talking about "untrusted server"), you may want to review this note : http://sunsolve.sun.com/search/document.do?assetkey=1−26−57436−1.

    13.33 Resolve a relative URL Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0297.html import java.net.URL; public class ResolveRelativeURL { public static void main (String[] args) throws java.net.MalformedURLException { URL relativeURL, baseURL; baseURL = new URL ("http://www.rgagnon.com/"); relativeURL = new URL ( baseURL, "./javadetails/java−0001.html"); System.out.println ( relativeURL.toExternalForm ()); /* output :

    13.33 Resolve a relative URL

    http://www.rgagnon.com/javadetails/java−0001.html */ } }

    13.34 File size from URL Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0298.html import java.io.*; import java.net.*; public class FileSizeFromURL { public static final void main(String[] args) { URL url; URLConnection conn; int size; if(args.length != 1) { System.out.println("Usage: FileSizeFromURL "); return; } try { url = new URL(args[0]); conn = url.openConnection(); size = conn.getContentLength(); if(size <0) System.out.println("Could not determine file size."); else System.out.println(args[0] + "\nSize: " + size); conn.getInputStream().close(); } catch(Exception e) { e.printStackTrace(); } } }

    13.35 Use the HTTPS protocol Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0308.html For Applets, both IE and NN have implemented https in their java.net.URL class so just use it exactly as you would for a regular http URL. URL ssl = new URL("https://www.secureserver.com); InputStream is = ssl.openStream();

    For application, take a look at the Sun's Secure Socket Extension (JSSE). Before connecting with a secure URL, we must do this first :

    13.34 File size from URL

    java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); A useful link for that is this JavaWorld's Tip

    Since JDK 1.4, the JSSE package is included so you don't have to add anything special. However you may need to import the certificate from the host (that is the server that you are connecting to using the https: protocol). One easy way to do this is to open a secured page (say https://mysecuredhost.com) with IE, click on the SSL−symbol (bottom right) and exported the key into the file "c:\cacerts.ce". Go in "%java_home%\bin" and type this: keytool −import −v −alias meincert −trustcacerts −file c:\

    13.36 Fetch a page from Google Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0399.html You can't directly fetch a page from Google because a check is made (by Google) to restrict access to "real" browser so a "403" HTTP code is returned to your Java program. You need to fool Google by pretending to be a legitimate browser. String search= "What you want to search for"; String google="http://www.google.ca/search?q=" + search + "e=UTF8";

    URL urlObject = new URL(google); URLConnection con = urlObject.openConnection(); con.setRequestProperty ( "User−Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" ); webData = new BufferedReader(new InputStreamReader(con.getInputStream())); ...

    Note : You may want to take a look at http://www.google.com/apis/ to learn how to interact with Google via the official API's. As seen above, you can directly override the HTTP header. Another way is to start the program with a modified System.property http.agent. >java "−Dhttp.agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" MyClass

    or in your program System.setProperty ("http.agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");

    13.36 Fetch a page from Google

    13.37 Upload a file to a server Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0543.html To upload a file to a server you need something on the server side to accept the file, you can't do it with client−side code only. A simple way to use the HTML tag in a FORM
    File to upload: <


    which looks like File to upload: The associated FORM target is a script on the server side that can handle HTTP file upload. Typically in Java, it's a servlet. The 2 most popular Java packages (server−side) to handle file upload are : • Jakarta Commons File Upload • O'reilly MultipartRequest (com.oreilly.servlet) On the client side, a java application can use Jakarta Commons HTTP client to initiate a file upload. Postlet is a Java applet used to enable websites to allow their users to send multiple files to a webserver with a few simple clicks. Postlet is useable with any server side scripting language that is capable of handling file uploads.

    13.38 Connect through a Proxy Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0085.html You have to set the following properties : http.proxyHost (default: <none>) http.proxyPort (default: 80 if http.proxyHost specified) http.nonProxyHosts (default: <none>)

    NOTE: proxyHost, proxyPort are deprecated. you have to prefix them with "http.". NOTE: Those properties are documented here : http://java.sun.com/j2se/1.4/docs/guide/net/properties.html. You can set the required properties when starting the JVM for a JAVA application from the command line: java

    −Dhttp.proxyHost=myproxyserver.com

    Or in your source : 13.37 Upload a file to a server

    −Dhttp.proxyPort=80 MyJavaApp

    import java.util.Properties; ... Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost", "myProxyServer.com"); systemSettings.put("http.proxyPort", "80"); System.setProperties(systemSettings);

    You might need to identify yourself to the proxy server. One way is to use the HTTP property "Proxy−Authorization" with a username:password base64 encoded. Properties systemSettings = System.getProperties(); ... System.setProperties(systemSettings); URL url=new URL("http://someserver/somepage"); URLConnection uc = url.openConnection (); String encoded = new String (Base64.base64Encode(new String("username:password").getBytes())); uc.setRequestProperty("Proxy−Authorization", "Basic " + encoded); uc.connect(); NOTE: For a base64 function, see this How−to.

    The following example dumps the content of a URL but before we identify ourself to the proxy import java.net.*; import java.io.*; import java.util.Properties; public class URLUtils { public static void main(String s[]) { URLUtils.dump("http://www.yahoo.com"); System.out.println("**************"); URLUtils.dump("https://www.paypal.com"); System.out.println("**************"); } public static void dump(String URLName){ try { DataInputStream di = null; FileOutputStream fo = null; byte [] b = new byte[1]; // PROXY Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost","proxy.mydomain.local") ; systemSettings.put("http.proxyPort", "80") ; URL u = new URL(URLName); HttpURLConnection con = (HttpURLConnection) u.openConnection(); // // it's not the greatest idea to use a sun.misc.* class // Sun strongly advises not to use them since they can // change or go away in a future release so beware. // sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder(); String encodedUserPwd = encoder.encode("mydomain\\MYUSER:MYPASSWORD".getBytes()); con.setRequestProperty ("Proxy−Authorization", "Basic " + encodedUserPwd);

    13.37 Upload a file to a server

    // PROXY −−−−−−−−−− di = new DataInputStream(con.getInputStream()); while(−1 != di.read(b,0,1)) { System.out.print(new String(b)); } } catch (Exception e) { e.printStackTrace(); } } }

    With JDK1.2, the java.net.Authenticator can be used to send the credentials when needed. When no username/password are provided then popup is shown to ask for the credentials. public static void dump(String URLName){ try { DataInputStream di = null; FileOutputStream fo = null; byte [] b = new byte[1]; // PROXY Properties systemSettings = System.getProperties(); systemSettings.put("http.proxyHost","proxy.mydomain.local") ; systemSettings.put("http.proxyPort", "80") ; Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("mydomain\\username","password".toCharArray()); }}); URL u = new URL(URLName); HttpURLConnection con = (HttpURLConnection) u.openConnection(); di = new DataInputStream(con.getInputStream()); while(−1 != di.read(b,0,1)) { System.out.print(new String(b)); } } catch (Exception e) { e.printStackTrace(); } }

    In intranet environment, you may need to bypass the proxy server and go directly to the http server. The http.nonProxyHosts property indicates the hosts which should be connected too directly and not through the proxy server. The value can be a list of hosts, each seperated by a |, and in addition a wildcard character (*) can be used for matching. java.exe −Dhttp.nonProxyHosts="*.mycompany.com|*.mycompany.local|localhost" MyClass

    13.37 Upload a file to a server

    13.39 Have timeout on socket connection Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0086.html [JDK11] ServerSocket server = new ServerSocket(port); // timeout after 60 seconds server.setSoTimeout(60000); try { Socket socket=server.accept(); } catch ( java.io.InterruptedIOException e ) { System.err.println( "Timed Out (60 sec)!" ); }

    This is true for READ operation too. Since READ operation blocks as long necessary it may be wise to use the setSoTimeout() method. Note that when the TIMEOUT expires, an InterruptException is thrown. However, the socket is still connected even though the Exception was raised.

    13.40 Ping a server Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0093.html It's not possible to really "ping" a machine to check if it's alive or not (it's a long story, but to keep it short I will just say that the Socket class is not low−level enough for that operation). But we can emulate a ping by talking the "echo port". On a server, the echo port is always port 7. We write a string to that port and the server will echo the string. import java.io.*; import java.net.*; public class PseudoPing { public static void main(String args[]) { try { Socket t = new Socket(args[0], 7); DataInputStream dis = new DataInputStream(t.getInputStream()); PrintStream ps = new PrintStream(t.getOutputStream()); ps.println("Hello"); String str = dis.readLine(); if (str.equals("Hello")) System.out.println("Alive!") ; else System.out.println("Dead or echo port not responding"); t.close(); } catch (IOException e) { e.printStackTrace();} } } } NOTE: To make this a more "complete PING", you may want to check this How−to to display the response time.

    13.39 Have timeout on socket connection

    Since JDK1.5, java.net.InetAddress.isReachable(int) can be used to check if a server is reachable or not. import java.io.*; import java.net.*; public class ReachableTest { public static void main(String args[]) { try { InetAddress address = InetAddress.getByName("web.mit.edu"); System.out.println("Name: " + address.getHostName()); System.out.println("Addr: " + address.getHostAddress()); System.out.println("Reach: " + address.isReachable(3000)); } catch (UnknownHostException e) { System.err.println("Unable to lookup web.mit.edu"); } catch (IOException e) { System.err.println("Unable to reach web.mit.edu"); } } }

    isReachable() will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host. But most Internet sites have disabled the service or blocked the requests (except some university web sites like the example above) .

    13.41 Get the Date from server Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0094.html This can be done by opening a socket to the port "daytime" (port 13) (on Unix or NT machine). import java.net.*; import java.io.*; public class GetTime { public static void main(String args[]) { if (args.length != 1) { System.out.println("Usage: GetTime HOST"); return; } try { Socket s = new Socket(args[0],13); InputStream is = s.getInputStream(); while (true) { byte b[] = new byte[100]; int i=is.read(b); if (i==−1) return; System.out.print(new String(b,0,i)); } } catch (Exception e) { e.printStackTrace(); } }

    13.41 Get the Date from server

    }

    13.42 Get the client IP address Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0095.html import java.net.*; import java.io.*; import java.applet.*; public class GetClientIP extends Applet { public void init() { try { InetAddress thisIp = InetAddress.getLocalHost(); System.out.println("IP:"+thisIp.getHostAddress()); } catch(Exception e) { e.printStackTrace(); } } } <APPLET CODE="GetClientIP.class" HEIGHT=10 WIDTH=10> Check JAVA console for output /BODY Try it here NOTE: Netscape returns the IP address with the default security settings so it's not problem. With IE5, you must go to the security TAB, Internet, Java Custom, Edit and select "Allow access to all IP address".

    Using a Servlet, this can be done with : public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { String IP = req.getRemoteAddr(); }

    If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    13.43 Use the java.net.Socket.setSoLinger method Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0293.html By using the setSoLinger() method, you can explicitly set a delay before a reset is sent, giving 13.42 Get the client IP address

    more time for data to be read or send, or you can specify a delay of zero, meaning a reset will be sent as soon as the java.net.Socket.close() method is invoked. You can possibly increase performance with a delay of zero. Note that if a linger time is set to zero, then any unsent packets are thrown away when the socket is closed otherwise the close() method blocks while waiting the specified number of seconds for the data to be sent, and acknowledgements to be received. The java.net.Socket.setSoLinger() method accepts as parameters a boolean and an int. The boolean flag activates or deactivates the SO_LINGER option, and the int controls the delay time (in seconds, max 65535). You get the current "linger" setting with java.net.Socket.getSoLinger()

    13.44 Use the java.net.Socket.setTcpNoDelay method Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0294.html java.net.Socket.setTcpNoDelay() is used to enable/disable TCP_NODELAY which disable/enable Nagle's algorithm. Nagle's algorithm try to conserve bandwidth by minimizing the number of segments that are sent. When applications wish to decrease network latency and increase performance, they can disable Nagle's algorithm (that is enable TCP_NODELAY). Data will be sent earlier, at the cost of an increase in bandwidth consumption. The Nagle's algorithm is described in RFC 896. You get the current "TCP_NODELAY" setting with java.net.Socket.getTcpNoDelay()

    13.45 Find out who is accessing my ServerSocket Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0295.html Socket aSock = myServerSocket.accept(); System.out.println ("Connection from : " + aSock.getInetAddress().getHostAddress() + ':' + aSock.getPort());

    13.46 Transfer a file via Socket Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0542.html A client module connects to a server then a file is sent to the client. This exemple is very simple with no authentication and hard−coded filename!

    First a server module.

    13.44 Use the java.net.Socket.setTcpNoDelay method

    import java.net.*; import java.io.*; public class FileServer { public static void main (String [] args ) throws IOException { // create socket ServerSocket servsock = new ServerSocket(13267); while (true) { System.out.println("Waiting..."); Socket sock = servsock.accept(); System.out.println("Accepted connection : " + sock); // sendfile File myFile = new File ("source.pdf"); byte [] mybytearray = new byte [(int)myFile.length()]; FileInputStream fis = new FileInputStream(myFile); BufferedInputStream bis = new BufferedInputStream(fis); bis.read(mybytearray,0,mybytearray.length); OutputStream os = sock.getOutputStream(); System.out.println("Sending..."); os.write(mybytearray,0,mybytearray.length); os.flush(); sock.close(); } } }

    The client module import java.net.*; import java.io.*; public class FileClient{ public static void main (String [] args ) throws IOException { int filesize=6022386; // filesize temporary hardcoded long start = System.currentTimeMillis(); int bytesRead; int current = 0; // localhost for testing Socket sock = new Socket("127.0.0.1",13267); System.out.println("Connecting..."); // receive file byte [] mybytearray = new byte [filesize]; InputStream is = sock.getInputStream(); FileOutputStream fos = new FileOutputStream("source−copy.pdf"); BufferedOutputStream bos = new BufferedOutputStream(fos); bytesRead = is.read(mybytearray,0,mybytearray.length); current = bytesRead; // thanks to A. Cádiz for the bug fix do { bytesRead = is.read(mybytearray, current, (mybytearray.length−current)); if(bytesRead >= 0) current += bytesRead; } while(bytesRead > −1); bos.write(mybytearray, 0 , current); long end = System.currentTimeMillis(); System.out.println(end−start);

    13.44 Use the java.net.Socket.setTcpNoDelay method

    bos.close(); sock.close(); } }

    Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

    13.44 Use the java.net.Socket.setTcpNoDelay method

    14 Security 14.1 java−security

    14.2 Encrypt a password Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0400.html Message digests are secure one−way hash functions that take arbitrary−sized data and output a fixed−length hash value. public class CryptoUtils { public static void main(String arg[]) { try { // quick way to do input from the keyboard, now deprecated... java.io.StreamTokenizer Input=new java.io.StreamTokenizer(System.in); // System.out.print("Input your secret password : "); Input.nextToken(); String secret = new String(CryptoUtils.encrypt(Input.sval)); System.out.println("the encrypted result : " + secret); boolean ok = true; String s = ""; while (ok) { System.out.print("Now try to enter a password : " ); Input.nextToken(); s = new String(CryptoUtils.encrypt(Input.sval)); if (secret.equals(s)){ System.out.println("You got it!"); ok = false; } else System.out.println("Wrong, try again...!"); } } catch (Exception e){ e.printStackTrace(); } } public static byte[] encrypt(String x) throws Exception { java.security.MessageDigest d =null; d = java.security.MessageDigest.getInstance("SHA−1"); d.reset(); d.update(x.getBytes()); return d.digest(); } }

    The output is :

    14 Security

    Input your secret password : howto the encrypted result : ûóbf−m¦esd Now try to enter a password : Howto Wrong, try again...! Now try to enter a password : howTo Wrong, try again...! Now try to enter a password : howto You got it!

    If you need to save the encrypted string into a file, you may need to transform it into a hexadecimal string because the encrypted string may contains non−printable characters. One technique is to encode using Base64 the encrypted string. sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder(); String encoded=encoder.encode(secret.getBytes()); // encoded is a string with printable characters.

    Or we can simply convert the byte array into an hexadecimal string: public class StringUtils { public static void main(String arg[]) { byte b[] = { 7, 42, −1, −127 }; // 7, 2A, FF, 81 System.out.println(byteArrayToHexString(b)); /* output : 072AFF81 */ b = hexStringToByteArray(byteArrayToHexString(b)); for (int i = 0; i < b.length; i++) { System.out.println(b[i]); } /* output : 7 42 −1 −127 */ } public static String byteArrayToHexString(byte[] b){ StringBuffer sb = new StringBuffer(b.length * 2); for (int i = 0; i < b.length; i++){ int v = b[i] &0xff; if (v < 16) { sb.append('0'); } sb.append(Integer.toHexString(v)); } return sb.toString().toUpperCase(); } public static byte[] hexStringToByteArray(String s) { byte[] b = new byte[s.length() / 2]; for (int i = 0; i < b.length; i++){ int index = i * 2; int v = Integer.parseInt(s.substring(index, index + 2), 16);

    14 Security

    b[i] = (byte)v; } return b; } }

    14.3 Create a checksum Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0416.html MD5 digests have been widely used in the software world to provide some assurance that a downloaded file has not been altered. A user can compare a published MD5 sum with the checksum of a downloaded file. import java.io.*; import java.security.MessageDigest; public class MD5Checksum { public static byte[] createChecksum(String filename) throws Exception { InputStream fis = new FileInputStream(filename); byte[] buffer = new byte[1024]; MessageDigest complete = MessageDigest.getInstance("MD5"); int numRead; do { numRead = fis.read(buffer); if (numRead > 0) { complete.update(buffer, 0, numRead); } } while (numRead != −1); fis.close(); return complete.digest(); } // see this How−to for a faster way to convert // a byte array to a HEX string public static String getMD5Checksum(String filename) throws Exception { byte[] b = createChecksum(filename); String result = ""; for (int i=0; i < b.length; i++) { result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); } return result; } public static void main(String args[]) { try { System.out.println(getMD5Checksum("apache−tomcat−5.5.17.exe")); // output : // 0bb2827c5eacf570b6064e24e0e6653b // ref : // http://www.apache.org/dist/ // tomcat/tomcat−5/v5.5.17/bin // /apache−tomcat−5.5.17.exe.MD5

    14.3 Create a checksum

    // 0bb2827c5eacf570b6064e24e0e6653b *apache−tomcat−5.5.17.exe } catch (Exception e) { e.printStackTrace(); } } }

    The next example is used to create a .chk file which contains a MD5 checksum of a given file. The same program is used to check if a file has been altered by looking at previously generated .chk file and compared with current checksum of the given file. import java.security.*; import java.io.*; public class Checksum { // // returns 0 error // 1 ok (create) // 1 same (check) // 2 different (check) // public static void main(String args[]) { if (args.length == 2) { if (args[0].equals("create")) { System.exit(new Checksum().create(args[1])); } else if (args[0].equals("check")) { System.exit(new Checksum().check(args[1])); } } else { System.out.println("Usage : java Checksum create [filename]\n"+ " java Checksum check [filename]"); } }

    public int create(String filename){ try { byte[] chk = createChecksum(filename); File f = new File(filename + ".chk"); OutputStream os = new FileOutputStream(f); os.write(chk); os.close(); return 1; } catch(Exception e) { e.printStackTrace(); return 0; } } public int check(String filename){ int rc = 0; try { byte[] chk1 = createChecksum(filename); byte[] chk2 = new byte[chk1.length]; File f = new File(filename + ".chk"); InputStream is = new FileInputStream(f);

    14.3 Create a checksum

    is.read(chk2); if (new String(chk2).equals(new String(chk1))) { System.out.println("Same!"); rc = 1; } else { System.out.println("Different!"); rc = 2; } is.close(); return rc; } catch(Exception e) { e.printStackTrace(); return rc; } } public byte[] createChecksum(String filename) throws Exception{ InputStream fis = new FileInputStream(filename); byte[] buffer = new byte[1024]; MessageDigest complete = MessageDigest.getInstance("MD5"); int numRead; do { numRead = fis.read(buffer); if (numRead > 0) { complete.update(buffer, 0, numRead); } } while (numRead != −1); fis.close(); return complete.digest(); } }

    The java.util.zip package can be used to create a checksum. import java.io.*; import java.util.zip.CRC32; import java.util.zip.Checksum; public class ComputeCRC32 { public static long getChecksumValue(Checksum checksum, String fname) { try { BufferedInputStream is = new BufferedInputStream( new FileInputStream(fname)); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) >= 0) { checksum.update(bytes, 0, len); } is.close(); } catch (IOException e) { e.printStackTrace(); } return checksum.getValue(); } public static void main(String[] args) { if (args.length != 1) { System.err.println("Usage: java ComputeCRC32 ");

    14.3 Create a checksum

    System.exit(1); } long cs = getChecksumValue(new CRC32(), args[0]); System.out.println("crc32 " + args[0] + " : " + cs); } }

    MD5 checksum can be used to validate a password without passing the actual password. 1. The server sends a random string to the client. 2. The client appends his password to the random string, and returns an MD5 sum of the result to the server. 3. On the server, do the same and compare the MD5 sums. 4. If both MD5 are identicals then the password is good. If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    14.4 Get the user name Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0048.html In application : String username; username = System.getProperty("user.name");

    or in JDK1.5 public class Test { public static void main(String args[]) { com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem(); System.out.println(NTSystem.getName()); } }

    In Applet there is no way unless you ask for it or use a signed applet. If you have access to a server−side, something like an ASP page can be used to detect the current NT user name if the client is configured correcty. See this related HowTo for a JSP hack!

    14.5 Get username using NT Challenge (NTLM) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0441.html 14.4 Get the user name

    Even if the application server do not support NTLM protocol, it is possible to use it to extract the Windows username. From the server, we ask the browser to identify the current user, and "by hand", we extract the response from the answer. The browser client must support NT Challenge authentification mechanism (IE does). This is a quick HACK to extract the username! There is no security into this. Beware... [username.jsp] <%@ page import="sun.misc.BASE64Encoder" %>

    Network Windows USERNAME without any login (ie)

    <% String auth = request.getHeader("Authorization"); if (auth == null) { response.setStatus(response.SC_UNAUTHORIZED); response.setHeader("WWW−Authenticate", "NTLM"); return; } if (auth.startsWith("NTLM ")) { byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5)); int off = 0, length, offset; String s; if (msg[8] == 1) { off = 18; byte z = 0; byte[] msg1 = {(byte)'N', (byte)'T', (byte)'L', (byte)'M', (byte)'S', (byte)'S', (byte)'P', z, (byte)2, z, z, z, z, z, z, z, (byte)40, z, z, z, (byte)1, (byte)130, z, z, z, (byte)2, (byte)2, (byte)2, z, z, z, z, // z, z, z, z, z, z, z, z}; // response.setStatus(response.SC_UNAUTHORIZED); response.setHeader("WWW−Authenticate", "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1).trim()); return; } else if (msg[8] == 3) { off = 30; length = msg[off+17]*256 + msg[off+16]; offset = msg[off+19]*256 + msg[off+18]; s = new String(msg, offset, length); //out.println(s + " "); } else return; length = msg[off+1]*256 + msg[off]; offset = msg[off+3]*256 + msg[off+2]; s = new String(msg, offset, length); //out.println(s + " "); length = msg[off+9]*256 + msg[off+8]; offset = msg[off+11]*256 + msg[off+10]; s = new String(msg, offset, length); out.println("Hello <span style='position:relative; width:190;" + " height:10;filter:glow(Color=#009966,Strength=1)'>");

    14.4 Get the user name

    out.println(s + ""); } %> NOTES: A comment from Weijun Ji : This technique only works if a user has its IE browser security setting set at middle/low (or if the server is trusted like in an intranet environment). With this setting, browser will grab login username automatically. If the security setting is at high, then a window will prompt user for input. At that time, whatever username the user put in will be passed to the "NTLM program". Since the user is not authenticated, you have no way to know if this user is a true user or not. In this way, any user can pretend to be anybody else as long as he has his security level set as high.

    A comment from A. Santana : It didn't work for Firefox, so I did a silly workaround in the midtime. I removed everything is not a word or space... look: s.replaceAll("[^a−zA−Z\s]",""); You want to deeper into this subject, take a look at these sites : http://www.innovation.ch/java/ntlm.html http://free.tagish.net/jaas/index.jsp http://www.luigidragone.com/networking/ntlm.html Starting from jdk1.4.2, Sun provides support for NTLM, see http://java.sun.com/j2se/1.4.2/changes.html#networking For a complete solution see JCIFS (for Tomcat and others) at http://jcifs.samba.org

    14.6 Check if the current user belongs a specific Windows group/role Current version of this HowTo : http://www.rgagnon.com/javadetails/../pbdetails/pb−0227.html You can connect to the ActiveDirectory or use some API but an easy way is to use a connection to SQL Server. Send the query : SELECT is_member('mydomain\g_dept')

    and the result can be 0

    Current user is not a member of group or role.

    1

    Current user is a member of group or role.

    NULL

    Either group or role is not valid.

    14.7 Prompt for password from the console Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0375.html A separate thread is used to send to the console the backspace character to erase the last−typed character.

    14.6 Check if the current user belongs a specific Windows group/role

    import java.io.*; import java.awt.*; public class PwdConsole { public static void main(String[] args) throws Exception { ConsoleEraser consoleEraser = new ConsoleEraser(); System.out.print("Password? "); BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); consoleEraser.start(); String pass = stdin.readLine(); consoleEraser.halt(); System.out.print("\b"); System.out.println("Password: '" + pass + "'"); } } class ConsoleEraser extends Thread { private boolean running = true; public void run() { while (running) { System.out.print("\b "); } } public synchronized void halt() { running = false; } }

    Java SE6 provides a buiilt−in mechanism to input a password from the console. java.io.Console cons; char[] passwd; if ((cons = System.console()) != null & (passwd = cons.readPassword("[%s]", "Password:")) != null) { ... }

    14.8 Prevent XSS exploit Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0627.html According to Wikipedia, XSS exploit is a type of computer security vulnerability found in web applications which allow code injection by malicious web users into the web pages viewed by other users. If your WebApp expects a URL like http://www.server.com/app?name=John then a malicious user can build a special URL like http://www.server.com/app?name=<script> ... to "inject" his own script into your web app. This can be be very dangerous if the data is stored into a database and displayed to other users. Here a list of XSS test cases : http://ha.ckers.org/xss.html There are two ways to deal with this issue.

    14.8 Prevent XSS exploit

    14.9 Sanitize the input by removing suspicious tags. This regex function removes the obvious code to inject unwanted scripting. public static String sanitize(String string) { return string .replaceAll("(?i)<script.*?>.*?", "") // case 1 .replaceAll("(?i)<.*?javascript:.*?>.*?", "") // case 2 .replaceAll("(?i)<.*?\\s+on.*?>.*?", ""); // case 3 }

    • (?i) make it case insensitive • case 1 : <script> are removed • case 2 : javascript: call are removed • case 3 : remove on* attributes like onLoad or onClick Nothing beats good validation but then make sure to sanitize the value if it fails before redisplaying it. While you can call yourself the method to sanitize the received parameters, you should consider installing this process into a Java EE filter so the container will automatically do it for you. See this page at http://greatwebguy.com/programming/java/simple−cross−site−scripting−xss−servlet−filter/.

    14.10 Sanitize the output by removing suspicious characters. The idea is to sanitize a string before displaying it a user. This is done by replacing supicious characters by the corresponding entity. The JSTL taglib provides the tag tag to display a string. This tag will sanitize a string by default.

    The substitutions are : This JSP will display the script code and the browser will not execute it. <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <script> alert("hello")

    out with escapeXml=true





    This JSP will not display the script code and the browser execute it. <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <script> alert("hello")

    14.9 Sanitize the input by removing suspicious tags.

    out with escapeXml=false





    14.11 Display a simple username/password Dialog from an Applet Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0128.html NOTE: This way to authenticate a user is NOT secured at all since the required information is embedded in the Applet. [MyApplet.java] import java.awt.*; import java.net.*; public class MyApplet extends java.applet.Applet { public String username = ""; public String password = ""; public void init() { if (!login()) { try { getAppletContext().showDocument (new URL(getCodeBase()+"accessdenied.html"),"_top"); } catch (Exception e) {e.printStackTrace(); } } else { // here the username and password are OK } } public boolean login() { boolean userValid = false; MyLogin login = new MyLogin (new Frame("")); requestFocus(); if (login.id) { username = login.username.getText(); password = login.password.getText(); userValid = validateUser(username , password); System.out.println ("The password for " + username + " is " + (userValid?"valid":"invalid")); } else System.out.println ("Cancel was pressed."); login.dispose(); return userValid;

    14.11 Display a simple username/password Dialog from an Applet

    } private boolean validateUser(String usr, String pwd) { // here you will code some logic to validate the username // password... for testing purpose : // username = java password = avaj return (usr.equals("java") &pwd.equals("avaj")); } }

    [MyLogin.java] import java.awt.*; import java.awt.event.*; public class MyLogin extends Dialog implements ActionListener { boolean id = false; Button ok,can; TextField username; TextField password;

    MyLogin(Frame frame){ super(frame, "Welcome", true); setLayout(new FlowLayout()); username = new TextField(15); password = new TextField(15); password.setEchoChar('*'); add(new Label("User :")); add(username); add(new Label("Password :")); add(password); addOKCancelPanel(); createFrame(); pack(); setVisible(true); } void addOKCancelPanel() { Panel p = new Panel(); p.setLayout(new FlowLayout()); createButtons( p ); add( p ); } void createButtons(Panel p) { p.add(ok = new Button("OK")); ok.addActionListener(this); p.add(can = new Button("Cancel")); can.addActionListener(this); } void createFrame() { Dimension d = getToolkit().getScreenSize(); setLocation(d.width/4,d.height/3); } public void actionPerformed(ActionEvent ae){ if(ae.getSource() == ok) { id = true; setVisible(false); }

    14.11 Display a simple username/password Dialog from an Applet

    else if(ae.getSource() == can) { id = false; setVisible(false); } } }

    the HTML to test it out : [login.html]
    <APPLET CODE=MyApplet.class WIDTH=300 HEIGHT=300>
    NOTE: View the java console for infos about the login process

    A simple "Access is denied" page : [accessdenied.html] access is denied

    Written and compiled Réal Gagnon ©2007 [email protected] http://www.rgagnon.com

    14.11 Display a simple username/password Dialog from an Applet

    15 Swing 15.1 java−swing

    15.2 * Read me * Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0193.html NOTE: With the JDK1.2 release, it's recommended to use import javax.swing.*;

    instead of import com.sun.java.swing.*;

    IE or Netscape don't support directly Swing Applet. You must use the Java plugins. Then you will need to use the (IE) or <EMBED> (Netscape) HTML tag instead of the regular <APPLET> tag.

    15.3 Change component default font Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0335.html public static void setUIFont (javax.swing.plaf.FontUIResource f){ // // sets the default font for all Swing components. // ex. // setUIFont (new javax.swing.plaf.FontUIResource // ("Serif",Font.ITALIC,12)); // 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); } }

    For a particuliar component UIManager.put("Label.font",new Font("Serif",Font.ITALIC,12)); Swing UI default If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    15 Swing

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.4 Repaint problem under the mouse cursor (JDK1.2) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0206.html You probably have installed a Microsoft Theme on your desktop. Simply switch the mouse cursor to the regular Windows mouse cursor to correct the problem.

    15.5 Set the LookAndFeel Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0207.html By default, Swing will use the Metal LookAndFeel. To set the LookAndFeel to the current OS under which the JVM is running, use this snippet : try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); }

    Even with the new naming mecanism in JDK1.2, some LookAndFeel packages are keeping the oldname. Windows Motif Mac Metal Basic Multi

    com.sun.java.swing.plaf.windows (no change) com.sun.java.swing.plaf.motif (no change) com.sun.java.swing.plaf.mac (no change) javax.swing.plaf.metal (new) javax.swing.plaf.basic (new) javax.swing.plaf.multi (new)

    These packages are located in the rt.jar file.

    15.6 Use any LookAndFeel on any plateform Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0208.html There is some restriction to the usage of LookAndFeel when there are some copyright involved. For example, you can't activate the Mac LookAndFeel in a Windows environment.

    15.4 Repaint problem under the mouse cursor (JDK1.2)

    The trick is to fool Swing by setting the property os.name to a different value than real one to enable the use of "forbidden" LookAndFeel. From the command line, to activate Windows LookAndFeel on a non−Windows environment java −Dos.name=windows MySwingApp

    to activate Mac LookAndFeel on a non−Mac environment java −Dos.name=mac MySwingApp

    or you can do it in your source by doing something like: Properties p = System.getProperties(); p.put("os.name", "Mac"); System.setProperties(p); NOTE: Current Swing release for Windows does not include the necessary classes for the Mac's LookAndFeel anymore.

    It's not bad idea to set the look and feel to a known good value and then try the not−so−sure value. try { // sure look and feel UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); // not−so−sure look and feel System.setProperty("os.name", "Windows"); System.setProperty("os.version", "5.1"); UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception ex) { ex.printStackTrace(); }

    15.7 Use a Timer Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0220.html See this How−to.

    15.8 Share ActionEvent handler Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0212.html In this example, a JMenu, JToolbar and JButtons on a JFrame are sharing common ActionEvent handlers. import javax.swing.*; import java.awt.event.*;

    15.7 Use a Timer

    import java.awt.*; public class OpenAction SaveAction QuitAction

    ShareAction extends JFrame { openAction = new OpenAction(); saveAction = new SaveAction(); quitAction = new QuitAction();

    public static void main(String argv[]) { new ShareAction().setVisible(true); } ShareAction() { createMenu(); createToolBar(); createButtons(); pack(); // deal closing via the upper right "X" by redirecting to // quitAction addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e) { ActionEvent ae = new ActionEvent (quitAction, ActionEvent.ACTION_PERFORMED, "bebye"); JFrame j = (JFrame)e.getSource(); j.dispatchEvent(ae); } } ); } public Dimension getPreferredSize() { return new Dimension(300,300); } private void createMenu(){ JMenuBar mb = new JMenuBar(); JMenu file = new JMenu("File"); mb.add(file); file.add(openAction); file.add(saveAction); file.add(quitAction); setJMenuBar(mb); } private void createToolBar() { JToolBar bar = new JToolBar(); bar.add(openAction); bar.add(saveAction); bar.add(quitAction); getContentPane().add(bar, "North"); } private void createButtons() { JPanel j = new JPanel(); JButton b1 = new JButton("Open"); JButton b2 = new JButton("Save"); JButton b3 = new JButton("Quit"); b1.addActionListener(openAction); b2.addActionListener(saveAction); b3.addActionListener(quitAction);

    15.7 Use a Timer

    j.add(b1); j.add(b2); j.add(b3); getContentPane().add(j, "East"); } } class OpenAction extends AbstractAction { public OpenAction() { super("Open", new ImageIcon("open.gif")); } public void actionPerformed(ActionEvent e) { System.out.println("Open action"); } } class SaveAction extends AbstractAction { public SaveAction() { super("Save", new ImageIcon("save.gif")); } public void actionPerformed(ActionEvent e) { System.out.println("Save action"); } } class QuitAction extends AbstractAction { public QuitAction() { super("Quit", new ImageIcon("quit.gif")); } public void actionPerformed(ActionEvent e) { System.out.println("Quit action"); System.out.println("Bye."); System.exit(0); } }

    15.9 Get default values for Swing−based user interface Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0507.html This little class will dump to stdout the default values used by Swing. You can redirect the result to a file with >java UIDefaults > swing.props import import import import import

    java.util.Comparator; java.util.Iterator; java.util.Map; java.util.Set; java.util.TreeSet;

    import javax.swing.UIManager; public class UIDefaults { public static void main(String[] args) { try { Set defaults = UIManager.getLookAndFeelDefaults().entrySet(); // this TreeSet will hold the sorted properties

    15.9 Get default values for Swing−based user interface

    TreeSet ts = new TreeSet(new Comparator() { public int compare(Object a, Object b) { Map.Entry ea = (Map.Entry) a; Map.Entry eb = (Map.Entry) b; return ((String) ea.getKey()).compareTo(((String)eb.getKey())); } }); ts.addAll(defaults); for (Iterator i = ts.iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); System.out.print(entry.getKey() + " = " ); System.out.println(entry.getValue()); }

    } catch (Exception ex) { ex.printStackTrace(); } } }

    • For an example on how to change a default value see this HowTo • To change a value for a particuliar component, see this HowTo • Here a sample list for JavaUIDefaults If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.10 Have a systray icon (Windows) Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0612.html JDK 1.6 provides support for the Systray on the Windows plateform. A small icon is located at the bottom right of the Desktop.

    you can click on it to trigger an action or use this area to display notification.

    Use this small image to run this demo : import import import import

    java.awt.*; java.awt.image.*; java.awt.event.*; javax.swing.*;

    public class SysTrayDemo { protected static TrayIcon trayIcon; private static PopupMenu createTrayMenu() { ActionListener exitListener = new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Bye from the tray");

    15.10 Have a systray icon (Windows)

    System.exit(0); } }; ActionListener executeListener = new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog (null, "Popup from the action on the systray!", "User action", JOptionPane.INFORMATION_MESSAGE); trayIcon.displayMessage ("Done", "You can do it again if you want!", TrayIcon.MessageType.INFO); } }; PopupMenu menu = new PopupMenu(); MenuItem execItem = new MenuItem("Action..."); execItem.addActionListener(executeListener); menu.add(execItem); MenuItem exitItem = new MenuItem("Exit"); exitItem.addActionListener(exitListener); menu.add(exitItem); return menu; } /** * Loading the image from a file */ private static TrayIcon createTrayIconFromFile() { Image image = Toolkit.getDefaultToolkit().getImage("/temp/trayrealhowto.jpg"); PopupMenu popup = createTrayMenu(); TrayIcon ti = new TrayIcon(image, "Java System Tray Demo", popup); ti.setImageAutoSize(true); return ti; } /** * Loading the image from the classpath * if in a folder in a jar, remember to add the folder! * ex. /img/realhowto.jpg */ private static TrayIcon createTrayIconFromResource() throws java.io.IOException { ClassLoader cldr = SysTrayDemo.class.getClassLoader(); java.net.URL imageURL = cldr.getResource("trayrealhowto.jpg"); Image image = Toolkit.getDefaultToolkit().getImage(imageURL); PopupMenu popup = createTrayMenu(); TrayIcon ti = new TrayIcon(image, "Java System Tray Demo", popup); ti.setImageAutoSize(true); return ti; } /** * using a built−in icon * we need to convert the icon to an Image */ private static TrayIcon createTrayIconFromBuiltInIcon() { Icon icon = UIManager.getIcon("OptionPane.warningIcon"); PopupMenu popup = createTrayMenu(); Image image = iconToImage(icon); TrayIcon ti = new TrayIcon(image, "Java System Tray Demo", popup);

    15.10 Have a systray icon (Windows)

    ti.setImageAutoSize(true); return ti; } static Image iconToImage(Icon icon) { if (icon instanceof ImageIcon) { return ((ImageIcon)icon).getImage(); } else { int w = icon.getIconWidth(); int h = icon.getIconHeight(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage image = gc.createCompatibleImage(w, h); Graphics2D g = image.createGraphics(); icon.paintIcon(null, g, 0, 0); g.dispose(); return image; } } public static void main(String[] args) throws Exception { if (!SystemTray.isSupported()) { System.out.println ("System tray not supported on this platform"); System.exit(1); } try { SystemTray sysTray = SystemTray.getSystemTray(); trayIcon = createTrayIconFromFile(); //trayIcon = createTrayIconFromResource(); //trayIcon = createTrayIconFromBuiltInIcon(); sysTray.add(trayIcon); trayIcon.displayMessage("Ready", "Tray icon started and tready", TrayIcon.MessageType.INFO); } catch (AWTException e) { System.out.println("Unable to add icon to the system tray"); System.exit(1); } } }

    This code can load the icon from a file, a file in the classpath (resource) or use a built−in icon in the JDK.

    15.11 Close a JFrame under condition Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0340.html import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CloseOrNot extends JFrame {

    15.11 Close a JFrame under condition

    JTextField field1; JPanel panel; public CloseOrNot() { super( "CloseOrNot Frame" ); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); panel = new JPanel(); field1 = new JTextField( 10 ); panel.add( new JLabel("type yes to close the Frame ")); panel.add( field1 ); getContentPane().add( "Center", panel ); addWindowListener( new WindowAdapter() { public void windowOpened( WindowEvent e ){ field1.requestFocus(); } public void windowClosing( WindowEvent e ){ if (field1.getText().equals("yes")) { if (JOptionPane.showConfirmDialog (null,"Are you sure ?")==JOptionPane.YES_OPTION) { setVisible(false); dispose(); } } } } ); pack(); setVisible( true ); } public static void main(String args[]) { new CloseOrNot(); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.12 Maximize a JFrame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0479.html import java.awt.*; import javax.swing.*; public class TestMaxJFrame extends JFrame { public TestMaxJFrame() { GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); /* The next line determines if the taskbar (win) is covered if unremarked, the task will not be covered by the maximized JFRAME. */ // this.setMaximizedBounds(env.getMaximumWindowBounds()); this.setExtendedState(this.getExtendedState() | this.MAXIMIZED_BOTH); }

    15.12 Maximize a JFrame

    public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true); TestMaxJFrame t = new TestMaxJFrame(); t.setVisible(true); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.13 Capture System.out into a JFrame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0435.html import java.awt.*; import javax.swing.*; import java.io.*;

    /** * http://tanksoftware.com/juk/developer/src/com/ * tanksoftware/util/RedirectedFrame.java * A Java Swing class that captures output to the command line ** (eg, System.out.println) * RedirectedFrame *

    * This class was downloaded from: * Java CodeGuru (http://codeguru.earthweb.com/java/articles/382.shtml)
    * The origional author was Real Gagnon ([email protected]); * William Denniss has edited the code, improving its customizability * * In breif, this class captures all output to the system and prints it in * a frame. You can choose weither or not you want to catch errors, log * them to a file and more. * For more details, read the constructor method description */

    public class RedirectedFrame extends JFrame { // Class information public static final String PROGRAM_NAME = "Redirect Frame"; public static final String VERSION_NUMBER = "1.1"; public static final String DATE_UPDATED = "13 April 2001"; public static final String AUTHOR = "Real Gagnon − edited by William Denniss";

    private private private private private private

    boolean catchErrors; boolean logFile; String fileName; int width; int height; int closeOperation;

    15.13 Capture System.out into a JFrame

    TextArea aTextArea = new TextArea(); PrintStream aPrintStream = new PrintStream( new FilteredStream( new ByteArrayOutputStream())); /** Creates a new RedirectFrame. * From the moment it is created, * all System.out messages and error messages (if requested) * are diverted to this frame and appended to the log file * (if requested) * * for example: * RedirectedFrame outputFrame = * new RedirectedFrame (false, false, null, 700, 600, JFrame.DO_NOTHING_ON_CLOSE); * this will create a new RedirectedFrame that doesn't catch errors, * nor logs to the file, with the dimentions 700x600 and it doesn't * close this frame can be toggled to visible, hidden by a controlling * class by(using the example) outputFrame.setVisible(true|false) * @param catchErrors set this to true if you want the errors to * also be caught * @param logFile set this to true if you want the output logged * @param fileName the name of the file it is to be logged to * @param width the width of the frame * @param height the height of the frame * @param closeOperation the default close operation * (this must be one of the WindowConstants) */ public RedirectedFrame (boolean catchErrors, boolean logFile, String fileName, int width, int height, int closeOperation) { this.catchErrors = catchErrors; this.logFile = logFile; this.fileName = fileName; this.width = width; this.height = height; this.closeOperation = closeOperation; Container c = getContentPane(); setTitle("Output Frame"); setSize(width,height); c.setLayout(new BorderLayout()); c.add("Center" , aTextArea); displayLog(); this.logFile = logFile; System.setOut(aPrintStream); // catches System.out messages if (catchErrors) System.setErr(aPrintStream); // catches error messages // set the default closing operation to the one given setDefaultCloseOperation(closeOperation); Toolkit tk = Toolkit.getDefaultToolkit(); Image im = tk.getImage("myicon.gif"); setIconImage(im); }

    15.13 Capture System.out into a JFrame

    class FilteredStream extends FilterOutputStream { public FilteredStream(OutputStream aStream) { super(aStream); } public void write(byte b[]) throws IOException { String aString = new String(b); aTextArea.append(aString); } public void write(byte b[], int off, int len) throws IOException { String aString = new String(b , off , len); aTextArea.append(aString); if (logFile) { FileWriter aWriter = new FileWriter(fileName, true); aWriter.write(aString); aWriter.close(); } } } private void displayLog() { Dimension dim = getToolkit().getScreenSize(); Rectangle abounds = getBounds(); Dimension dd = getSize(); setLocation((dim.width − abounds.width) / 2, (dim.height − abounds.height) / 2); setVisible(true); requestFocus(); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.14 Remove the titlebar of JInternalFrame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0333.html ((javax.swing.plaf.basic.BasicInternalFrameUI) myInternalFrame.getUI()).setNorthPane(null);

    15.15 Have borders on a JWindow/JFrame Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0204.html You can't have a border directly on a JWindow or JFrame. You need to put a JPanel with the desired border using the default JWindow/JFrame LayouManager (a BorderLayout). Then the JPanel is extended giving the impression that its borders are the JWindow one. 15.14 Remove the titlebar of JInternalFrame

    import import import import

    javax.swing.*; javax.swing.border.*; java.awt.event.*; java.awt.*;

    public class MyWindow{ public static void main(String s[]) { JWindow win = new JWindow(); JPanel pan = new JPanel(); pan.setBorder(new LineBorder(Color.blue)); win.getContentPane().add(pan,"Center"); pan.setLayout(new FlowLayout()); pan.add(new JButton("Hello")); pan.add(new JButton("World")); win.setSize(200,200); win.setVisible(true); } }

    15.16 Display HTML in a JScrollPane Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0205.html The JTextPane can display simple HTML page. import import import import

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

    public class TestShowPage { public static void main(String args[]) { JTextPane tp = new JTextPane(); JScrollPane js = new JScrollPane(); js.getViewport().add(tp); JFrame jf = new JFrame(); jf.getContentPane().add(js); jf.pack(); jf.setSize(400,500); jf.setVisible(true); try { URL url = new URL("http://www.tactika.com/realhome/contents.html"); tp.setPage(url); } catch (Exception e) { e.printStackTrace(); } } }

    If the HTML is a located into a jar, ... URL url = getClass().getResource("contents.html");

    15.16 Display HTML in a JScrollPane

    tp.setPage(url); ...

    to set an anchor, you get the URL then add the "#anchor". ... URL url = getClass().getResource("contents.html"); tp.setPage(new URL(url.toExternalForm() + "#section42")); ...

    15.17 Use a JOptionPane Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0376.html import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MessageBox { /* These are a list of STATIC MODAL dialogs int return codes of button pressed: −1 0 1 2

    − − − −

    WINDOW CLOSED − the X PRESSED YES and OK NO CANCEL

    (thanks to flipside for the idea) */ public static int yesno(String theMessage){ int result = JOptionPane.showConfirmDialog((Component) null, theMessage, "alert", JOptionPane.YES_NO_OPTION); return result; } public static int yesnocancel(String theMessage){ int result = JOptionPane.showConfirmDialog((Component) null, theMessage, "alert", JOptionPane.YES_NO_CANCEL_OPTION); return result; } public static int okcancel(String theMessage){ int result = JOptionPane.showConfirmDialog((Component) null, theMessage, "alert", JOptionPane.OK_CANCEL_OPTION); return result; } public static int ok(String theMessage){ int result = JOptionPane.showConfirmDialog((Component) null, theMessage, "alert", JOptionPane.DEFAULT_OPTION); return result; }

    15.17 Use a JOptionPane

    public static void main(String args[]){ int i = MessageBox.yesno("Are your sure ?"); System.out.println("ret : " + i ); i = MessageBox.yesnocancel("Are your sure ?"); System.out.println("ret : " + i ); i = MessageBox.okcancel("Are your sure ?"); System.out.println("ret : " + i ); i = MessageBox.ok("Done."); System.out.println("ret : " + i ); } }

    15.18 Localize a JOptionPane dialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0138.html This example will show 2 radio buttons, one for english messages and buttons and the other one for french. Press the button to display a localized JOptionPane according to the radio button selected. Create 2 properties files, one for english , one for french. [JOptionPane_en.properties] Yes=Yes No=No Cancel=Cancel SaveMsg=Do you want to save your data [JOptionPane_fr.properties] Yes=Oui No=Non Cancel=Annuler SaveMsg=Voulez−vous sauvegarder vos donnees

    Then import import import import

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

    public class MessageBoxExample extends JPanel implements ActionListener { JButton go; AbstractButton button; ButtonGroup group; Locale locale; String msg ; public MessageBoxExample() { group = new ButtonGroup(); locale = Locale.US; // default value button = new JRadioButton("English", true); button.setActionCommand("en"); button.addActionListener(this); group.add(button); add(button);

    15.18 Localize a JOptionPane dialog

    button = new JRadioButton("Francais"); button.setActionCommand("fr"); button.addActionListener(this); group.add(button); add(button); go = new JButton("Do it"); go.addActionListener(this); add(go); locale = Locale.US; } public void setUILanguage() { ResourceBundle rb; rb = ResourceBundle.getBundle("JOptionPane", locale); UIManager.put("OptionPane.yesButtonText", rb.getString("Yes")); UIManager.put("OptionPane.noButtonText", rb.getString("No")); UIManager.put("OptionPane.cancelButtonText", rb.getString("Cancel")); msg = rb.getString("SaveMsg"); } public void actionPerformed(ActionEvent e) { int result; if (e.getSource() instanceof JRadioButton) { if (e.getActionCommand().equals("en")) locale = Locale.US; else locale = Locale.FRANCE; setUILanguage(); } else { // the button action result = JOptionPane.showConfirmDialog(this,msg); System.out.println(result); } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); MessageBoxExample panel = new MessageBoxExample(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } }

    15.18 Localize a JOptionPane dialog

    15.19 Customize JOptionPane buttons Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0310.html String[] buttons = {"Yes", "Yes to all", "No", "Cancel"}; int rc = JOptionPane.showOptionDialog(null, "Do you really want to delete this file [" + filename + "]?", "Confirmation", JOptionPane.WARNING_MESSAGE, 0, null, buttons, buttons[2]); if (rc==−1) { System.out.println("Dialog closed without clicking a button."); } else { System.out.println(buttons[rc] + " was clicked"); }

    15.20 Localize a JFileChooser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0299.html Modern Swing release have now built−in ready−to−use translations for the JFileChooser. The language is choosen based on the current Locale. So you don't have to do anything to display the JFileChooser in the right language. The user interface elements provided by the J2SE Runtime Environment 5.0, include Swing dialogs, messages written by the runtime environment to the standard output and standard error streams, as well as messages produced by the tools provided with the JRE. These user interface elements are localized into the following languages: Sun Supported Locales This example will show 2 radio buttons, one for english, one for french. Press the button to display a localized JFileChooser according to the radio button selected. Create 2 properties files, one for english , one for french (these files are incomplete but should be enough to get you started). [JFileChooser_en.properties] Title=Real's JFileChooser lookInLabelText=Current filesOfTypeLabelText=File type upFolderToolTipText=go up

    [JFileChooser_fr.properties]

    15.19 Customize JOptionPane buttons

    Title=JFileChooser de R\u00e9al lookInLabelText=Courant filesOfTypeLabelText=Type de fichier upFolderToolTipText=Remonte

    Then [LocalizeJFileChooser.java] import import import import

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

    public class LocalizeJFileChooser extends JPanel implements ActionListener { JButton go; AbstractButton button; ButtonGroup group; Locale locale; String msg ; protected JFileChooser z_chooser; String z_choosertitle; public LocalizeJFileChooser() { group = new ButtonGroup(); locale = Locale.US; // default value button = new JRadioButton("English", true); button.setActionCommand("en"); button.addActionListener(this); group.add(button); add(button); button = new JRadioButton("Francais"); button.setActionCommand("fr"); button.addActionListener(this); group.add(button); add(button); go = new JButton("Do it"); go.addActionListener(this); add(go); locale = Locale.US; } public void setUILanguage() { ResourceBundle rb; rb = ResourceBundle.getBundle("JFileChooser", locale); z_choosertitle = rb.getString("Title"); UIManager.put ("FileChooser.lookInLabelText", rb.getString("lookInLabelText")); UIManager.put ("FileChooser.filesOfTypeLabelText", rb.getString("filesOfTypeLabelText"));

    15.19 Customize JOptionPane buttons

    UIManager.put ("FileChooser.upFolderToolTipText", rb.getString("upFolderToolTipText")); /* do the same with : FileChooser.fileNameLabelText FileChooser.homeFolderToolTipText FileChooser.newFolderToolTipText FileChooser.listViewButtonToolTipTextlist FileChooser.detailsViewButtonToolTipText FileChooser.saveButtonText=Save FileChooser.openButtonText=Open FileChooser.cancelButtonText=Cancel FileChooser.updateButtonText=Update FileChooser.helpButtonText=Help FileChooser.saveButtonToolTipText=Save FileChooser.openButtonToolTipText=Open FileChooser.cancelButtonToolTipText=Cancel FileChooser.updateButtonToolTipText=Update FileChooser.helpButtonToolTipText=Help Almost all Swing widgets can be customize this way. You can examine the Swing sources to get these values or check http://www.gargoylesoftware.com/papers/plafdiff.html for a list of them. */ } public void actionPerformed(ActionEvent e) { int result; if (e.getSource() instanceof JRadioButton) { if (e.getActionCommand().equals("en")) locale = Locale.US; else locale = Locale.FRANCE; setUILanguage(); } else { z_chooser = new JFileChooser(); z_chooser.setCurrentDirectory(new java.io.File(".")); z_chooser.setDialogTitle(z_choosertitle); if (z_chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); LocalizeJFileChooser panel = new LocalizeJFileChooser(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }

    15.19 Customize JOptionPane buttons

    ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } }

    15.21 Select a directory with a JFileChooser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0370.html import import import import

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

    public class DemoJFileChooser extends JPanel implements ActionListener { JButton go; JFileChooser chooser; String choosertitle; public DemoJFileChooser() { go = new JButton("Do it"); go.addActionListener(this); add(go); } public void actionPerformed(ActionEvent e) { int result; chooser = new JFileChooser(); chooser.setCurrentDirectory(new java.io.File(".")); chooser.setDialogTitle(choosertitle); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // // disable the "All files" option. // chooser.setAcceptAllFileFilterUsed(false); // if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory()); System.out.println("getSelectedFile() : " + chooser.getSelectedFile()); } else { System.out.println("No Selection "); } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame("");

    15.21 Select a directory with a JFileChooser

    DemoJFileChooser panel = new DemoJFileChooser(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.22 Disable the JFileChooser's "New folder" button Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0569.html No easy way to disable the "New Folder" button. You need to iterate the JFileChooser components until the right one and disable it. import import import import

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

    public class DemoJFileChooser extends JPanel implements ActionListener { JButton go; JFileChooser chooser; String choosertitle; public DemoJFileChooser() { go = new JButton("Do it"); go.addActionListener(this); add(go); } public void actionPerformed(ActionEvent e) { int result; chooser = new JFileChooser(); chooser.setCurrentDirectory(new java.io.File(".")); chooser.setDialogTitle(choosertitle); disableNewFolderButton(chooser); // int rc = chooser.showOpenDialog(this); if (rc == JFileChooser.APPROVE_OPTION) { System.out.println("getCurrentDirectory(): "

    15.22 Disable the JFileChooser's "New folder" button

    + chooser.getCurrentDirectory()); System.out.println("getSelectedFile() : " + chooser.getSelectedFile()); } else { System.out.println("No Selection!"); } }

    public void disableNewFolderButton( Container c ) { int len = c.getComponentCount(); for (int i = 0; i < len; i++) { Component comp = c.getComponent(i); if (comp instanceof JButton) { JButton b = (JButton)comp; Icon icon = b.getIcon(); if (icon != null && icon == UIManager.getIcon("FileChooser.newFolderIcon")) b.setEnabled(false); } else if (comp instanceof Container) { disableNewFolderButton((Container)comp); } } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); DemoJFileChooser panel = new DemoJFileChooser(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true); } }

    15.23 Validate a filename from a JFileChooser Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0568.html import import import import

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

    public class DemoJFileChooser extends JPanel implements ActionListener {

    15.23 Validate a filename from a JFileChooser

    JButton go; JFileChooser chooser; String choosertitle; public DemoJFileChooser() { go = new JButton("Do it"); go.addActionListener(this); add(go); } public void actionPerformed(ActionEvent e) { int result; chooser = new JFileChooser(); chooser.setCurrentDirectory(new java.io.File(".")); chooser.setDialogTitle(choosertitle); // int rc = chooser.showOpenDialog(this); // // loop until a .java file is selected // // possible to perform complex validation // using a regular expression with .matches(regexp) // while(rc == JFileChooser.APPROVE_OPTION && !chooser.getSelectedFile().getName().endsWith(".java")){ JOptionPane.showMessageDialog(null, "The file " + chooser.getSelectedFile() + " is not java source file.", "Open Error", JOptionPane.ERROR_MESSAGE); rc = chooser.showOpenDialog(this); }

    if (rc == JFileChooser.APPROVE_OPTION) { System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory()); System.out.println("getSelectedFile() : " + chooser.getSelectedFile()); } else { System.out.println("No Selection!"); } } public Dimension getPreferredSize(){ return new Dimension(200, 200); } public static void main(String s[]) { JFrame frame = new JFrame(""); DemoJFileChooser panel = new DemoJFileChooser(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.getContentPane().add(panel,"Center"); frame.setSize(panel.getPreferredSize()); frame.setVisible(true);

    15.23 Validate a filename from a JFileChooser

    } }

    15.24 Make a JFrame looks like a JDialog Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0582.html Make a JFrame unresizable and with no min/max button. The difference with JDialog is that a JFrame is shown on the taskbar (win) while a JDialog is not. import import import import

    java.awt.Dimension; java.awt.event.WindowAdapter; java.awt.event.WindowEvent; java.awt.event.ActionListener;

    import import import import import

    javax.swing.JFrame; javax.swing.JLabel; javax.swing.JButton; javax.swing.JRootPane; javax.swing.SwingUtilities;

    public class JFrameWithNoMinMax extends JFrame { public JFrameWithNoMinMax() { createAndShowUI(); } private void createAndShowUI(){ setTitle("This JFRAME looks like JDialog"); setSize(new Dimension(500,100)); setUndecorated(true); setResizable(false); getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); //addWindowListener(new WindowAdapter(){ // public void windowClosing(WindowEvent e) { // System.out.println("Window Closing"); // System.exit(0); // } //}); } public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ new JFrameWithNoMinMax().setVisible(true); } }); } }

    15.24 Make a JFrame looks like a JDialog

    15.25 Based on JTextField content, enable or disable a JButton Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0196.html import import import import

    java.awt.*; javax.swing.*; javax.swing.text.*; javax.swing.event.*;

    public class DemoJButtonDisabled extends JApplet { JButton button; JTextField textfield; Document document; public void init() { getContentPane().setLayout(new FlowLayout()); textfield = new JTextField(10); getContentPane().add(textfield); button = new JButton("foo"); getContentPane().add(button); button.setEnabled(false); document = textfield.getDocument(); document.addDocumentListener (new JButtonStateController(button)); } } class JButtonStateController implements DocumentListener { private JButton button; JButtonStateController(JButton b) { button = b; } public void changedUpdate(DocumentEvent e) { disableIfEmpty(e); } public void insertUpdate(DocumentEvent e){ disableIfEmpty(e); } public void removeUpdate(DocumentEvent e){ disableIfEmpty(e); } public void disableIfEmpty(DocumentEvent e) { button.setEnabled(e.getDocument().getLength() > 0); } }

    15.26 Apply special filter to a JtextField Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0197.html

    15.25 Based on JTextField content, enable or disable a JButton

    The following class will help a JTextField to filter numeric or alphanumeric characters. import javax.swing.*; import javax.swing.text.*; public class JTextFieldFilter extends PlainDocument { public static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz"; public static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static final String ALPHA = LOWERCASE + UPPERCASE; public static final String NUMERIC = "0123456789"; public static final String FLOAT = NUMERIC + "."; public static final String ALPHA_NUMERIC = ALPHA + NUMERIC; protected String acceptedChars = null; protected boolean negativeAccepted = false; public JTextFieldFilter() { this(ALPHA_NUMERIC); } public JTextFieldFilter(String acceptedchars) { acceptedChars = acceptedchars; } public void setNegativeAccepted(boolean negativeaccepted) { if (acceptedChars.equals(NUMERIC) || acceptedChars.equals(FLOAT) || acceptedChars.equals(ALPHA_NUMERIC)){ negativeAccepted = negativeaccepted; acceptedChars += "−"; } } public void insertString (int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; if (acceptedChars.equals(UPPERCASE)) str = str.toUpperCase(); else if (acceptedChars.equals(LOWERCASE)) str = str.toLowerCase(); for (int i=0; i <str.length(); i++) { if (acceptedChars.indexOf(str.valueOf(str.charAt(i))) == −1) return; } if (acceptedChars.equals(FLOAT) || (acceptedChars.equals(FLOAT + "−") &negativeAccepted)) { if (str.indexOf(".") != −1) { if (getText(0, getLength()).indexOf(".") != −1) { return; } } } if (negativeAccepted &str.indexOf("−") != −1) {

    15.25 Based on JTextField content, enable or disable a JButton

    if (str.indexOf("−") != 0 || offset != 0 ) { return; } } super.insertString(offset, str, attr); } } import java.awt.*; import javax.swing.*; public class TESTJTextFieldFilter extends JApplet{ JTextField tf1,tf1b,tf1c,tf2,tf3; JLabel l1,l1b,l1c,l2,l3; public void init() { getContentPane().setLayout(new FlowLayout()); // l1 = new JLabel("only numerics"); tf1 = new JTextField(10); getContentPane().add(l1); getContentPane().add(tf1); tf1.setDocument (new JTextFieldFilter(JTextFieldFilter.NUMERIC)); // l1b = new JLabel("only float"); tf1b = new JTextField(10); getContentPane().add(l1b); getContentPane().add(tf1b); tf1b.setDocument (new JTextFieldFilter(JTextFieldFilter.FLOAT)); // l1c = new JLabel("only float(can be negative)"); tf1c = new JTextField(10); getContentPane().add(l1c); getContentPane().add(tf1c); JTextFieldFilter jtff = new JTextFieldFilter(JTextFieldFilter.FLOAT); jtff.setNegativeAccepted(true); tf1c.setDocument(jtff); // l2 = new JLabel("only uppercase"); tf2 = new JTextField(10); getContentPane().add(l2); getContentPane().add(tf2); tf2.setDocument (new JTextFieldFilter(JTextFieldFilter.UPPERCASE)); // l3 = new JLabel("only 'abc123%$'"); tf3 = new JTextField(10); getContentPane().add(l3); getContentPane().add(tf3); tf3.setDocument (new JTextFieldFilter("abc123%$")); } }

    With JDK.14, you have the JFormattedTextField class. You can provide an input mask like (###) 15.25 Based on JTextField content, enable or disable a JButton

    ###−#### for a telephone number, and it will not accept any input that doesn't follow that format. import import import import

    java.awt.Container; javax.swing.*; javax.swing.text.*; java.text.ParseException;

    public class FormattedSample { public static void main (String args[]) throws ParseException { JFrame f = new JFrame("JFormattedTextField Sample"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container content = f.getContentPane(); content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS)); // canadian Social Security Number MaskFormatter mf1 = new MaskFormatter("###−###−###"); mf1.setPlaceholderCharacter('_'); JFormattedTextField ftf1 = new JFormattedTextField(mf1); content.add(ftf1); // telephone number MaskFormatter mf2 = new MaskFormatter("(###) ###−####"); JFormattedTextField ftf2 = new JFormattedTextField(mf2); content.add(ftf2); f.setSize(300, 100); f.setVisible(true); } }

    15.27 Limit JTextField input to a maximum length Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0198.html import com.sun.java.swing.text.*; public class JTextFieldLimit extends PlainDocument { private int limit; // optional uppercase conversion private boolean toUppercase = false; JTextFieldLimit(int limit) { super(); this.limit = limit; } JTextFieldLimit(int limit, boolean upper) { super(); this.limit = limit; toUppercase = upper; } public void insertString (int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; if ((getLength() + str.length()) <= limit) { if (toUppercase) str = str.toUpperCase(); super.insertString(offset, str, attr); } }

    15.27 Limit JTextField input to a maximum length

    } import java.awt.*; import javax.swing.*; public class DemoJTextFieldWithLimit extends JApplet{ JTextField textfield1; JLabel label1; public void init() { getContentPane().setLayout(new FlowLayout()); // label1 = new JLabel("max 10 chars"); textfield1 = new JTextField(15); getContentPane().add(label1); getContentPane().add(textfield1); textfield1.setDocument (new JTextFieldLimit(10)); } }

    15.28 Validate a value on the lostFocus event Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0199.html The problem is when the lostFocus occurs on a Component, the gainedFocus is already sent for the next component in the SystemEventQueue. We must grab this event, and request the focus for the previous component (if there is a validation error). We can't use Toolkit.getDefaultToolkit().getSystemEventQueue() directly to remove the gainedFocus event because of security restriction in Applet. This can be done with invokeLater method of the SwingUtilities class. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DemoLostFocus extends JApplet { JTextField tf1, tf2; JLabel label; public void init() { getContentPane().setLayout(new FlowLayout()); // label = new JLabel("must be 'a' or 'b' "); tf1 = new JTextField(5); getContentPane().add(label); getContentPane().add(tf1); tf2 = new JTextField(5); getContentPane().add(tf2); tf1.addFocusListener( new FocusListener() { public void focusGained(FocusEvent e) {}; public void focusLost(FocusEvent e) { if (!e.isTemporary() &isEnabled() ) { String content = tf1.getText();

    15.28 Validate a value on the lostFocus event

    if (!content.equals("a") &!content.equals("b")) { Toolkit.getDefaultToolkit().beep(); System.out.println("illegal value! " + content ); SwingUtilities.invokeLater(new FocusGrabber(tf1)); } }} }); } } class FocusGrabber implements Runnable { private JComponent component; public FocusGrabber(JComponent component) { this.component = component; } public void run() { component.grabFocus(); } }

    JDK1.3 provides a new class, InputVerfier, which can be used to do that. import import import import

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

    // the first JTextField expects the string "howto" as input, // and will allow focus to change only if the required string // is typed. class VerifierTest extends JFrame { public VerifierTest () { JTextField tf,tf2; tf = new JTextField ("howto is required"); getContentPane().add (tf, BorderLayout.NORTH); tf.setInputVerifier(new HowtoVerifier()); tf2 = new JTextField ("howto come here"); getContentPane().add (tf2, BorderLayout.SOUTH); addWindowListener(new WindowCloser()); }

    public static void main (String [] args) { Frame f = new VerifierTest (); f.pack(); f.show(); } } class WindowCloser extends WindowAdapter { public void windowClosing(WindowEvent e) { Window win = e.getWindow(); win.setVisible(false); System.exit(0); } }

    15.28 Validate a value on the lostFocus event

    class HowtoVerifier extends InputVerifier { public boolean verify(JComponent input) { JTextField tf = (JTextField) input; String pass = tf.getText(); return pass.equals("howto"); } }

    It's not a bad idea to give a visual cue that the textfield is not validated. Here a bad textfield will show a red border, a good one will be black. import javax.swing.border.*; ... class HowtoVerifier extends InputVerifier { public boolean verify(final JComponent input) { JTextField tf = (JTextField) input; String pass = tf.getText(); if (!pass.equals("howto")) { SwingUtilities.invokeLater(new Runnable(){ public void run(){ input.setBorder( new LineBorder(Color.RED) ); } }); return false; } SwingUtilities.invokeLater(new Runnable(){ public void run(){ input.setBorder( LineBorder.createBlackLineBorder() ); } }); return true; } } ...

    15.29 Make sure that my jTextfield has the focus when a JFrame is created Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0200.html In a JFrame, use a small WindowAdapter to listen to the WindowOpened event. From there, simply request the focus for the JTextfield. This is not needed with the Appletviewer or in Application, but with some browsers (like Netscape), you need to do it. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MyFrame extends JFrame { JTextField field1; JTextField field2; JPanel panel;

    15.29 Make sure that my jTextfield has the focus when a JFrame is created

    public MyFrame() { super( "This is my Frame" ); panel = new JPanel(); field1 = new JTextField( 10 ); field2 = new JTextField( 10 ); panel.add( new JLabel("Field 1:")); panel.add( field1 ); panel.add( new JLabel("Field 2:")); panel.add( field2 ); getContentPane().add( "Center", panel ); addWindowListener( new WindowAdapter() { public void windowOpened( WindowEvent e ){ field1.requestFocus(); } } ); pack(); setVisible( true ); } }

    To try it : import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MyFrameApplet extends JApplet { public void init() { MyFrame myFrame = new MyFrame(); } }

    15.30 Stop the beep on JFormattedTextField Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0427.html When the user inputs an invalid value into JFormattedTextField, the default behavior is to emit a beep. To avoid this annoying beep, simply overload the invalidEdit() method. class MyJFormattedTextField extends JFormattedTextField { ... protected void invalidEdit() {} ... } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.31 Right justified JTextfield content Current version of this HowTo : 15.30 Stop the beep on JFormattedTextField

    http://www.rgagnon.com/javadetails/../javadetails/java−0493.html import javax.swing. *; import java.awt.*; public class Test extends JApplet { JTextField textfield; public void init() { getContentPane().setLayout(new FlowLayout()); textfield = new JTextField(10); // Right−justify the text textfield.setHorizontalAlignment(JTextField.RIGHT); getContentPane().add(textfield); } } If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.32 Set the focus on a particuliar JTextField Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0510.html SwingUtilities.invokeLater(new Runnable() { public void run() { myJTextField.requestFocus(); } }); If you find this article useful, consider making a small donation to show your support for this Web site and its content.

    Written and compiled by Réal Gagnon ©1998−2005 [ home ]

    15.33 Make JTextField unselectable Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0546.html import import import import

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

    class UnselectableJTextField extends JFrame { public UnselectableJTextField () { JTextField tf1,tf2; tf1 = new JTextField ("you can select with the mouse"); getContentPane().add (tf1, BorderLayout.NORTH); tf2 = new JTextField ("you can't select with the mouse");

    15.32 Set the focus on a particuliar JTextField

    // disable mouse or keyboard selection to prevent "cut and paste" tf2.setHighlighter(null); // getContentPane().add (tf2, BorderLayout.SOUTH); addWindowListener(new WindowCloser()); }

    public static void main (String [] args) { Frame f = new UnselectableJTextField (); f.pack(); f.setVisible(true); } class WindowCloser extends WindowAdapter { public void windowClosing(WindowEvent e) { Window win = e.getWindow(); win.setVisible(false); System.exit(0); } } }

    15.34 Use a JTree to navigate in a site Current version of this HowTo : http://www.rgagnon.com/javadetails/../javadetails/java−0209.html This How−to will show you how to build a Tree (like this one) using Swing. NOTE: This Tree Applet is different since it's plain JDK1.0.2 Applet.

    First, we define the class representing a node. This node contains a title (the label), a URL, 2 icons (open and close). import javax.swing.*; public class RealSwingNode extends Object { private String _title; private String _link; private ImageIcon _openedIcon; private ImageIcon _closedIcon; RealSwingNode (String title, String link, ImageIcon closed, ImageIcon opened) { _title = title; _link = link; _openedIcon = opened; _closedIcon = closed; } String getTitle() { return _title; } String getLink() { return _link; } ImageIcon getOpenedIcon() { return _openedIcon; } ImageIcon getClosedIcon() { return _closedIcon; } public String toString() { return _title; } }

    15.34 Use a JTree to navigate in a site

    Then we define how the node would be shown in the Tree. This is done by implementing a Renderer class. import javax.swing.*; import javax.swing.tree.*; import java.awt.*; public class RealSwingTreeIconRenderer extends Object implements TreeCellRenderer { JLabel _label; RealSwingTreeIconRenderer() { _label = new JLabel(); _label.setOpaque(true); } public Component getTreeCellRendererComponent (JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { RealSwingNode _userObject = null; _label.setFont(tree.getFont()); if (selected){ _label.setForeground(tree.getBackground()); _label.setBackground(tree.getForeground()); } else { _label.setBackground(tree.getBackground()); _label.setForeground(tree.getForeground()); } if (value instanceof RealSwingNode) { _userObject = (RealSwingNode) value; } else if(value instanceof DefaultMutableTreeNode) { DefaultMutableTreeNode node; node = (DefaultMutableTreeNode) value; if (node.getUserObject() instanceof RealSwingNode) { _userObject = (RealSwingNode) node.getUserObject(); } }

    if(_userObject != null) { if (expanded) _label.setIcon(_userObject.getOpenedIcon()); else _label.setIcon(_userObject.getClosedIcon()); _label.setText(_userObject.getTitle()); } else { _label.setIcon(null); _label.setText(value.toString()); } return _label; } }

    15.34 Use a JTree to navigate in a site

    The next step is building the JTree in a JPanel. We use a datafile to define the Tree nodes. Since this Tree is designed to be used in Applet, we must pass a JApplet reference to be able to read some parameters passed via the HTML PARAM tags. import import import import import import import import

    javax.swing.*; javax.swing.tree.*; javax.swing.event.*; java.awt.event.*; java.awt.*; java.util.*; java.net.*; java.io.*;

    public class RealSwingTree extends JPanel implements TreeSelectionListener { private JApplet parentApplet; private JTree tree; private Font f; private ImageIcon treeIcons[]; private String targetFrame; public RealSwingTree() { System.out.println(System.getProperty("os.name")); try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex_ignored) { ex_ignored.printStackTrace(); } } public void setParentApplet(JApplet j) { parentApplet = j; } public void initTree() { // build the tree from the datafile DefaultMutableTreeNode rootNode = null; DefaultMutableTreeNode currentNode = null; DefaultMutableTreeNode node = null; RealSwingNode rsn = null; RealSwingTreeIconRenderer rstir; TreeSelectionModel tsm; int token, value=0, oldvalue=0, rootvalue=0, image1idx=0, image2idx=0; String strValue, lnkValue, imageValue; boolean rootDone=false; boolean itemDone=true; System.out.println("[RealSwingTree] Begin populateTree() " ); try { initTreeIcons(); targetFrame = parentApplet.getParameter("targetframe"); URL urlFile = new URL(parentApplet.getCodeBase(), parentApplet.getParameter("datafile")); Reader r = new BufferedReader (new InputStreamReader(urlFile.openStream())); StreamTokenizer st = new StreamTokenizer(r);

    15.34 Use a JTree to navigate in a site

    st.quoteChar('"'); st.eolIsSignificant(false); st.parseNumbers(); // // datafile structure