Realhowto Java
Realhowto Java
This is the PDF version of the Real's HowTo Web site ( http://www.rgagnon.com/howto.html ).
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
real@rgagnon.com
Contributions via PayPal are accepted in any amount using a credit card or checking account.
DISCLAIMER
Real's HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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 <br> 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 HowTo@www.rgagnon.com
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 HowTo@www.rgagnon.com
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
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 :
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.*;
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 java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
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.*;
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
/*
ScrollStatus.java
Optional parameters: message, width
Default values:
message = "Isn't scrolling text in the status line annoying? "
width = 36
Example usage:
<applet code="ScrollStatus.class"
width=0 height=0>
<param name="message" value="Hello World!">
<param name="width" value="24">
</applet>
*/
import java.util.*;
import java.applet.Applet;
import java.applet.Applet;
import java.net.*;
import java.awt.*;
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;
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.
import java.applet.*;
import java.awt.*;
import java.util.*;
import java.text.*;
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 MyClockThread(MyPanel a) {
mp = a;
}
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="MyClock.class"
HEIGHT=25 WIDTH=200>
<PARAM NAME="format" VALUE="yyyy−MM−dd hh:mm:ss">
</APPLET><P>
<APPLET CODE="MyClock.class"
HEIGHT=25 WIDTH=200>
<PARAM NAME="format" VALUE="h:mm a">
</APPLET><P>
<APPLET CODE="MyClock.class"
HEIGHT=25 WIDTH=200>
<PARAM NAME="format" VALUE="yyyy.MMMMM.dd GGG hh:mm aaa">
</APPLET><P>
<APPLET CODE="MyClock.class"
HEIGHT=25 WIDTH=200>
<PARAM NAME="format" VALUE="H:mm:ss:SSS">
</APPLET><P>
/BODY/HTML
Try it here.
[Applet1_0022.java]
import java.awt.*;
public class Applet1_0022 extends java.applet.Applet {
TextField inputText;
Button b;
[Applet2_0022.java]
import java.awt.*;
1.7 Have Applets on the same page communicate with each other
[HTML]
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="Applet1_0022.class"
NAME="applet1"
HEIGHT=200 WIDTH=150>
</APPLET>
<APPLET CODE="Applet2_0022.class"
NAME="applet2"
HEIGHT=200 WIDTH=400>
</APPLET>
</BODY></HEAD>
Try it here.
[HTML (java−0023.html)]
<HTML><HEAD></HEAD>
<FRAMESET COLS="50%,*">
<FRAME SRC="java−0023−f1.html" NAME="f1">
<FRAME SRC="java−0023−f2.html" NAME="f2">
</FRAMESET>
</HEAD>
<HTML><HEAD></HEAD>
<BODY>
<APPLET CODE="Java0023.class"
HEIGHT=200
WIDTH=200>
</APPLET>
</BODY></HTML>
import java.awt.*;
import java.applet.*;
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.
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
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="FirstAppletJ.class"
HEIGHT=100
WIDTH=300>
/APPLET/BODY/HTML
FirstAppletJ.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
SecondAppletJ.html
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="SecondAppletJ.class"
HEIGHT=100
WIDTH=400>
/APPLET/BODY/HTML
SecondApplet.java
import java.applet.*;
import java.awt.*;
import java.net.*;
/*
with JDK1.2, the decoding can be done
with java.net.URLDecoder.decode(theMessage).
tf.setText(theMessage);
}
}
You can try it here! NOTE : On IE, you must be connected to the Internet
If you need to pass the message via the PARAM tag of the SecondApplet then take a look at this
How−to.
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)
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="AppletLoader.class"
NAME="AppletLoader"
HEIGHT=200
WIDTH=200>
<PARAM NAME="appletToLoad" VALUE="SecondApplet0025">
<PARAM NAME="SecondAppletParm" VALUE="Hello World">
</APPLET></BODY></HTML>
import java.applet.Applet;
import java.applet.AppletStub;
import java.awt.*;
import java.awt.*;
In application :
String username;
username = System.getProperty("user.name");
or in JDK1.5
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.
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();
}
StringTokenizer st =
new StringTokenizer(searchURL, "
while(st.hasMoreTokens()){
String searchValue=st.nextToken();
System.out.println("value :" + searchValue);
}
initHashtable(searchURL);
dumpHashtable();
}
}
Test it here.
import java.applet.*;
import java.awt.*;
<HTML>
<TABLE><TR><TD>
<APPLET CODE=UnderlineText.class WIDTH=100 HEIGHT=100>
</APPLET>
/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.*;
[JDK1.0.2]
// 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]
import java.applet.Applet;
import java.net.*;
// TILE BACKGROUND
// in the HTML use :
// PARAM NAME="bgImage" VALUE="images/myImage.jpg"
// in the APPLET tag
<HTML>
<TABLE><TR><TD>
<APPLET CODE=Tile.class WIDTH=150 HEIGHT=150>
<PARAM NAME="bgImage" VALUE="images/jht.gif">
</APPLET>
/HMTL
Try it here.
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
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.
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!
<html>
<body leftmargin=0 topmargin=0 scroll=no>
<script src="myapplet.js"></script>
</body>
</html>
document.write
('<applet code="MyApplet.class" height="2000" width="196"></applet>')
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.
And now the same APPLET but with an external JS file 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) :
<HTML><HEAD></HEAD>
1.16.1 Solution #1
<BODY onload="rewriteApplet();">
<p>This example "rewrite" the applet tag from an external JS.
This way you can generate the Applet tag from a JSP like before.
<P>
<script language="Javascript1.2" src="./rewriteapplet.js">
</script>
<APPLET CODE="TextFieldWithLimitApplet.class"
HEIGHT=100
WIDTH=300>
</APPLET>
</BODY></HTML>
function rewriteApplet() {
var v=document.getElementsByTagName("applet");
for(i=0;i<v.length;i++){
var el=v[i];
el.outerHTML=el.outerHTML
}
}
Try it here!
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 </APPLET>. The
enclosed dynamic PARAM parameters are generated by the JSP (ASP page).
[rewriteapplet.js]
function writeHeader(urlApplet) {
document.write
('<applet codebase="' + urlApplet + '" code="myApplet.class"')
document.write
(' width="100%" height="98%" hspace="0" vspace="0" align="middle" >')
document.write
1.16.3 Solution #3
(' <PARAM NAME="printdialog" VALUE="false">')
}
function writeFooter() {
document.write('</applet>')
}
...
<script language="Javascript1.2"
src="<%= CONTEXT_PATH %>/scripts/rewriteapplet.js">
/script
...
<script>
writeHeader('<%=urlApplet %>');
</script>
<%
if(resultVB.isObjectInResult(idObject)) {
int i = 1;
Iterator itPages = pages.iterator();
while (itPages.hasNext()) {
String url = (String) itPages.next();
%>
<PARAM NAME="page<%=i%>" value="<%=url %>">
<%
i++;
}
}
else {
%>
<PARAM NAME="page1" value="<%=fileUrlErr %>">
<%
}
%>
<script>
writeFooter();
/script
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
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.
The Java Console Window Log is also stored on disk. On the Windows plateform, it's in the folder
:
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
<applet id="applet_name"
code="path_to_applet_class/class_name"
style="width: 1px; height: 1px; float: left;"
mayscript></applet>
.. or you can insert your Applet into an invisible frame. See this HowTo for an example.
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.
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.text.SimpleDateFormat;
One technique is to compute by hand the number of milliseconds between two dates and then
convert the result in days.
import java.util.*;
/*
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
*/
}
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.
/*
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
*/
}
}
Actually, the Calendar class provides a method to that very simply. For a given Calendar or
GregorianCalendar object :
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)
package com.rgagnon.howto;
import java.text.*;
add() and roll() are used to add or substract values to a Calendar object.
add() adds or substracts values to the specified Calendar field, the next larger field is modified when
the result makes the Calendar "rolls over".
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
There is a bug in the DateFormat/SimpleDateFormat classes. We must set the TimeZone manually.
The format "YYYYMMDD" can be useful when sorting records or comparing 2 dates.
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.*;
import java.text.*;
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()));
}
}
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
*/
}
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).
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
An alternate way :
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.*;
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;
/**
* 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−−;
// THIRD TEST
double date1 = toJulian(new int[]{2005,1,1});
/*
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.
import java.util.GregorianCalendar;
import java.util.Calendar;
private TimeUtils() { }
/**
* converts time (in milliseconds) to
* "<w> days, <x> hours, <y> 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;
We connect to a publicly accessible time server on the internet and parse the result.
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 java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;
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();
/*
ref : http://www.bldrdoc.gov/doc−tour/atomic_clock.html
| | | | | | | | |
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.
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.*;
private DateUtils() { }
if (type == IntervalType.Month) {
// first date of the month
startDate.set(Calendar.DATE, 1);
// previous month
startDate.add(Calendar.MONTH, −1);
}
catch (Exception e) {
e.printStackTrace();
}
}
/*
output :
** previous month (relative today)
2008−06−01
2008−06−30
** previous week (relative today)
2008−06−30
2008−07−06
** previous month (relative jan 1, 2007)
2006−12−01
2006−12−31
** previous week (relative jan 1, 2007)
2006−12−25
2006−12−31
*/
import java.util.Calendar;
import java.text.SimpleDateFormat;
static {
sdfHour = new SimpleDateFormat(HOUR_FORMAT);
}
private DateUtils() { }
/**
* @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));
}
SYSTEMTIME st;
GetLocalTime(
st.wHour = hour;
st.wMinute = minutes;
SetLocalTime(
}
class JavaHowTo {
public native void setSystemTime( short hour, short minutes);
static {
System.loadLibrary("javahowto");
}
}
// this example will set the system at 10h21 using the Windows API
// SetLocalTime.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
// Add cards
3 AWT
p0.add("First card", p1);
p0.add("2nd card", p2);
p0.add("3rd card", p3);
3 AWT
return new Dimension(w,h);
}
}
<HTML>
<TABLE><TR><TD>
<APPLET CODE=CardLayoutDemo.class WIDTH=300 HEIGHT=300>
</APPLET>
/HMTL
Try it here.
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];
}
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
import java.util.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");
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);
}
/*
** initialize a Popup for a particular Component
*/
setHash(c, pm);
c.add(pm);
c.addMouseListener(this);
}
PopupMenu getHash(Component c) {
/*
** return a Popup associated with a particular Component
*/
return (PopupMenu)(popupTable.get(c));
}
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 {
return fd.getFile();
by
return fd.getDirectory() +
System.getProperty("file.separator") + fd.getFile();
fd.setFilenameFilter(new FilenameFilter(){
public boolean accept(File dir, String name){
return (name.endsWith(".jpg") || name.endsWith(".gif"));
}
});
[JDK1.4]
The names of the most common fonts supported by Java are TimesRoman, Courier, and Helvetica.
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.
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
[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]);
}
}
}
import java.awt.*;
import java.applet.*;
}
}
<HTML>
<TABLE><TR><TD>
<APPLET CODE=SimpleApplet.class WIDTH=410 HEIGHT=500>
</APPLET>
</HMTL>
try it here
import java.awt.datatransfer.*;
import java.awt.*;
NOTE: You can only use text (no graphic) with this functionality provided by the current JDK (1.4).
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.*;
}
else {
System.err.println("Change display mode not supported");
}
}
else {
System.err.println("Full screen not supported");
}
}
}
device.setFullScreenWindow(null);
SWING jdk1.3
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);
[JDK1.0.2]
[JDK1.1 Method 1]
[JDK1.1 Method 2]
[JDK1.1 Method 3]
For a Dialog or a Window, a System.exit(0) may not be appropriate, call the dispose() method
instead.
[TestEventPanel.java]
import java.awt.*;
import java.awt.event.*;
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.*;
TestEventFrame(String title){
super(title);
setLayout(new FlowLayout());
p1 = new TestEventPanel();
void createFrame() {
Dimension d = getToolkit().getScreenSize();
setLocation(d.width/4,d.height/3);
setSize(400,100);
setVisible(true);
}
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));
}
and finally
[Java0268.java]
import java.awt.*;
Try it here.
There is a bug in JDK1.0.2 for Windows, so you are stuck with the JAVA coffee cup.
frame.setIconImage(Toolkit.getDefaultToolkit().getImage("myIcon.gif"));
frame.setIconImage
(Toolkit.getDefaultToolkit()
.getImage(getClass().
getResource("images/myIcon.gif")));
or
frame.setIconImage(
new ImageIcon(
YourApp.class.getResource("logo.png")
).getImage()
);
import java.awt.*;
import java.awt.event.*;
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.*;
NOTE: These How−to may not work with the Microsoft JVM. It's a feature...
import java.awt.*;
import java.awt.event.*;
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);
}
}
);
}
With plain AWT, this simple class can be used as a Message Box.
import java.awt.*;
import java.awt.event.*;
/*
* @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);
}
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);
}
if (message.isOk)
System.out.println("Ok pressed");
if (!message.isOk)
System.out.println("Cancel pressed");
message.dispose();
}
}
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
private FrameUtils() { }
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 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);
}
}
);
import java.util.*;
import java.io.*;
if (args.length > 0) {
folderToWatch = args[0];
}
to specify your own folder. This demo is watching for files with the extension txt only.
[JDK1.1]
thanks to Lionel Giltay
import java.awt.TextField ;
import java.awt.event.KeyAdapter ;
import java.awt.event.KeyEvent ;
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() ;
}
}
});
[JDK11]
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
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
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="FirstApplet.class"
NAME="myApplet"
HEIGHT=200 WIDTH=200>
</APPLET></BODY></HTML>
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
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);
}
}
);
}
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.*;
[TestImageButton.java]
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.applet.*;
import java.awt.*;
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.
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.
In real life, the preferred way would be to extend the java.awt.List and override the addItem method.
import java.awt.*;
import java.awt.event.*;
With a Layout Manager, you have to validate() the layout to redraw the components invalidated.
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.*;
MyPanel() { super(); }
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.applet.*;
import java.awt.*;
[JDK1.4]
import java.awt.geom.AffineTransform;
import java.awt.Graphics2D;
// 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);
}
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 MultiLineLabel() {
this("", 0);
}
f.validate();
}
}
[UnderlinedLabel.java]
import java.awt.*;
[TestUnderlinedLabel.java]
import java.applet.*;
import java.awt.*;
[testapplet.html]
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="TestUnderlinedLabel.class"
[URLLabel.java]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
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();
}
}
[TestURLLabel.java]
import java.applet.*;
import java.awt.*;
[testapplet.html]
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="TestURLLabel.class"
NAME="myApplet"
HEIGHT=200 WIDTH=200>
</APPLET></BODY></HTML>
Try it here.
import java.awt.*;
import java.awt.image.*;
import java.awt.*;
import java.awt.event.*;
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);
}
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);
}
}
);
}
The result :
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 java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
[JDK1.1 application]
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
Remember that it is always possible to the Java built−in icons so that you don't have to include your
own standard icons.
import java.awt.image.*;
import java.awt.*;
import java.net.*;
Try it here.
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 java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
Example :
Input:
Ouput:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.net.*;
public AlphaFilter() {
canFilterIndexColorModel = true;
}
Try it here.
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.*;
The next example will rotate a picture 5 degrees at a time. We are using the Java2D package (and
Swing).
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.applet.*;
import java.awt.*;
myCanvas() { super(); }
public void paint(Graphics g) {
if (!initDone)
initpaint(g);
else
g.drawImage(buffImage, 0, 0, this);
}
import java.applet.*;
import java.awt.*;
// 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);
}
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();
}
import java.applet.Applet;
import java.net.*;
// TILE BACKGROUND
// in the HTML use :
// PARAM NAME="bgImage" VALUE="images/myImage.jpg"
// in the APPLET tag
<HTML>
<TABLE><TR><TD>
<APPLET CODE=Tile.class WIDTH=150 HEIGHT=150>
<PARAM NAME="bgImage" VALUE="images/jht.gif">
</APPLET>
/HMTL
[imagelist.txt]
jht.gif|JAVA How−to
jsht.gif|Javascript How−to
pht.gif|Powerbuilder How−to
[application version]
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
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);
}
[applet version]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
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);
}
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.*;
To use such Canvas, try something like this. This example needs our Gumby GIFs ( and
).
import java.applet.*;
import java.awt.*;
import java.net.*;
Try it here.
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.*;
[app.java]
import java.awt.image.*;
import java.awt.*;
import java.net.*;
[x.html]
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="app.class"
NAME="myApplet"
HEIGHT=200 WIDTH=200>
</APPLET>
</BODY></HTML>
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();}
// [JDK1.2]
// img is a Java Image
//
BufferedImage bimg = null;
// 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.*;
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.net.*;
Try it here.
Like the previous How−to, using a Thread, we switch between 2 GIFs, for example ( and
).
Click the button to simulate some work, click again to terminate the "work in progress"
[JDK1.1]
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.net.*;
From here, individual pixel can be accessed via the pixels array.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage
...
import java.applet.*;
import java.awt.*;
import java.util.Vector;
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]);
3.59 Convert RGB value to Hexadecimal (to be used in HTML for example)
import java.awt.image.*;
import java.awt.*;
import java.applet.*;
import java.awt.*;
import java.applet.*;
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);
}
Using JDK1.2
On a Component
Using JDK1.3
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public MyPanel(){}
import java.util.*;
import java.awt.*;
import java.applet.Applet;
// "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);
}
}
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;
}
}
[JavaPie.hmtl]
<HTML>
<TABLE><TR><TD>
<APPLET CODE=Graph.class WIDTH=150 HEIGHT=150>
Try it here
It seems that drawRoundRect(….) 1,5 faster then drawRect(…..) , because one of them is
completely native.
import java.awt.*;
import java.awt.event.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.*;
import 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 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 javax.media.jai.PlanarImage;
import com.sun.media.jai.codec.ByteArraySeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.awt.Image;
import java.awt.image.RenderedImage;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
http://java.sun.com/javase/technologies/desktop/media/jai/
https://jai.dev.java.net/#Downloads
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.
http://java.sun.com/products/java−media/jai/index.jsp
>
import java.io.*;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.TIFFEncodeParam;
import java.awt.image.RenderedImage;
import javax.media.jai.RenderedOp;
import javax.media.jai.JAI;
import java.awt.image.renderable.ParameterBlock;
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/
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.
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
[JDK1.02]
import java.applet.*;
import java.awt.*;
[JDK11]
[JDK11]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.event.*;
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();
}
if (what.equals("Exit"))
processEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
In this example, when we click on a Button, we trigger the action attached to the another Button.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
b1.addActionListener(this);
b2.addActionListener(this);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
b1.addActionListener(this);
b2.addActionListener(this);
}
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.
then in myClass
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.*;
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;
}
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:
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" );
}
...
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" );
}
...
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;
}
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("LIBPATH: {" +
System.getProperty("java.library.path")+"}");
gives
on my linux workstation. (java added all those except /lib and /usr/lib). But these two lines aren't the
same on window either:
4 Environment
C:\Program Files\Executive Software\DiskeeperServer\;}
Java is prepending itself! That confused me−−− and broke my exec from ant.
JDK1.5
System.getenv() is back!
import java.util.*;
// 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());
}
}
}
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 :
NOTE : This is fine if the environment variable contains only regular 7−bit ASCII characters.
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
.java.class:
$(JAVAC) −classpath $(CLASSPATH) $(JAVACFLAGS) $<
CLASSFILES = GetImage.class \
myCanvas.class
SOURCEFILES = GetImage.java \
myCanvas.java
Name: myCanvas.class
Java−Bean: True
<<
doc : $(CLASSFILES)
javadoc −version −author −d $(DOC) $(SOURCEFILES)
install :
copy $CLASSESFILE $(DEST)
clean:
del $(CLASSFILES)
One way is to instanciate a known browser−specific method and catch the Exception if not found
import java.applet.*;
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.
<HTML></HTML><HEAD>
<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";
}
}
</SCRIPT></HEAD><BODY>
<APPLET CODE ="MyApplet.class"
HEIGHT=100
WIDTH=400
ARCHIVE=}; >
</APPLET>
</BODY></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.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;
If you execute this code, the JFrame title will have the word "DEBUG" appended to it.
<project default="buildme">
<target name="compileprod">
<copy todir="../out" includeEmptyDirs="false">
<filterchain>
<tokenfilter>
<replacestring from="//@STARTDEBUG@//" to="/*" />
<replacestring from="//@ENDDEBUG@//" to="*/" />
</tokenfilter>
</filterchain>
<fileset dir=".">
<include name="**/*.java" />
</fileset>
</copy>
<target name="compiledebug">
<javac srcdir="." />
</target>
After running this script, the source (in the ..\out directory)
package com.rgagnon.howto;
import javax.swing.JFrame;
In Netscape
In application
NOTE: This can be useful if you want to trim a JAR to include only classes actually used.
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 :
−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 :
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.
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).
Using Ant,
<javadoc
locale="fr"
sourcefiles="c:/client/Client.java"
destdir="javadoc/Client"
author="true"
version="true"
use="true"
private="true"
windowtitle="Client">
<doctitle><![CDATA[<h1>Client</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright © 2003 Real's Howto.</i>]]></bottom>
</javadoc>
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
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!) :
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
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).
import java.io.*;
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.
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();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
you get
The default JVM with a JIT (Just−In−Time compiler) for a "client" mode is used. The other available
mode is "server".
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.
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.
A content like
−server KNOWN
−client KNOWN
// Win95 (?)
javac −J−Djavac.pipe.output=true myClass.java >output.txt
// WinNT (or better)
javac MyClass.java 2output.txt
// [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.
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 <classname>
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).
package JavaCom;
public class JavaBeanSays {
private String _hello = "Hello World!";
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
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
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.
NOTE: There is a command−line interface available in the packager if you want to bypass the wizard.
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.
But applets are prevented from reading these system properties (for security reason):
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");
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();
}
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.
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.
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.
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.
You need to save the script in the SendTo subdirectory located in the Windows directory
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 .
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
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.
If WScript.Arguments.Count = 0 Then
Note : A JAR can be made self executable (with double click), see this HowTo
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
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.
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.
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.*;
reader.start();
process.waitFor();
reader.join();
if (p == −1)
return null;
reader.start();
process.waitFor();
reader.join();
if (p == −1)
return null;
reader.start();
process.waitFor();
reader.join();
if (p == −1)
return null;
String getResult() {
return sw.toString();
}
}
Use regedit utility to query the Windows registry, the result is written into a file.
@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
pause
The above script returns the default JVM if the PATH variable does not override it!
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.
However, it's easy to do from a VBS. You execute the script from Java, wait for its completion and
capture the return code.
import java.io.File;
import java.io.FileWriter;
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.*;
}
input.close();
}
catch (Exception err) {
err.printStackTrace();
}
return processes;
}
Thanks to M. Korbel
Another technique to build the required VBScript on−the−fly, execute it and capture its output.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.*;
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
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);
}
Based on this HowTo which list the currently running processes, we adapt it to check for a specific
program name.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
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;
}
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.
and then get the path of the JRE from the corresponding key
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.
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.
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()
/*
* 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{
/**
* Return the name of this custom tag.
*/
public String getName() {
return NAME;
}
/**
* Will return true since <code>@todo</code>
* can be used in field documentation.
* @return true since <code>@todo</code>
* can be used in field documentation and false
* otherwise.
*/
public boolean inField() {
return false;
}
/**
* Will return true since <code>@todo</code>
* can be used in constructor documentation.
* @return true since <code>@todo</code>
* can be used in constructor documentation and false
* otherwise.
*/
public boolean inConstructor() {
return true;
}
/**
* Will return true since <code>@todo</code>
* can be used in method documentation.
* @return true since <code>@todo</code>
* can be used in method documentation and false
/**
* Will return true since <code>@todo</code>
* can be used in method documentation.
* @return true since <code>@todo</code>
* can be used in overview documentation and false
* otherwise.
*/
public boolean inOverview() {
return true;
}
/**
* Will return true since <code>@todo</code>
* can be used in package documentation.
* @return true since <code>@todo</code>
* can be used in package documentation and false
* otherwise.
*/
public boolean inPackage() {
return true;
}
/**
* Will return true since <code>@todo</code>
* can be used in type documentation (classes or interfaces).
* @return true since <code>@todo</code>
* can be used in type documentation and false
* otherwise.
*/
public boolean inType() {
return true;
}
/**
* Will return false since <code>@todo</code>
* is not an inline tag.
* @return false since <code>@todo</code>
* is not an inline tag.
*/
/**
* 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);
}
/**
* 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 :
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.
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
Using Ant,
<javadoc
locale="fr"
sourcefiles="c:/client/Client.java"
destdir="javadoc/Client"
author="true"
version="true"
use="true"
private="true"
windowtitle="Client">
<doctitle><![CDATA[<h1>Client</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright © 2003 Real's Howto.</i>]]></bottom>
</javadoc>
com
rgagnon
HelloWorld.java
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.
<html><head></head><body>
this is <i>com.rgagnon</i> package description,
see <a href="http://www.rgagnon.com" target="_top">web site</a>
</body></html>
Now execute the javadoc utility located in [JDK]\bin directory from the root of the com.rgagnon
package.
Since JDK 1.5, to create a package comment file, you have a choice of two files to place your
comments:
See http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#packagecomment
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()
* </pre>
* @param args
*/
public static void main(String args[]){
Frame f = new Frame();
f.setSize(200,200);
f.setVisible(true);
}
}
You can represent any character with a numerical identity, the syntax is &#nnn; where nnn is the
Unicode code (decimal value) of the character.
/**
* To use this class use this XML
*
* <xml>
* <parameter>foo</parameter>
* <value>bar</value>
* </xml>
*
*/
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</parameter>
* <value>bar</value>
* </xml>
* }
* </pre>
*/
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>
* }
* </pre>
*/
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.*;
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();
}
}
import java.util.logging.*;
import java.io.*;
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();
}
}
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.
This class generate a stackTrace and then parse it according to the parameters received.
[StackTrace.java]
[SimpleTrace.java]
import java.io.*;
import java.util.*;
class MyClass {
MyClass() { }
NOTES:
The stackTrace() formatting may be different with the JVM used, in this example, it's the Sun's JDK 1.2.1.
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
public ExecutionTimer() {
reset();
}
See this HowTo to format a duration in ms into a string as "Days , Hours , minutes and seconds".
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.
/**
* 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);
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.
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 :
even if myValue is null, this toString() method will display "null" as the value and not throw a
NullPointerExeception.
While you can set the logging level through the configuration properties file
...
setLogLevel("DEBUG");
...
setLogLevel("INFO");
...
[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.
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>
</APPLET>
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.
To create a JAR file (compressed), use the JAR utility included with JDK1.1
According to some JAVA developers, JAR in CLASSPATH needs to be uncompressed (JDK1.1). To create uncompressed JAR:
[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:
<APPLET CODE="a.class"
ARCHIVE="abc.zip"
WIDTH=618
HEIGHT=410>
</APPLET>
[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 :
to create myArchive.cab.
It is possible sign a CAB file using the Authenticode mechanism, check the Microsoft Web site for
more infos.
<APPLET CODE="a.class"
WIDTH=100
HEIGHT=100>
<PARAM NAME="cabbase"
VALUE="abc.cab">
</APPLET>
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
while Netscape will use the ZIP file and ignore de CAB parameter, MSIE will use CAB and ignore
the ZIP file.
[ home ]
[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
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().
import java.awt.*;
import java.awt.event.*;
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.
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
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" .
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.
import java.net.*;
import java.io.*;
import java.io.*;
import java.util.jar.*;
import java.util.zip.*;
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();
}
}
Manifest−Version: 1.0
Classpath: .\mydb.jar
Main−Class: ExtractFromJAR
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
package com.rgagnon;
The output
>java com.rgagnon.HelloClass
file:/C:/DEV/WORK/JAVA/com/rgagnon/HelloClass.class
import java.util.jar.*;
import java.util.*;
import java.io.*;
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 :
*/
}
}
package com.rgagnon;
Manifest−Version: 1.0
Main−Class: com.rgagnon.Hello
Manifest−Version: 1.0
Main−Class: com.rgagnon.Hello
Specification−Version: 2.1
Implementation−Version: 1.1
Hello() {
Package p = this.getClass().getPackage();
System.out.println("Hello Specification Version : "
+ p.getSpecificationVersion());
System.out.println("Hello Implementation Version : "
+ p.getImplementationVersion());
}
This example opens a given Jar and outputs its version information.
package com.rgagnon.howto;
import java.util.jar.*;
System.out.println("Specification−Version: "
+ JarUtils.getJarSpecificationVersion(javaMailJar));
System.out.println("Implementation−Version: "
+ JarUtils.getJarImplementationVersion(javaMailJar));
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">
<target name="compile">
<javac srcdir="." />
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 EST 2006 META−INF/
55 Wed May 03 17:06:32 EST 2006 META−INF/MANIFEST.MF
55 Wed May 03 17:06:32 EST 2006 howto/
335 Wed May 03 16:36:16 EST 2006 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">
<target name="compile">
<javac srcdir="." />
</target>
<jar destfile="hello.jar"
basedir="."
includes="**/*.class"
manifest="MANIFEST.MF"
/>
</target>
<manifest file="MANIFEST.MF">
<attribute name="Built−By" value="${user.name}"/>
<attribute name="Main−Class" value="howto.Hello"/>
<attribute name="Implementation−Version"
value="${version.num}−b${build.number}"/>
</manifest>
<jar destfile="hello.jar"
basedir="."
includes="**/*.class"
manifest="MANIFEST.MF"
/>
</target>
<target name="jar">
<delete file="hello.jar"/>
<property name="version.num" value="1.00"/>
<buildnumber file="build.num"/>
<manifest file="MANIFEST.MF">
<attribute name="Built−By" value="${user.name}"/>
<attribute name="Main−Class" value="howto.Hello"/>
<attribute name="Implementation−Version"
value="${version.num}−b${build.number}"/>
</manifest>
<jar destfile="hello.jar"
<target name="cleanup">
<delete>
<fileset dir="." includes="**/*.class"/>
<fileset file="MANIFEST.MF"/>
</delete>
</target>
...
<target name="jar">
<delete file="hello.jar"/>
<property name="version.num" value="1.00"/>
<buildnumber file="build.num"/>
<tstamp>
<format property="TODAY" pattern="yyyy−MM−dd HH:mm:ss" />
</tstamp>
<manifest file="MANIFEST.MF">
<attribute name="Built−By" value="${user.name}"/>
<attribute name="Main−Class" value="howto.Hello"/>
<attribute name="Implementation−Version"
value="${version.num}−b${build.number}"/>
<attribute name="Built−Date" value="${TODAY}"/>
</manifest>
<jar destfile="hello.jar"
basedir="."
includes="**/*.class"
manifest="MANIFEST.MF"
/>
</target>
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
: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.
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
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.
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.
It's possible (but not so simple) to do it automatically without specifying each jar one by one :
<path id="build.classpath">
<fileset dir="${basedir}"/>
<include name="lib/*.jar"/>
</fileset>
</path>
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">
<fileset dir="${build.dir}">
<include name="*.jar"/>
</fileset>
</path>
<jar>
...
<manifest>
<attribute name="Main−Class" value="com.mycompany.TestMain"/>
<attribute name="Class−Path" value=". ${lib.list}"/>
</manifest>
...
</jar>
One way is to instanciate a known browser−specific method and catch the Exception if not found
import java.applet.*;
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
<HTML></HTML><HEAD>
<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";
}
}
</SCRIPT></HEAD><BODY>
<APPLET CODE ="MyApplet.class"
HEIGHT=100
WIDTH=400
ARCHIVE=}; >
</APPLET>
</BODY></HTML>
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.
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="MyApplet.class"
NAME="myApplet"
HEIGHT=400 WIDTH=400 ALT="Oups! You don't have JAVA enabled">
<A HREF="nojava.html">Oups! You don't have JAVA enabled, click here.</A>
</APPLET>
</BODY></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.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
// String
aLabel = new JLabel
(MyResources.rb.getString("aLabel"));
add(aLabel);
// Object
aCheckbox =
(JCheckBox)MyResources.rb.getObject("aCheckbox");
add(aCheckbox);
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));
setSize(400,400);
}
SwingUtilities.invokeLater(t);
}
}
import java.util.*;
import javax.swing.*;
import java.text.*;
5 Internationalization
}
import java.util.*;
import java.util.*;
import javax.swing.*;
import java.util.*;
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.
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.
import java.util.*;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
int localeChoosen = 0;
Locale localeCurrent;
ResourceBundle rb;
ButtonGroup bg;
JButton btnQuit;
JRadioButton r0, r1, r2;
JLabel today;
boolean defaultDone = false;
// 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);
// 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);
}
import java.util.*;
import java.util.*;
import java.util.*;
import java.util.*;
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
The ResourceBundle try to load the properties file from the current classpath.
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 java.util.*;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
int localeChoosen = 0;
Locale localeCurrent;
ResourceBundle rb;
ButtonGroup bg;
JButton btnQuit;
JRadioButton r0, r1, r2;
JLabel today;
boolean defaultDone = false;
// RADIO buttons
bg = new ButtonGroup();
// 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);
}
[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}
For example :
import java.awt.*;
public class TestUnicode extends java.applet.Applet {
Output :
Java not enabled!
á \u00e0 Á \u00c0
à \u00e1 À \u00c1
â \u00e2 Â \u00c2
é \u00e9 É \u00c9
è \u00e8 È \u00c8
ê \u00ea Ê \u00ca
î \u00ee Î \u00ce
ç \u00e7 Ç \u00c7
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.
[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 javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public MessageBoxExample() {
group = new ButtonGroup();
locale = Locale.US;
}
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");
}
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;
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
*/
}
}
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:
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 javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public LocalizeJFileChooser() {
group = new ButtonGroup();
locale = Locale.US;
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
*/
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 :
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.
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).
Using Ant,
<javadoc
Case sensitive
java.util.Arrays.sort(myArray);
Case insensitive
java.util.Arrays.sort(myArray, String.CASE_INSENSITIVE_ORDER);
import java.util.*;
import java.io.*;
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));
Before :
Réal Real Raoul Rico
After :
Raoul Real Réal Rico
...
Locale loc = Locale.FRENCH;
sortArray(Collator.getInstance(loc), words);
...
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.
// (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
Equality
class Test {
public static void main(String args[]) {
String s1 = "état";
String s2 = "État";
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 ");
}
}
}
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.
JDK1.4
import sun.text.Normalizer;
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 :
s = s.replaceAll("[èéêë]","e");
s = s.replaceAll("[ûù]","u");
s = s.replaceAll("[ïî]","i");
s = s.replaceAll("[àâ]","a");
s = s.replaceAll("Ô","o");
s = s.replaceAll("[ÈÉÊË]","E");
s = s.replaceAll("[ÛÙ]","U");
s = s.replaceAll("[ÏÎ]","I");
s = s.replaceAll("[ÀÂ]","A");
s = 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
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.*;
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().
Alternate technique
import java.io.*;
try {
ps = new PrintStream(System.out, true, "Cp850");
}
catch (UnsupportedEncodingException error) {
System.err.println(error);
System.exit(0);
}
ps.println(javaString);
}
}
>java Hello
Cp1252
Cp1252
windows−1252
See also java encoding table for the encoding sets supported.
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.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
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
Another way is to use a regular expression, see this Javascript HowTo for a hint!
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
import java.io.*;
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();
}
}
);
}
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();
}
}
}
import java.io.*;
}
catch (Exception e) {
System.out.println(stack2string(e));
}
}
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.*;
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().
Alternate technique
import java.io.*;
try {
ps = new PrintStream(System.out, true, "Cp850");
}
catch (UnsupportedEncodingException error) {
System.err.println(error);
System.exit(0);
}
ps.println(javaString);
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
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.
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();
}
}
}
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();
}
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();
}
}
}
java.io.DataInputStream in =
new java.io.DataInputStream(System.in);
String aLine = in.readLine();
NOTE: JDK 1.5 provides the Scanner class to do this, see this HowTo.
(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:").
// 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);
import java.io.*;
import javax.swing.filechooser.*;
The output
>java VolumeLabel c:
"temp"
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);
}
}
}
import java.io.File;
import java.io.FileWriter;
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.
import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
The result is
Now, rewrite this program to use a 512−bytes buffer and specify the ASCII as character−encoding
to be used.
import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
The result is
Note that your result will vary depending on your machine/java version but the performance gain
should in the same magnitude.
Be sure to read this Javaworld article. It describes the various pitfalls related to the Runtime.exec()
method.
import java.io.*;
public class CmdExec {
String line;
OutputStream stdin = null;
InputStream stderr = null;
InputStream stdout = null;
stdin.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
}
}
@java −garbage
@java −version
import java.io.*;
import java.util.*;
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.
[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.");
}
}
You still need to press ENTER to CONNECT, there is an option in the Connection properties to
connect automatically.
If you need to pass arguments, it's safer to a String array especially if they contain spaces.
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.
6.24 VBSCRIPT
// Win9x
Runtime.getRuntime().exec("start myscript.vbs");
// WinNT
Runtime.getRuntime().exec("cmd /c start myscript.vbs");
or
class StartExcel {
public static void main(String args[])
throws IOException
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.
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.
We simply extract to environnment variable called %programfiles% and build the complete path
from there.
[JDK1.5]
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
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));
}
}
then
// default browser
public static void browse(URI document) throws IOException {
Desktop dt = Desktop.getDesktop();
dt.browse(document);
}
While you can exec("java myaotherapp"), it is more appropriate to instanciate and called the main
method of the other application.
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");
}
}
C:\>java Program1a
Hello from Program1a
Hello from Program2
Hello from Program2
Hello from Program2
Hello from Program2
Hello from Program1a
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 How−to 1
http://www.rgagnon.com/javadetails/java−0002.html|JAVA How−to 2
http://www.rgagnon.com/javadetails/java−0003.html|JAVA How−to 3
http://www.rgagnon.com/javadetails/java−0004.html|JAVA How−to 4
http://www.rgagnon.com/javadetails/java−0005.htmL|JAVA How−to 5
[StartBrowser.java]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
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) {
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
for
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();
}
try {
Runtime.getRuntime().exec
("cmd /c start " + currentDir + "/viewLog.lnk");
}
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.*;
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.
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).
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.
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 java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
However, it's easy to do from a VBS. You execute the script from Java, wait for its completion and
capture the return code.
import java.io.File;
import java.io.FileWriter;
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.*;
try {
// that our CMD file in our JAR
InputStream is =
getClass().getResource("/screensaver.cmd").openStream();
BufferedReader brCmdLine =
new BufferedReader(new InputStreamReader(is));
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();
}
}
}
}
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 java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
item 1
item 2
item 3
item 4
item 5
ITEM 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.
import java.io.*;
import java.util.*;
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();
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 line 1
datafile1 line 2
datafile1 line 3
datafile1 line 4
datafile1 line 5
[/test/datafile2.txt]
datafile2 line 1
datafile2 line 2
datafile2 line 3
datafile2 line 4
datafile2 line 5
Try it :
import java.applet.*;
import java.io.*;
The html
<HTML><HEAD></HEAD><BODY>
<APPLET CODE=ReadFromJar.class width=1 height=1 archive=MyJarApplet.jar>
</APPLET>
See java console for output</BODY></HTML>
Try it here
import java.io.*;
import java.util.jar.*;
import java.util.zip.*;
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();
}
}
Manifest−Version: 1.0
Classpath: .\mydb.jar
Main−Class: ExtractFromJAR
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
[ReadingFloat.java]
[floatwithdelimitercolon.dat]
1.2,1.3,1.6,1.78,1.2345
2.2,2.3,2.6,2.78,2.2345
[floatwithdelimiterspace.dat]
[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());
}
}
}
[JDK1.1]
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.*;
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);
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"); .
import java.io.*;
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.
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;
/**
* Utilities log
*/
import java.io.*;
import java.text.*;
import java.util.*;
private SimpleLog() { }
try {
write("LOG file : " + filename);
}
catch (Exception e) {
System.out.println(stack2string(e));
}
SimpleLog.write("i am here");
import java.io.*;
and then
import java.io.*;
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.
will insert the string "HELLO WORLD" at line number 9 in the file "test.out".
[JDK1.1]
import java.io.*;
// input
FileInputStream fis = new FileInputStream(inFile);
BufferedReader in = new BufferedReader
(new InputStreamReader(fis));
// output
FileOutputStream fos = new FileOutputStream(outFile);
inFile.delete();
outFile.renameTo(inFile);
}
}
import java.io.*;
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.
import java.util.Vector;
import java.io.*;
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();
}
}
System.out.println(theQueue.toString());
}
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.
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";
import java.io.*;
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.*;
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 !" );
}
};
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.
public DirFilterWatcher() {
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 );
}
};
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/
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
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).
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) {
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
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.
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.TreeSet;
/**
* <CODE>
* 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]
* }
* </CODE>
*/
import java.io.File;
import java.io.FilenameFilter;
import java.util.regex.*;
import java.io.*;
import java.util.*;
public class DirUtils {
result = recurseInDirFrom(dir);
_result = result.split("\\|");
return Arrays.asList(_result);
}
result = dirItem;
/*
output:
//
// usage : java CreateAFile 2048 twokbytes.dat
//
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}
import java.io.File;
...
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,
if ( !(tempdir.endsWith("/") || tempdir.endsWith("\\")) )
tempdir = tempdir + System.getProperty("file.separator");
>java Hello
Cp1252
Cp1252
windows−1252
See also java encoding table for the encoding sets supported.
import java.io.File;
public ParsePathname() { }
There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about
OpenSource (and free) solutions.
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.
import java.io.IOException;
import java.io.OutputStream;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
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...).
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 Age Payment Bonus
${employee.name} ${employee.age} ${employee.payment} ${employee.bonus}
$[SUM(@employee.payment@)]
Employees
Name Age Payment Bonus
Derek 35 3000 30,00%
Else 28 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 jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
import java.io.File;
import 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());
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");
6.76 JCOM
xlRange.Item(1,filenames.length+2).Value("sum");
xlRange.Item(2,filenames.length+2).Formula(expression);
xlRange.Columns().AutoFit(); // fit columns
xlBook.Close(false,null,false);
excel.Quit();
See http://sourceforge.net/projects/jcom
See also this HowTo for an alternative package to access a COM package from Java.
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");
...
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());
// add to sheet
ImageHandle giffy = new ImageHandle(fin, sheet);
// 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);
}
See also this HowTo for a way to create a simple XLS without any additional library.
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.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.
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
<TABLE>
<th><h4>Just testing</h4>
<TR><TD width="20">1</TD><TD width="30">2</TD><TD width="40">3</TD></TR>
<TR><TD>4</TD><TD>4</TD><TD>6</TD></TR>
<TR><TD>7</TD><TD>8</TD><TD>9</TD></TR>
<TR><TD>=SUM(A3:A5)</TD><TD>=SUM(B3:B5)</TD><TD>=SUM(C3:C5)</TD></TR>
</TABLE>
Now you can double click on the saved file to load it into Excel and the translation will be done.
From a server, remember to send the appropriate MIME TYPE : application/excel to the client.
A nice OpenSource is http://www.lowagie.com/iText/ [ITEXT] . iText can deal with RTF and HTML
file too.
import com.lowagie.text.*;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
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.*;
/*
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]);
output.open();
output.addAuthor("RealHowTo");
output.addSubject(args[0]);
output.addTitle(args[0]);
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.*;
try {
in1 = new BufferedInputStream(new FileInputStream(file1));
in2 = new BufferedInputStream(new FileInputStream(file2));
return result;
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return false;
}
if (currentExtension.equals("")){
target = source + "." + newExtension;
}
else {
target = source.replaceAll("." + currentExtension, newExtension);
}
return new File(source).renameTo(new File(target));
}
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
import java.io.*;
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 <BODY> tag.
import java.io.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
public Html2Text() {}
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:
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.
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.*;
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.
Another tool is mime−util. This tool can detect using the file extension or the magic header
technique.
The nice thing about mime−util is that there is no dependency (with others Apache packages) so it
is very lightweight.
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
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:
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
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
@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;
}
}
import java.io.*;
import java.text.*;
import java.util.*;
Then
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
Use the numerical identity to represent the / in the javadoc section to avoid any conflict with a real
comment.
You can represent any character with a numerical identity, the syntax is &#nnn; where nnn is the
Unicode code (decimal value) of the character.
/*
** 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();
}
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.
/*
** 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();
}
err.println(e.getName());
}
}
/*
** a simple unZIP tool
**
** ex. java UnZip file.zip file1 to unzip file 1 from file.zip
** java UnZip file.zip to unzip file.zip
**
*/
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.text.*;
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();
}
(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.
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];
Tone.sound(1000,100);
Tone.sound(100,1000);
Tone.sound(5000,100);
} catch (LineUnavailableException lue) {
System.out.println(lue);
}
}
}
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);
import sun.audio.*;
...
...
AudioPlayer p=AudioPlayer.player;
try{
AudioStream as =
new AudioStream(new FileInputStream("aSound.au"));
p.start(as);
}
catch(IOException err){
err.printStackTrace();
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.*;
Since JDK1.3, you have also the javax.sound package, see this HowTo.
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 {
ResultSet rs;
Statement stmt;
String 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 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();
}
ResultSet rs;
rs = stmt.executeQuery();
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.
Statement stmt;
String sql;
int rows;
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.
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();
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).
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 "\".
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();
}
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();
}
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");
ResultSet rs;
...
if (rs.next()) {
do {
System.out.println("Record found");
} while (rs.next());
}
else {
System.out.println("Record not found");
}
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;
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();
}
}
}
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.*;
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.
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.
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.
In this example, we have a program with several threads. Each thread makes a connection but the
login process is done only once.
import java.util.Properties;
import java.sql.*;
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() { }
}
}
import java.sql.*;
TestDBOraclePool3Thread(int n) {
noThread = n;
}
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) { }
}
}
}
import java.net.URL;
import java.sql.*;
java.util.Date today =
new java.util.Date();
java.sql.Date sqlToday =
new java.sql.Date(today.getTime());
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
java.util.Date today =
new java.util.Date();
java.sql.Date sqlToday =
new java.sql.Date(today.getTime());
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 <?");
p.setDate(1, sqlToday);
ResultSet rs = p.executeQuery();
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' } )");
Connection conn;
then
// Procedure execution
ResultSet rs = cs.executeQuery();
int i = 0;
int j = 1;
return cs.getInt(1);
}
Some JDBC driver have limit about how big returned records can be.
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(*).
// 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");
import java.net.URL;
import java.sql.*;
class JDBCapp {
static MyConnection theConn;
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();
}
}
}
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
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 ();
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 ***");
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!)
// 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,"","");
LASTNAME FIRSTNAME ID
Reiser Beth 102
Ricci Dylan 111
Gugliuzza Brian 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 java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;
example 2
import java.io.*;
import java.sql.*;
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();
}
}
}
There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about
OpenSource (and free) solutions.
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.
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
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...).
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 Age Payment Bonus
${employee.name} ${employee.age} ${employee.payment} ${employee.bonus}
$[SUM(@employee.payment@)]
7.28 POI
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);
Employees
Name Age Payment Bonus
Derek 35 3000 30,00%
Else 28 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 jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
import java.io.File;
import 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());
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");
xlBook.Close(false,null,false);
excel.Quit();
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");
...
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();
}
// add to sheet
ImageHandle giffy = new ImageHandle(fin, sheet);
// 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);
See also this HowTo for a way to create a simple XLS without any additional library.
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver) ;
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: " + rs.getString(1) +
"\n " + rs.getString(2) +
"\n " + rs.getString(3) +
"\n " + rs.getString(4) );
[JDK1.2]
import java.net.URL;
import java.sql.*;
class JDBCapp {
static MyConnection theConn;
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();
}
}
}
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
}
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
class JDBCapp {
try {
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) {
}
}
}
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 :
*/
}
}
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.
st = con.createStatement();
rs = st.executeQuery
("SELECT value FROM vendors WHERE value LIKE 'one/_word' {escape '/'}");
st = con.createStatement();
rs = st.executeQuery
("SELECT value FROM vendors WHERE value LIKE '%one/%word' {escape '/'} ");
st = con.createStatement();
rs = st.executeQuery
("SELECT value FROM vendors WHERE value LIKE '$%%' {escape '$'}");
st = con.createStatement();
rs = st.executeQuery
("SELECT value FROM vendors WHERE value LIKE '%=_' {escape '='}");
SELECT value FROM vendors WHERE value LIKE '%=_%' ESCAPE '=';
ref : Labo−Oracle.com.
It's good idea to use the JDBC escape function instead of using a specific DBMS function. This way,
your code will be portable.
7.42 P6Spy
P6Spy is an open source framework for applications that intercept and optionally modify database
statements.
Download at http://p6spy.com/
It provides really nice logging facilities with the SQL statement and the running time.
Download at http://proxool.sourceforge.net/
7.43 Proxool
8 JNI
8.1 java−jni
• 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"
#include "JavaHowTo.h"
8 JNI
return env−>NewStringUTF("Hello world");
}
then from C, we want to call the Java sayHello() method which returns a String :
class JavaHowTo {
public native void sayHello();
static {
System.loadLibrary("javahowto");
}
}
8 JNI
8.4 Set the computer clock
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0285.html
SYSTEMTIME st;
GetLocalTime(
st.wHour = hour;
st.wMinute = minutes;
SetLocalTime(
}
class JavaHowTo {
public native void setSystemTime( short hour, short minutes);
static {
System.loadLibrary("javahowto");
}
}
// this example will set the system at 10h21 using the Windows API
// SetLocalTime.
Before calling a Java object's method from JNI, we need its signature. For example, the method
(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 Chararacter
boolean Z
byte B
char C
double D
float F
int I
long J
object L
short S
void V
array [
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 */
JNI provides special functions (relative to the type) to access Java arrays.
class JavaHowTo {
public static native int max(int [] t);
static {
System.loadLibrary("javahowto");
}
}
class JNIJavaHowTo {
public static void main(String[] args) {
int [] myArray = {4, 7, 5, 9, 2, 0, 1};
System.out.println(JavaHowTo.max(myArray));
}
}
[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.
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
Next version (JDK1.4) may provide this functionality but for now, you need some JNI functions.
class JavaHowTo {
public native double divide(double d1, double d2);
static {
System.loadLibrary("javahowto");
}
}
class JavaHowTo {
JNI requires that the function names follow a specific format. If you have a Java native method in a
class called MyClass like this:
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:
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
First you need the handle of the Window. Call this JNI function with Window Title.
#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);
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 :
NOTE : This is fine if the environment variable contains only regular 7−bit ASCII characters.
class JavaHowTo {
public native long getCurrentProcessId();
static {
System.loadLibrary("jni2");
}
}
#include "stdafx.h"
#include <process.h>
#include "JavaHowTo.h"
// return GetCurrentProcessId();
return getpid();
}
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 {
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 :−)
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.
#include "stdafx.h"
#include <stdlib.h>
#include "JavaHowTo.h"
int originalColors;
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!
}
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 );
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, foreground + background);
}
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole,
originalColors = ConsoleInfo.wAttributes;
}
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, originalColors);
}
System.out.print("http://www.rgagnon.com");
8.16 Clear the console, set color and cursor position (JNI)
// restore the orginal colors
jht.restoreColors();
NativeCall
NativeCall is a Java toolkit that lets you call operating system methods from whithin Java without
JNI code.
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/
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 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 <applet> tags to <embed> tag (more info on this is on the Mozilla site).
Thanks to Neil English for the tip
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.*;
9 Javascript interaction
Color b, f;
public MyThread(JavaChrono a) {
theApplet = a;
}
[HTML]
<HTML><HEAD></HEAD><BODY>
<APPLET CODE=JavaChrono.class
WIDTH=150
HEIGHT=150>
</APPLET>
<A HREF=""
onMouseOver="document.applets[0].startChrono()"
onMouseOut="document.applets[0].stopChrono()" >
<IMG SRC="whatever.gif" WIDTH=100 HEIGHT=100>
</A>
/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]
<HTML>
<HEAD></HEAD>
<BODY>
<APPLET NAME="myApplet" CODE="MyApplet.class" HEIGHT=1 WIDTH=1></APPLET>
<FORM>
<INPUT TYPE="button"
VALUE="Start the Applet"
onClick=
"if (document.applets[0].isActive()) document.myApplet.showFrame()">
<INPUT TYPE="button"
VALUE="Stop the Applet"
onClick=
"if (document.applets[0].isActive()) document.myApplet.disposeFrame()">
/FORM/BODY/HTML
[JAVA APPLET]
import java.applet.*;
import java.awt.*;
Try it here.
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.
[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);
}
}
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function getScreenDimension() {
alert("Screen Dimension\n" +
" width:" +
java.awt.Toolkit.getDefaultToolkit().getScreenSize().width +
" height:" +
java.awt.Toolkit.getDefaultToolkit().getScreenSize().height);
}
</SCRIPT>
<FORM>
<INPUT type="button" value="call Java Applet method"
onClick = "document.myApplet.sayHello()">
</FORM>
<APPLET CODE="InJava.class"
NAME="myApplet"
HEIGHT=100 WIDTH=100>
</APPLET>
/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;
}
}
<HTML><HEAD></HEAD><BODY>
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.
[IE4 or better]
<OBJECT ID="myApplet" ...>
...
<PARAM NAME="scriptable" value="true">
<PARAM NAME="mayscript" value="true">
...
</OBJECT>
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.
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).
import java.awt.*;
import java.applet.*;
public class InJava3 extends Applet{
public int iJava = 123;
public String sJava = "String from JAVA";
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function JavaSays() {
alert("Java says\n the value of iJava is :" +
document.myApplet.getIntJava() + "\n" +
"and sJava is :" +
document.myApplet.getStringJava());
}
</SCRIPT>
<FORM>
<INPUT type="button" value="Java says"
onClick = "JavaSays();">
</FORM>
<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.
[Java applet]
import java.applet.*;
import java.net.*;
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function doAlert(s) {
alert(s);
}
</SCRIPT>
<APPLET CODE="InJava4.class"
NAME="myApplet" MAYSCRIPT
HEIGHT=10 WIDTH=10>
</APPLET>
</BODY>
/HTML
Try it here
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
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.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import netscape.javascript.*;
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.
if (success)
System.out.println("eval succeeded, result is " + jsresult);
else
System.out.println("eval failed with error " + jsresult);
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.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import netscape.javascript.*;
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function createHTML(s) {
win = window.open("about:");
win.document.write(s);
win.document.close();
}
</SCRIPT>
<APPLET CODE=HtmlFromJava.class
MAYSCRIPT
WIDTH=150
HEIGHT=150>
/APPLET/BODY/HTML
Try it here
<HTML><HEAD></HEAD>
<FRAMESET COLS="50%,*">
<FRAME SRC="interframe1.html" NAME="f1" >
<FRAME SRC="interframe2.html" NAME="f2">
</FRAMESET>
</HEAD>
<HTML><HEAD></HEAD>
<SCRIPT>
function toOtherFrame(a, target) {
if (target == "f1")
parent.f1.document.app1.fromOtherFrame(a);
else
parent.f2.document.app2.fromOtherFrame(a);
}
</SCRIPT>
</HEAD>
<BODY>
<APPLET CODE="InterFrameDemo.class"
NAME="app1" MAYSCRIPT
HEIGHT=200
WIDTH=200>
<PARAM NAME="target"
VALUE="f2">
</APPLET></BODY></HTML>
<HTML><HEAD></HEAD>
<BODY>
<APPLET CODE="InterFrameDemo.class"
NAME="app2" MAYSCRIPT
HEIGHT=200
WIDTH=200>
WIDTH=200>
<PARAM NAME="target"
VALUE="f1">
</APPLET></BODY></HTML>
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
Try it here
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
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="FirstApplet.class"
HEIGHT=100
WIDTH=300>
/APPLET/BODY/HTML
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
SecondApplet.html
<HTML><HEAD></HEAD><BODY>
<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> '
SecondApplet.java
import java.applet.*;
import java.awt.*;
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]
<HTML><HEAD>
<SCRIPT>
function getValueFromApplet(){
document.myForm.q.value = document.myApplet.getFirstName();
return true;
}
9.11 Retrieve values from a Java applet for HTML form (CGI)
</SCRIPT>
<BODY>
<APPLET CODE="InitHTMLForm.class"
NAME="myApplet"
HEIGHT=0 WIDTH=0>
</APPLET>
<FORM ACTION="http://www.google.ca/search"
NAME="myForm"
onSubmit="return getValueFromApplet()">
<INPUT TYPE="hidden" VALUE="" NAME="q">
<INPUT TYPE="submit" VALUE="Submit" >
</FORM>
/BODY/HTML
Try it here
<SCRIPT>
function isAppletReady(a) {
return a.isActive();
}
</SCRIPT>
<FORM>
<INPUT TYPE=button
VALUE="Check applet"
onClick="if (!isAppletReady(document.applets[0])) alert("not ready");">
/FORM
An Applet is ready when it's loaded and its init() method is done.
<SCRIPT>
function waituntilok() {
if (document.myApplet.isActive()) {
doit();
}
else {
settimeout(waituntilok(),5000)
}
}
function doit() {
....
}
</SCRIPT>
...
<BODY onLoad="waituntilok();">
....
/BODY
Here a "browser friendly" solution from N. Witteman to check if an Applet can be loaded (or found).
<HTML>
<HEAD>
<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
}
</SCRIPT>
</HEAD>
PrivilegeManager.enablePrivilege("UniversalBrowserRead");
PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
But there is a workaround, simply pass the informations through Javascript functions!
[JSjava.java]
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import netscape.javascript.*;
JSObject win;
b1.addActionListener(this);
b2.addActionListener(this);
add(tf);add(b1);add(b2);
}
[JSjava.html]
<HTML><HEAD>
<SCRIPT>
function getHTMLInputText(){
return document.forms[0].elements[0].value;
}
function setHTMLInputText(s){
document.forms[0].elements[0].value = s;
}
</SCRIPT></HEAD><BODY>
<FORM>
<INPUT TYPE=text SZIE=20>
</FORM>
from Javascript :
function isJavaAvailable(){
return ( navigator.javaEnabled &navigator.javaEnabled() );
}
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;
}
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.
To compile such program, you have to include in the CLASSPATH a special jar included in the JRE
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
<HTML><HEAD></HEAD><BODY>
<APPLET CODE=TestCookie.class
MAYSCRIPT
HEIGHT=150
WIDTH=200>
/APPLET/BODY/HTML
import netscape.javascript.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
setLayout(new FlowLayout());
add(tf1);
add(tf2);
add(b1);
add(b2);
add(b3);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
}
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();
See this text file with some useful Javascript functions for cookies handling.
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.
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
var jsVar = "Hello World from jsVar";
function jsFnct() {
return "Hello World from jsFnct";
}
</SCRIPT></HEAD><BODY>
<<APPLET CODE ="MyApplet.class" HEIGHT=100 WIDTH=400>
<PARAM NAME="first" VALUE="&{jsVar};">
<param name="second" value="&{jsFnct()};">
<param name="third"
value="&{'hello world'.toUpperCase() + ' from js Expression'};">
</APPLET>
/BODY/HTML
import java.applet.*;
import java.awt.*;
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.
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.*;
k = javaArray.length;
s = javaArray[0];
for (int i= 1 ; i < k; i++) {
s += "|" + javaArray[i] ;
}
return s;
}
while(st.hasMoreTokens()){
javaArray[i++] = st.nextToken();
}
}
}
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);
}
</SCRIPT>
<FORM>
<INPUT type="button" value="get JAVA array"
onClick = "getJavaArray();">
<INPUT type="button" value="get JAVA array (as a string)"
onClick = "getJavaArrayAsAString();">
<INPUT type="button" value="put JAVA array"
onClick = "putJavaArray();">
</FORM>
<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)
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)
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
}
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
[SimpleJ2JS.HTML]
<FRAMESET ROWS="100%,*">
<FRAME NAME="mainFrame" SRC="visiblepage.html" border=0>
<FRAME NAME="scriptFrame" SRC="invisiblepage.html" border=0>
</FRAMESET>
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]
<HTML><HEAD>
<SCRIPT>
function showMessage(s) {
alert(s)
}
</SCRIPT>
</HEAD><BODY><H1>Simple Java to Javascript interaction</H1><P>
<APPLET CODE=SimpleApplet.class
WIDTH=150
HEIGHT=150>
</APPLET></BODY></HTML>
invisiblepage.html contains the function to extract the parameter and call the showMessage()
function in the visible frame.
<HTML><HEAD>
<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))
}
}
</SCRIPT>
</HEAD><BODY onLoad="getAndSendMessage();">
</BODY></HTML>
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.*;
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]
<FRAMESET ROWS="100%,*">
<FRAME NAME="visibleFrame" SRC="visiblepage2.html" border=0>
<FRAME NAME="invisibleFrame" SRC="invisiblepage2.html" border=0>
</FRAMESET>
[visiblepage2.html]
<HTML><HEAD>
<SCRIPT>
function send2Java() {
// you may need to encode the value with the escape() function
parent.invisibleFrame.location =
"invisiblepage2.html?" + document.forms[0].FromJs.value
}
</SCRIPT>
</HEAD><BODY><H1>Simple Javascript to Java interaction</H1>
<FORM>
<INPUT TYPE=input NAME=FromJs WIDTH=50 VALUE="HelloWorld">
<APPLET CODE=SimpleApplet2.class
WIDTH=300
HEIGHT=150>
</APPLET></BODY></HTML>
The class to hold a static pointer to SimpleApplet2. This pointer will be used by the InvisibleApplet.
[SimpleAppletRegistered.java]
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.*;
[invisiblepage2.html]
<HTML><HEAD>
</HEAD>
<BODY>
<APPLET CODE=InvisibleApplet.class
WIDTH=1
HEIGHT=1>
</APPLET>
</BODY></HTML>
[InvisibleApplet.java]
import java.applet.Applet;
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.
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
<HTML><HEAD>
<SCRIPT>
function reload_master() {
window.master.location.href = "./selector.html";
blank.html
<HTML<<HEAD><TITLE
</TITLE></HEAD><BODY>
</BODY></HTML>
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
<HTML><HEAD>
<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);
}
</SCRIPT></HEAD>
<BODY onLoad ="putLinksIntoApplet()">
<P ALIGN="center">Doubleclick to view
<APPLET
CODE=Selector.class
HEIGHT=100
WIDTH=400
NAME=Selector>
<PARAM NAME="targetFrame" VALUE="detail">
</APPLET>
</BODY>
/HTML
Selector.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
import java.net.*;
while(st.hasMoreTokens()){
s = st.nextToken();
l.add(s); // or l.addItem(s);
System.out.println(s);
}
okToDisplay = true;
}
}
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import netscape.javascript.*;
Try it here
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]
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
document.write("<APPLET CODE='MyApplet.class' HEIGHT=100 WIDTH=400>");
[MyApplet.java]
import java.applet.*;
import java.awt.*;
Initially the visible attribute is false. When the page is completely loaded, the DIV visibility attribute is
set to true.
<HTML>
<HEAD>
<SCRIPT>
function doIt() {
if (document.all)
mypage.style.visibility="visible"
else
document.mypage.visibility="visible"
}
</SCRIPT></HEAD>
<BODY onLoad="doIt();">
<DIV name=mypage style="visibility:hidden" >
...
</DIV>
</BODY>
</HTML>
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.
<HTML>
<HEAD></HEAD>
<BODY>
<FORM METHOD=POST ACTION="/servlet/MyServlet">
value : <INPUT TYPE="TEXT" NAME="someValue">
</FORM>
</BODY>
</HTML>
import javax.servlet.*;
import javax.servlet.http.*;
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
}
}
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.servlet.http.*;
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.
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.
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.
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.
You set attributes on your request object and then forward the request object to the other
servlet/jsp.
A Bean
Use the servlet request's isSecure() or getAuthType() methods. Or you look at these HTTP headers
: CERT_KEYSIZE , CERT_KEYSIZE, HTTPS_KEYSIZE
In a JSP
In a Servlet
<%
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") );
%>
You can't.
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]
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.
<%@page contentType="text/html"%>
<html>
<head><title>JSP Page</title></head>
<body>
<%@ page import="java.sql.*" %>
<%
com.sybase.jaguar.jcm.JCMCache jcmCache= null;
try {
jcmCache =
com.sybase.jaguar.jcm.JCM.getCacheByName(jcmCacheString);
dbConn =
jcmCache.getConnection(com.sybase.jaguar.jcm.JCMCache.JCM_WAIT);
if(rs != null) {
while(rs.next()) {
msg = rs.getString("msg");
}
}
rs.close();
dbConn.close();
}
catch (Exception e) {
out.println("OUPS " + e.getMessage() + "<BR>");
}
%>
msgtext =
<i><%= msg %></i>
</body>
</html>
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.
while (rs.next()) {
//do something
}
<env−entry>
<env−entry−name>docPath</env−entry−name>
<env−entry−value>c:/doc/doc1</env−entry−value>
<env−entry−type>java.lang.String</env−entry−type>
</env−entry>
<env−entry>
<env−entry−name>docUser</env−entry−name>
<env−entry−value>net1</env−entry−value>
<env−entry−type>java.lang.String</env−entry−type>
</env−entry>
<%
com.company.MyBean bean=new com.company.MyBean(1, 2, 3, 4);
session.putAttribute("myBean", bean);
%>
<%!
public String sayHello(){
return "Hello";
}
%>
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.
<html><head><title>Precompiling *.JSPs</title></head>
<body><h4>Precompiling *.JSPs:</h4>
<ul>
<%
HttpServletRequest req = new HttpServletRequestWrapper(request) {
public String getQueryString() {
// can be "jsp_precompile=true"
return "jsp_precompile";
};
};
NOTE: Many Application servers provide an utility to precompile JSP pages (ex. EAServer, BEAWLS). Check for a JSPC command file.
<h1>Directories</h1>
<ul>
<%
String root="c:/Repository/WebApplication/mydocs/javadoc/";
java.io.File file;
java.io.File dir = new java.io.File(root);
if (list.length > 0) {
I have a class
• 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.
package test;
import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
return SKIP_BODY;
}
}
<taglib>
<tag>
<name>hello</name>
<tagclass>test.HelloTag</tagclass>
</tag>
</taglib>
In a JSP
In a Servlet
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:params>
<jsp:fallback>
<p> unable to start plugin </p>
</jsp:fallback>
</jsp:plugin>
<%
response.setHeader("Cache−Control","no−cache");
response.setHeader("Pragma","no−cache");
response.setDateHeader ("Expires", −1);
%>
See http://support.microsoft.com/kb/q222064/.
<%
response.setHeader("Cache−Control","no−cache");
response.setHeader("Pragma","no−cache");
response.setDateHeader ("Expires", −1);
%>
<HTML>
<HEAD>
</HEAD>
<BODY>
my page body
</BODY>
<HEAD>
<META HTTP−EQUIV="PRAGMA" CONTENT="NO−CACHE">
<META HTTP−EQUIV="Expires" CONTENT="−1">
</HEAD>
</HTML>
NOTE: Pragma: no−cache prevents caching only when used over a secure connection, Expires: −1
should do the job over unsecure conection.
<jsp−descriptor>
<jsp−param>
<param−name>
keepgenerated
</param−name>
<param−value>
true
</param−value>
</jsp−param>
</jsp−descriptor>
To configure your new application, run this program java weblogic.marathon.Main testapp
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.
Attach the xsl to the xml by adding this line to the xml file :
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;
// get the PARAM=??? (assumes you have used GET request method!)...
// assume something like http://.../docxml.asp?xmlfile=myxml.xml
xmlfile = '' + Request.QueryString('xmlfile');
oXML.load(SrcXML);
// 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 );
}
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>
<container−descriptor>
<prefer−web−inf−classes>true</prefer−web−inf−classes>
</container−descriptor>
</weblogic−web−app>
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−name>
<param−value>60</param−value>
</jsp−param>
</jsp−descriptor>
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.
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.
If you can't find then you may want to look at these other sites :
Java Glossary
Many subjects covered in depth.
Stack Overflow
A site where you can ask question (not restricted to Java), really innovative in the way it works.
Participants are really cool.
Usenet's newgroups are very useful too. Check out the comp.lang.java.* groups on your favorite
Usenet newserver.
• forums.sybase.com
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
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/
The output
JDK1.4
The output
doit
JDK1.5
main
doit
doitagain
main
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
*/
}
class Class1 {
public String class1Method1() {
return "*** Class 1, Method1 ***";
}
import java.lang.reflect.*;
class Class1 {
public void say( String s1, String s2) {
System.out.println(s1 + " " + s2);
}
}
import java.lang.reflect.*;
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.
try {
String name = "java.lang.String";
String methodName = "toLowerCase";
// create an instance
System.out.println(result);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
import java.lang.reflect.*;
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
*/
}
class TestClass {
public double firstValue = 3.1416;
public int secondValue = 42;
public String thirdValue = "Hello world";
}
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
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);
While you can exec("java myaotherapp"), it is more appropriate to instanciate and called the main
method of the other application.
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
class InnerClass {
public void sayHello() {
TestIt.this.enclosingClassMethod();
}
}
}
or
class InnerClass {
public void sayHello() {
testItClass.enclosingClassMethod();
}
}
}
class Outer {
public class Inner {
public void hello(){
System.out.println("Hello from Inner()");
}
}
}
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.
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.
NOTE : This is not considered as good practice (depending on who you are talking to!) to use an
interface this way.
JDK1.5
JDK1.5 import statement can be used to import only static member from a class.
To serialize an object, it must implements the Serializable interface. The object needs 2 functions
with these signatures
Many standard Java objects already implements the Serializable interface so there is almost
nothing to do.
import java.util.Vector;
import java.io.*;
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();
}
If you need to serialize and manipulate huge objects, take a look at this open−source project.
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.
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.
In your source, when you need some debugging codes, you included them in a if statement like
During compilation, since Debug.RELEASE is always true, the code will be present. In the
production environment, the Debug class looks like this:
When compiling in that environment, the debugging code will be absent from the class file since
Debug.release is always false.
A singleton is a class that can be instantiated only one time in a JVM. Repeated calls always return
the same instance.
private OnlyOne(){}
To use it
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();
...
A nice idea is to put this toString() into a base class so all the descendents inherit from it.
class ToStringHelper {
public static String toString( Object o ) {
ArrayList list = new ArrayList();
toString( o, o.getClass(), list );
return o.getClass().getName().concat( list.toString() );
}
class Ober {
int i = 123;
private double d = 3.1415;
}
import java.util.Date;
class MyData {
MyData() {
aDate = new Date();
}
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
import java.util.Date;
class MyData {
MyData() {
aDate = new Date();
}
class Bar {
public Bar ( ) throws Exception {
}
}
static {
try {
bar = new Bar() ;
}
catch ( Exception e ) {
e.printStackTrace() ;
}
}
}
class Bar {
public Bar ( ) throws Exception {
}
}
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[]) {
import java.io.PrintWriter;
import java.io.StringWriter;
This can be useful if you want to format the StackTrace before showing it to the user.
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.
[ArraySorter.java] JDK1.1
/*
** 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;
[testArraySorter.java]
JDK1.4 case−sensitive
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);
}
}
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"
}
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
k = s.length;
if (k > 0) {
result = s[0];
for (int i= 1 ; i < k; i++) {
result += sep + s[i] ;
}
}
return result;
}
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;
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;
list.add(l1);
list.add(l2);
list.add(l3);
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.
You can also use the new shorthand notation to iterate through an array :
import java.util.*;
import java.io.*;
class InitStaticArray {
static {
integerArray= new Integer[] {
new Integer(1),
new Integer(2),
new Integer(3),
new Integer(4),
};
}
Data in hashtable are not sorted. We extract the keys and sort them.
import java.util.*;
System.out.println("============");
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.
import java.util.*;
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");
^
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.*;
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.*;
@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);
}
}
}
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
We want to sort a Collection of Person objects based on their LastName and Firstname.
12 ANT
return ((deptComp == 0) ? lastName.compareTo(emp.getLastName())
: deptComp);
}
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;
return ((nameComp == 0) ?
emp1.getFirstName().compareTo(emp2.getFirstName()) :
nameComp);
}
}
To test it :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Iterator;
// 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());
}
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]
*/
}
}
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 {
Result :
while (it.hasNext()) {
String file = (String)it.next();
}
[Java 5]
[Java 1.4]
while (it.hasNext()) {
Object o = it.next();
if(o.equals(value)) {
return o;
}
}
return null;
}
You get an exception if while scanning a Collection, you decide to remove an item.
import java.util.ArrayList;
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
The trick is to use an Iterator and remove the item with Iterator.remove()
import java.util.ArrayList;
import java.util.Iterator;
list.add("Bart");
list.add("Lisa");
list.add("Marge");
list.add("Barney");
list.add("Homer");
list.add("Maggie");
for(String s: list)
{
System.out.println(s);
}
}
/*
output :
Bart
Lisa
Marge
Homer
Maggie
Bart
Lisa
Marge
Homer
Maggie
*/
}
/**
** 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
theSimpsons.add("Bart");
theSimpsons.add("Lisa");
theSimpsons.add("Marge");
theSimpsons.add("Barney");
theSimpsons.add("Homer");
theSimpsons.add("Maggie");
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.
# 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();
}
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();
}
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 :
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!
You add a slash ("\") to continue the value on the next line.
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
import java.util.*;
class XMLProps {
public static void main(String args[]) {
new XMLProps().doit();
}
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();
}
}
}
With JDK1.4, the Preferences class can use the Windows registry (on Unix, a file is used) :
import java.util.prefs.Preferences;
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
Create a SortedProperties class which extend the regular Properties. Then override the keys()
method to return the sorted keys instead.
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
/**
* 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
*/
}
}
JDK1.6
java.net.NetworkInterface
import java.io.*;
import java.net.*;
import java.util.*;
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").
import java.net.InetAddress;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
13 Networking
import java.text.ParseException;
import java.util.StringTokenizer;
//
// inspired by
// http://forum.java.sun.com/thread.jspa?messageID=902023
//
StringTokenizer tokenizer =
new StringTokenizer(ipConfigOutput, "\n");
String lastMacAddress = null;
while(tokenizer.hasMoreTokens()) {
String line = tokenizer.nextToken().trim();
13 Networking
// see if line contains MAC address
int macAddressPosition = line.indexOf(":");
if(macAddressPosition <= 0) continue;
The output
import java.net.*;
import java.util.*;
import java.io.*;
import java.nio.*;
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();
}
}
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).
To get the IP of a client from the server side, see this HowTo.
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.
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
java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
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
/*
* 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
*/
}
import org.apache.commons.codec.binary.Base64;
13.9 MiGBase64
• MiGBase64 is a very fast Base64 Codec written in Java. http://migbase64.sourceforge.net/.
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 java.util.Hashtable;
import javax.naming.*;
import javax.naming.directory.*;
13.9 MiGBase64
Attribute attr = attrs.get( "MX" );
if( attr == null ) return( 0 );
return( attr.size() );
}
}
The output is
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).
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.
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 java.io.*;
import java.net.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
return res;
}
return;
}
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;
}
// 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() ) );
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;
}
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:
and later
if (hasMX)
{
mailhost = f[1];
}
else
{
13.9 MiGBase64
mailhost = f[0];
}
import java.io.*;
import java.net.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
return res;
}
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" );
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;
}
// 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() ) );
13.9 MiGBase64
if ( res != 250 ) throw new Exception( "Sender rejected" );
// 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;
}
Code Description
211 System status, or system help reply.
214 Help message.
220 Domain service ready.
Ready to start TLS.
13.9 MiGBase64
221 Domain service closing transmission channel.
250 OK, queuing for node node started.
Requested mail action okay, completed.
251 OK, no messages waiting for node node.
User not local, will forward to forwardpath.
252 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.
253 OK, messages pending messages for node node started.
354 Start mail input; end with ..
355 Octet−offset is the transaction offset.
421 Domain service not available, closing transmission channel.
432 A password transition is needed.
450 Requested mail action not taken: mailbox unavailable.
(ex. mailbox busy)
451 Requested action aborted: local error in processing.
Unable to process ATRN request now
452 Requested action not taken: insufficient system storage.
453 You have no mail.
454 TLS not available due to temporary reason.
Encryption required for requested authentication mechanism.
458 Unable to queue messages for node node.
459 Node node not allowed: reason.
500 Command not recognized: command.
Syntax error.
501 Syntax error, no parameters allowed.
502 Command not implemented.
503 Bad sequence of commands.
504 Command parameter not implemented.
521 Machine does not accept mail.
530 Must issue a STARTTLS command first.
Encryption required for requested authentication mechanism.
534 Authentication mechanism is too weak.
538 Encryption required for requested authentication mechanism.
550 Requested action not taken: mailbox unavailable.
551 User not local; please try forwardpath.
552 Requested mail action aborted: exceeded storage allocation.
553 Requested action not taken: mailbox name not allowed.
554 Transaction failed.
RFC0821
Unless you have a good reason, try to use the JavaMail API (see section Mail(Javamail)).
import java.net.*;
import java.io.*;
import java.net.*;
import java.io.*;
receive(in);
send(out, "USER " + user);
receive(in);
send(out, "PASS " + pass);
receive(in);
return getNumberOfMessages(in, out);
}
send(out, "LIST");
receive(in);
while((s = receive(in)) != null) {
if (!(s.equals("."))) {
i++;
}
else
return i;
}
return 0;
}
}
import java.net.*;
import java.io.*;
send(out, "LIST");
receive(in);
while((s = receive(in)) != null) {
if (!(s.equals("."))) {
i++;
}
else {
return i;
}
}
return 0;
}
}
In this example, Elvis is sending a GIF of his old Gumby friend. The attachment is encodded
using the BASE64 algorithm.
import java.io.*;
import java.net.*;
import java.io.*;
m 01101101
e 01100101
n 01101110
01101101 01100101
0110110101100101
011011 010110 0101
111111 (AND to fill the missing bits)
011011 010110 010100
b W U
b W U = ("=" is the padding character)
01101101
011011 01
111111 (AND to fill the missing bits)
011011 010000
b Q = = (two paddings are added)
*/
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
...
...
// 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!
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", "");
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", "");
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
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", "");
message.setContent(mp);
message.addRecipient(Message.RecipientType.TO,
new InternetAddress("elvis@presley.org"));
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import java.util.Properties;
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
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.
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");
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");
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");
//
// This HTML mail have to 2 part, the BODY and the embedded image
//
MimeMultipart multipart = new MimeMultipart("related");
// add it
multipart.addBodyPart(messageBodyPart);
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
telnet mymailserver 25
for example, you can detect if your firewall is blocking your connection.
It's not uncommon that the outgoing mail needs to be encrypted using the SMTPS protocol.
import javax.mail.*;
import javax.mail.internet.*;
import java.util.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");
message.addRecipient(Message.RecipientType.TO,
new InternetAddress("elvis@presley.org"));
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");
ref : http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package−summary.html
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)
// PLAIN TEXT
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("Here is your plain text message");
multipart.addBodyPart(messageBodyPart);
// HTML TEXT
messageBodyPart = new MimeBodyPart();
String htmlText = "<H1>I am the html part</H1>";
messageBodyPart.setContent(htmlText, "text/html");
message.setContent(multipart);
Transport.send(message);
When Outlook Express saves an email, it uses the EML format which is a good thing because the
format is a standard.
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.*;
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).
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 java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
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: real@rgagnon.com
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: real@rgagnon.com
Subject: Example for HowTo
Content−Type: text/plain; charset=us−ascii; format=flowed
Content−Transfer−Encoding: 7bit
X−UIDL: oP#!!c]^!!1;−!!T@1"!
URL u =null;
long timestamp = 0;
try {
u = new URL(getDocumentBase(), "test.gif");
URLConnection uc = u.openConnection();
uc.setUseCaches(false);
[JDK1.1]
import java.net.*;
import java.io.*;
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;
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:
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);
One way is to use the HTTP property "Proxy−Authorization" with a username:password base64
encoded.
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;
// PROXY
Properties systemSettings = System.getProperties();
systemSettings.put("http.proxyHost","proxy.mydomain.local") ;
systemSettings.put("http.proxyPort", "80") ;
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.
// 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());
}});
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
import java.net.*;
import java.io.*;
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.
Check this HowTo for a more official way to encode/decode to/from Base64.
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.
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.
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);
}
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;
/**
* 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
import java.io.*;
import java.net.*;
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);
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");
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.
import java.net.URL;
import java.io.*;
import java.net.*;
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();
}
}
}
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.
For application, take a look at the Sun's Secure Socket Extension (JSSE).
System.setProperty
("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
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:
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.
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)");
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:
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.
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:
Or in your source :
One way is to use the HTTP property "Proxy−Authorization" with a username:password base64
encoded.
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;
// PROXY
Properties systemSettings = System.getProperties();
systemSettings.put("http.proxyHost","proxy.mydomain.local") ;
systemSettings.put("http.proxyPort", "80") ;
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.
// 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());
}});
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
[JDK11]
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.
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.*;
NOTE: To make this a more "complete PING", you may want to check this How−to to display the response time.
import java.io.*;
import java.net.*;
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) .
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.*;
import java.net.*;
import java.io.*;
import java.applet.*;
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="GetClientIP.class"
HEIGHT=10 WIDTH=10>
</APPLET>
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".
By using the setSoLinger() method, you can explicitly set a delay before a reset is sent, giving
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.
System.out.println
("Connection from : "
+ aSock.getInetAddress().getHostAddress()
+ ':' + aSock.getPort());
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!
// 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();
}
}
}
import java.net.*;
import java.io.*;
// 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;
bos.write(mybytearray, 0 , current);
long end = System.currentTimeMillis();
System.out.println(end−start);
Message digests are secure one−way hash functions that take arbitrary−sized data and output a
fixed−length hash value.
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.
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
*/
14 Security
b[i] = (byte)v;
}
return b;
}
}
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;
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.*;
//
// 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]");
}
}
MD5 checksum can be used to validate a password without passing the actual password.
In application :
String username;
username = System.getProperty("user.name");
or in JDK1.5
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.
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]
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;
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
For a complete solution see JCIFS (for Tomcat and others) at http://jcifs.samba.org
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')
A separate thread is used to send to the console the backspace character to erase the last−typed
character.
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) {
...
}
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> ... </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.
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/.
The JSTL taglib provides the tag <c:out ... > tag to display a string. This tag will sanitize a string
by default.
This JSP will display the script code and the browser will not execute it.
This JSP will not display the script code and the browser execute it.
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.*;
login.dispose();
return userValid;
[MyLogin.java]
import java.awt.*;
import java.awt.event.*;
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);
}
<HTML><HEAD><BODY>
<TABLE><TR><TD>
<APPLET CODE=MyApplet.class WIDTH=300 HEIGHT=300>
</APPLET></TABLE>
NOTE: View the java console for infos about the login process
</BODY></HEAD>
</HMTL>
<HTML>
access is denied
</HMTL>
15.2 * Read me *
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0193.html
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 <OBJECT> (IE) or <EMBED> (Netscape) HTML tag instead of the regular
<APPLET> tag.
UIManager.put("Label.font",new Font("Serif",Font.ITALIC,12));
Swing UI default
15 Swing
Written and compiled by Réal Gagnon ©1998−2005
[ home ]
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.
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.
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.
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");
In this example, a JMenu, JToolbar and JButtons on a JFrame are sharing common ActionEvent
handlers.
import javax.swing.*;
import java.awt.event.*;
ShareAction() {
createMenu();
createToolBar();
createButtons();
pack();
This little class will dump to stdout the default values used by Swing. You can redirect the result to a
file with
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.UIManager;
JDK 1.6 provides support for the Systray on the Windows plateform.
you can click on it to trigger an action or use this area to display notification.
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
/**
* 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);
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.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
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 );
}
import java.awt.*;
import javax.swing.*;
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
* <p>
* This class was downloaded from:
* Java CodeGuru (http://codeguru.earthweb.com/java/articles/382.shtml) <br>
* The origional author was Real Gagnon (real.gagnon@tactika.com);
* 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
*/
// 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";
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;
Toolkit tk = Toolkit.getDefaultToolkit();
Image im = tk.getImage("myicon.gif");
setIconImage(im);
}
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();
}
}
}
((javax.swing.plaf.basic.BasicInternalFrameUI)
myInternalFrame.getUI()).setNorthPane(null);
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.
pan.setLayout(new FlowLayout());
pan.add(new JButton("Hello"));
pan.add(new JButton("World"));
win.setSize(200,200);
win.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
try {
URL url = new URL("http://www.tactika.com/realhome/contents.html");
tp.setPage(url);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
...
URL url = getClass().getResource("contents.html");
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"));
...
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/*
These are a list of STATIC MODAL dialogs
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.
[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 javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public MessageBoxExample() {
group = new ButtonGroup();
locale = Locale.US;
}
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");
}
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");
}
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:
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]
Then
[LocalizeJFileChooser.java]
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public LocalizeJFileChooser() {
group = new ButtonGroup();
locale = Locale.US;
z_choosertitle = rb.getString("Title");
UIManager.put
("FileChooser.lookInLabelText",
rb.getString("lookInLabelText"));
UIManager.put
("FileChooser.filesOfTypeLabelText",
rb.getString("filesOfTypeLabelText"));
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.
*/
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
JFileChooser chooser;
String choosertitle;
public DemoJFileChooser() {
go = new JButton("Do it");
go.addActionListener(this);
add(go);
}
No easy way to disable the "New Folder" button. You need to iterate the JFileChooser components
until the right one and disable it.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
JFileChooser chooser;
String choosertitle;
public DemoJFileChooser() {
go = new JButton("Do it");
go.addActionListener(this);
add(go);
}
disableNewFolderButton(chooser);
//
int rc = chooser.showOpenDialog(this);
if (rc == JFileChooser.APPROVE_OPTION) {
System.out.println("getCurrentDirectory(): "
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
JFileChooser chooser;
String choosertitle;
public DemoJFileChooser() {
go = new JButton("Do it");
go.addActionListener(this);
add(go);
}
if (rc == JFileChooser.APPROVE_OPTION) {
System.out.println("getCurrentDirectory(): "
+ chooser.getCurrentDirectory());
System.out.println("getSelectedFile() : "
+ chooser.getSelectedFile());
}
else {
System.out.println("No Selection!");
}
}
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 java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
public JFrameWithNoMinMax() {
createAndShowUI();
}
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
document = textfield.getDocument();
document.addDocumentListener
(new JButtonStateController(button));
}
}
JButtonStateController(JButton b) {
button = b;
}
import javax.swing.*;
import javax.swing.text.*;
public JTextFieldFilter() {
this(ALPHA_NUMERIC);
}
public JTextFieldFilter(String acceptedchars) {
acceptedChars = acceptedchars;
}
if (acceptedChars.equals(UPPERCASE))
str = str.toUpperCase();
else if (acceptedChars.equals(LOWERCASE))
str = str.toLowerCase();
if (acceptedChars.equals(FLOAT) ||
(acceptedChars.equals(FLOAT + "−") &negativeAccepted)) {
if (str.indexOf(".") != −1) {
if (getText(0, getLength()).indexOf(".") != −1) {
return;
}
}
}
import java.awt.*;
import javax.swing.*;
//
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 (###)
import java.awt.Container;
import javax.swing.*;
import javax.swing.text.*;
import java.text.ParseException;
import com.sun.java.swing.text.*;
JTextFieldLimit(int limit) {
super();
this.limit = limit;
}
import java.awt.*;
import javax.swing.*;
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.*;
tf1.addFocusListener(
new FocusListener() {
public void focusGained(FocusEvent e) {};
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
addWindowListener(new WindowCloser());
}
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.*;
...
...
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.*;
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.*;
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.
import javax.swing. *;
import java.awt.*;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myJTextField.requestFocus();
}
});
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
public UnselectableJTextField () {
JTextField tf1,tf2;
addWindowListener(new WindowCloser());
}
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.*;
RealSwingNode
(String title, String link, ImageIcon closed, ImageIcon opened) {
_title = title;
_link = link;
_openedIcon = opened;
_closedIcon = closed;
}
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
RealSwingTreeIconRenderer() {
_label = new JLabel();
_label.setOpaque(true);
}
_label.setFont(tree.getFont());
if (selected){
_label.setForeground(tree.getBackground());
_label.setBackground(tree.getForeground());
}
else {
_label.setBackground(tree.getBackground());
_label.setForeground(tree.getForeground());
}
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;
}
}
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;
public RealSwingTree() {
System.out.println(System.getProperty("os.name"));
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ex_ignored) {
ex_ignored.printStackTrace();
}
}
initTreeIcons();
targetFrame = parentApplet.getParameter("targetframe");
URL urlFile =
new URL(parentApplet.getCodeBase(),
parentApplet.getParameter("datafile"));
tree.addTreeSelectionListener(this);
tsm = tree.getSelectionModel();
tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
add(new JScrollPane(tree),"Center");
}
rootImage = parentApplet.getParameter("rootimage");
pathImages = parentApplet.getParameter("images");
leaveImagesList = parentApplet.getParameter("leaveimageslist");
System.out.println("begin initImage()");
StringTokenizer leavesList =
new StringTokenizer(leaveImagesList, ",");
while(leavesList.hasMoreTokens()){
String s=leavesList.nextToken();
leaveImage.addElement(s);
}
if (path != null) {
dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
rsn = (RealSwingNode)dmtn.getUserObject();
System.out.println("Click! link: " + rsn.getLink());
if (!rsn.getLink().equals("")) {
try {
URL newURL = new URL
(parentApplet.getCodeBase() + rsn.getLink());
System.out.println(" url: " + newURL.toString()
+ " target:" +targetFrame);
parentApplet.getAppletContext().showDocument
(newURL,targetFrame);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
import javax.swing.*;
import java.awt.*;
Here a sample datafile. The structure is "[level] [label] [link] [image1] [image2]". The image number
is the index of the image passed via the PARAM leaveimageslist.
[treedata.txt]
<HTML><BODY>
<APPLET CODE="RealSwingTreeApplet.class"
NAME="RealTree"
HEIGHT=2000 WIDTH=196>
<PARAM NAME="datafile" VALUE="treedata.txt">
<PARAM NAME="bgcolor" VALUE="FFFFFF">
<PARAM NAME="font" VALUE="Courier">
<PARAM NAME="point" VALUE="11">
<PARAM NAME="images" VALUE="./images">
<PARAM NAME="targetframe" VALUE="_top">
<PARAM NAME="rootimage" VALUE="root.gif">
<PARAM NAME="leaveimageslist"
VALUE="fclose.jpg,fopen.jpg,page.jpg">
</APPLET></BODY></HTML>
The <APPLET> tag and Swing applet are ok with Appletviewer, but in most browser, you need to
execute the Applet under the Java plugin. Therefore, you need to use the <EMBED> tag with
Netscape or <OBJECT> tag with IE. So for example, with Netscape, the HTML will be like this :
<HTML><BODY>
<EMBED type="application/x−java−applet;version=1.2.2" width="200"
height="2000" code="RealSwingTreeApplet.class"
datafile="treedata.txt"
bgcolor="FFFFFF"
... other params here ...
pluginspage="http://java.sun.com/products/plugin/1.2/plugin−install.html">
<NOEMBED>
No JDK 1.2 support for APPLET!!
</NOEMBED>
</EMBED>
</BODY></HTML>
Finally, you may want to grab these images used in this How−to .
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
b1 = new JButton("Expand");
b3 = new JButton("Expand to last");
b2 = new JButton("Collapse");
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
getContentPane().add(b1,"West");
getContentPane().add(b3,"North");
getContentPane().add(b2,"East");
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowCloser());
}
/*
// alternate version, suggested by C.Kaufhold
public void expandToLast(JTree tree) {
TreeModel data = tree.getModel();
Object node = data.getRoot();
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setForeground(Color.black);
frame.setBackground(Color.lightGray);
frame.getContentPane().add(panel,"Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
frame.addWindowListener(new WindowCloser());
}
}
addMouseListener (
new MouseAdapter () {
}
public void actionPerformed(ActionEvent ae) {
DefaultMutableTreeNode dmtn, node;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
b1.addActionListener(this);
getContentPane().add(b1,"West");
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowCloser());
}
In your code
...
tree.putClientProperty("JTree.lineStyle", "Angled");
...
None
No lines are drawn anywhere on the tree.
Angled
Vertical lines between nodes at the same level,
horizontal line to child node.
Horizontal
A single horizontal line between nodes immediately
attached to the root node. This is the default setting.
See also List of undocumented properties to change the behavior of Swing in Suns JVM.
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.io.*;
myJTree.addTreeWillExpandListener
myJTree.getSelectionModel().
setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
Also you may want to disable the CTRL−A key which select the entire tree.
[JDK1.2]
KeyStroke ks = KeyStroke.getKeyStroke("ctrl A");
tree.unregisterKeyboardAction(ks);
[JDK1.3+]
KeyStroke ks = KeyStroke.getKeyStroke("ctrl A");
tree.getInputMap().put(ks, "none");
Example
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowCloser());
}
}
import javax.swing.*;
import java.awt.event.*;
import java.awt.event.*;
import java.awt.*;
aTable.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2){
System.out.println(" double click" );
}
}
} );
}
if (selRows.length > 0) {
for (int i= 0; i <3 ; i++) {
// get Table data
TableModel tm = aTable.getModel();
value = tm.getValueAt(selRows[0],i);
System.out.println("Selection : " + value );
}
System.out.println();
}
}
}
The first line of the data file contains the column names. Fields are separated by the "|" character.
[customers.dat]
Id|Name|City|Phone
102|Beth Reiser|New York|(212)5558725
111|Dylan Ricci|Syracuse|(315)5554486
116|Brian Gugliuzza|Mamaroneck|(914)5553817
120|Gertrude Stein|Elmsford|(914)5553476
131|Daljit Sinnot|Bohemia|(516)5559811
First we need a TableModel to define the data structure to used by the JTable.
[DataFileTableModel.java]
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;
return colName;
}
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
f = new Font("SanSerif",Font.PLAIN,24);
setFont(f);
setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setForeground(Color.black);
frame.setBackground(Color.lightGray);
frame.getContentPane().add(panel,"Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
frame.addWindowListener(new WindowCloser());
}
}
aTable.setRowSelectionAllowed(false);
aTable.setColumnSelectionAllowed(false);
aTable.setCellSelectionEnabled(false);
15.48 Read a data file into a JTable and reload if data file have
changed
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0214.html
We use the Observer/Observable mechanism to detect if the data file have been modifed since the
last time.
We use the same data file and DataFileTableModel as the previous How−to. Some minor
modifications are needed for the DataFileTable class. This class now implements the Observer
interface (see the update() method which will be called when the Observable object send a
notification).
[DataFileTable.java]
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
f = new Font("SanSerif",Font.PLAIN,24);
setFont(f);
setLayout(new BorderLayout());
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
frame.addWindowListener(new WindowCloser());
}
}
The DataFileWatchdog, an Observable object, is simple. We use a Swing Timer to check every
second if a given file have changed. If the timestamp is different then the last one, then all
registered Observers are notified about it.
[DataFileWatchdog.java]
import javax.swing.Timer;
import java.awt.event.*;
import java.io.*;
import java.util.*;
DataFileWatchdog (String s) {
file = s;
To hide one column (or more) in a JTable, don't give a column name. To get back the hidden data,
you must use the TableModel.
[TableHideColumn.java]
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.event.*;
import java.awt.*;
if (!e.getValueIsAdjusting()) {
selRows = tableView.getSelectedRows();
if (selRows.length > 0) {
for (int i= 0; i < 3 ; i++) {
// get Table data
TableModel tm = tableView.getModel();
value = tm.getValueAt(selRows[0],i);
System.out.print(value + " " );
}
System.out.println();
}
}
}
This technique is not the best one since a exception is generated when Swing tries to display an
"hidden column".
http://www.codeguru.com/java/articles/660.shtml
http://www.experts−exchange.com/Programming/Programming_Languages/Java/Q_20394392.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");
import javax.swing.*;
import java.awt.event.*;
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
if (al == null) return;
Object ob[] = getSelectedValues();
if (ob.length > 1) return;
if (me.getClickCount() == 2) {
System.out.println("Sending ACTION_PERFORMED to ActionListener");
al.actionPerformed(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
ob[0].toString()));
me.consume();
}
}
});
addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
if (al == null) return;
Object ob[] = getSelectedValues();
if (ob.length > 1) return;
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
System.out.println("Sending ACTION_PERFORMED to ActionListener");
al.actionPerformed(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
ob[0].toString()));
ke.consume();
}
}
});
this.setSelectedIndex(0);
To try it:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
String[] items =
{ "item 0", "item 1", "item 2", "item 3" , "item 4",
"item 5", "item 6", "item 7", "item 8" , "item 9" };
ajl.setVisibleRowCount(5);
ajl.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("action in Panel " + ajl.getSelectedValue());
}
});
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(ex.mj);
frame.getContentPane().add(button);
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
DefaultListModel dlm =
(DefaultListModel)JListExample.mj.list.getModel();
dlm.addElement
((Object) new Long(System.currentTimeMillis()));
JListExample.mj.list.ensureIndexIsVisible
(JListExample.mj.list.getModel().getSize() − 1);
}
});
frame.setSize(300, 300);
frame.setVisible(true);
}
}
public MyJList() {
setLayout(new BorderLayout());
list = new JList();
add(new JScrollPane(list));
}
import javax.swing.*;
import java.awt.*;
import java.util.*;
public JListWithImages() {
setCellRenderer(new CustomCellRenderer());
}
// first line
JPanel jp1 = new JPanel();
jp1.add(new JLabel(new ImageIcon("gumby.gif")));
jp1.add(new JLabel("A line for Gumby"));
jp1.add(new JLabel(new ImageIcon("gumby2.gif")));
// second line
JPanel jp2 = new JPanel();
jp2.add(new JLabel(new ImageIcon("gumby.gif")));
jp2.add(new JLabel("Another line for Gumby"));
jp2.add(new JLabel(new ImageIcon("gumby2.gif")));
vector.addElement(jp1);
vector.addElement(jp2);
panel.add(jlwi);
frame.getContentPane().add(panel);
frame.setSize(300,300);
frame.setVisible(true);
}
The above How−to use the default layout, so each line line in the JList are centered. The version
below is showing each line left justified instead.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.util.*;
public JListWithImages() {
setCellRenderer(new CustomCellRenderer());
}
// first line
JPanel jp1 = new JPanel(new FlowLayout(FlowLayout.LEFT)); // NEW
jp1.add(new JLabel(new ImageIcon("gumby.gif")));
jp1.add(new JLabel("A line for Gumby"));
jp1.add(new JLabel(new ImageIcon("gumby2.gif")));
// second line
JPanel jp2 = new JPanel(new FlowLayout(FlowLayout.LEFT)); // NEW
jp2.add(new JLabel(new ImageIcon("gumby.gif")));
jp2.add(new JLabel("Another line for Gumby"));
jp2.add(new JLabel(new ImageIcon("gumby2.gif")));
vector.addElement(jp1);
vector.addElement(jp2);
panel.add(jlwi);
frame.getContentPane().add(panel);
frame.setSize(300,300);
frame.setVisible(true);
}
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public ClearJList(){
frame.setSize(200,200);
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.text.Collator;
// import java.util.Locale;
public SortJList(){
frame.setSize(200,200);
frame.setVisible(true);
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.getContentPane().add(panel,"Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public PopUpJList(){
Vector data;
setLayout(new BorderLayout());
list = new JList();
list.setModel(new DefaultListModel());
add(new JScrollPane(list),"Center");
add(jb1 = new JButton("Add"), "East");
add(jb2 = new JButton("Clear"), "West");
jb1.addActionListener(this);
jb2.addActionListener(this);
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
// if right mouse button clicked (or me.isPopupTrigger())
if (SwingUtilities.isRightMouseButton(me)
&!list.isSelectionEmpty()
&list.locationToIndex(me.getPoint())
== list.getSelectedIndex()) {
popupMenu.show(list, me.getX(), me.getY());
}
}
}
);
jmi1.addActionListener(this);
jmi2.addActionListener(this);
frame.setSize(200,200);
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
// a look−alike JLabel
JTextField f = new JTextField("You can select me");
f.setEditable(false);
f.setBorder(null);
f.setForeground(UIManager.getColor("Label.foreground"));
f.setFont(UIManager.getFont("Label.font"));
add(f);
}
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.getContentPane().add(panel,"Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
}
}
The JLabel background is transparent by default, so changing the background color doesn't seem to
do anything. Do something like this :
aJLabel.setOpaque(true);
aJLabel.setBackround(myColor)
Font f = label.getFont();
// bold
label.setFont(f.deriveFont(f.getStyle() ^ Font.BOLD));
// unbold
label.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
Swing 1.1.1 (or better) offers the possibility to use HTML tag to format the JLabel's text. But don't be
to fancy since the HTML support is minimal.
Since Swing (JDK1.2) implements simple HTML rendering for its components, it's possible to
display underlined string (on JLabel or JButton for example).
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
super("Underline In Swing");
setSize(400, 300);
getContentPane().setLayout(new FlowLayout());
String htmlText =
"<html><p><font color=\"#800080\" "+
"size=\"4\" face=\"Verdana\">HTML in JLabel</font></p>"+
"<font size=\"2\"><u>"+
"underline is possible</u><br><b> and bold too</b></font>"+
"";
JLabel lbl = new JLabel(htmlText);
getContentPane().add(lbl);
myLabel.setText("Real's HowTo");
SwingUtilities.updateComponentTreeUI(myLabel);
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
frame.getContentPane().setLayout(new java.awt.FlowLayout());
frame.getContentPane().add(bl);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
To the top
myJTextArea.setCaretPosition(0);
To the end
myJTextArea.setCaretPosition(myJTextArea.getDocument().getLength());
We saw that since Swing (JDK1.2) implements simple HTML rendering for its components, it's
possible to display underlined string (on JLabel or JButton for example). The same feature is true
for JToolTip.
myComponent.setToolTipText
("<html><p>This ToolTip is</p><p>two lines</p></html>");
javax.swing.plaf.ColorUIResource[R=204,G=204,B=255]
NOTE:Most Swing resources can be customize this way. Here a list of the resource names and their default values.
import javax.swing.*;
import javax.swing.plaf.*;
import java.awt.event.*;
import java.awt.*;
// globally
UIManager.put("ToolTip.font",
new FontUIResource("SansSerif", Font.BOLD, 18));
JButton b1 = new JButton("tooltip 1");
b1.setToolTipText("tool tip sansserif bold");
getContentPane().add(b1);
// only one
String html =
"<html><p><font color=\"#800080\" " +
"size=\"4\" face=\"Verdana\">tool tip verdana" +
"</font></p></html>";
JButton b2 = new JButton("tooltip 2");
b2.setToolTipText(html);
getContentPane().add(b2);
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
getContentPane().add(b1);
First technique
output :
Second technique
import java.io.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.filechooser.FileSystemView;
output:
If you need more generic image, you use a JFileChooser and extract the image for a file or
directory.
import java.io.*;
String s = "c:/windows/regedit.exe";
JFileChooser chooser = new JFileChooser();
import javax.swing.*;
import java.awt.event.*;
class RightJMenuBar {
public static void main(String args[]) {
// Create a menu
JMenu menu = new JMenu("Menu Label");
JMenuItem item = new JMenuItem("item");
menu.add(item);
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.setSize(300,300);
frame.setVisible(true);
}
}
import java.awt.*;
import java.net.*;
import javax.swing.*;
}
catch (Exception e) {
e.printStackTrace();
}
}
}
How it looks :
In this example, when we click on a Button, we trigger the action attached to the another Button.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
b1.addActionListener(this);
b2.addActionListener(this);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
b1.addActionListener(this);
b2.addActionListener(this);
}
Pipeline Thread
+−−−−−−−−−−+ +−−−−−−−−−−+
| thread A | −−− > | thread B |
+−−−−−−−−−−+ +−−−−−−−−−−+
(PRODUCE) (CONSUME)
[ProduceData.java]
import java.io.*;
[ConsumeData.java]
import java.io.*;
16 Thread
public void run(){
while(dataConsumption());
}
}
[SendProduction.java]
import java.io.*;
SendProduction(OutputStream os) {
super(os);
this.output = os;
}
[ReceiveProduction.java]
import java.io.*;
ReceiveProduction(InputStream is) {
super(is);
this.input = is;
}
16 Thread
catch (Exception e) {
e.printStackTrace();
}
return true;
}
}
[TestThread.java]
import java.io.*;
The idea is to make the READ operation ATOMIC. Once the READING is started for one thread, it
cannot be interrupted by another one.
Pipeline Thread
+−−−−−−−−−−+ +−−−−−−−−−−+
| thread A | −−−− > | thread B |
+−−−−−−−−−−+ | +−−−−−−−−−−+
(produce) | (consume)
|
|
| +−−−−−−−−−−+
+− > | thread C |
+−−−−−−−−−−+
(CONSUME)
The ProduceData.class and ConsumeData.class are the same as the previous JAVA How−to.
[AtomicInputStream.java]
import java.io.*;
AtomicInputStream(int atom) {
super();
this.atom = atom;
}
[SendProduction.java]
import java.io.*;
SendProduction(OutputStream os) {
super(os);
this.os = os;
}
while(!done) {
try {
os.write(j, 0, 3);
}
catch (Exception e) {
e.printStackTrace();
return true;
}
}
return done;
}
}
[ReceiveProduction.java]
import java.io.*;
ReceiveProduction(AtomicInputStream as) {
super(as);
this.as = as;
}
[TestThread.java]
import java.io.*;
Using a PipedOutputStream is complicated, a simpler solution is to use Queue (especially with Java
5). A producer sends data to the Queue and the the consumers extract the data. See this HowTo.
JDK 1.3 (or better) provides new classes called java.util.Timer and java.util.TimerTask.
import java.util.Timer;
import java.util.TimerTask;
Swing also provide a Timer class. A Timer object will send an ActionEvent to the registered
ActionListener.
import javax.swing.Timer;
import java.awt.event.*;
import java.util.*;
TimerDemo() {
t.start();
}
In the following example, we are using a special class, DelayedMethod, which extends the Thread
class. This Thread will receive a pointer to the "parent class" in its constructor. This pointer will be
used to call a know method at a specified interval.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
DelayedMethod(AnnoyingPopUps myObj) {
this.myObj = myObj;
this.delay = 2000;
}
NOTE: Check this How−to to achieve to same goal by using the Timer object.
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
// pool size == 5
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(5);
SimpleTask01 st01 = new SimpleTask01();
// start right now and after every 5 sec.
stpe.scheduleAtFixedRate(st01, 0, 5, TimeUnit.SECONDS);
import java.util.*;
public class RW {
private static Vector data = new Vector();
The following Exception is generated very quickly because the Producer is trying to modify the data
(a Vector) while the Consumer is using it.
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
The solution is to use the keyword synchronized to put a lock on the data while we are using it.
import java.util.*;
public class RW {
private static Vector data = new Vector();
mport java.io.*;
import java.util.concurrent.*;
PrepareProduction(BlockingQueue<String> q) { queue = q; }
A Consumer extract a value from the Queue and execute an operation. If there is no data in the
Queue, the BlockingQueue will wait. The end−of−data is marked by the presence of a special
marker (the "*" in this example).
import java.util.concurrent.BlockingQueue;
DoProduction(BlockingQueue<String> q) { queue = q; }
A test class
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
BlockingQueue<String> q =
new LinkedBlockingQueue<String>();
p1.start();
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
c6.start();
c7.start();
c8.start();
c9.start();
p1.join();
c1.join();
c2.join();
c3.join();
c4.join();
c5.join();
c6.join();
c7.join();
c8.join();
c9.join();
System.out.println("Done.");
Using a LinkedList
If you need don't need all the benefits of BlockingQueue then a simple LinkedList can be more
appropriate, especially if you need to process large amount of data in a batch process. Since you
are in a multi−threaded world, it's safer to use the synchronized version of the LinkedList
implementation. Keep in mind that theses examples are minimal and need more error checking!
import java.io.*;
import java.util.*;
PrepareProduction(List<String> q) { queue = q; }
The Consumer
import java.util.*;
public class DoProduction implements Runnable {
private final List<String> queue;
DoProduction(List<String> q) { queue = q; }
The test
import java.util.*;
List q = Collections.synchronizedList
(new LinkedList<String>());
p1.start();
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
c6.start();
c7.start();
c8.start();
c9.start();
p1.join();
c1.join();
c2.join();
c3.join();
c4.join();
c5.join();
c6.join();
c7.join();
c8.join();
c9.join();
System.out.println("Done.");
}
• The conditions for uniqueness for objects of the class java.rmi.server.UID are satisfied
♦ An independently generated UID instance is unique over time with respect to the
host it is generated on as long as the host requires more than one millisecond to
reboot and its system clock is never set backward. A globally unique identifier can be
constructed by pairing a UID instance with a unique host identifier, such as an IP
address.
• An address can be obtained for this host that is unique and constant for the lifetime of this
object.
The format is :
Code :
Output :
d578271282b42fce:−2955b56e:107df3fbc96:−8000
d578271282b42fce:−2955b56e:107df3fbc96:−7fff
d578271282b42fce:−2955b56e:107df3fbc96:−7ffe
import java.util.concurrent.AtomicLong;
See also this HowTo for unique numerical id based on the system time.
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).
• The conditions for uniqueness for objects of the class java.rmi.server.UID are satisfied
♦ An independently generated UID instance is unique over time with respect to the
host it is generated on as long as the host requires more than one millisecond to
reboot and its system clock is never set backward. A globally unique identifier can be
constructed by pairing a UID instance with a unique host identifier, such as an IP
address.
• An address can be obtained for this host that is unique and constant for the lifetime of this
object.
The format is :
17 Varia
Code :
Output :
d578271282b42fce:−2955b56e:107df3fbc96:−8000
d578271282b42fce:−2955b56e:107df3fbc96:−7fff
d578271282b42fce:−2955b56e:107df3fbc96:−7ffe
import java.util.concurrent.AtomicLong;
See also this HowTo for unique numerical id based on the system time.
When you need to know hardware details, Java is not the best tool unless you call a JNI routine or
an external utility. The JNI solution is always the best because it is designed to interact closely with
Java but it may be more complex to develop. If your need is simple (no interaction) and the need to
be cross plateform is not present then calling an external utility is maybe "a good enough" choice.
In these 2 examples, we create the appropriate VBS script file on−the−fly and capture its output.
They are very Windows oriented since they rely on the "Windows Script Host" to execute the
generated scripts.
The vbscript queries a WMI class to get a specific hardware information. Here we are using the
Win32_BaseBoard but they are many others, see
http://msdn2.microsoft.com/en−us/library/aa389273.aspx for complete list.
String vbs =
"Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_BaseBoard\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.SerialNumber \n"
+ " exit for ' do the first cpu only! \n"
+ "Next \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();
}
17.8 Get the hard disk serial number or Motherboard serial number
catch(Exception e){
e.printStackTrace();
}
return result.trim();
}
[ArraySorter.java] JDK1.1
/*
** 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;
[testArraySorter.java]
JDK1.4 case−sensitive
case−insensitive
Case sensitive
java.util.Arrays.sort(myArray);
Case insensitive
java.util.Arrays.sort(myArray, String.CASE_INSENSITIVE_ORDER);
import java.util.*;
import java.io.*;
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));
Before :
Réal Real Raoul Rico
...
Locale loc = Locale.FRENCH;
sortArray(Collator.getInstance(loc), words);
...
import java.util.*;
import java.io.*;
/**
* Check if number is valid
/*
** For testing purpose
**
** java SSNUtils or java SSNUtils
**
*/
public static void main(String args[]) throws Exception {
String aSSN = "";
if (args.length > 0)
aSSN = args[0];
else {
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("SSN number : ");
aSSN = input.readLine();
}
System.out.println
("The SSN " + aSSN + " is " +(validSSN(aSSN)?" good.":" bad."));
}
}
import java.util.*;
import java.io.*;
/**
* Valid a Credit Card number
/**
* Get the Card type
* returns the credit card type
* INVALID = −1;
* VISA = 0;
* MASTERCARD = 1;
* AMERICAN_EXPRESS = 2;
* EN_ROUTE = 3;
* DINERS_CLUB = 4;
*/
public static int getCardID(String number) {
int valid = INVALID;
if (isNumber(number)) {
/* −−−−
** VISA prefix=4
** −−−− length=13 or 16 (can be 15 too!?! maybe)
*/
if (digit1.equals("4")) {
if (number.length() == 13 || number.length() == 16)
valid = VISA;
}
/* −−−−−−−−−−
** MASTERCARD prefix= 51 ... 55
** −−−−−−−−−− length= 16
*/
else if (digit2.compareTo("51")>=0 &digit2.compareTo("55")<=0) {
if (number.length() == 16)
valid = MASTERCARD;
}
/* −−−−
** AMEX prefix=34 or 37
** −−−− length=15
*/
else if (digit2.equals("34") || digit2.equals("37")) {
if (number.length() == 15)
valid = AMERICAN_EXPRESS;
}
/* −−−−−
** ENROU prefix=2014 or 2149
** −−−−− length=15
*/
else if (digit4.equals("2014") || digit4.equals("2149")) {
if (number.length() == 15)
valid = EN_ROUTE;
}
/* −−−−−
** DCLUB prefix=300 ... 305 or 36 or 38
** −−−−− length=14
/* −−−−
** DISCOVER card prefix = 60
** −−−−−−−− lenght = 16
** left as an exercise ...
*/
int checksum = 0;
if (i > 0) {
k = Integer.valueOf(s1[i−1]).intValue() * 2;
if (k > 9) {
String s = "" + k;
k = Integer.valueOf(s.substring(0,1)).intValue() +
Integer.valueOf(s.substring(1)).intValue();
}
checksum += Integer.valueOf(s1[i]).intValue() + k;
}
else
checksum += Integer.valueOf(s1[0]).intValue();
}
return ((checksum % 10) == 0);
}
catch (Exception e) {
e.printStackTrace();
/*
** For testing purpose
**
** java CCUtils [credit card number] or java CCUtils
**
*/
public static void main(String args[]) throws Exception {
String aCard = "";
if (args.length > 0)
aCard = args[0];
else {
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("Card number : ");
aCard = input.readLine();
}
if (getCardID(aCard) > −1) {
System.out.println("This card is supported.");
System.out.println("This a " + getCardName(getCardID(aCard)));
System.out.println
("The card number " + aCard + " is "
+ (validCC(aCard)?" good.":" bad."));
}
else
System.out.println("This card is invalid or unsupported!");
}
}
class MyClass {
MyClass() {
System.out.println
(this.getClass().getName() + " is loaded from " +
this.getClass().getProtectionDomain().getCodeSource().getLocation());
}
}
>java LoadingFromWhere
LoadingFromWhere is loaded from file:/C:/temp/
MyClass is loaded from file:/C:/temp/
The output
The output
Frame
java.awt.Frame
java.awt
−−−−
ClassUtils
ClassUtils
−−−−
GregorianCalendar
java.util.GregorianCalendar
java.util
Alternate way to get only the package name (null if there is no package) :
Use the javap included in the JDK bin directory. javap is class disassembler, the result is similar to
the assembly code but for the JVM.
class Test1 {
public static void main(String args[]) {
new Integer(1);
new Integer(2);
new Integer(3);
Compile the source code and then disassemble the bytecode with
javap −c Test1
// to redirect the output to a file
javap −c Test1 >test1.out
The Result is
and compile the following class and dissassemble the Test2 class.
class Test2 {
public static void main(String args[]) {
int i = 1;
new Integer(i++);
new Integer(i++);
new Integer(i++);
}
}
class Test3 {
public static void main(String args[]) {
int i = 1;
new Integer(i++);
new Integer(i);
i = i + 1;
new Integer(i);
}
}
Note this is very low−level optimization, the gain in performance is not very significative, the class is
little bit smaller.
A self replicating programs (also known as Quine) is computer program which prints its own listing!
First example
Second example
Third example
author Daniel Pitts
[Q.java]
The URL in the middle does not generate any compiler warning because http: is considered as a
label and the //www.rgagnon... is seen as a comment.
The next one is strange. From the main(), we create a Foo instance, then we call getFoo() which
returns a null and from "null" , we can access the value of fubar!
public class Foo {
static int fubar = 42;
Foo getFoo() {
return null;
}
(from Usenet)
> I am new to java, and I really havent had time to do much work in it.
> However, I have a small project that is due next week for my class. Can
> anyone help me by providing some code? It should do the following;
>
> The program is simple. It should allow a user to input a string of digits,
> and then output the sum of those digits.
>
> For example; the user inputs 3563
> the program would then output 17 (3+5+6+3)
Signature programs are short programs that people have been using as part of their signature in
Usenet message or email. They are small programs, that are often rather cryptic because they have
to save space as much as possible.
Here collection of classic signature programs, my own signature when I was a the Universite de
Montreal (a long time ago...) is there!
A signature program in Java is not an easy task because Java is lot more verbose than C. Here an
attempt, try it to see the output!
The above code is shown as an image to make sure that special characters are rendered correctly.
To see the actual code, download the source : Howto.java.
1:
int x = 0;
2:
int i = 0;
if (i = 0){
System.out.println("Won't print, why ?");
3:
4:
Because each application is running in it's own JVM, there is no obvious way to detect if a particuliar
application is already running.
In this example, the simple server is running on the same machine as the application so the
machine name is "localhost", the port 80 is used, you may want to customize the port number for
your machine.
[JustOneServer.java]
import java.io.*;
import java.net.*;
[JustOne.java]
import java.io.*;
import java.net.*;
while(true) {
try { System.out.print("."); Thread.sleep(5 * 60); }
catch(Exception e) { e.printStackTrace(); }
}
}
}
In console 2, type java JustOne and the application should response "Already running!".
[JustOneLock.java]
import java.io.*;
import java.nio.channels.*;
try {
lock = channel.tryLock();
}
catch (OverlappingFileLockException e) {
// already locked
closeLock();
return true;
}
Runtime.getRuntime().addShutdownHook(new Thread() {
// destroy the lock when the JVM is closing
public void run() {
closeLock();
deleteFile();
}
});
return false;
}
catch (Exception e) {
closeLock();
return true;
}
}
[JustOneTest.java]
void test() {
JustOneLock ua = new JustOneLock("JustOneId");
if (ua.isAppActive()) {
System.out.println("Already active.");
System.exit(1);
}
else {
System.out.println("NOT already active.");
try {
while(true) {
try { System.out.print("."); Thread.sleep(5 * 60); }
catch(Exception e) { e.printStackTrace(); }
}
}
catch (Exception e) { }
}
}
}
The Java virtual machine shuts down in response to two kinds of events:
• The program exits normally, when the last non−daemon thread exits or when the exit
(equivalently, System.exit) method is invoked.
• The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a
system−wide event, such as user logoff or system shutdown.
JDK1.3
Now check the out.log file, you will find "*** END ***" written by our ShutdownHook.
import java.util.List;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
Mozilla Rhino
Short name : js
Short name : rhino
Short name : JavaScript
Short name : javascript
Short name : ECMAScript
Short name : ecmascript
*/
42
*/
}
catch (ScriptException ex) {
ex.printStackTrace();
}
}
}
18.2 Read me
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0405.html
These HowTo's are about the way XML can be used from Java or directly through a browser (tested
with IE6).
XML(Extensible Markup Language) is a flexible way to create common information formats and
share both the format and the data on the WWW, intranets, and elsewhere.
XSL (Extensible Style Language) is a language for creating a style sheet that describes how data
sent over the Web using XML is to be presented to the user.
XSL−T (XSL Transformations) is a standard way to describe how to transform ( or change) the
structure of an XML document into an XML document with a different structure.
XML−FOP (XSL Formatting Object Processor) is used to transform XML into something else (ex.
PDF).
DOM (Document Object Model) represents the XML as hierarchy to simplify the access. JDOM is
an implementation for Java.
SAX (Simple API for XML) is an event−driven interface. The programmer specifies an event that
may happen and, if it does, SAX gets control and handles the situation.
JAXP (Java API for XML Processing) provides basic functionality for reading, manipulating, and
generating XML documents through pure Java APIs.
XQL (XML Query Language) is a way to locate and filter the elements (data fields) and text in an
XML document. It is based on the pattern syntax used in the Extensible Stylesheet Language (XSL)
and is proposed as an extension to it.
XPointer is a language for locating data within an XML document based on properties such as
location within the document, character content, and attribute values.
18 XML
XPath is a language that describes a way to locate and process items in XML documents by using
an addressing syntax based on a path through the document's logical structure or hierarchy.
Xalan is a specification for transforming XML documents into HTML or other XML document types.
Useful links:
• JAXP overview
<HTML>
<HEAD><TITLE>Real's java HowTo</TITLE>
</HEAD>
<XML id="HowTo">
<howto>
<topic>
<title>Java</title>
<url>http://www.rgagnon/javahowto.htm</url>
</topic>
<topic>
<title>PowerBuilder</title>
<url>http://www.rgagnon/pbhowto.htm</url>
</topic>
<topic>
<title>Javascript</title>
<url>http://www.rgagnon/jshowto.htm</url>
</topic>
<topic>
<title>VBScript</title>
<url>http://www.rgagnon/vbshowto.htm</url>
</topic>
</howto>
</XML>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF0000"
VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
<TABLE datasrc="#howto">
<THEAD><TR><TH>TOPIC</TH><TH>URL</TH>
</THEAD>
<TR>
<TD><SPAN datafld="title"></SPAN></TD>
<TD><SPAN datafld="url"></SPAN></TD>
</TR>
</TABLE>
</BODY>
</HTML>
[howto.xml]
<?xml version="1.0"?>
<howto>
<topic>
<title>Java</title>
<url>http://www.rgagnon/javahowto.htm</url>
</topic>
<topic>
<title>PowerBuilder</title>
<url>http://www.rgagnon/pbhowto.htm</url>
</topic>
<topic>
<title>Javascript</title>
<url>http://www.rgagnon/jshowto.htm</url>
</topic>
<topic>
<title>VBScript</title>
<url>http://www.rgagnon/vbshowto.htm</url>
</topic>
</howto>
[howto.xsl]
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<html>
<head><title>Real's HowTo</title></head>
<body>
<table border="1">
<tr>
<th>Title</th>
<th>URL</th>
</tr>
<xsl:for−each select="howto/topic">
<tr>
<td><xsl:value−of select="title"/></td>
<td><xsl:value−of select="url"/></td>
</tr>
</xsl:for−each>
</table>
</body></html>
</xsl:template>
</xsl:stylesheet>
[HowToXSLT.java]
// jdk1.4.1
import javax.xml.transform.*;
Transformer transformer =
tFactory.newTransformer
(new javax.xml.transform.stream.StreamSource
("howto.xsl"));
transformer.transform
(new javax.xml.transform.stream.StreamSource
("howto.xml"),
new javax.xml.transform.stream.StreamResult
( new FileOutputStream("howto.html")));
}
catch (Exception e) {
e.printStackTrace( );
}
}
}
DOM (Document Object Model) represents the XML as hierarchy to simplify the access. Since
everything is in memory, it is more ressource intensive.
SAX − creates events and calls callback methods that the programmer write to handle them.
<?xml version="1.0"?>
<howto>
<topic>
<title>Java</title>
<url>http://www.rgagnon/javahowto.htm</url>
</topic>
<topic>
<title>PowerBuilder</title>
<url>http://www.rgagnon/pbhowto.htm</url>
</topic>
<topic>
<title>Javascript</title>
<url>http://www.rgagnon/jshowto.htm</url>
</topic>
<topic>
<title>VBScript</title>
<url>http://www.rgagnon/vbshowto.htm</url>
</topic>
Title: Java
Url: http://www.rgagnon/javahowto.htm
Title: PowerBuilder
Url: http://www.rgagnon/pbhowto.htm
Title: Javascript
Url: http://www.rgagnon/jshowto.htm
Title: VBScript
Url: http://www.rgagnon/vbshowto.htm
[HowToListerSAX.java]
// jdk1.4.1
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
// using SAX
public class HowToListerSAX {
class HowToHandler extends DefaultHandler {
boolean title = false;
boolean url = false;
public void startElement(String nsURI, String strippedName,
String tagName, Attributes attributes)
throws SAXException {
if (tagName.equalsIgnoreCase("title"))
title = true;
if (tagName.equalsIgnoreCase("url"))
url = true;
}
[HowToListerDOM.java]
// using DOM
public class HowtoListerDOM {
public static void main(String[] args) {
File file = new File("howto.xml");
try {
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(file);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "?";
}
}
import javax.xml.parsers.*;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
import java.io.*;
try {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
DocumentBuilderFactory factory
= DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation impl = builder.getDOMImplementation();
Element e2 = doc.createElement("java");
e1.appendChild(e2);
e2.setAttribute("url","http://www.rgagnon.com/howto.html");
Consider the following XML file, a simple xsl is attached to nicely format the data.
Modern browsers (like N7 or IE5.5) support XML and XSL transformation.
bruce.xml
bruce.xsl
Try it here
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
process(xmldoc, root);
Element e1 = xmldoc.createElement("TITLE");
Node n1 = xmldoc.createTextNode("Java");
e1.appendChild(n1);
Element e2 = xmldoc.createElement("URL");
Node n2 = xmldoc.createTextNode
("http://www.rgagnon/topics/java−xml.html");
e2.appendChild(n2);
e0.appendChild(e1);
e0.appendChild(e2);
root.appendChild(e0);
}
The result is
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
process(xmldoc, root);
Node pi = xmldoc.createProcessingInstruction
("xml−stylesheet", "type=\"text/xsl\" href=\"howto.xsl\"");
xmldoc.insertBefore(pi, root);
Element e1 = xmldoc.createElement("TITLE");
Node n1 = xmldoc.createTextNode("Java");
e1.appendChild(n1);
Element e2 = xmldoc.createElement("URL");
Node n2 = xmldoc.createTextNode
("http://www.rgagnon/topics/java−xml.html");
e2.appendChild(n2);
e0.appendChild(e1);
e0.appendChild(e2);
root.appendChild(e0);
}
The result is
<HOWTOS>
<TOPIC>
<TITLE>Java</TITLE>
<URL>http://www.rgagnon/topics/java−xml.html</URL>
</TOPIC>
</HOWTOS>
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.
Attach the xsl to the xml by adding this line to the xml file :
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;
var oXML;
var oXSL;
var oXSLTemplate;
var oXSLProcessor;
var SrcXSL;
var SrcXML;
// get the PARAM=??? (assumes you have used GET request method!)...
// assume something like http://.../docxml.asp?xmlfile=myxml.xml
xmlfile = '' + Request.QueryString('xmlfile');
oXML.load(SrcXML);
// 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 );
}
The java.beans package provides useful methods to save an object state into an XML file and easily
read it back.
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.*;
Foo f2 = FooHelper.read("foo.xml");
System.out.println("Foo" + f2.getFoo());
// the output : Foobar
}
}
Just for fun, here the resulting XML file (with my installation)
Java|http://www.rgagnon/javahowto.htm
PowerBuilder|http://www.rgagnon/pbhowto.htm
Javascript|http://www.rgagnon/jshowto.htm
VBScript|http://www.rgagnon/vbshowto.htm
import java.io.*;
// SAX classes.
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.sax.*;
BufferedReader in;
StreamResult out;
TransformerHandler th;
AttributesImpl atts;
th = tf.newTransformerHandler();
Transformer serializer = th.getTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING,"ISO−8859−1");
// pretty XML output
serializer.setOutputProperty
("{http://xml.apache.org/xslt}indent−amount", "4");
serializer.setOutputProperty(OutputKeys.INDENT,"yes");
th.setResult(out);
th.startDocument();
atts = new AttributesImpl();
th.startElement("","","HOWTOS",atts);
}
th.startElement("","","TITLE",atts);
th.characters(elements[0].toCharArray(),0,elements[0].length());
th.endElement("","","TITLE");
th.startElement("","","URL",atts);
th.characters(elements[1].toCharArray(),0,elements[1].length());
th.endElement("","","URL");
th.endElement("","","TOPIC");
}
Java|http://www.rgagnon/javahowto.htm
PowerBuilder|http://www.rgagnon/pbhowto.htm
Javascript|http://www.rgagnon/jshowto.htm
VBScript|http://www.rgagnon/vbshowto.htm
NOTE: Since DOM constructs the XML tree in memory, it may be more appropriate to use SAX instead if you have to deal with big data files.
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
BufferedReader in;
StreamResult out;
Document xmldoc;
Element root;
Element e1 = xmldoc.createElement("TITLE");
Node n1 = xmldoc.createTextNode(elements[0]);
e1.appendChild(n1);
Element e2 = xmldoc.createElement("URL");
Node n2 = xmldoc.createTextNode(elements[1]);
e2.appendChild(n2);
e0.appendChild(e1);
e0.appendChild(e2);
root.appendChild(e0);
}
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
class JDBCapp {
try {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder =factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element results = doc.createElement("Results");
doc.appendChild(results);
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));
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 :
*/
}
}
[J2SE 1.5]
<?xml version="1.0"?>
<howto>
<topic name="Java">
<url>http://www.rgagnon/javahowto.htm</url>
</topic>
<topic name="PowerBuilder">
<url>http://www.rgagnon/pbhowto.htm</url>
<url>http://www.rgagnon/pbhowtonew.htm</url>
</topic>
<topic name="Javascript">
<url>http://www.rgagnon/jshowto.htm</url>
</topic>
<topic name="VBScript">
<url>http://www.rgagnon/vbshowto.htm</url>
</topic>
</howto>
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
int j = nodes.getLength();
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
This can be useful to reduce the size of a file or before writting a message to a queue.
/*
output :
<tag>test 3</tag>
<tag>test 4</tag>
<tag>test 3</tag><tag>test 4</tag>
*/
}
}
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
process(xmldoc, root);
Element e1 = xmldoc.createElement("TITLE");
Node n1 = xmldoc.createTextNode("Java");
e1.appendChild(n1);
Element e2 = xmldoc.createElement("URL");
Node n2 = xmldoc.createTextNode
("http://www.rgagnon/topics/java−xml.html");
e2.appendChild(n2);
e0.appendChild(e1);
e0.appendChild(e2);
root.appendChild(e0);
}
The result is
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
process(xmldoc, root);
Node pi = xmldoc.createProcessingInstruction
("xml−stylesheet", "type=\"text/xsl\" href=\"howto.xsl\"");
xmldoc.insertBefore(pi, root);
Element e1 = xmldoc.createElement("TITLE");
Node n1 = xmldoc.createTextNode("Java");
e1.appendChild(n1);
Element e2 = xmldoc.createElement("URL");
Node n2 = xmldoc.createTextNode
("http://www.rgagnon/topics/java−xml.html");
e2.appendChild(n2);
e0.appendChild(e1);
e0.appendChild(e2);
root.appendChild(e0);
}
The result is
<HOWTOS>
<TOPIC>
<TITLE>Java</TITLE>
<URL>http://www.rgagnon/topics/java−xml.html</URL>
</TOPIC>
</HOWTOS>
import java.util.*;
import java.io.*;
class XMLProps {
public static void main(String args[]) {
new XMLProps().doit();
}
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();
}
}
}
<data>
<employee>
<name>John</name>
<title>Manager</title>
</employee>
<employee>
<name>Sara</name>
<title>Clerk</title>
</employee>
</data>
You locate the element to change with an XPath query. You change the text and then save back the
data.
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
The result
RSS is a method to syndicate content on the web. This is done by creating an XML document which
summarizes specific content such as news, blog posts or comments or any informations. There are
many versions but the 2 most used are RSS 2.0 and ATOM.
<rss version="2.0">
<item>
<title>JS: Resize an IFRAME based on its content</title>
<description>Using the onLoad event, resize the IFRAME</description>
<link>http://www.rgagnon.com/jsdetails/js−0129.html</link>
<pubDate>23 May 2007 00:00:00 GMT</pubDate>
<guid>http://www.rgagnon.com/jsdetails/js−0129.html</guid>
</item>
</channel>
</rss>
18.20.2 Atom
Atom was an answer to the incompatibilites between all the RSS versions. Adopted by the IETF, the
official specification is RFC4287, http://www.ietf.org/rfc/rfc4287.
18.20.2 Atom
<?xml version="1.0" encoding="utf−8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<subtitle>A subtitle.</subtitle>
<link href="http://example.org/"/>
<updated>2003−12−13T18:30:02Z</updated>
<author>
<name>John Doe</name>
<email>johndoe@example.com</email>
</author>
<id>urn:uuid:60a76c80−d399−11d9−b91C−0003939e0af6</id>
<entry>
<title>Atom−Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695−cfb8−4ebb−aaaa−80da344efa6a</id>
<updated>2003−12−13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>
To create a RSS feed without using external librairies, see this HowTo.
While you can create the XML file using a regular text editor, it's more interesting to do it from code.
You can do it using regular XML library and make sure that all the required tags are there or use
special tools which encapsulate the complexity of generating a valid feed. We will look at two of
them.
The org.apache.commons.digester is a package designed manipulating XML file. In the first release
there are a few classes to deal with RSS feed, it was the org.apache.commons.digester.rss
package. However, in the latest version, the binaries of this package is no longer distributed. It's still
possible to build it from the examples but it's no longer part of the official "Commons Digester".
So you need the main Commons Digester plus, as usual with Apache software, you have depencies
with the BeanUtils v1.7 and Commons Logging
Don't forget the famous commons−digester−rss.jar, you can build it from the Commons Digester
examples jar or download it from here.
import org.apache.commons.digester.rss.Channel;
import org.apache.commons.digester.rss.Item;
import org.apache.commons.digester.rss.RSSDigester;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
class CreateRSSFeedUsingCommons {
SimpleDateFormat formatter=
new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z");
String today = formatter.format(new Date());
try {
FileOutputStream fout = new FileOutputStream("feed.xml");
newChannel.render(fout);
fout.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
The result is :
<?xml version="1.0"?>
<rss version="0.91">
<channel>
<title>null</title>
<description>Useful Java code examples</description>
<link>http://www.rgagnon.com/howto.html</link>
<language>en</language>
<copyright>(c)Real Gagnon 2007</copyright>
<pubDate>29 mai 2007 23:48:42 −0400</pubDate>
<item>
<title>Real's HowTo</title>
<link>http://www.rgagnon.com/java−details/</link>
<description>Cool java snippet!</description>
</channel>
</rss>
The RSS created is at version 0.91 level. To support RSS v2 file then you need to modify the
source files yourself ... that's what OpenSource is all about!
ROME includes a set of parsers and generators for the various flavors of syndication feeds, as well
as converters to convert from one format to another. The project is hosted by java.net at
http://wiki.java.net/bin/view/Javawsxml/Rome.
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.io.SyndFeedOutput;
import java.io.FileWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
feed.setTitle("Real's HowTo");
feed.setLink("http://www.rgagnon.com/howto.html");
feed.setDescription("Useful Java code examples");
feed.setEntries(entries);
RSS Feed are XML files. They are easy to create, you can do it yourself.
package com.rgagnon.howto.rss;
package com.rgagnon.howto.rss;
package com.rgagnon.howto.rss;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
package com.rgagnon.howto.rss;
import java.io.FileOutputStream;
import java.util.Iterator;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
writer.add(endSection);
writer.add(eventFactory.createEndElement("", "", "channel"));
writer.add(endSection);
writer.add(eventFactory.createEndElement("", "", "rss"));
writer.add(endSection);
writer.add(eventFactory.createEndDocument());
writer.close();
}
package com.rgagnon.howto.rss;
import java.util.ArrayList;
import java.util.Calendar;
feed.setHeader(header);
feed.setEntries(entries);
try {
RSSWriter.write(feed, TestRSSWriter.RSSFEED);
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println("Done.");
}
}
The result is
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Real's HowTo</title>
<link>http://www.rgagnon.com</link>
<description>Useful code snippets for Java</description>
<language>en</language>
<copyright>Copyright by Real Gagnon</copyright>
<pubDate>Mon, 23 Jun 2008 11:15:31 −0400</pubDate>
<item>
<title>The PDF are updated</title>
<description>Java (756 pages), Powerbuilder (197), Javascript (99) and VBS (32)</descriptio
<link>http://64.18.163.122/rgagnon/download/index.htm</link>
<guid>http://64.18.163.122/rgagnon/download/index.htm</guid>
<pubDate>Mon, 23 Jun 2008 11:15:31 −0400</pubDate>
</item>
<item>
<title>Java : Display a TIF</title>
<description>Using JAI, how to display a TIF file</description>
<link>http://www.rgagnon.com/javadetails/java−0605.html</link>
<guid>http://www.rgagnon.com/javadetails/java−0605.html</guid>
<pubDate>Mon, 23 Jun 2008 11:15:31 −0400</pubDate>
</item>
</channel>
</rss>
In a previous HowTo, we saw how to create a RSS feed using commons.digester or ROME
packages. In this HowTo, we are parsing a given feed using the packages.
import org.apache.commons.digester.rss.Channel;
import org.apache.commons.digester.rss.Item;
import org.apache.commons.digester.rss.RSSDigester;
import java.net.HttpURLConnection;
import java.net.URL;
Item rssItems[]=channel.findItems();
for (int i=0;i<rssItems.length;i++) {
System.out.println(rssItems[i].getTitle());
System.out.println(rssItems[i].getLink());
System.out.println(rssItems[i].getDescription());
System.out.println();
}
/*
to parse from a file instead of a URL
import java.io.FileInputStream;
...
String feed = "feed.xml"
FileInputStream fis = new FileInputStream(feed);
Channel channel=(Channel)digester.parse(fis);
...
*/
}
}
the output
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import java.net.URL;
import java.util.List;
import java.util.Iterator;
import java.io.FileInputStream;
...
String feed = "feed.xml"
FileInputStream fis = new FileInputStream(feed);
Live Bookmark is used to subscribe easily to the RSS feed from a particular web site. A Live
bookmark is possible if you see an orange icon in the address bar. Simply click on the icon and then
a live bookmark is created.
To make sure your generated RSS feed is ok, use this very handy site : http://feedvalidator.org/.
It works with RSS 0.90, 0.91, 0.92, 0.93, 0.94, 1.0, 1.1, and 2.0. It also validates Atom feeds.
To use it, simply enter the address of your feed and click Validate. If the validator finds any
problems in your feed, it will give you messages for each type of problem and highlight where the
problem first occurs in your feed. If you're unsure what a message means, click the "help" link next
to the message for a fuller explanation.
Browser (ex. IE7/FF) may apply their own style when displaying a RSS Feed so even if you specify
a stylesheet it will be ignored.
18.22.3 RSS−UTIL.TLD
<?xml version="1.0" encoding="utf−8"?>
<?xml−stylesheet title="XSL_formatting" type="text/xsl" href="feed.xsl"?>
<rss version="2.0">
...
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="channel">
<html>
<head>
<link title="mystyle" href="howto.css"
type="text/css" rel="stylesheet"/>
<link rel='alternate' type='application/rss+xml'
title="Real's HowTo" href='http://www.rgagnon.com/feed.xml'/>
<title>What's new − Real's HowTo</title>
<script type="text/javascript" src="scripts/rss.js" />
<style>
.box {
border−width: 1px 1px 1px 1px;
border−spacing: 2px;
border−style: solid solid solid solid;
border−color: blue blue blue blue;
border−collapse: separate;
background−color: white;
}
</style>
</head>
<body onload="setURLS();">
<a href='http://www.rgagnon.com/howto.html'
title='Useful code snippets for Java, JS or PB developers!'>
<img src='images/realhowto−left.jpg' border='0' />
</a>
<h2>What's new, the last 10 updates</h2>
<div class="box" align="center">
Copy the URL in the box below into your preferred RSS reader.
New content will be delivered as it's published.
<br/>
<input type="text" size="50" id="rss−url"/>
</div>
<br/>
<xsl:for−each select="item">
<h4><xsl:value−of select="title"/></h4>
<i><xsl:value−of select="pubDate"/></i><br/>
<xsl:value−of select="description"/><br/>
<a HREF="{link}"><xsl:value−of select="link"/></a>
<p/>
</xsl:for−each>
<p/>
<hr/>
<div align="center">
Written and compiled by Real Gagnon ©1998−2007<br/>
[<A HREF="http://www.rgagnon.com/" TARGET="_top"> home </A>]
</div>
</body></html>
</xsl:template>
</xsl:stylesheet>
18.22.3 RSS−UTIL.TLD
See the result.
18.22.3 RSS−UTIL.TLD
19 DEPRECATED
19.1 java−deprecated
These examples works only in a Microsoft JVM and are very Windows−oriented so portabilty here is
not issue.
Microsoft SDK is no longer available. Try to search for the file SDKjava40.exe (20,243,128 bytes) in
Google to find a copy on the Net.
import java.io.*;
public class IO {
public static void PressAnyKey() {
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("Press any key...");
try { input.readLine();}
catch (Exception e) { e.printStackTrace();}
}
}
For example
19 DEPRECATED
19.4 Read the Registry (this howto is deprecated)
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0188.html
See also this How−to for a solution using the Sun's JVM and the REG utility.
/** @dll.import("ADVAPI32") */
static native void GetUserNameA
(StringBuffer userName, long buffer[]);
// string by ref are passed with a StringBuffer
// basic scalar type by ref are passed via an array
/** @dll.import("USER32") */
private static native int MessageBox
(int hwndOwner, String text,String title, int fuStyle);
}
If an error is returned by the Win32 API called, you can't get the actual error code by calling the
standard getLastError() Win32 API. You must use the special keyword setLastError in the
@dll.import directive to instruct the JVM to keep the error code. Then you retrieve the error code by
calling the getLastWin32Error() method from the DllLib class.
import com.ms.dll.DllLib;
/** @dll.import("KERNEL32",setLastError) */
static native boolean SetCurrentDirectoryA(StringBuffer newdir);
}
NOTE: The example above call the Win32 API to change the current direcotry but you should note that you don't really need to do that. Simply
call the static method setCurrentDirectory() from the File class instead...
import com.ms.security.*;
...
PolicyEngine.assertPermission(PermissionID.SYSTEM);
The standard Java Image object doesn't support the BMP format (only JPG or GIF). While it's
possible to use pure Java classes to let an Image use a BMP−encoded image (see this How−to), in
a Microsoft−oriented environment, it's easier to use the WFC control PictureBox which can display
BMP/, GIF or JPEG images.
In VJ++, create a Windows application. In the Java form, drag the WFC picturebox control and a
button. In the button click event, put the following to call the Win FileOpen dialog to let you select
the image to be displayed.
import com.ms.win32.Winmm;
import com.ms.win32.wins;
While the Microsoft Java Virtual Machine can run "almost" any 100% pure Java classes, the other
way is not true, non−MS JVM are not able to run classes that used Microsoft−specific classes
(com.ms.*). Check this How−to for some techniques to detect Virtual machine in use.
The Microsoft Java Virtual Machine is no longer available from Microsoft directly due to legal
wrangling with Sun, however it still can be downloaded... Check this list of URL's.
Use the Microsoft javareg utility to register a java class as a COM server. Once registered, the Java
class will be visible from all languages that can deal with COM objects. I am giving here some
examples in VbScript, JScript, ASP and Powerbuilder.
NOTE: The class can compiled with any JDK but the actual execution will use the Microsoft JVM installed on the system.
The javareg utility is part of the Microsoft Java SDK which can be freely downloaded from the
Microsoft Web site.
[JavaSays.java]
package JavaCom;
public class JavaSays {
public String Hello() {
return "Hello world" ;
}
public String Say(String what) {
return what ;
}
}
That's it. The system now has a COM object called JavaCom.JavaSays installed.
VbScript and JScript are useful scripting tools. They are now part of a regular Windows installation
(or IE). If your Windows installation is too old, you can download the Windows Scripting Host from
the Microsoft Web site.
[VbScript TestJavaCom.vbs]
strFromJava = objJava.Hello
MsgBox strFromJava, _
0, _
"JAVA COM OUTPUT"
[JScript TestJavaCom.js]
strFromJava = objJava.Hello()
WSHShell.Popup(strFromJava,
0,
"JAVA COM OUTPUT",
0 );
[ASP TestJavaCom.asp]
<%
Set objJava = Server.CreateObject("JavaCom.JavaSays")
%>
<BR>
test 1 : <% =objJava.Hello() %><BR>
test 2 : <% =objJava.Say("From ASP via a Java Object") %>
[PowerBuilder]
OLEObject objJava
string strFromjava
strFromJava = objJava.Hello()
MessageBox("From PB via JavaCom", strFromJava)
DESTROY objjava
A Certificate for developer can be purchased for about $200 (with $100/year to renew it), see
Thawte certification for example. For non US citizen, it can be difficult to obtain a certificate from US
based trusted source, because of the exportation limitation imposed on encryption technique.
Certificates used to sign email are not secured enough to sign applets, they are CLASS 1
certificate, you need something like CLASS 3 to be able to sign an applet.
Signing an Applet means signing the JAR containing the Applet. To sign a JAR, you need tools
provided by Netscape. Zigbert is a command−line utility. Also a GUI JAR packager can be used to
sign JARS. You may look at this JAVA How−to for infos about JAR file.
Sun's JAVAKEY utility can't be used to produce/sign certificate/JAR compatible for the Netscape
security manager. Read the Netscape's security FAQ or Netscape OBJECT SIGNING
RESOURCES for more informations.
Once the Applet signed, we must use the netscape.security (also called Capabilities) package to
grant/remove privileges. This package is included with Netscape v4 or can be downloaded from the
Netscape Web site.
When compiling a JAVA source containing references to the Capabilities class, we must adjust to
CLASSPATH to include the JAR java40.jar (with v4).
set CLASSPATH=
.;c:\windev\jdk1.1.3\lib\classes.zip;
c:\program files\netscape\communicator\program\java\classes\java40.jar;
Netscape provides a way to accept a codebase as trusted (then a certificate is not needed). This
can be useful during development or in a private Intranet. In the Netscape Users directory, there is a
file called prefs.js. Adding the line
user_pref("signed.applets.codebase_principal_support", true);
WILL ENABLEJAR file without a certificate to request privileges on your machine. If you agree, it
will be possible for an Applet to lauch a program, write a file on your hard disk or print on the printer.
You will still have to ask for privileges in your program using the Netscape capabilites classes.
Another way is to lower general security setting to more allow more freedom when running applets
locally. Add or modify the following entries in the prefs.js:
Then you don't need to asked for privileges for local classes.
NOTE: When adding or modifying the file prefs.js, Netscape must not be running because your modification will be overwritten. So shut down
Netscape, edit the prefs.js and then restart Netscape.
With IE, you can achieve the same thing through the Internet option menu.
Internet Options
Security Tab
Internet Custom level
Java permissions
Custom radio buttons
Java Custom settings
select the permissions given to unsigned content.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import netscape.security.*;
Before opening the new Frame or Window, use (with Netscape capabilities classes)
PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import netscape.security.*;
19.15 Get rid of the message "Warning − unsigned applet window" (this howto is deprecated)
loadButton = new Button("Load");
saveButton = new Button("Save");
add(loadButton);
add(saveButton);
loadButton.addActionListener(this);
saveButton.addActionListener(this);
filename = new TextField(20);
add(filename);
content = new TextArea(5,20);
add(content);
browserName = System.getProperty("java.vendor");
if (browserName.indexOf("Netscape") > −1)
securitySupported = true;
setSize(200, 200);
}
else {
getAppletContext().showStatus("security not installed");
}
}
}
}
19.17 Write "other−browser−friendly" code when using the Netscape Capabilities package (this howto is dep
try {
try {
netscape.security.PrivilegeManager.enablePrivilege
("UniversalTopLevelWindow");
}
catch(netscape.security.ForbiddenTargetException e) {
}
}
catch(NoSuchMethodError e) {
/*
** add here code required by IE or
** any other supported browser
*/
}
When a JIT is active, Exception don't output the line number where the exception occurs. To
retrieve line numbers, simply disable the JIT compiler. With Microsoft IE, simply check the option in
the Preferences Dialog. With Netscape v4, rename the DLL jit3240.dll in the directory
program/java/bin.
In application, with the Sun JVM, you have the following options:
With the MS JVM, you set the environment variable MSJAVA_ENABLE_JIT to 0 to disable the
Microsoft JIT, or use the Registry key
HKEY_CURRENT_USER\Software\Microsoft\Java VM\EnableJIT
With the latest JVM this is not necessarily true. To retrieve the line numbers, make sure that the
classes are compiled with the debugging infos.
Go into the properties Tab panel of the Netscape icon and specify that you want to start Netscape
with the option −start_java.
For example:
?: help
b: break into the debugger (Windows only)
c: clear console window
d: dump applet context state to console
f: finalize objects on finalization queue
g: garbage collect
h: print this help message
l: capture all classes loaded by an applet to a directory
m: print current memory use to console
q: hide console
s: dump memory summary to "memory.out"
t: dump thread info to "memory.out"
x: dump memory to "memory.out"
X: dump memory (detailed) to "memory.out"
0−9: set applet debug level to <n>
In Windows, open a DOS window, go to the directory where the HTML file is located. Type
SET CLASSPATH=
and then
19.19 Start automatically JAVA when opening Netscape (this howto is deprecated)
START MYPAGE.HTML
import sun.net.nntp.*;
import java.io.*;
Here some java code to illustrate NTTP protocol without using the undocumented classes,
Communicating with an NNTP server.
Sun's JavaMail APi can be used to interact with a NTTP server, check out the Knife Plugin.
import sun.net.nntp.*;
import java.io.*;
19.22 Post a message on a newsserver using NNTP protocol (this howto is deprecated)
public class NntpGetGroup {
public static void main(String[] args)
throws IOException {
/*
** pass your news server, newsgroup as parameter
** eg. java NttpPost news.server.com alt.test
*/
NntpClient c = new NntpClient(args[0]);
c.setGroup(args[1]);
NewsgroupInfo ni = c.getGroup(args[1]);
int first = ni.firstArticle;
int last = ni.lastArticle;
for (int i = first; i <= last; i++) {
String aLine;
BufferedReader br = null;
InputStream anArticle = null;
try {
anArticle = c.getArticle(i);
br = new BufferedReader(new InputStreamReader(anArticle));
System.out.println("−−−−−−−−−−−−−−−−−\nArticle " + i);
while ((aLine = br.readLine()) != null) {
System.out.println(aLine);
}
}
catch (NntpProtocolException e) {
/*
** probably a cancelled article, just skip it
*/
}
}
}
}
import sun.net.nntp.*;
import java.io.*;
import sun.net.nntp.*;
import sun.net.*;
import java.io.*;
import java.util.*;
19.25 Get a list of all available newsgroup from a newsserver (this howto is deprecated)
19.26 Detect if Swing is installed (this howto is deprecated)
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0194.html
<HTML><HEAD></HEAD><BODY>
<APPLET CODE="SwingSniffer.class"
HEIGHT=1 WIDTH=1>
<A HREF="/nojava.html">
Oups! You don't have JAVA enabled, click here.</A>
</APPLET>
/BODY/HTML
To be able use Swing classes (without download delay) from Netscape, copy Swing JAR files
(swingall.jar) in the PLUGINS directory and restart Netscape. This is ok with pre−Java 2 Swing.
With that version you need the Java plug−in to be able to use the swing classes.
20.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.
If you can't find then you may want to look at these other sites :
Java Glossary
Many subjects covered in depth.
Stack Overflow
A site where you can ask question (not restricted to Java), really innovative in the way it works.
Participants are really cool.
Usenet's newgroups are very useful too. Check out the comp.lang.java.* groups on your favorite
Usenet newserver.
• forums.sybase.com
20 String/Number
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
integer to String :
int i = 42;
String str = Integer.toString(i);
or
String str = "" + i
double to String :
long to String :
float to String :
String to integer :
str = "25";
int i = Integer.valueOf(str).intValue();
or
int i = Integer.parseInt(str);
String to double :
Double d = Double.valueOf(str).doubleValue();
String to long :
String to float :
Float f = Float.valueOf(str).floatValue();
decimal to binary :
int i = 42;
String bin = Integer.toBinaryString(i);
decimal to hexadecimal :
int i = 42;
String hexstr = Integer.toString(i, 16);
or
String hexstr = Integer.toHexString(i);
int i = 64;
String aChar = new Character((Char)i).toString();
char c = 'A';
int i = (int) c; // i == 65 DECIMAL
integer to boolean
b = (i != 0);
// ex : 42 != 0 −−> true
boolean to integer
i = (b)?1:0;
// true −−> 1
Note :To catch illegal number conversion, try using the try/catch mechanism.
try{
i = Integer.parseInt(aString);
}
catch(NumberFormatException e) {
...
}
The following snippet will strip or keep from a given string the specified characters.
To remove a character :
Check this Optimize How−to for a more efficient String handling technique.
New with JDK1.4, the String class offers the replaceAll() method that can be used with String or
char.
Since Java String are immutable (can't be changed), we return a new String.
public static String replace (String target, String from, String to) {
// target is the original string
// from is the string to be replaced
// to is the string which will used to replace
// returns a new String!
int start = target.indexOf(from);
if (start == −1) return target;
int lf = from.length();
char [] targetChars = target.toCharArray();
StringBuffer buffer = new StringBuffer();
int copyFrom = 0;
while (start != −1) {
buffer.append (targetChars, copyFrom, start−copyFrom);
buffer.append (to);
copyFrom = start + lf;
start = target.indexOf (from, copyFrom);
}
buffer.append (targetChars, copyFrom, targetChars.length − copyFrom);
return buffer.toString();
}
[JDK1.4]
System.out.println
(text.replaceAll("(?:hello world)+", "bonjour le monde"));
System.out.println
(text.replaceFirst("(?:hello world)+", "bonjour le monde"));
/*
output :
bonjour le monde from www.rgagnon.com : bonjour le monde
bonjour le monde from www.rgagnon.com : hello world
*/
}
}
Keep in mind, that you need to escape characters like $ or | since they have special meaning when
used in a regular expression.
import java.util.*;
...
StringTokenizer st =
new StringTokenizer
("This is the string to be tokenized", " ");
while(st.hasMoreTokens()){
String s=st.nextToken();
System.out.println(s);
}
/*
output is :
This
is
the
string
to
be
tokenized
*/
StringTokenizer does not react correctly if you have two separators consecutively.
/**
* Same as the StringTokenizer constructor. No added functionality.
*/
public EnhancedStringTokenizer(String str, String delim){
setMode(this.NO_RETURN_DELIMS);
setDelimiter(delim);
st = new StringTokenizer(str, delim);
}
/**
* Same as the StringTokenizer constructor. No added functionality.
*/
/**
* Using this constructor allows use of the NO_CONSECUTIVE_DELIMS mode
* of operation.
*/
public EnhancedStringTokenizer(String str, String delim, int mode) {
setMode(mode);
setDelimiter(delim);
switch (getMode()) {
case NO_RETURN_DELIMS :
st = new StringTokenizer(str, delim, false);
break;
case RETURN_DELIMS :
st = new StringTokenizer(str, delim, true);
break;
case NO_CONSECUTIVE_DELIMS :
default :
init(str);
break;
}
}
See also this HowTo to split a given String into an array based on a specific separator.
The String class has a split() method, that will return a String array.
[JDK1.4]
/*
output :
−−−−−−−−−−−−
Real
How
To
−−−−−−−−−−−−
*/
split() is based on regex expression, a special attention is needed with some characters which have
a special meaning in a regex expression.
For example :
String s3 = "Real.How.To";
...
temp = s3.split("\\.");
or
String s3 = "Real|How|To";
...
temp = s3.split("\\|");
The result does not include the empty strings between the "|" separator. To keep the empty strings :
How
To
We have an extra element. The fix is to specify a regular expression to match one or more spaces.
Since String.split() is based on regular expression, you can make some complex operations with a
simple call!
public class StringSplit {
public static void main(String args[]) throws Exception{
new StringSplit().doit();
}
/*
output :
−−−−−−−−−−−−
RealHowto
usage of String.split()
−−−−−−−−−−−−
note : extra element with empty string :−(
*/
(thanks to B. Wilkinson)
String concatenation via the "+" operator is one of the most convenient things to do in Java. It is
also one of the most expensive, in terms of memory and performance.
or any other concatenation, it **ACTUALLY** generates (for runtime use) the code sequence that
follows (or, at least, the bytecode equivalent of it):
The weak spot in all this is the construction of the StringBuffer object: the size of the buffer is
ALWAYS 16 characters. Then, as data is appended to the buffer, if more space is needed the size
of the buffer is doubled and the old data is copied to the new buffer.
So to optimize we have to bypass the automatic StringBuffer when possible. In this JAVA How−to, a
snippet is given to replace a character at a specific position. An optimized version, using the
StringBuffer would be:
Only one buffer created, exactly the right size. Converting a StringBuffer to a String costs almost
nothing, as the actual buffer is shared between the two.
In the same How−to, a snippet about removing a character in a String can be optimized like:
In the original version, a new String object was created and discarded immediately!
The weak spot of the original method to remove a character is when the parameter s passed havee
than 17 characters, the temporary StringBuffer created by the compiler will have to be extended. To
optimize, simply rewrite the method using a StringBuffer with the correct size:
[JDK1.5]
The String trim() method returns a copy of the string, with leading and trailing whitespace omitted.
ref : http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#trim()
[JDK1.4]
Here a complete solution to remove leading or trailing spaces in a String using regular expressions.
import java.util.regex.*;
import java.util.regex.Pattern;
boolean startsWithDigitOrUpper(String s) {
return Pattern.compile("^[A−Z0−9]").matcher(s).find();
}
/**
** pad a string S with a size of N with char C
** on the left (True) or on the right(flase)
**/
public synchronized String paddingString
( String s, int n, char c , boolean paddingLeft ) {
StringBuffer str = new StringBuffer(s);
int strLength = str.length();
if ( n > 0 && n > strLength ) {
for ( int i = 0; i <= n ; i ++ ) {
if ( paddingLeft ) {
if ( i < n − strLength ) str.insert( 0, c );
}
else {
if ( i > strLength ) str.append( c );
}
}
}
return str.toString();
}
[JDK1.4]
import java.util.regex.Pattern;
import java.util.regex.Matcher;
...
if (m.find()) {
newString = m.replaceAll("<br>");
}
or use the String.replaceAll(regex,replacement) method which is doing basically the same thing.
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.
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;
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 :
s = s.replaceAll("[èéêë]","e");
s = s.replaceAll("[ûù]","u");
s = s.replaceAll("[ïî]","i");
s = s.replaceAll("[àâ]","a");
s = s.replaceAll("Ô","o");
s = s.replaceAll("[ÈÉÊË]","E");
s = s.replaceAll("[ÛÙ]","U");
s = s.replaceAll("[ÏÎ]","I");
s = s.replaceAll("[ÀÂ]","A");
s = 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
String and then do a lookup in the second String.
JDK1.4
Character Description
# Any valid number, uses Character.isDigit .
' Escape character, used to escape any of
the special formatting characters.
U Any character ( Character.isLetter ).
All lowercase letters are mapped to upper case.
L Any character ( Character.isLetter ).
All upper case letters are mapped to lower case.
A Any character or number
( Character.isLetter or Character.isDigit )
? Any character ( Character.isLetter ).
* Anything.
H Any hex character (0−9, a−f or A−F).
The String class now provides a new method called format(). The parameter substitution
mechanism is heavily inspired by C's printf.
String s = String.format
("Welcome %s at %s", "Real's HowTo", "http://www.rgagnon.com");
// output : Welcome Real's HowTo at http://www.rgagnon.com
System.out.printf
("Welcome %s at %s", "Real's HowTo", "http://www.rgagnon.com");
You can use this new feature to quickly format strings into table :
System.out.format(String.format(format, (Object[])ex));
}
}
Output:
It can be quite an adventure to deal with the "\" since it is considered as an escape character in
Java. You always need to "\\" a "\" in a String. But the fun begins when you want to use a "\" in
regex expression, because the "\" is an escape character in regex too. So for a single "\" you need
to use "\\\\" in a regex expression.
myString = myString.replaceAll("\\\\","\\\\\\\\");
java.text.MessageFormat is a very powerful API, you should study the javadoc to see all the
possibilities.
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.
// (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
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";
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 ");
}
}
}
20.21 Create a String with fixed length and filled with a specific
character
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0512.html
20.21 Create a String with fixed length and filled with a specific character
}
}
We use the fact that the Properties unquote a String, so we simply simulate a Property read with our
String.
import java.io.*;
import java.util.*;
Here another snippet to convert a String to HTML. This one is little bit better because it deals with
space versus non−breaking space ( ) and Unicode characters.
i = source.indexOf("&", start);
if (i > −1) {
j = source.indexOf(";" ,i);
if (j > i) {
String entityToLookFor = source.substring(i , j + 1);
String value = (String)htmlEntities.get(entityToLookFor);
if (value != null) {
source = new StringBuffer().append(source.substring(0 , i))
.append(value)
.append(source.substring(j + 1))
.toString();
return unescapeHTML(source, start + 1); // recursive call
}
}
}
return source;
}
/*
i = s.indexOf("&", start);
start = i + 1;
if (i > −1) {
j = s.indexOf(";" ,i);
/*
we don't want to start from the beginning
the next time, to handle the case of the &
thanks to Pieter Hertogh for the bug fix!
*/
if (j > i) {
// ok this is not most optimized way to
// do it, a StringBuffer would be better,
// this is left as an exercise to the reader!
String temp = s.substring(i , j + 1);
// search in htmlEscape[][] if temp is there
k = 0;
while (k < htmlEscape.length) {
if (htmlEscape[k][0].equals(temp)) break;
else k++;
}
if (k < htmlEscape.length) {
/*
output :
© 2000 Réal Gagnon <www.rgagnon.com>
−−>
© 2000 Réal Gagnon <www.rgagnon.com>
*/
}
}
This HowTo deals only with a small subset of the available HTML entities. See this Wikipedia article
for a complete list :
http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entities_in_HT
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
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!");
Another way is to use a regular expression, see this Javascript HowTo for a hint!
20.28 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
import java.io.*;
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 <BODY> tag.
import java.io.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
20.28 Remove HTML tags from a file to extract only the TEXT
StringBuffer s;
public Html2Text() {}
A faster way
import java.io.UnsupportedEncodingException;
System.out.println(StringUtils.getHexString(byteArray));
/*
* output :
* fffefdfcfbfa
*/
}
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
#600How−To
Elvis Presley
John O'Connor &Steeve Mcmillan
for the "mcmillan", well this may be not enough and you will need
to process it as a special case if needed...
*/
}
}
/*
import org.apache.commons.codec.binary.Base64;
// 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();
}
}
}
20.36 MiGBase64
• MiGBase64 is a very fast Base64 Codec written in Java. http://migbase64.sourceforge.net/.
/*
justify a string,
here only left justification is implemented
*/
public class FormatLine {
public static String justifyLeft( int width,String st) {
formatted_string = FormatLine.justifyLeft(25,original_string);
System.out.println("−−−−−−−−−");
System.out.println(original_string);
System.out.println("−−−−−−−−−");
System.out.println(formatted_string);
/*
output :
−−−−−−−−−
01234567890123456789 01234567890 0123 4565789
−−−−−−−−−
01234567890123456789
01234567890 0123
4565789
*/
}
}
integer to String :
int i = 42;
String str = Integer.toString(i);
or
double to String :
long to String :
float to String :
String to integer :
str = "25";
int i = Integer.valueOf(str).intValue();
or
int i = Integer.parseInt(str);
String to double :
Double d = Double.valueOf(str).doubleValue();
String to long :
long l = Long.valueOf(str).longValue();
or
Long L = Long.parseLong(str);
String to float :
Float f = Float.valueOf(str).floatValue();
decimal to binary :
int i = 42;
String bin = Integer.toBinaryString(i);
decimal to hexadecimal :
int i = 42;
String hexstr = Integer.toString(i, 16);
or
String hexstr = Integer.toHexString(i);
int i = 64;
String aChar = new Character((Char)i).toString();
char c = 'A';
int i = (int) c; // i == 65 DECIMAL
integer to boolean
b = (i != 0);
// ex : 42 != 0 −−> true
boolean to integer
i = (b)?1:0;
// true −−> 1
Note :To catch illegal number conversion, try using the try/catch mechanism.
try{
i = Integer.parseInt(aString);
}
catch(NumberFormatException e) {
...
}
JDK1.5 simplifies the operation of conversion between primitive types (such as int) and wrapper
types (such as Integer). This feature is called Autoboxing/Unboxing.
// output :
// 1
// 4
}
}
In the next example, a boolean is being stored and then retrieved from an ArrayList. The 1.5
version leaves the conversion required to transition to an Boolean and back to the compiler.
import java.util.Collection.*;
import java.util.*;
import java.util.Collection.*;
import java.util.*;
Note : To be able to compile that code with the JDK1.5, you need to specify the switch −source
1.4 on the javac command line.
JDK1.0.2
JDK1.1
import java.math.*;
public class TestRound11 {
public static void main(String args[]){
double d = 3.1537;
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(2,BigDecimal.ROUND_HALF_UP);
// output is 3.15
System.out.println(d + " : " + round(d, 2));
// output is 3.154
System.out.println(d + " : " + round(d, 3));
}
[JDK1.1]
On Windows, the regional settings (Control Panel) are used for decimal point and hundred
separator.
If the decimal separator is set to "," in your Regional Settings and you really want a "." then
import java.text.*;
public class DemoNumber {
public static void main(String args[]) {
double d = 123456.78;
DecimalFormat df = new DecimalFormat("#####0.00");
DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
// make sure it's a '.'
dfs.setDecimalSeparator('.');
df.setDecimalFormatSymbols(dfs);
System.out.println(df.format(d));
}
}
JDK1.5
System.out.println() directly supports formatting so it's possible to give a known Locale (with the
right decimal separator) to bypass the current Locale.
JDK1.0.2
import java.text.*;
import java.math.*;
double d = 0.12345;
formatter = new DecimalFormat("0.#####E0");
System.out.println(formatter.format(d)); // 1.2345E−1
import java.text.*;
public class DemoNumber {
public static void main(String args[]) {
// pre−jdk1.1
String ds = Long.toString(n); // double to string
String z = mask.substring(0 , mask.length() − ds.length()) + ds;
System.out.println(z);
}
}
JDK1.1, Random.nextInt() returns the next pseudorandom, uniformly distributed int value from
this random number generator's sequence.
In JAVA, a byte always considered as signed when converted to another type. We must mask the
sign bit to JAVA, cast to an integer and process the masked bit if needed. The following method
implements this idea :
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(unsignedByteToInt(b1));
int i = 0;
int pos = 0;
i += unsignedByteToInt(buf[pos++]) << 24;
i += unsignedByteToInt(buf[pos++]) << 16;
i += unsignedByteToInt(buf[pos++]) << 8;
I += unsignedByteToInt(buf[pos++]) << 0;
NOTE: when converting byte representing an integer, it's possible that you will have to deal with the big−endian vs little−endian format. See
this How−to
Java virtual machine always used big−endian, Intel x86 used little−endian.
Sometimes you may need to pass an integer to be able to change its value. "integer" are always
passed by value in Java. An easy way to pass by reference is to use a single element array.
void add2(int[] a) {
a[0] = a[0] + 2;
}
returns "Incompatible type for constructor. Explicit cast needed to convert double to int." even if
the constructor Color (float r, float g, float b) is valid. That's because the compiler interprets
numbers like 0.1 as double not float. You must use the suffixe "f" to indicate that the number is a
float.
The output
4
0
0
10
10
4
10
10
6
10
8.13013058393518
0.6631286078928067
4.382003543427801
7.2768144451559795
7.312852816962123
8.69257797289748
2.4967782036871657
4.451145854389913
1.82517092998838
English
import java.text.DecimalFormat;
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9,12));
String tradBillions;
switch (billions) {
case 0:
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1 :
tradHundredThousands = "one thousand ";
break;
default :
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
/**
* testing
* @param args
*/
public static void main(String[] args) {
System.out.println("*** " + EnglishNumberToWords.convert(0));
System.out.println("*** " + EnglishNumberToWords.convert(1));
System.out.println("*** " + EnglishNumberToWords.convert(16));
System.out.println("*** " + EnglishNumberToWords.convert(100));
System.out.println("*** " + EnglishNumberToWords.convert(118));
System.out.println("*** " + EnglishNumberToWords.convert(200));
System.out.println("*** " + EnglishNumberToWords.convert(219));
System.out.println("*** " + EnglishNumberToWords.convert(800));
System.out.println("*** " + EnglishNumberToWords.convert(801));
/*
*** zero
*** one
*** sixteen
*** one hundred
*** one hundred eighteen
*** two hundred
*** two hundred nineteen
*** eight hundred
*** eight hundred one
*** one thousand three hundred sixteen
*** one million
*** two millions
*** three millions two hundred
*** seven hundred thousand
*** nine millions
*** nine millions one thousand
*** one hundred twenty three millions four hundred
** fifty six thousand seven hundred eighty nine
*** two billion one hundred forty seven millions
** four hundred eighty three thousand six hundred forty seven
*** three billion ten
**/
}
}
Français
Quite different than the english version but french is a lot more difficult!
package com.rgagnon.howto;
import java.text.*;
class FrenchNumberToWords {
private static final String[] dizaineNames = {
"",
"",
"vingt",
"trente",
"quarante",
"cinquante",
"soixante",
"soixante",
"quatre−vingt",
"quatre−vingt"
};
switch (laDizaine) {
case 1 :
case 7 :
case 9 :
lUnite = lUnite + 10;
break;
default:
}
// dizaines en lettres
switch (laDizaine) {
case 0:
resultat = uniteNames1[lUnite];
break;
case 8 :
if (lUnite == 0) {
resultat = dizaineNames[laDizaine];
}
else {
resultat = dizaineNames[laDizaine]
+ laLiaison + uniteNames1[lUnite];
}
break;
default :
resultat = dizaineNames[laDizaine]
+ laLiaison + uniteNames1[lUnite];
}
return resultat;
}
String resultat;
switch (lesCentaines) {
case 0:
resultat = sReste;
break;
case 1 :
if (leReste > 0) {
resultat = "cent " + sReste;
}
else {
resultat = "cent";
}
break;
default :
if (leReste > 0) {
resultat = uniteNames2[lesCentaines] + " cent " + sReste;
}
else {
resultat = uniteNames2[lesCentaines] + " cents";
}
}
return resultat;
}
// XXXnnnnnnnnn
int lesMilliards = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int lesMillions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int lesCentMille = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int lesMille = Integer.parseInt(snumber.substring(9,12));
String tradMilliards;
switch (lesMilliards) {
case 0:
tradMilliards = "";
break;
case 1 :
tradMilliards = convertLessThanOneThousand(lesMilliards)
+ " milliard ";
break;
default :
tradMilliards = convertLessThanOneThousand(lesMilliards)
+ " milliards ";
}
String resultat = tradMilliards;
String tradMillions;
switch (lesMillions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(lesMillions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(lesMillions)
+ " millions ";
}
resultat = resultat + tradMillions;
String tradCentMille;
switch (lesCentMille) {
case 0:
tradCentMille = "";
break;
case 1 :
tradCentMille = "mille ";
break;
default :
tradCentMille = convertLessThanOneThousand(lesCentMille)
+ " mille ";
}
resultat = resultat + tradCentMille;
return resultat;
}
You can handle "dollar and cent" conversion by calling the "convert" method two times.
For Oracle
CONVERTED_FORM
−−−−−−−−−−−−−−−−−−−−−−−−−−−
EIGHT HUNDRED SEVENTY−THREE
SQL>
'JSP' means :
• J : the Julian format.
• SP : spells the word for the number passed to to_date
The unexpected result is coming from the fact that internal floating−point number representation
is not well suited for that kind of operation.
if (x % 2 == 0) {
// even
}
if (x % 2 != 0) {
// odd
}
if (( x & 1 ) == 0) {
// even
}
if (( x & 1 ) != 0) {
// odd
}
// Check if given string is number with dot separator and two decimals.
public static boolean isNumberWith2Decimals(String string) {
return string.matches("^\\d+\\.\\d{2}$");
}
/*
* output
* 42.1 valid ? false
* 42 valid ? true
*
* 42.1 valid ? true
* −42.1 valid ? true
* −42.1a valid ? false
*
* 42.10 valid ? true
* 42.101 valid ? false
* 42,10 valid ? false
* 42 valid ? false
*/
• The conditions for uniqueness for objects of the class java.rmi.server.UID are satisfied
♦ An independently generated UID instance is unique over time with respect to the
host it is generated on as long as the host requires more than one millisecond to
reboot and its system clock is never set backward. A globally unique identifier can
be constructed by pairing a UID instance with a unique host identifier, such as an
IP address.
• An address can be obtained for this host that is unique and constant for the lifetime of this
object.
The format is :
Code :
Output :
d578271282b42fce:−2955b56e:107df3fbc96:−8000
d578271282b42fce:−2955b56e:107df3fbc96:−7fff
d578271282b42fce:−2955b56e:107df3fbc96:−7ffe
import java.util.concurrent.AtomicLong;
See also this HowTo for unique numerical id based on the system time.
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;
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
*/
}
}
NativeCall
NativeCall is a Java toolkit that lets you call operating system methods from whithin Java without
JNI code.
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/
21.4 com4j
A Java library that allows Java applications to seemlessly interoperate with Microsoft Component
Object Model.
First generate Java type definitions from a COM type library. Here we are doing for the type library
for the Windows Scripting Host.
21 Open Source
System.out.println(fs.getFileVersion(file));
}
}
https://com4j.dev.java.net/
21.5 j−interop
Implementation of DCOM wire protocol (MSRPC) to enable development of Pure Bi−Directional,
Non−Native Java applications which can interoperate with any COM component. The
implementation is itself purely in Java and does not use JNI to provide COM access.
http://sourceforge.net/projects/j−interop
21.6 j−xchange
Pure java implementation of the entire Collaboration Data Objects (CDO 1.21) library for accessing
Microsoft Exchange Server in a platform independent manner.
http://sourceforge.net/projects/j−xchange/
See also this HowTo for an alternative package to access a COM package from Java.
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.
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.
21.5 j−interop
21.8 Create entity−relation diagram
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java−0584.html
Linguine Maps is an open−source Java library that conducts programmatic visualization of various
text files, generating from them easy−to−understand entity−relation diagrams.
http://www.softwaresecretweapons.com/jspwiki/linguinemaps
One interesting use is the Linguine Maps for Apache Ant. This utility produces easy to read
diagrams from Ant build files. The diagram shows all the task dependencies and colors default,
normal, and optional task in different colors. Tis a great way to document your Ant build file.
Java Remote Desktop Protocol (RDP) Client is an Open Source Java RDP client for Windows
Terminal Server.
It runs on Java 1.1 and up, and works on Linux, Windows, Mac and other Java enabled systems.
http://www.elusiva.com/opensource/
Linguine Maps is an open−source Java library that conducts programmatic visualization of various
text files, generating from them easy−to−understand entity−relation diagrams.
http://www.softwaresecretweapons.com/jspwiki/linguinemaps
One interesting use is the Linguine Maps for Apache Ant. This utility produces easy to read
diagrams from Ant build files. The diagram shows all the task dependencies and colors default,
21.12 WinRun4J
http://winrun4j.sourceforge.net/
WinRun4j is a java launcher for Windows. It provides an alternative to javaw.exe and provides the
following benefits:
• Use of INI file for specifying classpath, main class, vm args, program args.
• Custom executable name that appears in task manager.
• Built−in icon replacer for custom icon.
• Windows NT Service wrapper.
• Windows EventLog API
• and more ...
21.13 JSmooth
http://jsmooth.sourceforge.net/
JSmooth is a Java Executable Wrapper. It creates native Windows launchers (standard .exe) for
your java applications.
When no VM is available, the wrapper can automatically download and install a suitable JVM, or
simply display a message or redirect the user to a web site.
A Swing−based project editor allows you to easily configure the executable binary for your software.
All the parameters are configured with a GUI, just click and compile the project.
21.14 Launch4J
http://launch4j.sourceforge.net/
Launch4j is a cross−platform tool for wrapping Java applications distributed as jars in lightweight
21.17 opencsv
A simple csv parser library for Java
http://opencsv.sourceforge.net/
21.18 ServingXML
Framework for flat/XML data transformations. Supported transformations : flat−XML,
XML−flat, flat−flat, and XML−XML
http://servingxml.sourceforge.net/
21.20 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
21.21 CSVFile
A simple set of Java classes used to handle CSV
http://sourceforge.net/projects/csvfile
There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only
about OpenSource (and free) solutions.
21.25 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.
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
21.22 FlatPack
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/
21.26 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...).
The name was originally an acronym for "Poor Obfuscation Implementation" (ref: Wikipedia).
See http://jakarta.apache.org/poi/
21.27 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.
21.26 POI
Example :
The XLS Template
Employees
Name Age Payment Bonus
${employee.name} ${employee.age} ${employee.payment} ${employee.bonus}
$[SUM(@employee.payment@)]
Employees
Name Age Payment Bonus
Derek 35 3000 30,00%
Else 28 1500 15,00%
4500
See http://jxls.sourceforge.net/
21.28 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/
21.29 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 jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
import java.io.File;
import java.util.Date;
class TestExcel {
public static void main(String[] args) throws Exception {
ReleaseManager rm = new ReleaseManager();
try {
System.out.println("EXCEL startup...");
21.28 xlSQL
// 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());
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");
xlBook.Close(false,null,false);
excel.Quit();
21.28 xlSQL
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.
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");
...
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();
}
// add to sheet
ImageHandle giffy = new ImageHandle(fin, sheet);
// 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);
}
See also this HowTo for a way to create a simple XLS without any additional library.
Here 2 nice utilities to browse (and even create) messages. Both are free to use and one is
open source.
21.33 Jad
Jad, the fast JAva Decompiler, is a program that reads one or more Java class files and
converts them into Java source files which can be compiled again.
Jad is a 100% pure C++ program and it generally works several times faster than
decompilers written in Java. Jad doesn't use the Java runtime for its functioning, therefore
no special setup is required (like changes to the CLASSPATH variable).
On Windows, a file association with the .class extension is made so if you click on a class
file then the decompiled is shown in FrontEnd Plus right away.
http://www.kpdus.com/jad.html
21.34 JadClipse
JadClipse is a plug−in that seamlessly integrates Jad (the fast Java decompiler) with
Eclipse.
Normally, when opening a class file the Class File Viewer will show a brief API outline of the
class. If you install this plug−in, however, the Class File Viewer will be replaced with the
JadClipse Class File Viewer that shows the decompiled source of the class.
http://jadclipse.sourceforge.net/wiki/index.php/Main_Page
21.35 JarPlug
By default, the support for viewing and editing JAR file in Eclipse is very limited.
http://jar−plug.sourceforge.net/
21.37 One−Jar
Any non−trivial Java application is going to rely on any number of supporting Jar files. So
your deployment will include your application jar plus the supporting jars (ex. Apache
Commons, Log4j,...).
Unfortunately it's not possible to include a jar into another jar because the Java classloader
does not know how to load classes from a Jar inside a Jar.
One−Jar is special classloader able to do this. The One−JAR JarClassLoader looks for a
main program inside a main directory in the Jar file, and looks for supporting Jar files inside
a lib directory.
The kit includes a special ANT task to simplify the process of preparing your application to
be distributed as a One−Jar application.
http://one−jar.sourceforge.net/
http://fjep.sourceforge.net/
When Outlook Express saves an email, it uses the EML format which is a good thing
because the format is a standard.
But Outlook (not the Express but the one with Office) can only save an email with the MSG
format which is Microsoft specific.
21.40 msgparser
http://auxilii.com/msgparser/
import java.util.List;
import com.auxilii.msgparser.*;
import com.auxilii.msgparser.attachment.*;
HSMF is the POI Project's pure Java implementation of the Outlook MSG format.
21.42 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).
21.45 JNotify
http://jnotify.sourceforge.net/
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).
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
In this blog entry, the package NativeCall is used to call the Windows API to get notification
about modification in given folder.
21.48 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).
21.51 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.*;
/*
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]);
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]);