Realhowto Java 201511
Realhowto Java 201511
Table of Contents
Real's HowTo PDF version (november 2015)..................................................................................................1
AWT.....................................................................................................................................................................3
java-awt....................................................................................................................................................3
Use the CardLayout manager...................................................................................................................3
Detect which card is visible with a CardLayout......................................................................................6
Use Popups..............................................................................................................................................6
Use a File Dialog.....................................................................................................................................9
Use TrueType font.................................................................................................................................10
Display available fonts...........................................................................................................................11
Font with 3D effect................................................................................................................................11
Use the System Clipboard......................................................................................................................12
Maximize a Frame.................................................................................................................................13
Center a Frame/Dialog...........................................................................................................................15
Close a Frame........................................................................................................................................16
Call events on a Frame from a Panel.....................................................................................................17
Set the small top-left icon on a Frame...................................................................................................19
Prevent a Frame to be resized................................................................................................................20
Embed an image into a Frame...............................................................................................................21
Display a message box...........................................................................................................................23
Display a Splash screen.........................................................................................................................25
Vibrate a Window..................................................................................................................................27
Limit TextField input to numeric value.................................................................................................30
Limit TextField input to a maximum length..........................................................................................31
React to the ENTER key in a Textfield.................................................................................................32
Make the ENTER key act like the TAB key..........................................................................................33
Reset all textfields in one shot...............................................................................................................34
Limit a TextField to Uppercase.............................................................................................................35
Have an ImageButton............................................................................................................................36
Reset a checkbox group.........................................................................................................................39
Set the listbox width..............................................................................................................................40
Align the column in a List.....................................................................................................................41
Have a srolling text display using a List................................................................................................41
Label dynamic resizing..........................................................................................................................42
Make a TextArea "word-wrap"..............................................................................................................44
Synchronize a TextArea versus a Choice..............................................................................................44
Display underlined text..........................................................................................................................45
Display vertical text...............................................................................................................................45
Have Label with many lines..................................................................................................................46
Have a Label with underlined text.........................................................................................................51
Have a Label acting as HTML HREF (URLLabel)...............................................................................52
Display a GIF in a Canvas.....................................................................................................................54
Embed an image into a Frame...............................................................................................................55
i
Real's HowTo PDF version
Table of Contents
AWT
Load several images from a single GIF.................................................................................................57
Load an Image from a JAR file..............................................................................................................58
Load an Image from a JAR file (again).................................................................................................59
Scale an Image.......................................................................................................................................60
Fade an image........................................................................................................................................62
Rotate an image......................................................................................................................................64
Create a scrollable canvas......................................................................................................................67
Use an Image as the Applet background................................................................................................70
Have a simple Image browser................................................................................................................72
Simulate a "mouse over" event to toggle an image...............................................................................75
Hide the mouse cursor...........................................................................................................................77
Make a color transparent........................................................................................................................77
Save an Image as a GIF or JPEG file.....................................................................................................79
Use the same background color as the browser.....................................................................................80
Do simple animation using Images........................................................................................................81
Do simple animation to show "work in progress".................................................................................82
Get the color of a specific pixel.............................................................................................................84
Do "rubber-band" drawing.....................................................................................................................85
Convert RGB value to Hex (to be used in HTML)................................................................................87
Draw a line or set a pixel in my own image..........................................................................................87
Draw dashed line....................................................................................................................................88
Draw a line with a thickness..................................................................................................................89
Draw a pie chart.....................................................................................................................................91
Draw faster rectangles............................................................................................................................94
Get a screen capture and save it as a JPEG............................................................................................95
Detect a double click versus a simple click...........................................................................................95
Detect the mouse button used when clicking.........................................................................................97
Exit an application from a menu (single exit point)..............................................................................98
Trigger a click on a Button....................................................................................................................99
Display a TIF.......................................................................................................................................100
Convert a multi-page TIF into single-page TIF...................................................................................102
Convert many single-page TIF into one multi-page TIF.....................................................................103
Convert an Image to a BufferedImage.................................................................................................104
Detect if a TIF is blank........................................................................................................................105
Convert TIF to PDF.............................................................................................................................108
Convert TIF to JPG..............................................................................................................................110
ii
Real's HowTo PDF version
Table of Contents
Date and Time
Get the number of days in a month......................................................................................................115
Validate a date......................................................................................................................................115
Determine the day of the week............................................................................................................117
Add/Substract Day/Month/Year to a Date...........................................................................................118
Get the correct TimeZone on DateFormat...........................................................................................119
Simply format a date as "YYYYMMDD"...........................................................................................120
Compare 2 dates...................................................................................................................................120
Parse a String to obtain a Date/GregorianCalendar object..................................................................121
Use System time to generate unique ID...............................................................................................122
Get the day name.................................................................................................................................122
Find the date format pattern.................................................................................................................123
Get a julian date...................................................................................................................................124
Calculate the age..................................................................................................................................127
Format a duration in milliseconds into a human-readable format.......................................................128
Get the atomic time..............................................................................................................................131
Get a date interval................................................................................................................................133
Determine if a given hour is between an interval................................................................................135
Set the computer clock (JNI)...............................................................................................................137
Get unique numerical id based on the system time..............................................................................138
Get the month (or day) name (localized).............................................................................................138
Detect a leap year.................................................................................................................................139
Environment....................................................................................................................................................141
java-env................................................................................................................................................141
Read environment variables from an application................................................................................141
Read environment variables (JDK1.5).................................................................................................145
Read environment variables (JNI).......................................................................................................146
Use a MAKE file.................................................................................................................................147
Detect the browser/JVM type..............................................................................................................148
Fix the "Wrong magic number" error message....................................................................................150
Use a precompiler "à la C" with Java..................................................................................................150
Determine what are the classes actually used......................................................................................152
Set the memory available to the JVM..................................................................................................153
Generate the Javadoc "en français"......................................................................................................153
Use JDK1.5 new features.....................................................................................................................154
Check the class version........................................................................................................................155
Get the system properties or the JVM uptime.....................................................................................156
Detect if running in a 64bit JVM.........................................................................................................157
Set the default JVM type......................................................................................................................158
Select a particular JRE from the command line...................................................................................159
Get the PID (pure Java solution)..........................................................................................................160
Get the PID (JNI solution)...................................................................................................................161
iii
Real's HowTo PDF version
Table of Contents
Environment
Set default value for Java property or JVM option (system wide)......................................................162
Detect if running in debug mode.........................................................................................................163
Configure Java deployment with properties........................................................................................163
Wrap a Java bean in a COM object (using Sun ActiveX bridge)........................................................167
Query the Windows Registry (reg.exe)...............................................................................................169
Query/Update the Windows Registry (hack).......................................................................................172
Quickly retrieve available Java JVM on a workstation (Windows)....................................................181
Detect if a Windows service is running (capture VBS return code)....................................................182
List currently running processes (Windows).......................................................................................184
Check if a program or process is running (Windows).........................................................................186
Check if a process is running (Windows) using WMIC......................................................................188
Windows registry vs Java JDK/JRE installation.................................................................................189
Get the current Java version from a BAT file......................................................................................190
Get the Windows "My Documents" path.............................................................................................192
Get the Windows Desktop path...........................................................................................................192
Get the Windows Special Folders........................................................................................................194
Create an Internet Shortcut..................................................................................................................195
Detect if running in remote session (Windows)..................................................................................197
Detect if running in a Citrix session (Windows).................................................................................198
Create a Taglet to document database access (Javadoc)......................................................................199
Generate the Javadoc "en français"......................................................................................................203
Document a package using Javadoc....................................................................................................204
Display a comment in a Javadoc..........................................................................................................205
Display XML in a Javadoc..................................................................................................................206
Add a copyright notice to a Javadoc....................................................................................................207
Use a Log file.......................................................................................................................................207
Trace the execution..............................................................................................................................210
Time the execution...............................................................................................................................212
Log information efficiently (with Log4J)............................................................................................213
Change the logging level on-the-fly (Log4J).......................................................................................214
Enable debug log level on OpenSource package(Apache Commons Logging)..................................215
Make a JAR executable.......................................................................................................................216
Application with multiples Jars...........................................................................................................218
Extract a file from a Jar........................................................................................................................218
Determine if running from JAR...........................................................................................................220
Get list of classes in package (in a Jar)................................................................................................221
Add version to Jar packaging...............................................................................................................223
Use ANT to Build a JAR with version/build number..........................................................................225
Include all jars in the classpath definition............................................................................................229
Detect browser type from an Applet....................................................................................................233
Detect if Java is enabled from HTML.................................................................................................234
See the Java Console Window Log (Java plugin)...............................................................................235
iv
Real's HowTo PDF version
Table of Contents
Internationalization........................................................................................................................................236
java-inter..............................................................................................................................................236
Load resources based upon client environment at startup...................................................................236
Load resources dynamically................................................................................................................239
Load resources via a resource file........................................................................................................243
Display "special character" using Unicode..........................................................................................247
Display chinese/japanese characters in an Applet...............................................................................248
Localize a JOptionPane dialog.............................................................................................................249
Validate/Convert a number using the current Locale()........................................................................251
Localize a JFileChooser.......................................................................................................................252
Disable localization..............................................................................................................................255
Generate the Javadoc "en français"......................................................................................................256
Sort an array with international characters..........................................................................................257
Accentuated characters in Properties/ResourceBundle file.................................................................259
Compare accentuated letters................................................................................................................259
Remove accent from letters (ex .é to e)...............................................................................................261
Output accentuated characters to the console......................................................................................265
Get the default character set of the JVM.............................................................................................266
Convert OEM (DOS) file to Ansi (Windows).....................................................................................267
Detect non-ASCII character in a String...............................................................................................268
Get the month (or day) name (localized).............................................................................................269
IO......................................................................................................................................................................271
java-io..................................................................................................................................................271
Redirect output(stdout/stderr) to a frame.............................................................................................271
Redirect printStackTrace() to a String.................................................................................................272
Redirect to NULL device.....................................................................................................................273
Print a text file using the javax.print API............................................................................................274
Print a String using the javax.print API...............................................................................................276
Print text to a printer easily..................................................................................................................278
Print without a Dialog..........................................................................................................................278
Initialize and write to a serial port.......................................................................................................279
Open or close a CD/DVD drive...........................................................................................................279
Get the volume label............................................................................................................................281
Detect the storage device type.............................................................................................................282
Turn on MQ Debug mode....................................................................................................................283
Get faster console output (System.out.println() replacement).............................................................283
Simple input from the keyboard..........................................................................................................285
Output french character to the console................................................................................................286
Clear the console and control attributes...............................................................................................288
Easy keyboard input (JDK1.5).............................................................................................................290
Force keyboard input in CAPS LOCK on...........................................................................................292
Automatic conversion of System.out output........................................................................................293
v
Real's HowTo PDF version
Table of Contents
IO
Execute an external program and capture the output...........................................................................294
Launch the application associated with a file extension......................................................................301
Launch an application from another application.................................................................................302
Start the default browser from an application......................................................................................304
Execute a Windows Shortcut (.lnk).....................................................................................................306
Create a file association with a Java program......................................................................................307
Capture the output from a VBS...........................................................................................................308
Get a return code from a VBS..............................................................................................................310
Execute a CMD file stored in a JAR....................................................................................................311
Open the default file explorer..............................................................................................................312
Read the content of a file.....................................................................................................................313
Read a text file from a Jar....................................................................................................................315
Read a text file from the internet.........................................................................................................318
Extract a file from a Jar........................................................................................................................318
Read a data file with floats...................................................................................................................320
Write to the end of a file......................................................................................................................321
Write "real" ascii file...........................................................................................................................322
Copy a file............................................................................................................................................323
Use a "log file".....................................................................................................................................326
Delete files with a certain extension....................................................................................................327
Insert a line in a file.............................................................................................................................328
Read a file into a variable in one shot..................................................................................................329
Serialize an object to a file...................................................................................................................330
Redirect stdout to a file........................................................................................................................332
Get the "last modified" date from a file...............................................................................................332
Get the file creation time......................................................................................................................332
Check if a file exists.............................................................................................................................333
Detect file (or folder) modification......................................................................................................333
File/directory polling to detect change................................................................................................337
Detect file (or folder) modification (Java 7)........................................................................................338
Get the current directory......................................................................................................................339
Get the "root" of an application...........................................................................................................340
Get the content of a directory with a Filter..........................................................................................340
Get the content of a directory with subdirectories...............................................................................343
Get directory content faster with many files........................................................................................345
Make a directory..................................................................................................................................347
Create a fixed-length file.....................................................................................................................347
Delete a non-empty directory...............................................................................................................347
Create a temporary file.........................................................................................................................348
Get the default character set of the JVM.............................................................................................349
Parse a pathname..................................................................................................................................350
Handle CSV files.................................................................................................................................350
vi
Real's HowTo PDF version
Table of Contents
IO
Convert OEM (DOS) file to Ansi (Windows).....................................................................................352
Close a stream in a try/catch block......................................................................................................353
Rename a file extension.......................................................................................................................354
Remove a file extension.......................................................................................................................356
Remove HTML tags from a file to extract only the TEXT.................................................................356
Get the Mime Type from a File...........................................................................................................359
Sort a directory listing (based on the last modified timestamp)..........................................................364
Sort files by the extension....................................................................................................................365
Filter a directory listing by date...........................................................................................................367
Convert wildcard to a regex expression...............................................................................................368
Shorten a long path..............................................................................................................................369
Force a valid Windows filename.........................................................................................................374
Check if filename is valid....................................................................................................................374
Dump a file to a HEX file....................................................................................................................375
List all files in the classpath or in a Jar................................................................................................377
Handle UTF8 file with BOM...............................................................................................................378
Touch a file..........................................................................................................................................381
Handle Excel files................................................................................................................................382
Create an Excel file (the easy way)......................................................................................................388
Detect if a XLS Excel file contains a macro (using POI)....................................................................389
Create or process PDF files..................................................................................................................390
iText - Create a PDF............................................................................................................................393
Split a PDF file (using iText)...............................................................................................................394
Concatenate PDF files (using iText)....................................................................................................395
Convert TIF to PDF.............................................................................................................................397
Convert HTML to PDF using iText.....................................................................................................399
Convert HTML to PDF using YAHP..................................................................................................401
Convert PNG/JPG/GIF to PDF using iText.........................................................................................403
Print a PDF...........................................................................................................................................404
Extract text from a PDF using Apache Tika........................................................................................405
Create a compressed (ZIP) file............................................................................................................405
Display compressed (ZIP) file content................................................................................................407
Expand the compressed (ZIP) file........................................................................................................408
Emit a beep..........................................................................................................................................409
Emit a tone...........................................................................................................................................409
Play an audio file from an application.................................................................................................411
Produce special sound effect................................................................................................................412
Use the Java Speech API (JSPAPI).....................................................................................................416
Play a Windows sound.........................................................................................................................418
vii
Real's HowTo PDF version
Table of Contents
JDBC................................................................................................................................................................420
java-jdbc...............................................................................................................................................420
Get JDBC driver for major database vendors......................................................................................420
Connect to a database via JDBC-ODBC.............................................................................................420
SELECT data from a table...................................................................................................................422
INSERT data into a table.....................................................................................................................423
MODIFY data in a table......................................................................................................................425
DELETE data in a table.......................................................................................................................425
Test for an empty ResultSet.................................................................................................................426
Get row count from SQL.....................................................................................................................426
Store and retrieve an object from a table.............................................................................................427
Retrieve an Image................................................................................................................................429
Insert an Image.....................................................................................................................................429
Call a stored procedure........................................................................................................................430
Stored procedure with Input/Output parms and a ResultSet................................................................430
Fix incomplete field returned by the ResultSet....................................................................................432
Transfer a ResultSet to a JTable..........................................................................................................432
Detect SQL error or warning...............................................................................................................432
Make DSN-less connection..................................................................................................................434
Select a CharSet when connecting to DBMS......................................................................................435
List tables in a database.......................................................................................................................435
Enable JDBC logging..........................................................................................................................437
Detect if a table exists..........................................................................................................................438
Convert a ResultSet in XML...............................................................................................................439
Display ResultSet data in an HTML Table in Servlet.........................................................................441
Escape special character in a LIKE clause..........................................................................................442
Log the SQL Statements......................................................................................................................442
Insert data in batch mode.....................................................................................................................444
Retrieve large ResultSet.......................................................................................................................446
Handle dates.........................................................................................................................................447
Get current date using JDBC...............................................................................................................449
Insert the current date...........................................................................................................................450
Read Excel worksheet..........................................................................................................................450
Handle Excel files................................................................................................................................452
Connect to an Oracle database with JDBC..........................................................................................459
Connect to Oracle using a connection pool.........................................................................................461
Retrieve the generated keys (JDBC Oracle)........................................................................................464
Debug Oracle JDBC connection..........................................................................................................465
Connect to an Oracle database using Kerberos....................................................................................467
Identify the connected program to an Oracle database........................................................................469
Use a CHAR field in the WHERE clause in a PreparedStatement......................................................470
viii
Real's HowTo PDF version
Table of Contents
JNI/JNA...........................................................................................................................................................473
java-jni.................................................................................................................................................473
Use native code through JNI (HelloWorld).........................................................................................473
Pass string to/from Java to/from C......................................................................................................473
Set the computer clock.........................................................................................................................475
Determine the signature of a method...................................................................................................476
Use arrays.............................................................................................................................................477
Load a DLL..........................................................................................................................................479
Use the MouseWheel...........................................................................................................................480
Throw an exception in JNI...................................................................................................................480
Throw my own exception in JNI.........................................................................................................481
JNI from a Package..............................................................................................................................482
Make a Window stay on top................................................................................................................482
Start JVM from C................................................................................................................................483
Retrieve environment variable (JNI)...................................................................................................484
Get the PID..........................................................................................................................................484
Clear the console, set color and cursor position (JNI).........................................................................485
Call Windows API (Open source solution).........................................................................................488
Detect if a program is running (JNA)..................................................................................................489
Close an external windows program using JNA..................................................................................490
Get Windows Special Folders (JNA)...................................................................................................492
Javascript interaction.....................................................................................................................................494
java-js...................................................................................................................................................494
* Read me *.........................................................................................................................................494
Wake-up a Java applet.........................................................................................................................494
Call a Java method from Javascript.....................................................................................................497
Call a Java method from Javascript using DOM.................................................................................499
Access Java variables from Javascript.................................................................................................499
Call Javascript from a Java applet.......................................................................................................500
Create dynamic HTML from a Java applet..........................................................................................503
Inter-Applets communication across frames.......................................................................................504
Inter-Applet communication across pages...........................................................................................506
Write HTML FORM values from a Java applet..................................................................................508
Detect if an Applet is ready.................................................................................................................509
Read/Write HTML field values from Java..........................................................................................510
Detect if Java is enabled......................................................................................................................512
Detect if Java 1.1 (with event delegation) is available........................................................................512
Access Cookies from a Java Applet.....................................................................................................513
Set Applet PARAM VALUE from Javascript.....................................................................................516
Pass an Array between Java and Javascript.........................................................................................517
Interaction without LiveConnect.........................................................................................................520
Directory listing on the Web server in a Java Applet..........................................................................525
ix
Real's HowTo PDF version
Table of Contents
Javascript interaction
Have a Java button close the browser window....................................................................................528
Detect if cookies are enabled...............................................................................................................528
Display a page after all Applets are loaded.........................................................................................529
Detect browser type from an Applet....................................................................................................530
Servlet/JSP.......................................................................................................................................................533
java-jsp.................................................................................................................................................533
Read me...............................................................................................................................................533
Get servlet parameters..........................................................................................................................533
Servlet with no args.............................................................................................................................534
Set a Cookie from a servlet..................................................................................................................535
Read a Cookie from a servlet...............................................................................................................535
Delete a Cookie from a servlet.............................................................................................................536
Ask a password from a Servlet............................................................................................................536
Talk to a Servlet/JSP from an Applet..................................................................................................537
Test for Cookies support......................................................................................................................538
Display ResultSet data in an HTML Table in Servlet.........................................................................539
Specify the filename to be used for a file sent by a Servlet.................................................................539
Pass information to another servlet/jsp................................................................................................540
Handle PDF output..............................................................................................................................540
Detect if a connection is secured.........................................................................................................541
In a Servlet, check if Form Field is present.........................................................................................541
Get the root dir of a web app...............................................................................................................541
Get Client IP from JSP.........................................................................................................................541
Binary output from a JSP.....................................................................................................................542
Use a connection cache from JSP........................................................................................................543
Read a web application property..........................................................................................................545
Use EJB from JSP................................................................................................................................545
Define a method in a JSP page............................................................................................................546
Precompile JSP page............................................................................................................................546
Get a list of directories from JSP.........................................................................................................547
Use and share a class in JSP pages......................................................................................................548
Get the root dir of a web app...............................................................................................................549
Launch an applet from a JSP...............................................................................................................550
Prevent caching of a JSP output...........................................................................................................550
Launch an external program, capture its output and display it in a JSP..............................................551
Call another EJB..................................................................................................................................553
Keep java files generated from JSP (BEA WLS)................................................................................553
Get the server version (BEA WLS).....................................................................................................553
Quickly create a Web application with BEA WLS.............................................................................554
Nicely display WEB.XML informations.............................................................................................554
Reverse the CLASSLOADER order (BEA)........................................................................................556
x
Real's HowTo PDF version
Table of Contents
Servlet/JSP
Detect change in JSP and recompile (BEA)........................................................................................557
Obtain a remote connection to a DataSource or EJB (Weblogic).......................................................557
Language..........................................................................................................................................................560
java-language.......................................................................................................................................560
*Read me*...........................................................................................................................................560
Obtain from where a Class is loaded...................................................................................................560
Get the class name in a static method..................................................................................................561
Get the current method name...............................................................................................................562
Call a method dynamically..................................................................................................................564
Detect if a package is available............................................................................................................566
Create an Object from a String............................................................................................................567
Get a variable value from the variable name.......................................................................................568
Make methods that have unspecified number of parameters...............................................................569
Create a java source dynamically, compile and call............................................................................570
Launch an application from another application.................................................................................573
Access the enclosing class from an inner class....................................................................................574
Access inner class from outside...........................................................................................................575
Use globally defined constants............................................................................................................576
Serialize an Object...............................................................................................................................577
Serialize an Object over a Socket........................................................................................................579
Easily remove my debugging code......................................................................................................579
Have a Singleton..................................................................................................................................580
Multiple expressions in for loops.........................................................................................................581
Handle the List conflict (java.awt.List/java.util.List)..........................................................................581
Use a generic toString().......................................................................................................................582
Use a Object.clone().............................................................................................................................584
Static field, constructor and exception.................................................................................................585
Use a Label break.................................................................................................................................586
Put printStackTrace() into a String......................................................................................................586
Iterate enum values..............................................................................................................................587
Get fields and values from an Object...................................................................................................588
Use a Hashtable....................................................................................................................................589
Scan the content of a hashtable............................................................................................................590
Sort an array.........................................................................................................................................590
Initialize multidimensional array.........................................................................................................592
Get array upperbound..........................................................................................................................593
Convert a String to an array or an array to a String.............................................................................593
Sort Collection in reverse order...........................................................................................................595
Resize an array.....................................................................................................................................596
Dump array content (JDK1.5)..............................................................................................................597
Initialize a static array..........................................................................................................................598
xi
Real's HowTo PDF version
Table of Contents
Language
Sort an Hashtable.................................................................................................................................599
Eliminate "[unchecked] unchecked call ..." compiler warning............................................................600
Sort on many fields..............................................................................................................................602
Optimize Collection usage...................................................................................................................605
Sort an HashMap..................................................................................................................................606
Get keys corresponding to a value from a Map...................................................................................608
Iterate a Collection and remove an item..............................................................................................609
Count distinct elements in a Vector.....................................................................................................611
Dump the content of a Collection (JDK 1.5).......................................................................................612
Initialize a Collection...........................................................................................................................614
Merge (or add) two arrays into one......................................................................................................616
Define an array (or Map, or ENUM) of functions...............................................................................617
Join a List as a String...........................................................................................................................620
Remove duplicates from a List............................................................................................................621
Convert a Map to a Properties (or vice versa).....................................................................................622
Use an INI file (properties)..................................................................................................................623
Load a properties file...........................................................................................................................625
Accentuated characters in Properties/ResourceBundle file.................................................................626
Have a multi-line value in a properties file..........................................................................................626
Use XML with Properties....................................................................................................................627
Use the Registry to store informations.................................................................................................628
Sort Properties when saving.................................................................................................................629
Resolve environment variable in a property value..............................................................................630
Networking......................................................................................................................................................633
java-net.................................................................................................................................................633
Extract network card address...............................................................................................................633
Get the workstation name/ip................................................................................................................636
Find a port number not in use..............................................................................................................638
Disable DNS caching...........................................................................................................................638
Examine the internal DNS cache.........................................................................................................639
Allow user:password in URL...............................................................................................................642
Encode/Decode to/from Base64..........................................................................................................642
Lookup using MX record to validate mail server................................................................................644
Send an email using the SMTP protocol.............................................................................................654
Check if there is mail waiting..............................................................................................................655
Receive email.......................................................................................................................................657
Send email with an attachment............................................................................................................659
Send email with JavaMail....................................................................................................................666
Send email with authentication (JavaMail)..........................................................................................668
HTML mail with images (JavaMail)...................................................................................................669
Debug a Javamail Program..................................................................................................................672
xii
Real's HowTo PDF version
Table of Contents
Networking
Send email with SMTPS (eg. Google GMail) (Javamail)...................................................................673
Mix plain text and HTML content in a mail........................................................................................675
Read an Outlook MSG file (OpenSource packages)...........................................................................676
Handle EML file with JavaMail..........................................................................................................679
Receive email (and attachment) using IMAP......................................................................................681
Receive email (and attachment) using POP3.......................................................................................684
Debug a HttpURLConnection problem...............................................................................................686
Check if a file was modified on the server..........................................................................................688
Check if a page exists..........................................................................................................................688
Connect through a Proxy.....................................................................................................................690
Identify yourself using HTTP Authentification...................................................................................694
Talk to a CGI/Servlet...........................................................................................................................696
Write/Read cookies using HTTP.........................................................................................................697
Read a text file from the internet.........................................................................................................700
Read a GIF or CLASS from an URL save it locally............................................................................700
Resolve a relative URL........................................................................................................................702
File Size from URL..............................................................................................................................702
Using HTTPS protocol........................................................................................................................703
Fix certificate problem in HTTPS........................................................................................................704
Fetch a page from Google....................................................................................................................706
Upload a file.........................................................................................................................................707
Remove HTML tags from a file to extract only the TEXT.................................................................707
Extract links from an HTML page.......................................................................................................710
Call a web service (generated with BEA ServiceGen)........................................................................712
Do basic authentication when calling a webservice............................................................................714
Have a simple HTTP server.................................................................................................................715
Handle JSON Object............................................................................................................................717
HttpUrlConnection with GZIP encoding.............................................................................................727
Connect through a Proxy.....................................................................................................................730
Have timeout on socket connection.....................................................................................................733
Ping a server.........................................................................................................................................734
Get the Date from server......................................................................................................................735
Use Socket's setSoLinger()..................................................................................................................735
Use Socket's setTcpNoDelay()............................................................................................................736
Find who is connecting to a ServerSocket...........................................................................................736
Transfer a file via Socket.....................................................................................................................737
Check if a document exists in a Sharepoint library.............................................................................739
Delete a document in a Sharepoint library...........................................................................................741
Get a document from a Sharepoint library...........................................................................................743
Put or store a document in a Sharepoint library...................................................................................745
Handle MS Exchange public folders...................................................................................................747
xiii
Real's HowTo PDF version
Table of Contents
Open Source....................................................................................................................................................750
java-os..................................................................................................................................................750
Call Windows API...............................................................................................................................750
Call COM object..................................................................................................................................750
Create entity-relation diagram.............................................................................................................751
Java Remote desktop tool....................................................................................................................752
Create entity-relation diagram.............................................................................................................753
Launch a java program as a Windows EXE file..................................................................................753
Tools to handle CSV files....................................................................................................................755
Tools to handle Excel files...................................................................................................................756
Browse a Queue (JMS/MQ).................................................................................................................763
Convert a .class to .java file (decompiler)...........................................................................................763
Deploy an application as only 1 jar......................................................................................................765
Read an Outlook MSG file..................................................................................................................765
File/directory polling to detect change................................................................................................769
Jansi/Jcurses - Clear the console and control attributes.......................................................................770
Disable Checkstyle from code.............................................................................................................773
Create or process PDF files..................................................................................................................774
iText - Create a PDF............................................................................................................................776
Split a PDF file (using iText)...............................................................................................................777
Concatenate PDF files (using iText)....................................................................................................779
Convert TIF to PDF.............................................................................................................................780
Convert HTML to PDF using iText.....................................................................................................782
Convert HTML to PDF using YAHP..................................................................................................784
Convert PNG/JPG/GIF to PDF using iText.........................................................................................786
Print a PDF...........................................................................................................................................787
Extract text from a PDF using Apache Tika........................................................................................788
Detect and remove blank page in pdf (iText)......................................................................................789
Security............................................................................................................................................................792
java-security.........................................................................................................................................792
Encrypt a password..............................................................................................................................792
Create a checksum...............................................................................................................................797
Get the username..................................................................................................................................801
Get the username using NTLM from a JSP.........................................................................................802
Check if the current user belongs a specific Windows group/role......................................................804
Allow user:password in URL...............................................................................................................804
Input password from the console.........................................................................................................805
Prevent XSS exploit.............................................................................................................................806
Display a simple username/password Dialog from an Applet.............................................................808
Solve "Application blocked by security settings" message with unsigned Applet..............................811
xiv
Real's HowTo PDF version
Table of Contents
String/Number.................................................................................................................................................814
java-stringnumber................................................................................................................................814
*Read me*...........................................................................................................................................814
Convert from type X to type Y............................................................................................................814
Strip certain characters from String.....................................................................................................817
Replace/remove character in a String..................................................................................................818
Replace every occurences of a string within a string...........................................................................819
"Tokenize" a string..............................................................................................................................821
Split a string using String.split()..........................................................................................................827
Optimize String operations..................................................................................................................830
Remove spaces from a String..............................................................................................................832
Test if a String starts with a digit or uppercase letter..........................................................................833
Get InputStream from a String.............................................................................................................833
Easy String padding.............................................................................................................................834
Replace \r\n with the <br> tag.............................................................................................................836
Remove accent from letters (ex .é to e)...............................................................................................836
Apply a mask to a string......................................................................................................................840
Format a String (JDK1.5)....................................................................................................................841
Replace a "\" by "\\".............................................................................................................................842
Substitute tokens in a String................................................................................................................843
Compare accentuated letters................................................................................................................843
Create a String with a fixed length......................................................................................................845
Unquote a String..................................................................................................................................846
Escape HTML special characters from a String..................................................................................846
Unescape HTML special characters from a String..............................................................................849
Detect non-ASCII character in a String...............................................................................................853
Remove HTML tags from a file to extract only the TEXT.................................................................854
Extract links from an HTML page.......................................................................................................857
Convert a byte array to a Hex string....................................................................................................859
Apply proper uppercase and lowercase on a String.............................................................................861
Encode/Decode to/from Base64..........................................................................................................862
Justify string with wordwrap...............................................................................................................864
Shorten a long path..............................................................................................................................865
Ellipse a long string.............................................................................................................................869
Display an ASCII banner.....................................................................................................................870
Convert from type X to type Y............................................................................................................871
Type conversion (JDK1.5)...................................................................................................................874
Round a double....................................................................................................................................875
Display numbers with commas............................................................................................................876
Display numbers in scientific notation................................................................................................877
Display numbers with leading zeroes..................................................................................................879
Get a random number...........................................................................................................................880
Convert an UNSIGNED byte to a JAVA integer................................................................................880
xv
Real's HowTo PDF version
Table of Contents
String/Number
Deal with the big-endian and little-endian order.................................................................................882
Pass an integer by reference.................................................................................................................882
Pass floats as string literals to a method..............................................................................................882
Get random numbers............................................................................................................................883
Convert number to words.....................................................................................................................884
Arithmetic with double........................................................................................................................893
Detect even/odd number......................................................................................................................894
Convert bytes to megabytes.................................................................................................................894
Validate a number................................................................................................................................895
Get a unique identifier.........................................................................................................................896
Validate/Convert a number using the current Locale()........................................................................897
Transform a fraction to a Double.........................................................................................................899
Get short ordinal representation of a number......................................................................................900
Swing................................................................................................................................................................902
java-swing............................................................................................................................................902
*Read me*...........................................................................................................................................902
Change default component font...........................................................................................................902
Repaint problem under the mouse cursor (JDK1.2)............................................................................903
Set the LookAndFeel...........................................................................................................................903
Use any LookAndFeel on any plateform.............................................................................................903
Use a Timer..........................................................................................................................................904
Share ActionEvent handler..................................................................................................................905
Get default values for Swing-based user interface..............................................................................907
Have a systray icon (Windows)...........................................................................................................908
Close a JFrame under condition...........................................................................................................910
Maximize a JFrame..............................................................................................................................911
Capture System.out into a JFrame.......................................................................................................912
Remove the titlebar of JInternalFrame................................................................................................915
Have borders on a JWindow/JFrame...................................................................................................915
Display HTML in a JScrollPane..........................................................................................................915
Use a JOptionPane...............................................................................................................................916
Localize a JOptionPane dialog.............................................................................................................918
Customize a JOptionPane dialog.........................................................................................................920
Localize a JFileChooser.......................................................................................................................920
Select a directory with a JFileChooser.................................................................................................924
Disable the JFileChooser's 'New folder' button...................................................................................925
Validate a filename from a JFileChooser.............................................................................................927
Make a JFrame looks like a JDialog....................................................................................................928
Make a JFrame always visible.............................................................................................................929
Show a JFrame on a specific screen in a dual monitor configuration.................................................930
Make a frame not visible in the taskbar...............................................................................................930
xvi
Real's HowTo PDF version
Table of Contents
Swing
Based on JTextField content, enable or disable a JButton...................................................................931
Apply special filter to a JtextField.......................................................................................................932
Limit JTextField input to a maximum length......................................................................................936
Validate a value on the lostFocus event...............................................................................................937
Force the focus on a JTextfield when a JFrame is created..................................................................939
Stop the beep on JFormattedTextField................................................................................................940
Right justified JTextfield content........................................................................................................941
Set the focus on a particuliar JTextField..............................................................................................941
Make JTextField unselectable..............................................................................................................942
Disable copy paste functionality on JTextField...................................................................................942
Use a JTree to navigate in a site...........................................................................................................944
Expand or collapse a JTree..................................................................................................................951
Have a popup attached to a JTree........................................................................................................954
Traverse a JTree...................................................................................................................................956
Dotted Lines in a JTree........................................................................................................................958
Explore directories with a JTree..........................................................................................................958
Prevent JTree collapsing......................................................................................................................960
Single selection in a JTree...................................................................................................................960
Reduce JTree children indentation.......................................................................................................961
Use + or - for JTree Icons....................................................................................................................961
Change JTable header color.................................................................................................................963
Detect doubleclick on a JTable............................................................................................................964
Read a data file into a JTable...............................................................................................................966
Disable row selection in a JTable........................................................................................................969
Detect a data file modification and reload a JTable.............................................................................969
Hide a column in JTable......................................................................................................................971
Scroll a JTable to the last row..............................................................................................................973
Transfer a ResultSet to a JTable..........................................................................................................973
Have on a JScrollPane/JTable an horizontal JScrollbar......................................................................974
Make a JList select an item on doubleclick or the ENTER key..........................................................974
Make a JList like a scrolling text display.............................................................................................976
Have images in a JList.........................................................................................................................977
Add a row and clear a JList..................................................................................................................980
Sort a JList...........................................................................................................................................981
Double click on a JList........................................................................................................................982
Have a PopUp on a JList......................................................................................................................984
Make a JLabel selectable via the mouse..............................................................................................985
Change JLabel background color.........................................................................................................986
Bold/UnBold a JLabel.........................................................................................................................986
Multi-line JLabel..................................................................................................................................987
Underline in Swing..............................................................................................................................987
Update a JLabel....................................................................................................................................988
xvii
Real's HowTo PDF version
Table of Contents
Swing
Display a blinking JLabel....................................................................................................................988
Set the cursor position in a JTextArea.................................................................................................990
Have Multi-line string in a JToolTip...................................................................................................990
Change Tooltip color...........................................................................................................................991
Change a JTooltip font.........................................................................................................................991
Keep a JTooltip visible........................................................................................................................992
Display icon associated with an executable.........................................................................................993
Have items in JMenubar at rightmost position....................................................................................995
Have an JButton with an Image...........................................................................................................996
Trigger a click on a Button..................................................................................................................997
Thread..............................................................................................................................................................999
java-thread............................................................................................................................................999
Pipe the output of a thread to the input of another one........................................................................999
Pipe the output of a thread to the input of other threads....................................................................1001
Wait the for the completion of one thread.........................................................................................1004
Control a thread from outside............................................................................................................1005
Create a Timer object.........................................................................................................................1005
Pause the execution............................................................................................................................1007
Execute a method at regular interval.................................................................................................1007
Execute a process at regular interval.................................................................................................1009
Handle concurrent read/write.............................................................................................................1010
Communicate between threads using a Queue..................................................................................1012
Get a unique identifier.......................................................................................................................1017
Varia...............................................................................................................................................................1020
java-varia............................................................................................................................................1020
Use System time to generate unique ID.............................................................................................1020
Get a unique identifier.......................................................................................................................1020
Get the hard disk serial number or Motherboard Serial number.......................................................1022
Sort an array 1....................................................................................................................................1024
Sort an array 2....................................................................................................................................1026
Do a selection sort..............................................................................................................................1029
Validate a Social Security Number (canadian)..................................................................................1029
Validate a Credit Card Number.........................................................................................................1031
Obtain from where a Class is loaded.................................................................................................1035
Get the class name with or without the package................................................................................1036
See the generated bytecode................................................................................................................1037
Self-replicating programs...................................................................................................................1040
A curiosity..........................................................................................................................................1041
Common Bugs...................................................................................................................................1043
Number of the beast! :-).....................................................................................................................1044
xviii
Real's HowTo PDF version
Table of Contents
Varia
Use Java scripting engine (JDK 1.6)..................................................................................................1044
Pass or retrieve values from a scripting engine (JDK 1.6)................................................................1045
Preventing multiple instances of an application................................................................................1048
Trap JVM shutdown..........................................................................................................................1052
Minimize all programs on Windows to show the Desktop................................................................1052
Display a progress indicator in the console.......................................................................................1053
XML...............................................................................................................................................................1055
java-xml.............................................................................................................................................1055
Read me.............................................................................................................................................1055
Display XML using plain HTML......................................................................................................1056
Transform XML into HTML using XSLT.........................................................................................1057
Parse using SAX or DOM..................................................................................................................1059
Parse an XML string..........................................................................................................................1061
Create an XML document with DOM...............................................................................................1063
Attach a stylesheet to an XML file....................................................................................................1064
Create an XML file and attach an XSL.............................................................................................1065
Nicely display WEB.XML informations...........................................................................................1068
Serialize an object using XML..........................................................................................................1070
Convert flat file to XML using SAX.................................................................................................1071
Convert flat file to XML using DOM................................................................................................1073
Convert a ResultSet in XML.............................................................................................................1076
Parse with XPath................................................................................................................................1078
Strip extra spaces in a XML string....................................................................................................1082
Create an XML file and attach an XSL.............................................................................................1083
Use XML with Properties..................................................................................................................1087
Change a particular node in XML.....................................................................................................1088
Validate XML using a DTD..............................................................................................................1089
Validate XML using a XSD (XML schema).....................................................................................1093
Sanitize XML String..........................................................................................................................1099
Produce HTML entities when using XSLT.......................................................................................1100
Transform XML into CSV using XSLT............................................................................................1100
Create a RSS feed (part 1).................................................................................................................1102
Create a RSS feed (part 2).................................................................................................................1108
Parse a RSS XML file........................................................................................................................1115
Add a Live bookmark........................................................................................................................1117
Validate a RSS feed...........................................................................................................................1117
Attach a CSS to RSS feed..................................................................................................................1118
Handle JSON Object..........................................................................................................................1119
xix
Real's HowTo PDF version (november 2015).
This is the PDF version of the Real's HowTo Web site ( http://www.rgagnon.com/howto.html ). For
up-to-date content, please refer to the Web site. There are 4 files : Real's Java , Real's Javascript, Real's
Powerbuilder and Real's VBS and Misc Prog HowTo. Please don't make PDF versions available on the
internet (it's ok in intranet). From the PDF, you can't run the examples and the links to other How-to's are not
working.
If you feel that effort has been useful to you, perhaps you will consider giving something back? You can make
a donation through PayPal at https://www.paypal.com , make you donation to [email protected]
Contributions via PayPal are accepted in any amount using a credit card or checking account.
DISCLAIMER
A CardLayout object is a layout manager for a container. It treats each component in the container as a card.
Only one card is visible at a time, and the container acts as a stack of cards.
In this HowTo, when a button is clicked the corresponding card is made visible.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Panel;
AWT 3
Real's HowTo PDF version
setBackground(co);
setLayout(la);
}
and then
import java.applet.Applet;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
c2.addItem("Option C");
p2.add(c2);
// Add cards
p0.add("First card", p1);
p0.add("2nd card", p2);
p0.add("3rd card", p3);
if (c[i].isVisible()) {
t2.setText("" + (i+1));
break;
}
else
i ++;
}
}
}
}
<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];
}
Use Popups
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0238.html
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;
public 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");
m.add(item);
MenuBar mb = new MenuBar();
mb.add(m);
setMenuBar(mb);
setSize(100, 100);
setLayout(new BorderLayout());
/*
** label with a popup
*/
Label l = new Label("label");
addPopup(l, "label");
add(l, "North");
/*
** panel with popup
*/
Panel p = new Panel();
p.setBackground(new Color(0).red);
addPopup(p, "Panel");
add(p, "Center");
/*
** button with popup
*/
Button b = new Button("button");
addPopup(b, "button");
add(b, "South");
addWindowListener
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
setVisible(true);
}
Use Popups 7
Real's HowTo PDF version
/*
** initialize a Popup for a particular Component
*/
setHash(c, pm);
c.add(pm);
c.addMouseListener(this);
}
Use Popups 8
Real's HowTo PDF version
popupTable.put(c, p);
}
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 {
System.out.println
("Saving : "
+ ufd.saveFile(new Frame(), "Save...", ".\\", "*.java"));
System.exit(0);
}
}
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. To add
fonts, simply edit the properties.font file located in the lib of your JDK installation.
On a Windows system, to check what are the fonts available, go in the Font applet in the Parameters folder.
Choose a font and doubleclick on it. Check the name of the font. For example, on my system, I have a font
called Kaufmann, the real name is "Kaufmann BT". To be able to use this font, I add the following line in the
properties.font file in the section called # for backword compatibility.
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.*;
if (sm != null) {
try {
sm.checkSystemClipboardAccess();
}
catch (Exception e) {e.printStackTrace();}
}
Toolkit tk = Toolkit.getDefaultToolkit();
StringSelection st =
new StringSelection("Hello world from Java");
Clipboard cp = tk.getSystemClipboard();
cp.setContents(st, this);
}
NOTE: You can only use text (no graphic) with this functionality provided by the current JDK (1.4).
Maximize a Frame
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0222.html
JDK1.4
import java.awt.*;
...
GraphicsDevice device;
Frame frame = new Frame();
device =
GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice();
if ( device.isFullScreenSupported() ) {
device.setFullScreenWindow(frame);
}
else {
The "full-screen" Frame is in exclusive mode. In this mode you can change the resolution
import java.awt.*;
class ScreenRes {
public static void main(String args[]) {
new ScreenRes().doit();
}
}
else {
System.err.println("Change display mode not supported");
}
}
else {
System.err.println("Full screen not supported");
}
}
}
device.setFullScreenWindow(null);
SWING jdk1.3
Maximize a Frame 14
Real's HowTo PDF version
Center a Frame/Dialog
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0223.html
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);
Center a Frame/Dialog 15
Real's HowTo PDF version
Close a Frame
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0225.html
[JDK1.0.2]
[JDK1.1 Method 1]
[JDK1.1 Method 2]
[JDK1.1 Method 3]
Close a Frame 16
Real's HowTo PDF version
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
}
}
For a Dialog or a Window, a System.exit(0) may not be appropriate, call the dispose() method instead.
A component on a Panel can easily call events on the parent Frame. This way, we can put all the logic in one
place. In this example, a Frame contains 1 button and a Panel with 2 buttons on it. The first button on the
Panel will generate an event for the button on the Frame while the second panel button will trigger a request to
close the Frame and the application.
[TestEventPanel.java]
import java.awt.*;
import java.awt.event.*;
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) {
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.
In JDK1.1, this is fixed. You have to use a GIF file (not ICO file!). The GIF dimension should be 16x16. With
1.5, you can use a PNG or JPG file.
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.*;
this.setResizable(false);
this.setSize(200,200);
}
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.*;
ImageFrame() {
super("");
try {
MediaTracker mt = new MediaTracker (this);
// for Applet, change the method to retrieve the image
// and of course use your own image!
image = Toolkit.getDefaultToolkit().getImage("images/jht.gif");
mt.addImage(image, 0);
mt.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
setLayout(new FlowLayout());
add(new TextField(10));
add(new Button("hello"));
add(new List(20));
add(new TextArea(20,20));
// Label may not look too good ...
add(new Label("Hello"));
setSize(500, 500);
addWindowListener
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// change this for an Applet
System.out.println("Bye.");
System.exit(0);
}
}
);
}
int x = 0, y = 0;
while(y < getSize().height) {
x = 0;
while(x< getSize().width) {
g.drawImage(image, x, y, this);
x= x + image.getWidth(null);
}
y = y + image.getHeight(null);
}
}
else {
g.clearRect(0, 0, getSize().width, getSize().height);
}
}
The result :
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();
}
}
This Splash class display a window containing a specified image while a parent Frame is doing its
initialization. When the parent is activated, the Splash window is destroyed.
[JDK1.1]
import java.awt.*;
import java.awt.event.*;
this.imgName = imgName;
tk = Toolkit.getDefaultToolkit();
splashImage = loadSplashImage();
showSplashScreen();
f.addWindowListener(new WindowListener());
}
public Image loadSplashImage() {
MediaTracker tracker = new MediaTracker(this);
Image result;
result = tk.getImage(imgName);
tracker.addImage(result, 0);
try {
tracker.waitForAll();
}
catch (Exception e) {
e.printStackTrace();
}
imgWidth = result.getWidth(this);
imgHeight = result.getHeight(this);
return (result);
}
The following example use this image (jht.gif) as the splash image.
import java.awt.*;
import java.awt.event.*;
Vibrate a Window
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0622.html
import java.awt.*;
Vibrate a Window 27
Real's HowTo PDF version
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);
Vibrate a Window 28
Real's HowTo PDF version
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];
}
Vibrate a Window 29
Real's HowTo PDF version
to specify your own folder. This demo is watching for files with the extension txt only.
[JDK1.0.2]
[JDK1.1]
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.*;
addKeyListener(this);
}
public TextFieldWithLimit (int col,int maxLength) {
this("",col,maxLength);
}
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
Toolkit.getDefaultToolkit().beep();
System.out.println("ENTER pressed");
}
}
}
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
First create a TextField that listen to the Enter and react like a Tab key [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.*;
resetTextFields(this);
}
<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);
}
}
);
}
Have an ImageButton
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0245.html
This implementation of an ImageButton requires JDK1.1 and is a good example of the new Event
architecture. This ImageButton needs 2 GIF images representing the normal and pressed state ( ).
Also a method to disable the button by using a special filter is given.
[ImageButton.java]
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;
Have an ImageButton 36
Real's HowTo PDF version
try {
UPimage = getToolkit().getImage(up);
DOWNimage = getToolkit().getImage(down);
tracker = new MediaTracker(this);
tracker.addImage(UPimage,0);
tracker.addImage(DOWNimage,1);
tracker.waitForAll();
}
catch (InterruptedException e) {
e.printStackTrace();
}
disabledimage=createImage(new FilteredImageSource
(UPimage.getSource(),new ImageButtonDisableFilter()));
w=UPimage.getWidth(this);
h=UPimage.getHeight(this);
}
Have an ImageButton 37
Real's HowTo PDF version
down=true;
repaint();
}
}
public void mouseReleased(MouseEvent e) {
Point p = e.getPoint();
if (down) {
down=false;
repaint();
}
if ((p.x < w)&&(p.y < h)&&(p.x > 0)&&(p.y > 0)&&(clicked==true)) {
ActionEvent ae =
new ActionEvent(e.getComponent(),0,"click");
if (actionListener != null) {
actionListener.actionPerformed(ae);
}
}
clicked=false;
}
}
public class ImageButtonMouseMotionListener extends
MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
if ((p.x < w)&&(p.y < h)&&(p.x > 0)&&(p.y > 0)&&(clicked==true)) {
if (down==false) {
down=true;
repaint();
}
}
else {
if (down==true) {
down=false;
repaint();
}
}
}
}
Have an ImageButton 38
Real's HowTo PDF version
}
}
}
[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.
A srolling text display can be used to log informations or events. In this snippet, we are using a List
component to display the data. We are keeping only the last 10 events. It's a good idea to limit the amount of
data kept in the List , in fact we have no choice because the maximum capacity is about 32k (Win).
import java.awt.*;
import java.awt.event.*;
With a Layout Manager, you have to validate() the layout to redraw the components invalidated.
this.validate();
While this method works in Netscape or the Appletviewer, on IE4/5 there is no resizing. You may want to try
this instead (thanks to Dan for the tip):
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.*;
setVisible(true);
}
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);
}
super.paint(g);
Dimension d = getSize();
if ( (offGraphics == null) ||
(d.width != offDimension.width) ||
(d.height != offDimension.height)
) {
offDimension = d;
offImage = createImage(d.width, d.height);
offGraphics = offImage.getGraphics();
}
offGraphics.setColor(getBackground());
offGraphics.fillRect
(x, y, getSize().width - 1,
getSize().height - 1);
if (border) {
offGraphics.setColor(borderColor);
offGraphics.drawRect
(x, y, getSize().width - 1, getSize().height - 1);
}
int j = line_ascent +
(d.height - num_lines * line_height) / 2;
for (int k = 0; k < num_lines; ) {
int i;
switch (alignment) {
case 0:
i = 0;
break;
case 2:
i = d.width - line_widths[k];
break;
default:
i = (d.width - line_widths[k]) / 2;
break;
}
i += leftRightMargin;
offGraphics.setColor(getForeground());
offGraphics.drawString(lines[k], i + x, j + y);
k++;
j += line_height;
}
g.drawImage(offImage,0,0,this);
}
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"
NAME="myApplet"
HEIGHT=200 WIDTH=200>
</APPLET></BODY></HTML>
[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.*;
add(ull3);
URLLabel ull4 = new URLLabel(this,
"http://www.rgagnon.com/javadetails/java-0002.html",
"Java How-to 0002");
add(ull4);
validate();
}
}
[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.*;
if (argv.length <1) {
System.out.println
("usage: ImageCanvas.class [image file name]");
System.exit(0);
}
Frame frame = new Frame(argv[0]);
frame.setLayout(new BorderLayout());
frame.add("Center", new ImageCanvas(argv[0]));
frame.resize(400,400);
frame.show();
}
}
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);
}
catch (Exception e) {
e.printStackTrace();
}
setLayout(new FlowLayout());
add(new TextField(10));
add(new Button("hello"));
add(new List(20));
add(new TextArea(20,20));
// Label may not look too good ...
add(new Label("Hello"));
setSize(500, 500);
addWindowListener
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// change this for an Applet
System.out.println("Bye.");
System.exit(0);
}
}
);
}
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]
catch (Exception e) {
e.printStackTrace();
}
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
//
BufferedInputStream bis = new BufferedInputStream(is);
// a buffer large enough for our image
//
// can be
// byte[] byBuf = = new byte[is.available()];
// is.read(byBuf); or something like that...
byte[] byBuf = = new byte[10000];
Remember that it is always possible to the Java built-in icons so that you don't have to include your own
standard icons.
Scale an Image
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0243.html
import java.awt.image.*;
import java.awt.*;
import java.net.*;
Scale an Image 60
Real's HowTo PDF version
resizedImage = createImage(prod);
media.addImage(resizedImage,1);
media.waitForID(1);
}
catch(InterruptedException e) {}
}
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.*;
Scale an Image 61
Real's HowTo PDF version
}
}
}
Example :
Input:
Ouput:
Fade an image
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0249.html
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.net.*;
Fade an image 62
Real's HowTo PDF version
f.setLevel(level);
fis = new FilteredImageSource(img.getSource(), f) ;
Fade an image 63
Real's HowTo PDF version
sleep(delay);
fadeApplet.fadeIt();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
public AlphaFilter() {
canFilterIndexColorModel = true;
}
Try it here.
Rotate an image
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0248.html
The following snippet rotates an image (90 degrees). The applet assumes the dimension 32x32 for the image.
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import java.net.*;
Rotate an image 64
Real's HowTo PDF version
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.*;
Rotate an image 65
Real's HowTo PDF version
}
catch (Exception e) {
e.printStackTrace();
}
}
Rotate an image 66
Real's HowTo PDF version
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();
}
else
g.drawImage(buffImage, x, y, this);
}
import java.applet.Applet;
import java.net.*;
// TILE BACKGROUND
// in the HTML use :
<HTML>
<TABLE><TR><TD>
<APPLET CODE=Tile.class WIDTH=150 HEIGHT=150>
<PARAM NAME="bgImage" VALUE="images/jht.gif">
</APPLET>
</HMTL>
Try it here.
[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.*;
img1 = Toolkit.getDefaultToolkit().getImage(n1);
img2 = Toolkit.getDefaultToolkit().getImage(n2);
tracker.addImage(img1,0);
tracker.addImage(img2,1);
tracker.waitForAll();
addMouseListener(this);
}
catch (Exception e) {
e.printStackTrace();
}
}
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 {
tgc = new ToggleGifCanvas
(new URL(getDocumentBase(),"images/gumby.gif"),
new URL(getDocumentBase(),"images/gumby2.gif"));
add(tgc);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Try it here.
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.*;
// the color we are looking for... Alpha bits are set to opaque
public int markerRGB = color.getRGB() | 0xFF000000;
[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;
int w = img.getWidth(null);
int h = img.getHeight(null);
int [] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(img,0,0,w,h,pixels,0,w);
try {
pg.grabPixels();
}
catch(InterruptedException ie) {
ie.printStackTrace();
}
// 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.*;
implements ActionListener{
Image [] img;
int index = 0;
int maxImg;
boolean working = false;
Button b;
MediaTracker tracker;
this.animationApplet = a;
this.delay = delay;
}
From here, individual pixel can be accessed via the pixels array.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage
...
int c = image.getRGB(x,y);
int red = (c & 0x00ff0000) >> 16;
int green = (c & 0x0000ff00) >> 8;
int blue = c & 0x000000ff;
// and the Java Color is ...
Color color = new Color(red,green,blue);
Do "rubber-band" drawing
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0251.html
import java.applet.*;
import java.awt.*;
import java.util.Vector;
Do "rubber-band" drawing 85
Real's HowTo PDF version
}
}
}
Do "rubber-band" drawing 86
Real's HowTo PDF version
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]);
import java.awt.image.*;
import java.awt.*;
import java.applet.*;
double xincdash=(x2-x1)/(linelength/(dashlength));
double yincdash=(y2-y1)/(linelength/(dashlength));
int counter=0;
for (double i=0;i<linelength-dashlength;i+=dashlength+spacelength){
g.drawLine((int) (x1+xincdashspace*counter),
(int) (y1+yincdashspace*counter),
(int) (x1+xincdashspace*counter+xincdash),
(int) (y1+yincdashspace*counter+yincdash));
counter++;
}
if ((dashlength+spacelength)*counter<=linelength)
g.drawLine((int) (x1+xincdashspace*counter),
(int) (y1+yincdashspace*counter),
x2,y2);
}
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;
colors.put("green", Color.green);
colors.put("red", Color.red);
colors.put("blue", Color.blue);
colors.put("yellow", Color.yellow);
colors.put("magenta", Color.magenta);
colors.put("cyan", Color.cyan);
colors.put("orange", Color.orange);
colors.put("pink", Color.pink);
colors.put("white", Color.white);
colors.put("black", Color.black);
// "value-color,value-color,..."
StringTokenizer t = new StringTokenizer(at, ",");
String s;
int i;
while (t.hasMoreTokens()) {
s = t.nextToken();
i = s.indexOf('-');
value = Float.valueOf(s.substring(0, i)).floatValue();
c.addSlice(value, (Color)colors.get(s.substring(i + 1)));
}
resize(c.getMinimumSize().width, c.getMinimumSize().height);
add("Center", c);
}
}
if(gfxBuff == null) {
gfxBuff = createImage(d.width, d.height);
offGraphics = gfxBuff.getGraphics();
offGraphics.setColor(getBackground());
// 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>
<PARAM NAME="depth" VALUE="30">
<PARAM NAME="width" VALUE="120">
<PARAM NAME="values" VALUE="1-red,5-green,7-blue">
</APPLET>
<TD>
<TABLE>
<TR><TD>item 1<TD BGCOLOR="#FF0000">
Try it here
It seems that drawRoundRect(.) is 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);
}
}
[JDK1.02]
import java.applet.*;
import java.awt.*;
[JDK11]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
[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"))
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);
}
Display a TIF
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0605.html
The regular JDK can only deal with JPG, GIF, BMP or PNG file with the package ImageIO, see this HowTo.
To deal with TIF file, you must use the JAI (Java Advanced Imaging) package.
This example will display a given TIF file. It will also display other types (JPG,...) by detecting the type.
import 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.
See also : Convert many single-page TIF into one multi-page TIF
This HowTo takes a list of single-page TIF and convert them into one multi-page TIF.
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.awt.image.BufferedImage;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import javax.media.jai.PlanarImage;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.SeekableStream;
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;
System.out.println("Done.");
}
}
http://www.rgagnon.com/javadetails/../javadetails/java-0601.html
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
You need to do something to transform an Image to BufferedImage. But since BufferedImage extends Image,
so there isn't a back-conversion, it's not needed.
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.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.PixelGrabber;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
/**
* This utility loads a given TIF and try to detect if it's
* blank or not.
*
* We create in-memory image and then calculate the standard
* deviation of the color information. If a certain value is not
* reached then we assume that the image is mainly uniform and
* probably blank. The threshold value is an estimate. Depending
* the source of the TIF this value can be higher. For example,
* TIF from a FAX machine or a scanner can be dirty, with hair/dust presence,
* but with no content.
*
* jai_core.jar and jai_codec.jar are required.
* http://java.sun.com/products/java-media/jai/index.jsp
*
* @author http://www.rgagnon.com/howto.html
*/
/**
* Creates an Image from a byte array
* @param data
* @return Image
* @throws Exception
*/
public static Image load(byte[] data) throws Exception {
Image image = null;
SeekableStream stream = new ByteArraySeekableStream(data);
String[] names = ImageCodec.getDecoderNames(stream);
ImageDecoder dec =
/**
* Converts an Image to a BufferedImage
* @param im une Image
* @return BufferedImage
*/
public static BufferedImage imageToBufferedImage(Image im) {
BufferedImage bi = new BufferedImage
(im.getWidth(null),im.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics bg = bi.getGraphics();
bg.drawImage(im, 0, 0, null);
bg.dispose();
return bi;
}
/**
* Check if an Image is blank or not
* Computes the standard deviation based on the color information
* @param bi bufferedimage
* @return true it's blank
*/
public static boolean isBlank(BufferedImage bi) throws Exception {
long count = 0;
long total = 0;
double totalVariance = 0;
double stdDev = 0;
int height = bi.getHeight();
int width = bi.getWidth();
/**
* Accept on the command line the path to a TIF file
*
* Returns an errorlevel based on the analysis
* 0 - blank
* 1 - not blank
* 2 - IO error
*
* @param args path vers complet vers un PROPS
*/
public static void main(String[] args) {
try {
if (args.length==0) {
System.out.println("Missing parameter.");
System.exit(FAILURE);
}
String path = args[0];
FileInputStream in = new FileInputStream(path);
FileChannel channel = in.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int)channel.size());
channel.read(buffer);
Image image = load(buffer.array());
BufferedImage bufferedImage = imageToBufferedImage(image);
boolean isBlank = BlankDetection.isBlank(bufferedImage);
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You pass one or many tif files as argument and corresponding PDF are produced.
Multipage TIF are supported. TIF are resized to fit a letter-page dimension.
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
++pages;
}
}
catch (Throwable e) {
System.out.println("Exception " + tiff + " page "
+ (c + 1) + " " + e.getMessage());
}
}
ra.close();
document.close();
}
catch (Throwable e) {
e.printStackTrace();
}
System.out.println("done");
}
}
}
http://java.sun.com/javase/technologies/desktop/media/jai/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.image.RenderedImage;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageCodec;
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.
The package java.util.concurrent.TimeUnit; provides a class to make conversion between milliseconds and
days easier.
import java.util.*;
import java.util.concurrent.TimeUnit;
/*
testing
*/
public static void main(String[] args) {
java.text.SimpleDateFormat sdf =
new java.text.SimpleDateFormat("yyyyMMdd");
Calendar augustfirst2008 = Calendar.getInstance();
augustfirst2008.set(2008, Calendar.AUGUST, 1); // 2008-08-01
Calendar today = Calendar.getInstance(); // today
System.out.println
(getDifference(augustfirst2008,today,TimeUnit.DAYS)
+ " day(s) between "
+ sdf.format(augustfirst2008.getTime()) + " and "
+ sdf.format(today.getTime()));
}
/*
* output :
* 921 day(s) between 20080801 and 20110208
*/
}
Actually, the Calendar class provides a method to that very simply. For a given Calendar or
GregorianCalendar object :
calObject.getActualMaximum(calobject.DAY_OF_MONTH)
In the Java API documentation there is a note saying that The version (getActualMaximum()) of this function
on Calendar uses an iterative algorithm to determine the actual maximum value for the field. There is almost
always a more efficient way to accomplish this (in most cases, you can simply return getMaximum()).
GregorianCalendar overrides this function with a more efficient implementation. So it looks like it's a lot
more efficient to call getActualMaximum from a GregorianCalendar object than a Calendar object. (Thanks to P.
Harris for the tip)
gregCalObject.getActualMaximum(gregCalObject.DAY_OF_MONTH)
Validate a date
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0099.html
Using DateFormat
import java.text.*;
DateFormat.getDateInstance
(DateFormat.SHORT); // YYYY-MM-DD
df.setLenient(false); // this is important!
df.parse(date);
}
catch (ParseException e) {
return false;
}
catch (IllegalArgumentException e) {
return false;
}
return true;
}
Using SimpleDateFormat
package com.rgagnon.howto;
import java.text.*;
Using GregorianCalendar
import java.util.*;
add() and roll() are used to add or substract values to a Calendar object.
You specify which Calendar field is to be affected by the operation (Calendar.YEAR, Calendar.MONTH,
Calendar.DATE).
add() adds or substracts values to the specified Calendar field, the next larger field is modified when the result
makes the Calendar "rolls over".
import java.util.Calendar;
import java.text.SimpleDateFormat;
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 year while add() substract the
YEAR field for the correct result.
import java.util.Calendar;
import java.text.SimpleDateFormat;
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;
Compare 2 dates
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0104.html
import java.util.*;
import java.util.*;
import java.text.*;
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()));
}
}
import java.util.Date;
import java.util.Locale;
import java.util.Calendar;
import java.text.SimpleDateFormat;
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.*;
import java.util.*;
public class Dtest {
public static void main(String args[]) {
SimpleDateFormat df = (SimpleDateFormat)
DateFormat.getDateInstance(DateFormat.SHORT);
System.out.println("The short date format is " + df.toPattern());
Locale loc = Locale.ITALY;
df = (SimpleDateFormat)
DateFormat.getDateInstance(DateFormat.SHORT, loc);
System.out.println("The short date format is " + df.toPattern());
}
}
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. and 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) julian
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--;
today.get(Calendar.DATE)});
System.out.println("Julian date for today : " + todayJulian);
results = fromJulian(todayJulian);
System.out.println
("... back to calendar : " + results[0] + " " + results[1]
+ " " + results[2]);
// THIRD TEST
double date1 = toJulian(new int[]{2005,1,1});
double date2 = toJulian(new int[]{2005,1,31});
System.out.println("Between 2005-01-01 and 2005-01-31 : "
+ (date2 - date1) + " days");
/*
expected output :
Julian date for May 23, 1968 : 2440000.0
... back to calendar 1968 5 23
Julian date for today : 2453487.0
... back to calendar 2005 4 26
Between 2005-01-01 and 2005-01-31 : 30.0 days
*/
}
}
There is a lot of variation around the idea of a "Julian date". You can have the Modified Julian Date (JD) or
the Truncated Julian Date (TJD). The main difference is the starting for counting the days.
Before Y2K, many applications (especially mainframe systems) were storing dates in a format called "the
Julian format". This format is a 5 digit number, consisting of a 2 digit year and a 3 digit day-of-year number.
For example, 17-July-1998 is stored as 98221, since 17-July is the 221th day of the year. This format is not
really useful since Y2K! The main reason for using the 5-digits Julian date was to save disk space and still
have a format easy to use to handle. dates.
A variation of this idea is to used the first four digits for the year and 3 digits for day-of-year, 17-July-1998
will be represented by 1998221.
This is a very simple format which can be manipulated easily from Java.
import java.util.Calendar;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
return sb.append(cal.get(Calendar.YEAR))
.append(String.format("%03d", cal.get(Calendar.DAY_OF_YEAR)))
.toString();
}
/*
* output :
* Sun Aug 09 00:00:00 EDT 1998
* 1998221
*/
}
}
import java.util.GregorianCalendar;
import java.util.Calendar;
Given a time in ms, this HowTo will output the long form "<w> days, <x> hours, <y> minutes and (z)
seconds" and the short form "<dd:>hh:mm:ss".
private TimeUtils() {
}
/**
* converts time (in milliseconds) to human-readable format
* "<w> days, <x> hours, <y> minutes and (z) seconds"
*/
public static String millisToLongDHMS(long duration) {
StringBuffer res = new StringBuffer();
long temp = 0;
if (duration >= ONE_SECOND) {
temp = duration / ONE_DAY;
if (temp > 0) {
duration -= temp * ONE_DAY;
res.append(temp).append(" day").append(temp > 1 ? "s" : "")
.append(duration >= ONE_MINUTE ? ", " : "");
}
/**
* converts time (in milliseconds) to human-readable format
* "<dd:>hh:mm:ss"
*/
public static String millisToShortDHMS(long duration) {
String res = "";
duration /= ONE_SECOND;
int seconds = (int) (duration % SECONDS);
duration /= SECONDS;
int minutes = (int) (duration % MINUTES);
duration /= MINUTES;
int hours = (int) (duration % HOURS);
int days = (int) (duration / HOURS);
if (days == 0) {
res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
} else {
res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
}
return res;
}
System.out.println(millisToLongDHMS(42 * ONE_DAY));
/*
output :
0 second
5 seconds
1 day, 1 hour
1 day and 2 seconds
1 day, 1 hour, 2 minutes
4 days, 3 hours, 2 minutes and 1 second
5 days, 4 hours, 1 minute and 23 seconds
42 days
*/
System.out.println(millisToShortDHMS(123));
System.out.println(millisToShortDHMS((5 * ONE_SECOND) + 123));
System.out.println(millisToShortDHMS(ONE_DAY + ONE_HOUR));
System.out.println(millisToShortDHMS(ONE_DAY + 2 * ONE_SECOND));
System.out
.println(millisToShortDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
System.out.println(millisToShortDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
+ (2 * ONE_MINUTE) + ONE_SECOND));
System.out.println(millisToShortDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
+ ONE_MINUTE + (23 * ONE_SECOND) + 123));
System.out.println(millisToShortDHMS(42 * ONE_DAY));
/*
output :
00:00:00
00:00:05
1d01:00:00
1d00:00:02
1d01:02:00
4d03:02:01
5d04:01:23
42d00:00:00
*/
}
}
Using java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit;
...
/**
* converts time (in milliseconds) to human-readable format
* "<dd:>hh:mm:ss"
*/
public static String millisToShortDHMS(long duration) {
String res = "";
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration)
- TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
if (days == 0) {
res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
else {
res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
}
return res;
}
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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
try {
conn = new Socket(ATOMICTIME_SERVER, ATOMICTIME_PORT);
in = new BufferedReader
(new InputStreamReader(conn.getInputStream()));
String atomicTime;
while (true) {
if ( (atomicTime = in.readLine()).indexOf("*") > -1) {
break;
}
}
System.out.println("DEBUG 1 : " + atomicTime);
String[] fields = atomicTime.split(" ");
GregorianCalendar calendar = new GregorianCalendar();
// deals with the timezone and the daylight-saving-time (you may need to adjust this)
// here i'm using "EST" for Eastern Standart Time (to support Daylight Saving Time)
TimeZone tz = TimeZone.getTimeZone("EST"); // or .getDefault()
int gmt = (tz.getRawOffset() + tz.getDSTSavings()) / 3600000;
System.out.println("DEBUG 2 : " + gmt);
/*
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;
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));
/*
* output example :
* 21:01 between 14:00-14:26?
* false
*
*/
}
}
SYSTEMTIME st;
GetLocalTime(&st);
st.wHour = hour;
st.wMinute = minutes;
SetLocalTime(&st);
}
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.
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.text.DateFormatSymbols;
import java.util.Locale;
System.out.println(DateUtils.getMonthName(1));
System.out.println(DateUtils.getMonthName(1, new Locale("it")));
System.out.println
(DateUtils.getDayName(java.util.Calendar.SUNDAY, Locale.getDefault()));
/*
* output :
* january
* gennaio
* sunday
*/
}
}
import java.util.Calendar;
import java.util.GregorianCalendar;
// using GregorianCalendar
public static boolean isLeap0(int year) {
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.YEAR, year);
return cal.isLeapYear(cal.get(Calendar.YEAR));
}
// using a Calendar
public static boolean isLeap1(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
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.*;
Environment 141
Real's HowTo PDF version
}
else if ( (OS.indexOf("nt") > -1)
|| (OS.indexOf("windows 2000") > -1 )
|| (OS.indexOf("windows xp") > -1) ) {
// thanks to JuanFran for the xp fix!
p = r.exec( "cmd.exe /c set" );
}
else {
// 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.
[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 {
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:
Java is prepending itself! That confused me--- and broke my exec from ant.
Belorussian translation
JDK1.5
System.getenv() is back!
import java.util.*;
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
<<
# end ---- JAR support ----------
doc : $(CLASSFILES)
install :
copy $CLASSESFILE $(DEST)
clean:
del $(CLASSFILES)
This HowTo is obsolete. Check this one instead : Detect browser type from an Applet
One way is to instanciate a known browser-specific method and catch the Exception if not found
import java.applet.*;
For an application, by looking at the string representation of the getDefaultToolkit() method, we detect the
JVM type
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=&{archiveToBeUsed}; >
</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.
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.
Ant
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;
See this HowTo. This technique relies on the compiler optimization which remove code in the bytecode
generated because it will never be executed.
In Netscape
In application
NOTE: This can be useful if you want to trim a JAR to include only classes actually used.
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 :
The default value for the minimum is 2Mb, for the maximum it's 64Mb.
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
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>
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();
}
}
}
System.getProperty("java.vm.name")
.toLowerCase().indexOf("64") >= 0;
}
// probably 32bit
return false;
}
}
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
-client KNOWN
-server KNOWN
-server KNOWN
-client KNOWN
If the JRE is properly installed on Windows, informations about each version are stored in the registry. The
installation process installs a special java.exe in the system PATH. So you don't need to alter you PATH
because this special java.exe will find the current JRE. From a command line, type java -version to display the
current jre version installed.
With release 1.6, it's now possible to select a different JRE installation than the last one without any registry
modification.
It's probably the 1.6 JRE that will be used since it's the last installed.
If the bytecode is incompatible with the given JRE then .. it won't work, of course.
You can always give the complete path to use a specific installation. Launching the JVM this way does not
use the registry setting at all.
This solution use the RuntimeMXBean. The name of the bean contains the pid (ex. 12345@localhost).
Warning : The returned name string can be any arbitrary string and a Java virtual machine implementation can
choose to embed platform-specific useful information in the returned name string.
private SystemUtils() {}
javax.swing.JOptionPane.showConfirmDialog((java.awt.Component)
null, msg, "SystemUtils", javax.swing.JOptionPane.DEFAULT_OPTION);
The result is
class JavaHowTo {
public native long getCurrentProcessId();
static {
System.loadLibrary("jni2");
}
}
#include "stdafx.h"
#include <process.h>
#include "JavaHowTo.h"
// return GetCurrentProcessId();
return getpid();
}
Set default value for Java property or JVM option (system wide)
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-set-java-properties-system-wide.html
If you find yourself using the same options over and over before laucing a java process, you can set up a
special environment variable to contain your default options and the JVM will pick up the the values.
If the Java process is launch via java.exe then the environment variable is called _JAVA_OPTIONS,
e.g. In Windows:
In Linux:
ref : http://java.sun.com/j2se/1.5.0/docs/guide/2d/flags.html
If the Java process is launch via javaw.exe (Applet) then the environment variable is called
_JPI_VM_OPTIONS.
For example :
_JPI_VM_OPTIONS = -Dsome.property=true
For a Java Web Start process (javaws.exe), the environment variable is called JAVAWS_VM_ARGS.
For example :
JAVAWS_VM_ARGS = -Dsome.property=true
ref : http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/plugin.html#gcexdd
If you want to detect if your program is running in debug mode (ex. Eclipse).
User level
The deployment.properties file is used for storing and retrieving deployment configuration properties
shown in the Java Control Panel. The properties are also used for customizing runtime behavior for both Java
Plug-in and Java Web Start.
Set default value for Java property or JVM option (system wide) 163
Real's HowTo PDF version
On the Windows, <User Application Data Folder> is typically C:\Users\<your username>\AppData (or
%APPDATA%) which is hidden by default.
#deployment.properties https://gist.githubusercontent.com/MyITGuy/9628895/raw/3727348918e036ba
# Security Tab
# Enable Java content in the browser
deployment.webjava.enabled=true
deployment.webjava.enabled.locked
# Security Level
deployment.security.level=MEDIUM
deployment.security.level.locked
# Advanced Tab
# Debugging\Enable tracing
deployment.trace=false
deployment.trace.locked
# Debugging\Enable logging
deployment.log=false
deployment.log.locked
# Debugging\Show applet lifecycle exceptions
deployment.javapi.lifecycle.exception=false
deployment.javapi.lifecycle.exception.locked
# Java console
deployment.console.startup.mode.locked
deployment.console.startup.mode=HIDE
# Default Java for browsers\Microsoft Internet Explorer
deployment.browser.vm.iexplorer=true
deployment.browser.vm.iexplorer.locked
# Default Java for browsers\Mozilla family
deployment.browser.vm.mozilla.locked
deployment.browser.vm.mozilla=false
# Java Plug-in\Enable the next-generation Java Plug-in (requires browser restart)
# This must be done by executing one of the following commands as an administrator:
# [Disable] - {JREInstallPath}\bin\ssvagent.exe -high -jpisetup -old
# [Enable] - {JREInstallPath}\bin\ssvagent.exe -high -jpisetup -new
# Shortcut Creation
deployment.javaws.shortcut=ASK_IF_HINTED
deployment.javaws.shortcut.locked
# JNLP File/MIME Association
deployment.javaws.associations=ASK_USER
deployment.javaws.associations.locked
# Application Installation
deployment.javaws.install=IF_HINT
deployment.javaws.install.locked
#JRE Auto-Download
deployment.javaws.autodownload=NEVER
deployment.javaws.autodownload.locked
# Security Execution Environment\Enable granting elevated access to signed apps
deployment.security.SSLv2Hello=false
deployment.security.SSLv2Hello.locked
# Advanced Security Settings\Use SSL 3.0
deployment.security.SSLv3=true
deployment.security.SSLv3.locked
# Advanced Security Settings\Use TLS 1.0
deployment.security.TLSv1=true
deployment.security.TLSv1.locked
# Advanced Security Settings\Use TLS 1.1
deployment.security.TLSv1.1=false
deployment.security.TLSv1.1.locked
# Advanced Security Settings\Use TLS 1.2
deployment.security.TLSv1.2=false
deployment.security.TLSv1.2.locked
# Miscellaneous\Place Java icon in system tray
# Miscellaneous\Java Quick Starter
deployment.system.tray.icon=false
deployment.system.tray.icon.locked
# Screen: Your Java version is insecure. or Your Java version is out of date.
deployment.expiration.check.enabled=false
deployment.expiration.check.enabled.locked
#
deployment.capture.mime.types=true
deployment.capture.mime.types.locked
deployment.security.expired.warning=false
deployment.security.expired.warning.locked
deployment.user.security.exception.sites=C:\\WINDOWS\\Sun\\Java\\Deployment\\exception.sites
deployment.user.security.exception.sites.locked
# Java 7 Update 10
deployment.expiration.decision.10.10.2.locked
deployment.expiration.decision.10.10.2=later
deployment.expiration.decision.suppression.10.10.2.locked
deployment.expiration.decision.suppression.10.10.2=true
deployment.expiration.decision.timestamp.10.10.2.locked
deployment.expiration.decision.timestamp.10.10.2=2/28/2014 12\:1\:31
Example of a deployment.properties
#deployment.properties
deployment.webjava.enabled=true
deployment.security.level=MEDIUM
deployment.security.level.locked
deployment.user.security.exception.sites=c\:/Windows/Sun/Java/Deployment/exception.sites
The exception.sites file is a one URL per line list of sites that you want in the Exception Site List field
found in the Java Control Panel. Nothing else goes in this file.
System level
The deployment.config file is used for specifying the system-level deployment.properties in the
infrastructure. By default no deployment.config file exists, so no system-wide deployment.properties file
exists.
deployment.system.config=file\://ourserver.local/deploy/Sun/Java/Deployment/deployment.properti
deployment.system.config.mandatory=true
This example points to a deployment.properties file on a DFS path //ourserver.local/deploy/. Since the
property deployment.system.config.mandatory=true then if the deployment.properties file is not found, then
nothing is allowed to run.
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
directory under (the one containing manifest.txt), we built the jar with :
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
Wrap a Java bean in a COM object (using Sun ActiveX bridge) 168
Real's HowTo PDF version
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.
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.*;
"\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\"
+ "Explorer\\Shell Folders\" /v Personal";
private static final String CPU_SPEED_CMD = REGQUERY_UTIL +
"\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\""
+ " /v ~MHz";
private static final String CPU_NAME_CMD = REGQUERY_UTIL +
"\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\""
+ " /v ProcessorNameString";
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;
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter();
}
String getResult() {
return sw.toString();
}
}
For a better way to access the Registry, see Read/Write Windows Registry using JNA.
The JDK contains the required code (java.util.prefs.WindowsPreferences) to access the Windows registry but
to preserve the "purity" of Java, the code is declared as private so it's not visible. The trick is to use reflection
to access private methods defined in the WindowsPreference class.
Remember : This code is a hack and may break anytime. A better alternative is to use JNA.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
static {
try {
regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
new Class[] { int.class, byte[].class, int.class });
regOpenKey.setAccessible(true);
regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
new Class[] { int.class });
regCloseKey.setAccessible(true);
regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
new Class[] { int.class, byte[].class });
regQueryValueEx.setAccessible(true);
regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
new Class[] { int.class, int.class, int.class });
regEnumValue.setAccessible(true);
regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",
new Class[] { int.class });
regQueryInfoKey.setAccessible(true);
regEnumKeyEx = userClass.getDeclaredMethod(
"WindowsRegEnumKeyEx", new Class[] { int.class, int.class,
int.class });
regEnumKeyEx.setAccessible(true);
regCreateKeyEx = userClass.getDeclaredMethod(
"WindowsRegCreateKeyEx", new Class[] { int.class,
byte[].class });
regCreateKeyEx.setAccessible(true);
regSetValueEx = userClass.getDeclaredMethod(
"WindowsRegSetValueEx", new Class[] { int.class,
byte[].class, byte[].class });
regSetValueEx.setAccessible(true);
regDeleteValue = userClass.getDeclaredMethod(
"WindowsRegDeleteValue", new Class[] { int.class,
byte[].class });
regDeleteValue.setAccessible(true);
regDeleteKey = userClass.getDeclaredMethod(
"WindowsRegDeleteKey", new Class[] { int.class,
byte[].class });
regDeleteKey.setAccessible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
private WinRegistry() { }
/**
* Read a value from key and value name
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @param valueName
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static String readString(int hkey, String key, String valueName)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readString(systemRoot, hkey, key, valueName);
}
else if (hkey == HKEY_CURRENT_USER) {
return readString(userRoot, hkey, key, valueName);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Read value(s) and value name(s) form given key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s) plus the value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static Map<String, String> readStringValues(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringValues(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringValues(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Read the value name(s) from a given key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> readStringSubKeys(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringSubKeys(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringSubKeys(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Create a key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void createKey(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int [] ret;
if (hkey == HKEY_LOCAL_MACHINE) {
ret = createKey(systemRoot, hkey, key);
regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
}
else if (hkey == HKEY_CURRENT_USER) {
ret = createKey(userRoot, hkey, key);
regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
if (ret[1] != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
}
}
/**
* Write a value in a given key/value name
* @param hkey
* @param key
* @param valueName
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue
(int hkey, String key, String valueName, String value)
/**
* Delete a given key
* @param hkey
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteKey(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteKey(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteKey(userRoot, hkey, key);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + " key=" + key);
}
}
/**
* delete a value from a given key/value name
* @param hkey
* @param key
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteValue(systemRoot, hkey, key, value);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteValue(userRoot, hkey, key, value);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + " key=" + key + " value=" + value);
}
}
// =====================
private static String readString(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
if (handles[1] != REG_SUCCESS) {
return null;
}
byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
new Integer(handles[0]), toCstr(value) });
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return (valb != null ? new String(valb).trim() : null);
}
regSetValueEx.invoke(root,
new Object[] {
new Integer(handles[0]), toCstr(valueName), toCstr(value)
});
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
}
// utility
private static byte[] toCstr(String str) {
byte[] result = new byte[str.length() + 1];
How to use it :
package com.rgagnon.howto;
WinRegistry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\AcroRd32.exe",
"");
System.out.println("Acrobat Reader Path = " + value);
/*
this code is broken under win7 64 :-( 20130112
WinRegistry.createKey(
WinRegistry.HKEY_CURRENT_USER, "SOFTWARE\\rgagnon.com");
WinRegistry.writeStringValue(
WinRegistry.HKEY_CURRENT_USER,
"SOFTWARE\\rgagnon.com",
"HowTo",
"java");
// WinRegistry.deleteValue(
// WinRegistry.HKEY_CURRENT_USER,
// "SOFTWARE\\rgagnon.com", "HowTo");
// WinRegistry.deleteKey(
// WinRegistry.HKEY_CURRENT_USER,
// "SOFTWARE\\rgagnon.com\\");
System.out.println("Done." );
}
}
The output :
Using regedit
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
pause
Output example :
C:\temp>findjava.cmd
Java Version = 1.6
Java home path (per registry) = C:\\applications\\dev\\jre6
Note :
The above script returns the default JVM if the PATH variable does not override it!
Oracle client installation is famous to force an outdated Java at the beginning of the PATH. This one-liner
displays the java.exe (if any) found in the PATH :
The java.exe in the system32 relies on the CurrentVersion registry setting to determine which registry key to
use to look up the location of the Java RE.
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;
Using TASKLIST.EXE
The Microsoft TASKLIST.EXE is used to dump the list of the currently running processes. It is similar to
tasklist window but for the console.
From a Java program, we are launching TASKLIST.EXE and capture its output.
Note : TASKLIST.EXE is not included the HOME edition of XP. But you can download it from Web, for
example : http://www.computerhope.com/download/winxp.htm.
import java.io.*;
import java.util.*;
}
input.close();
}
catch (Exception err) {
err.printStackTrace();
}
return processes;
}
while (it.hasNext()) {
result += it.next() +",";
i++;
if (i==10) {
result += "\n";
i = 0;
}
}
msgBox("Running processes : " + result);
}
Thanks to M. Korbel
Using a VBS
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;
while ((line = input.readLine()) != null) {
processList.add(line);
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
return processList;
}
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;
}
WMIC is a powerful Windows utility. You can use to know if a particular process is running or not.
This example detects if a Tomcat instance (can be anything, ex: Apache or Excel) is running from a batch file.
@echo off
wmic process list brief | find /i "tomcat.exe"
set result=%ERRORLEVEL%
if "%result%"=="1" echo "not running"
if "%result%"=="0" echo "running"
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
try {
ProcessBuilder builder = new ProcessBuilder(command);
Process process = builder.start();
is = process.getInputStream();
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.
Finally, the JRE will only use the registry if it is run from the Windows system directory (ex .
C:/winnt/system32/java.exe). This would happen if the user just types "java" on the commandline in some
random directory, because the system directory is always in the user's path. In this situation, the java.exe will
locate the current Java installation by looking at the registry key
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.
This command file queries the registry to find out the path of the current JRE installation and then launch it to
display the version found .
@echo off
cls
setlocal ENABLEEXTENSIONS
set KEY_NAME="HKLM\SOFTWARE\JavaSoft\Java Runtime Environment"
set VALUE_NAME=CurrentVersion
::
:: get the current version
::
FOR /F "usebackq skip=2 tokens=3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
set ValueValue=%%A
)
if defined ValueValue (
@echo the current Java runtime is %ValueValue%
) else (
@echo %KEY_NAME%\%VALUE_NAME% not found.
goto end
)
set JAVA_CURRENT="HKLM\SOFTWARE\JavaSoft\Java Runtime Environment\%ValueValue%"
set JAVA_HOME=JavaHome
::
:: get the javahome
::
FOR /F "usebackq skip=2 tokens=3*" %%A IN (`REG QUERY %JAVA_CURRENT% /v %JAVA_HOME% 2^>nul`) DO
set JAVA_PATH=%%A %%B
)
echo the path of the current Java JVM according to the registry is
echo %JAVA_PATH%
echo.
echo now if we try it :
"%JAVA_PATH%\bin\java.exe" -version
:end
[j.cmd XP version]
@echo off
cls
setlocal ENABLEEXTENSIONS
set KEY_NAME="HKLM\SOFTWARE\JavaSoft\Java Runtime Environment"
set VALUE_NAME=CurrentVersion
::
:: get the current version
::
FOR /F "usebackq skip=4 tokens=3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
set ValueValue=%%A
)
if defined ValueValue (
::
:: get the javahome
::
FOR /F "usebackq skip=4 tokens=3,4" %%A IN (`REG QUERY %JAVA_CURRENT% /v %JAVA_HOME% 2^>nul`) D
set JAVA_PATH=%%A %%B
)
echo the path of the current Java JVM according to the registry is
echo %JAVA_PATH%
echo.
echo now if we try it :
"%JAVA_PATH%\bin\java.exe" -version
:end
Output :
>j.cmd
the current Java runtime is 1.6
the path of the current Java JVM according to the registry is
C:\Program Files\Java\jre1.6.0_06
now if we try it :
java version "1.6.0_06"
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) Client VM (build 10.0-b22, mixed mode, sharing)
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.
import javax.swing.JFileChooser;
javax.swing.filechooser.FileSystemView;
import java.io.*;
private WindowsUtils() {}
reader.start();
process.waitFor();
reader.join();
if (p == -1)
return null;
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Desktop directory : "
+ getCurrentUserDesktopPath());
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter();
}
String getResult() {
return sw.toString();
}
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
private VBSUtils() { }
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
result = input.readLine();
input.close();
}
catch(Exception e){
e.printStackTrace();
}
return result;
}
See also :
Get Windows Desktop path using the registry
Get Windows "My Documents" path using FileSystemView.getDefaultDirectory()
import java.io.*;
private WindowsUtils() { }
// see note
private static final String WINDOWS_DESKTOP = "Desktop";
/**
* the current user desktop path
* @return the current user desktop path
*/
public static String getWindowsCurrentUserDesktopPath() {
return System.getenv("userprofile") + "/" + WINDOWS_DESKTOP ;
}
/**
* Create an Internet shortcut on User's Desktop no icon specified
/**
* Create an Internet shortcut on User's Desktop, icon specified
* @param name name of the shortcut
* @param target URL
* @param icon URL (ex. http://www.server.com/favicon.ico)
* @throws IOException
*/
public static void createInternetShortcutOnDesktop
(String name, String target, String icon)
throws IOException
{
String path = getWindowsCurrentUserDesktopPath() + "/"+ name + ".URL";
createInternetShortcut(name, path, target, icon);
}
/**
* Create an Internet shortcut
* @param name name of the shortcut
* @param where location of the shortcut
* @param target URL
* @param icon URL (ex. http://www.server.com/favicon.ico)
* @throws IOException
*/
public static void createInternetShortcut
(String name, String where, String target, String icon)
throws IOException
{
FileWriter fw = new FileWriter(where);
fw.write("[InternetShortcut]\n");
fw.write("URL=" + target + "\n");
if (!icon.equals("")) {
fw.write("IconFile=" + icon + "\n");
}
fw.flush();
fw.close();
}
/**
* @param args
*/
public static void main(String[] args) throws IOException {
WindowsUtils.createInternetShortcutOnDesktop
("GOOGLE", "http://www.google.com");
}
}
NOTE:
Prior Vista, the desktop path for a localized Windows can be different. With an english version, it's Desktop
while for a french version, it's called Bureau.
The only way to get the right name is to ask the Registry, see this HowTo.
[Windows only]
To detect if an application is running in a Remote Desktop session, you can call the Windows API
GetSystemMetrics. The GetSystemMetrics() function will return a non-zero value with a
SM_REMOTESESSION parameter value if the application is associated with a client terminal session.
In Java, you need to use JNI (Java Native Interface) to call this Windows native API. Native Call is an Open
Source project which provide an easy way to that.
http://johannburkard.de/software/nativecall/
All you need is 2 jars (nativecall-0,4,1.jar and nativeloader-200505172341.jar) plus 1 DLL (NativeCall.dll) in
your classpath.
When running from Eclipse, the DLL should be in the bin directory of your application.
import java.io.IOException;
import com.eaio.nativecall.IntCall;
import com.eaio.nativecall.NativeCall;
private WindowsUtils() {}
An easy way is to check the Windows environment variable sessionname. The value of this environment
variable will be 'Console' for a normal, local session. For an Remote Desktop session it will contain the phrase
'RDP'.
Note that environment varialbe values are read at the JVM startup. So if the JVM process was started by a
console session, but then accessed by an RDP session, further calls to System.getenv("sessionname") still
return 'Console'
The easiest way is to query the environment variable SESSIONNAME. The value starts with ICA... in a Citrix
session, RDP if in remote desktop session or Console if directly on a workstation.
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
newMethod
Returns:
value
Table(s):
employee address
firstname city
lastname country
/*
* 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
* otherwise.
*/
public boolean inMethod() {
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 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 the <code>Tag</code> representation of this custom
* tag, return its string representation.
/**
* 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 :
Run the javadoc tool using the -taglet and -tagletpath options. For example, if your taglet class file is defined
to be in package com.rgagnon.taglet and is stored in C:\taglets\com\rgagnon\taglet\Table.class, then you
should set tagletpath to C:\taglets. This example calls javadoc on package com.package1, including Table
taglet tags:
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}
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>
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:
• package-info.java - Can contain a package declaration, package annotations, package comments and
Javadoc tags. This file is new in JDK 5.0, and is preferred over package.html.
• package.html - Can contain only package comments and Javadoc tags, no package annotations.
See http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#packagecomment
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();
}
}
<record>
<date>2005-02-28T21:21:09</date>
<millis>1109643669328</millis>
<sequence>1</sequence>
<logger>TestLog</logger>
<level>WARNING</level>
<class>TestLog</class>
<method>main</method>
<thread>10</thread>
<message>my warning message</message>
</record>
<record>
<date>2005-02-28T21:21:09</date>
<millis>1109643669328</millis>
<sequence>2</sequence>
<logger>TestLog</logger>
<level>INFO</level>
<class>TestLog</class>
<method>main</method>
<thread>10</thread>
<message>my info message</message>
</record>
</log>
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();
}
}
Default values are defined in JRE_HOME/lib/logging.properties. To use a different properties file, you
specify a filename with the java.util.logging.config.file system property.
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.
JDK1.5+
[LogUtils.java]
class Test {
public void doit() {
System.out.println("*Howto Trace only 1 level\n" + LogUtils.getStack(1));
System.out.println("*Howto Trace only 10 levels\n" + LogUtils.getStack(10));
System.out.println("*Howto Trace no level (current)\n" + LogUtils.getStack(0));
}
}
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);
You put the properties file in the classpath and then from your code
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
It may be useful to change it on-the-fly for debugging purpose. You need to get the Log4J "root" Logger
and then change its "level".
...
setLogLevel("DEBUG");
...
setLogLevel("INFO");
...
root.setLevel(org.apache.log4j.Level.DEBUG);
}
else {
root.setLevel(org.apache.log4j.Level.INFO);
}
}
You can enable the logging at the DEBUG level by simply setting 2 environment variable.
For example, if you have something using the Axis library to do a Web Service call, then
java.exe -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.defaultlog=debug
MyClassUsingAxis
will launch the program and output to stdout the debugging information.
...
...
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.showdatetime=true
-Dorg.apache.commons.logging.simplelog.log.httpclient.wire=debug
-Dorg.apache.commons.logging.simplelog.log.org.apache.commons.httpclient=debug
if (logger.isDebugEnabled()) {
Logger logpdfengine = Logger.getLogger("org.apache.pdfbox.util.PDFStreamEngine");
logpdfengine.setLevel(org.apache.log4j.Level.OFF);
}
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.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
Run it ... and the mydb.mdb file should appear in the current directory.
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
Here a variation on this subject, a method to return the name of the current running jar.
package com.rgagnon.howto;
/*
output :
*/
See these related HowTo's : Obtain from where a Class is loaded Get the "root" of an application
import java.util.jar.*;
import java.util.*;
import java.io.*;
private PackageUtils() {}
while(true) {
jarEntry=jarFile.getNextJarEntry ();
if(jarEntry == null){
break;
}
if((jarEntry.getName ().startsWith (packageName)) &&
/**
*
*/
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 :
Found com.sun.mail.handlers.image_jpeg.class
Found com.sun.mail.handlers.multipart_mixed.class
Found com.sun.mail.handlers.message_rfc822.class
[com.sun.mail.handlers.text_html.class,
com.sun.mail.handlers.text_xml.class, com
.sun.mail.handlers.image_jpeg.class,
, com.sun.mail.handlers.message_rfc822.class]
*/
}
}
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
package com.rgagnon;
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.*;
private JarUtils() {}
System.out.println("Specification-Version: "
+ JarUtils.getJarSpecificationVersion(javaMailJar));
System.out.println("Implementation-Version: "
+ JarUtils.getJarImplementationVersion(javaMailJar));
/*
* output :
* Specification-Version: 1.3
* Implementation-Version: 1.3.1
*/
}
}
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="." />
</target>
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"
basedir="."
includes="**/*.class"
manifest="MANIFEST.MF"
/>
</target>
<target name="cleanup">
<delete>
<fileset dir="." includes="**/*.class"/>
<fileset file="MANIFEST.MF"/>
</delete>
</target>
</project>
• Build and launch the Hello class
> ant buildHello
...
> java -jar hello.jar
Hello World
version : 1.00-b3
...
<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>
Specifying all the required jar in the classpath can be a pain. Here some techniques to set the classpath
definition automatically.
For Windows 2000 (or better), we need a set of 3 CMD files to scan a given directory and build the
classpath defintion with all the jars found.
main.cmd
@echo off
call buildclasspath.cmd .\lib
Echo The Classpath definition is %CLASSPATH%
...
java MyClass
buildclasspath.cmd
set _CLASSPATH=%CLASSPATH%
set CLASSPATH=%1
for %%i in ( %1\*.jar ) do call buildclasspath_append.cmd %%~fsi
: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
JDK6
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
The best solution when you have a jar is to try to include the required jars into the manifest declaration.
Manifest-Version: 1.0
Class-Path:
customer_client.jar
mailer_client.jar
signon_client.jar
The manifest file format restrictions mandated by the JDK requires the use of a space ' ' character as the line
continuation character, so ensure that your editor is not set up to trim trailing spaces on saves and exits.
The line with the Class-Path: header must end with a space character and each of the lines referencing the
client jar's should start and end with a space ' ' character and the manifest file as a whole must end with a
blank line.
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.
</target>
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>
To compile, make sure that you have the plugin.jar in the classpath (or Eclipse Build Path). This jar is
usually located in [JRE]/lib folder. During runtime, it's already included by the Java plugin so you don't
have to worry about that.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import netscape.javascript.*;
TextField tf;
Button b1;
JSObject win;
b1.addActionListener(this);
add(tf);add(b1);
}
Don't forget the MAYSCRIPT parameter in the APPLET tag, it's required since the Applet is using the
JSObject to interact with the Javascript.
<html>
<head>
<script>
function getUserAgent() {
return navigator.userAgent;
}
</script>
</head><body>
<applet code="GetUserAgent.class" MAYSCRIPT height=100 width=500></Applet>
</body>
</html>
Try it here
You need to parse the returned value to detect browser type. Look at this utility,
http://code.google.com/p/user-agent-utils/ or at this code : http://nerds.palmdrive.net/useragent/code.html
to get the idea.
When serving the HTML containing the Applet, you add the User-Agent as parameter for the Applet.
In a JSP/EL
<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>
The Java Console Window Log is also stored on disk. On the Windows plateform, it's in the folder :
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);
Internationalization 236
Real's HowTo PDF version
setSize(400,400);
}
SwingUtilities.invokeLater(t);
}
}
import java.util.*;
import javax.swing.*;
import java.text.*;
import java.util.*;
import java.util.*;
import javax.swing.*;
import java.util.*;
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);
if (!defaultDone) {
String rDef = rb.getString("rDefault");
if (rDef.equals("r0"))
r0.setSelected(true);
else if (rDef.equals("r1"))
r1.setSelected(true);
else
r2.setSelected(true);
defaultDone = true;
}
else {
if (localeChoosen == 0)
r0.setSelected(true);
else if (localeChoosen == 1)
r1.setSelected(true);
else
r2.setSelected(true);
}
// QUIT button
btnQuit = new JButton();
add(btnQuit);
// today label
today = new JLabel();
add(today);
//
r0.addActionListener(this);
r1.addActionListener(this);
r2.addActionListener(this);
btnQuit.addActionListener(this);
setSize(400,100);
setVisible(true);
}
i.initLocale();
i.initGUI();
i.initText();
i.pack();
}
};
SwingUtilities.invokeLater(t);
}
}
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 mechanism used for
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;
(rb.getString("today"), localeCurrent);
today.setText(mf.format(new Object [] { d }));
}
// 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);
}
[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 {
add(a);
add(b);
}
}
Output :
Java not enabled!
á \u00e0 Á \u00c0
à \u00e1 À \u00c1
â \u00e2 Â \u00c2
é \u00e9 É \u00c9
è \u00e8 È \u00c8
ê \u00ea Ê \u00ca
î \u00ee Î \u00ce
ç \u00e7 Ç \u00c7
The Indian rupee symbol ( ₹ HTML entity : ₹) is quite new (2010) so you need to make sure that
the Font that you are using has it. To display it from Java, you need to use Swing because AWT won't be able
to display it.
import java.awt.*;
import javax.swing.*;
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");
}
frame.getContentPane().add(panel,"Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
}
}
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;
private NumberUtils() {}
Localize a JFileChooser
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0299.html
Modern Swing release have now built-in ready-to-use translations for the JFileChooser. The language is
choosen based on the current Locale. So you don't have to do anything to display the JFileChooser in the right
language.
The user interface elements provided by the J2SE Runtime Environment 5.0, include Swing dialogs, messages
written by the runtime environment to the standard output and standard error streams, as well as messages
produced by the tools provided with the JRE. These user interface elements are localized into the following
languages:
Language Locale ID
Chinese (Simplified) zh_CN
Chinese (Traditional) zh_TW
English en
French fr
German de
Italian it
Japanese ja
Korean ko
Spanish es
Swedish sv
Sun Supported Locales
This example will show 2 radio buttons, one for english, one for french. Press the button to display a localized
JFileChooser according to the radio button selected.
Create 2 properties files, one for english , one for french (these files are incomplete but should be enough to
get you started).
[JFileChooser_en.properties]
Title=Real's JFileChooser
lookInLabelText=Current
filesOfTypeLabelText=File type
upFolderToolTipText=go up
[JFileChooser_fr.properties]
Title=JFileChooser de R\u00e9al
lookInLabelText=Courant
filesOfTypeLabelText=Type de fichier
upFolderToolTipText=Remonte
Then
[LocalizeJFileChooser.java]
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public LocalizeJFileChooser() {
group = new ButtonGroup();
add(button);
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
examine the Swing sources to get these values or check
http://www.gargoylesoftware.com/papers/plafdiff.html for
a list of them.
*/
Disable localization
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0418.html
By default, the JVM uses the current locale as defined by the OS. To bypass this configuration, you specify on
the command line the locale to be used :
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
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>
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 (String s : words) {
w.write(s + " ");
}
w.flush();
w.close();
}
catch(Exception e){
e.printStackTrace();
}
The output is :
Before :
Réal Real Raoul Rico
After :
Raoul Real Rico Réal
java.util.Arrays.sort(words);
by
java.util.Arrays.sort(words, java.text.Collator.getInstance(java.util.Locale.FRENCH));
// or
// java.util.Arrays.sort(words, java.text.Collator.getInstance());
Before :
Réal Real Raoul Rico
After :
Raoul Real Réal Rico
import java.util.Locale;
import java.text.Collator;
...
Locale loc = Locale.FRENCH;
sortArray(Collator.getInstance(loc), words);
...
In this code, we have 2 strings, "état" and "famille". We expect that "état" is before "famille". But
String.compareTo() will return that "famille" is before "état".
class Test {
public static void main(String args[]) {
String s1 = "état";
String s2 = "famille";
import java.text.Collator;
String s1 = "état";
String s2 = "famille";
// Collator c = Collator.getInstance(java.util.Locale.FRANCE);
Collator c = Collator.getInstance();
c.setStrength(Collator.PRIMARY);
Equality
To compare without taking into account the presence of accentued so that "é" == "e", we use a Collator.
import java.text.Collator;
// import java.util.Locale;
The following snippets remove from a String accented letters and replace them by their regular ASCII
equivalent.
These can be useful before inserting data into a database to made sorting easier.
Using java.text.Normalizer
We are calling the normalize(). If we pass à, the method returns a + ` . Then using a regular expression, we
clean up the string to keep only valid US-ASCII characters.
import java.text.Normalizer;
import java.util.regex.Pattern;
Using String.replaceAll()
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
}
}
The String.indexOf()
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.
As a bonus, here a method to convert a given string to uppercase with no accent. This can be useful in a
database field to simplify name searching with accent or not.
return null;
}
String txtUpper = txt.toUpperCase();
StringBuilder sb = new StringBuilder();
int n = txtUpper.length();
for (int i = 0; i < n; i++) {
char c = txtUpper.charAt(i);
int pos = UPPERCASE_UNICODE.indexOf(c);
if (pos > -1){
sb.append(UPPERCASE_ASCII.charAt(pos));
}
else {
sb.append(c);
}
}
return sb.toString();
}
In Java 1.6 you can use System.console() instead of System.out.println() to display accentuated characters to
console.
C:\temp>java Test
caractþres franþais : Ó Ú Ú
caractères français : à é é
When starting 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().
import java.io.*;
try {
ps = new PrintStream(System.out, true, "Cp850");
}
catch (UnsupportedEncodingException error) {
System.err.println(error);
System.exit(0);
}
ps.println(javaString);
}
}
System.out.println(java.nio.charset.Charset.defaultCharset().name());
}
}
>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.*;
w.flush();
}
w.close();
r.close();
System.exit(0);
}
}
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
A different (and simpler) approach is to take a given string and check if it's possible to encode it into ASCII.
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
/*
* output :
* Réal isPureAscii() : false
* Real isPureAscii() : true
*/
}
}
Another way is to use a regular expression, see this Javascript HowTo for a hint!
import java.text.DateFormatSymbols;
import java.util.Locale;
System.out.println(DateUtils.getMonthName(1));
System.out.println(DateUtils.getMonthName(1, new Locale("it")));
System.out.println
(DateUtils.getDayName(java.util.Calendar.SUNDAY, Locale.getDefault()));
/*
* output :
* january
* gennaio
* sunday
*/
}
}
[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();
}
}
);
}
IO 271
Real's HowTo PDF version
aTextArea.append(aString);
}
public void write(byte b[], int off, int len) throws IOException {
String aString = new String(b , off , len);
aTextArea.append(aString);
if (logFile) {
FileWriter aWriter = new FileWriter("error.log", true);
aWriter.write(aString);
aWriter.close();
}
}
}
import java.io.*;
Class.forName("unknown").newInstance();
// or this could be changed to:
// throw new Exception();
}
catch (Exception e) {
System.out.println(stack2string(e));
}
}
// 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);
You may want to suppress output done with the regular System.out but maintain the ability to write to the
original streams directly when necessary.
This example will print a given text file using the javax.print API.
• With cheap personal printer (at least with mine!), you cannot select many options... more than one copy and
page orientation (portrait or landscape) won't work.
• You need to set the "flavor" as AUTOSENSE so the content is sent as "OCTET-STREAM" even if it's
possible, according to the Javadoc, to set the "flavor" as UTF8 or US_ASCII. I believe this is a limitation of
the Windows platform implementation.
• You need to send a FORMFEED between each print job to eject the last page.
• A special class, PrintJobWatcher, is used to wait for the completion of a print job.
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
String defaultPrinter =
PrintServiceLookup.lookupDefaultPrintService().getName();
System.out.println("Default printer: " + defaultPrinter);
class PrintJobWatcher {
boolean done = false;
PrintJobWatcher(DocPrintJob job) {
job.addPrintJobListener(new PrintJobAdapter() {
public void printJobCanceled(PrintJobEvent pje) {
allDone();
}
public void printJobCompleted(PrintJobEvent pje) {
allDone();
}
public void printJobFailed(PrintJobEvent pje) {
allDone();
}
public void printJobNoMoreEvents(PrintJobEvent pje) {
allDone();
}
void allDone() {
synchronized (PrintJobWatcher.this) {
done = true;
System.out.println("Printing done ...");
PrintJobWatcher.this.notify();
}
}
});
}
public synchronized void waitForDone() {
try {
while (!done) {
wait();
}
} catch (InterruptedException e) {
}
}
}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
String defaultPrinter =
PrintServiceLookup.lookupDefaultPrintService().getName();
System.out.println("Default printer: " + defaultPrinter);
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
class PrintJobWatcher {
boolean done = false;
PrintJobWatcher(DocPrintJob job) {
job.addPrintJobListener(new PrintJobAdapter() {
public void printJobCanceled(PrintJobEvent pje) {
allDone();
}
public void printJobCompleted(PrintJobEvent pje) {
allDone();
}
public void printJobFailed(PrintJobEvent pje) {
allDone();
}
public void printJobNoMoreEvents(PrintJobEvent pje) {
allDone();
}
void allDone() {
synchronized (PrintJobWatcher.this) {
done = true;
System.out.println("Printing done ...");
PrintJobWatcher.this.notify();
}
}
});
}
public synchronized void waitForDone() {
try {
while (!done) {
wait();
}
} catch (InterruptedException e) {
}
}
}
A quick and simple way to output some text to a printer is to print to OS logical device attached a printer.
import java.io.FileWriter;
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();
(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:").
In this HowTo, we are creating a temporary vbs file and execute it. This technique is useful to do something
that a regular Java can't do because it's too specific to OS where the Java is running. The vbs file is created
in the "temporary" folder and is deleted by the JVM at the end.
import java.io.File;
import java.io.FileWriter;
}
catch(Exception e){
e.printStackTrace();
}
}
import java.io.*;
import javax.swing.filechooser.*;
}
}
The output
>java VolumeLabel c:
"temp"
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.swing.filechooser.FileSystemView;
*Disquette 3½ pouces
*Disque local
*Lecteur CD
*Disque local
*/
}
}
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.swing.filechooser.FileSystemView;
*
*REGA1 (C:)
*
*My Book (F:)
*/
}
}
Websphere MQ exposes many properties to control debugging inforation output. See this document.
When starting the JRE, set the properties on the command line. For example :
-Dcom.ibm.msg.client.commonservices.trace.status=ON
-Dcom.ibm.msg.client.commonservices.trace.outputName=C:\myapps\logs\mq.log
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;
}
out.flush();
System.err.println("Loop time: " +
(System.currentTimeMillis() - start));
}
The result is
Note that your result will vary depending on your machine/java version but the performance gain should in
the same magnitude.
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.
In Java 1.6 you can use System.console() instead of System.out.println() to display accentuated characters to
console.
C:\temp>java Test
caractþres franþais : Ó Ú Ú
caractères français : à é é
When starting 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().
import java.io.*;
try {
ps = new PrintStream(System.out, true, "Cp850");
}
catch (UnsupportedEncodingException error) {
System.err.println(error);
System.exit(0);
}
ps.println(javaString);
}
}
To clear the screen, you can use many System.out.println();, that's about it!
While it is possible to use the DOS ANSI.SYS driver with Windows 9x and make old JVM use it ... it won't
work with modern Windows installations. Windows NT (or better) CMD.EXE does not support ANSI
escape sequences at all.
Fortunately many Open Source solutions are coming to the rescue and Jansi and JCurses are two of them.
Jansi
Jansi is a small java library that allows you to use ANSI escape sequences to format your console output
which works even on Windows.
import org.fusesource.jansi.AnsiConsole;
}
}
NOTE: Check this "old" text file to have an overview of ANSI Escape Sequences.
The above example shows that it's possible to use ANSI codes directly but Jansi provides a neat mechanism
to help building the required ANSI sequence.
JCurses
The Java Curses Library (JCurses) is a library for developing text terminal based applications using Java
programming language. It is implemented as a Windowing toolkit similar to AWT, but built upon the
UNIX "curses" windowing system.
JCurses works on Unix and Windows (32 bit only, on a 64-bit OS you need to use JCurses with a 32-bit
JVM).
This example will display a character-based window with a label, a textfield and a button (don't click with
you mouse, use the keyboard!).
import jcurses.system.*;
import jcurses.widgets.*;
import jcurses.util.*;
import jcurses.event.*;
mgr.addWidget(
new Label("Hello World!",
new CharColor(CharColor.WHITE, CharColor.GREEN)),
0, 0, 20, 10,
WidgetsConstants.ALIGNMENT_CENTER,
WidgetsConstants.ALIGNMENT_CENTER);
button.setShortCut('q');
button.addListener(this);
window.addListener((WindowListener) this);
window.show();
}
import java.util.Scanner;
class TestScanner {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.println(sc.nextLine());
System.out.println("Done");
}
}
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.Scanner;
class TestScanner {
public static void main(String args[]) {
// if input is
// 10,12
// then the output is
// 10
// 12
//
// we use a regex as delimiter to combine "," and
// whitespace (in this case the ENTER key)
Scanner sc = new Scanner(System.in).useDelimiter("[,\\s]");
while (sc.hasNextInt()) {
int i = sc.nextInt();
System.out.println(i);
}
System.out.println("Done");
}
}
Scanner can be used with String or Stream. For exemple, the above HowTo can be written like this :
import java.util.Scanner;
class TestScanner {
public static void main(String args[]) {
String input = "10,12"
Scanner sc = new Scanner(System.in).useDelimiter(",");
while (sc.hasNextInt()) {
int i = sc.nextInt();
System.out.println(i);
}
System.out.println("Done");
}
}
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
NOTE : This technique changes the keyboard state so the effect is also seen outside the Java program.
System.setOut(new PrintStream(System.out) {
public void println(String s) {
super.println(s.toUpperCase());
}
});
os2.close();
}
System.out.println("*");
for (int i = 1; i<= 10; i++) {
System.out.println(i);
}
System.out.println("*");
System.setOut(originalOutStream);
System.out.println("Done. Check the log");
}
}
Be sure to read this Javaworld article. It describes the various pitfalls related to the Runtime.exec()
method.
Using Runtime.exec()
This example will capture the output (from stdio) of an external program.
package com.rgagnon.howto;
import java.io.*;
(new InputStreamReader(p.getErrorStream()));
while ((line = bri.readLine()) != null) {
System.out.println(line);
}
bri.close();
while ((line = bre.readLine()) != null) {
System.out.println(line);
}
bre.close();
p.waitFor();
System.out.println("Done.");
}
catch (Exception err) {
err.printStackTrace();
}
}
}
The next example, launch CMD.EXE, grab stdin/stdout and push to stdin command to be interpreted by the
shell.
String line;
OutputStream stdin = null;
InputStream stderr = null;
InputStream stdout = null;
stdin.close();
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();
}
}
}
@java -garbage
@java -version
Since 1.5, the ProcessBuilder class provides more controls overs the process to be started. It's possible to
set a starting directory.
import java.io.*;
import java.util.*;
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.
You can include a path for the program to be executed. On the Win plateform, you need to put the path in
quotes if the path contains spaces.
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.
VBSCRIPT
// Win9x
Runtime.getRuntime().exec("start myscript.vbs");
// WinNT
Runtime.getRuntime().exec("cmd /c start myscript.vbs");
or
Runtime.getRuntime().exec("hh.exe myhelpfile.chm");
Start Excel
import java.io.IOException;
class StartExcel {
public static void main(String args[])
throws IOException
{
Runtime.getRuntime().exec("cmd /c start excel.exe");
}
}
To load a worksheet
import java.io.IOException;
class StartExcel {
public static void main(String args[])
throws IOException
{
String fileName = "c:\\temp\\xls\\test2.xls";
String[] commands = {"cmd", "/c", "start", "\"DummyTitle\"",fileName};
Runtime.getRuntime().exec(commands);
}
}
It's important to pass a dummy title to the Windows start command where there is a possibility that the
filename contains a space. It's a feature.
You use the RUNAS command from the command line to start an application under another account (not
available with XP Home edition). There are many switches that can enhance the behaviour of RUNAS.
Typing "runas /?" from the command prompt gets you all the options.
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 want to execute the textpad editor located in C:\Program Files\TextPad 4 but without hard coding the
path since it can be different for a localized version of Windows.
We simply extract to environnment variable called %programfiles% and build the complete path from
there.
[JDK1.5]
String[] commands =
{"cmd.exe",
"/c",
WIN_PROGRAMFILES
+ FILE_SEPARATOR
+ "textpad 4"
+ FILE_SEPARATOR + "textpad.exe"};
Runtime.getRuntime().exec(commands);
}
}
NOTE : Prior Vista, System folders were localized on disk like C:\Program Files -> C:\Archivos de
programa on the Windows with the Spanish localization. Since Vista, System Folders always exists with
the english name BUT when viewed through Explorer, the localized name is shown. See
http://msmvps.com/blogs/carlosq/archive/2007/02/12/windows-vista-junctions-points-mui-and-localized-folder-nam
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 myanotherapp"), 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
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) {
System.exit(0);
}
}
);
setVisible(true);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
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 http://java.sun.com/javase/6/docs/api/java/awt/Desktop.html
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));
JDK1.6
Open the default file explorer.
import java.io.File;
import java.io.IOException;
import java.awt.Desktop;
try {
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
desktop.open(file);
}
else {
System.out.println("desktop is not supported");
}
catch (IOException e){ }
}
}
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
try {
fin = new FileInputStream("D:/temp/howto.txt");
isr = new InputStreamReader(fin);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
finally {
if (br != null) br.close();
if (isr != null) isr.close();
if (fin != null) fin.close();
}
}
The following method read a data file and return the content as a String. We use a StringBuilder to optimize
string concatenation operations.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
try {
fr = new FileReader(filename);
br = new BufferedReader(fr);
String nextLine = "";
StringBuilder sb = new StringBuilder();
while ((nextLine = br.readLine()) != null) {
sb.append(nextLine); // note: BufferedReader strips the EOL character
// so we add a new one!
sb.append(EOL);
}
return sb.toString();
}
finally {
if (br != null) br.close();
if (fr != null) fr.close();
}
}
JDK1.5 provides the java.util.Scanner class which can be used to quickly read a file.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
scanner.close();
}
}
JDK7+ provides, with the NIO package, a new way to get all the content of file quickly. You don't need to
close anything because readAllLines() is taking care of that.
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
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();
}
finally {
try {
if (br != null) br.close();
if (is != null) is.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
return list;
}
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 :
datafile1 line 1
datafile1 line 2
datafile1 line 3
datafile1 line 4
datafile1 line 5
datafile2 line 1
datafile2 line 2
datafile2 line 3
datafile2 line 4
datafile2 line 5
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.IOException;
import java.net.URL;
import java.util.Scanner;
private NetUtils() {}
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
Run it ... and the mydb.mdb file should appear in the current directory.
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]
}
return(values);
}
[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"));
[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);
w.flush();
w.close();
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");.
Copy a file
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0064.html
[Java 7]
import java.nio.file.Paths;
import java.io.*;
import java.nio.channels.*;
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;
while (position < size) {
position +=
inChannel.transferTo(position, maxCount, outChannel);
}
...
import java.io.*;
/**
* 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);
PrintWriter out = new PrintWriter(fos);
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";
To display the value of lastModified(), you need to create a Date object and then use SimpleDateFormat to
get the String representation.
Java.io.File returns the last modified time. To get the creation time, you need to use java.nio.Paths class.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.SimpleDateFormat;
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.*;
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.
import java.util.*;
import java.io.*;
import java.io.*;
public DirFilterWatcher() {
this.filter = "";
}
The example watches the c:/temp folder for any activities on any *.txt files.
import java.util.*;
import java.io.*;
http://jpoller.sourceforge.net/
A general purpose Java component to enable polling on directories and aysnchronously notify client code
of incoming files. It's instrumented via JMX and controllable (also) via a JMX agent, like JBoss' JMX
console.
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).
https://github.com/twall/jna#readme
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
http://johannburkard.de/blog/programming/java/Call-native-methods-in-a-DLL-from-Java-without-JNI.html
In this blog entry, the package NativeCall is used to call the Windows API to get notification about
modification in given folder.
Java 7
Java 7 provides a mechanism to get notification on file change without polling (WatchService).
Java 7 provides a mechanism to get notification on file change without polling (WatchService).
In this example, we set up a thread to watch CREATE event in a given folder. DELETE and MODIFY can
also be watched.
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;
Path myDir;
WatchService watcher;
WatchThread(String path) {
try {
myDir = Paths.get(path);
watcher = myDir.getFileSystem().newWatchService();
myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
}
catch (Exception e) {
e.printStackTrace();
}
}
// StandardWatchEventKinds.ENTRY_DELETE
// StandardWatchEventKinds.ENTRY_MODIFY
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
System.out.println("Created: " + event.context().toString());
}
}
watchKey.reset();
}
catch (Exception e) {
System.out.println("Error: " + e.toString());
}
}
}
}
To use it :
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) {
e.printStackTrace();
}
}
}
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. You 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.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.*;
If your need is simple then you don't need a complete class to implement a FilenameFilter. You can declare
an anonymous class with this simple onle-liner.
import java.io.File;
import java.io.FilenameFilter;
...
files = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
}
);
File [] foldersToBeChecked =
new File("J:\\").listFiles
(new FileFilter() {
public boolean accept(File pathname) {
return (pathname.isDirectory());
}
}
);
for(File f : foldersToBeChecked) {
System.out.println(f);
}
}
}
import java.io.*;
import java.util.*;
public class DirUtils {
result = recurseInDirFrom(dir);
_result = result.split("\\|");
return Arrays.asList(_result);
}
result = dirItem;
/*
output:
With Java 7, there is a new possibility to handle directory with a large amount of file (say more than 10 000
files). With the previous JDK versions, File.listFiles() returns a File array. The performance is not so good
since you have to wait for the array to be completed before starting the processing. This is especially bad if
you need to work only on subset of the content. With Java 7, java.nio offers an alternative with a huge gain
in performance.
In this HowTo, we want to process only the 10 first files of directory with more than 60 000 files.
The classical approach gets an array with all the files and then loop to process the first 10 files.
With the java.nio approach, a stream is opened and the files are processed as needed, the stream is closed
after the 10th file.
package misc;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
the result is :
IO run
1: 1355970441334_000000_AA000000.PDF
2: 1355970441334_000000_AA000000.props
3: 1355970441335_530025_AA000000.PDF
4: 1355970441335_530025_AA000000.props
5: 1355970441336_832300_AA000000.PDF
6: 1355970441336_832300_AA000000.props
7: 1355970441337_877400_AA000000.PDF
8: 1355970441337_877400_AA000000.props
9: 1355970441338_879900_AA000000.PDF
10: 1355970441338_879900_AA000000.props
Elapsed: 73455 ms
Make a directory
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0057.html
//
// 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.
Parse a pathname
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0514.html
import java.io.File;
public ParsePathname() { }
CSVPrinter/CSVParser/ExcelCSVPrinter/ExcelCSVParser
http://ostermiller.org/utils/CSV.html
opencsv
ServingXML
Framework for flat/XML data transformations. Supported transformations : flat-XML, XML-flat, flat-flat,
and XML-XML
http://servingxml.sourceforge.net/
Super CSV
This CSV reader/writer makes it easy to read/write objects/maps/string lists with automatic type conversion
and constraint checking.
http://supercsv.sourceforge.net/
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
CSVFile
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.
http://flatpack.sourceforge.net/
CSVJDBC
CsvJdbc is a simple read-only JDBC driver that uses Comma Separated Value (CSV) files as database
tables.
http://csvjdbc.sourceforge.net/
FFP
FFP - Flat file parsing library, is used to parse text files where lines can be interpreted according to
positional patterns. The library can handle both multi-line formats and files containing lines have different
known formats ("mixed format" files).
http://jffp.sourceforge.net/
XSLT
XSLT is built-in in the JDK, you need to create your own transformation in a XSL file. Transform XML
into CSV using XSLT
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.*;
w.flush();
}
w.close();
r.close();
System.exit(0);
}
}
try {
in1 = new BufferedInputStream(new FileInputStream(file1));
in2 = new BufferedInputStream(new FileInputStream(file2));
return result;
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
finally {
close(in1);
close(in2);
}
return false;
}
is.close();
}
catch ( IOException ioe ) {
ioe.printStackTrace();
}
}
}
if (currentExtension.equals("")){
target = source + "." + newExtension;
}
else {
target = source.replaceAll("." + currentExtension, newExtension);
}
return new File(source).renameTo(new File(target));
}
This code very very seriously flawed (the first version -ed.).
• The toLowerCase() can cause this to fail on OS that have case sensitive file names. It should be
removed.
• The replaceAll() call is flawed since
♦ the '.' in the pattern is not taken literally but is interpreted as any character.
♦ the regex has no end-of-line anchor so if the extracted extension occurs more than once in
the filename then all occurrences will be changed.
♦ if the extracted extension contains any regex meta characters then they will be interpreted
as part of the regex and the replaceAll() will probably fail. This can even cause an
exception.
♦ If the replacement extension contains any of the replacement meta characters then at best
one will get the wrong extension and it can cause an exception.
target = source.replaceFirst(Pattern.quote("." +
currentExtension) + "$", Matcher.quoteReplacement("." + newExtension));
A revised version
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
if (currentExtension.equals("")){
target = source + "." + newExtension;
}
else {
target = source.replaceFirst(Pattern.quote("." +
currentExtension) + "$", Matcher.quoteReplacement("." + newExtension));
}
return new File(source).renameTo(new File(target));
}
A special regular expression is used to strip out anything between a < and > .
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.
Using javax.swing.text.html.HTMLEditorKit
In most cases, the HTMLEditorKit is used with a JEditorPane text component but it can be also used
directly to extract text from an HTML page.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.MutableAttributeSet;
Note that the HTMLEditorKit can be easily confused if the HTML to be parsed is not well-formed.
Remove HTML tags from a file to extract only the TEXT 357
Real's HowTo PDF version
This is maybe the best solution (if the choosen parser is good !).
There are many parsers available on the net. In this HowTo, I will use the OpenSource package Jsoup.
Jsoup is entirely self contained and has no dependencies which is a good thing.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.io.BufferedReader;
import org.jsoup.Jsoup;
Apache Tika
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
Remove HTML tags from a file to extract only the TEXT 358
Real's HowTo PDF version
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/java-x.html");
ContentHandler contenthandler = new BodyContentHandler();
Metadata metadata = new Metadata();
Parser parser = new AutoDetectParser();
parser.parse(is, contenthandler, metadata, new ParseContext());
System.out.println(contenthandler.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null) is.close();
}
}
}
See Extract text from a PDF using Apache Tika, Get Mime Type from a file.
Using Java 7
Files.html#probeContentType
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
The default implementation is OS-specific and not very complete. It's possible to register a better detector,
like for example Apache Tika, see Transparently improve Java 7 mime-type recognition with Apache Tika.
Using javax.activation.MimetypesFileTypeMap
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.
Using java.net.URL
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.*;
I was trying to find the best way of getting the mime type of a file
and found your sight very useful. However I have now found a way of
getting the mime type using URLConnection that isn't as slow as the
way you describe.
import java.net.FileNameMap;
import java.net.URLConnection;
return type;
}
Tika is subproject of Lucene, a search engine. It is a toolkit for detecting and extracting metadata and
structured text content from various documents using existing parser libraries.
This package is very up-to-date regarding the filetypes supported, Office 2007 formats are supported
(docs/pptx/xlsx/etc...).
Apache Tika
Tika has a lot of dependencies ... almost 20 jars ! But it can do a lot more than detecting filetype. For
example, you can parse a PDF or DOC to extract the text and the metadata very easily.
import java.io.File;
import java.io.FileInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
FileInputStream is = null;
try {
File f = new File("C:/Temp/mime/test.docx");
is = new FileInputStream(f);
You can download here a ZIP containing the required jars if you want to check it out.
Using JMimeMagic
Checking the file extension is not a very strong way to determine the file type. A more robust solution is
possible with the JMimeMagic library. JMimeMagic is a Java library (LGLP licence) that retrieves file and
stream mime types by checking magic headers.
// http://sourceforge.net/projects/jmimemagic/
Using mime-util
Another tool is mime-util. This tool can detect using the file extension or the magic header technique.
import eu.medsea.mimeutil.MimeUtil;
The nice thing about mime-util is that it is very lightweight. Only 1 dependency with slf4j
Using Droid
DROID (Digital Record Object Identification) is a software tool to perform automated batch identification
of file formats.
DROID uses internal and external signatures to identify and report the specific file format versions of
digital files. These signatures are stored in an XML signature file, generated from information recorded in
the PRONOM technical registry. New and updated signatures are regularly added to PRONOM, and
DROID can be configured to automatically download updated signature files from the PRONOM website
via web services.
It can be invoked from two interfaces, a Java Swing GUI or a command line interface.
http://droid.sourceforge.net/wiki/index.php/Introduction
Aperture framework
Aperture is an open source library and framework for crawling and indexing information sources such as
file systems, websites and mail boxes.
The Aperture code consists of a number of related but independently usable parts:
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
This HowTo sorts a directory listing in ascending or descending order (based on the last modified
timestamp).
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()
{
@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.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Comparator;
/**
* returns a folder content sorted by extension
* case-insensitive ,ascending order
* subfolders are not included
* @param folder folder name
* @return
* @throws IOException if not a folder or not found
*/
@SuppressWarnings("unchecked")
public static File[] dirListByExtension(File folder) throws IOException {
if (!folder.isDirectory() || !folder.exists()) {
throw new IOException( folder.getName() + " : Not a folder or not exist");
}
File files[] = FileUtils.list(folder, false); // don't include subfolder
Arrays.sort(files, new Comparator() {
public int compare(final Object o1, final Object o2) {
String s1 = ((File) o1).getName().toLowerCase();
String s2 = ((File) o2).getName().toLowerCase();
final int s1Dot = s1.lastIndexOf('.');
final int s2Dot = s2.lastIndexOf('.');
//
if ((s1Dot == -1) == (s2Dot == -1)) { // both or neither
s1 = s1.substring(s1Dot + 1);
s2 = s2.substring(s2Dot + 1);
return s1.compareTo(s2);
} else if (s1Dot == -1) { // only s2 has an extension, so s1 goes first
return -1;
} else { // only s1 has an extension, so s1 goes second
return 1;
}
}
});
return files;
}
/**
* returns the content of a folder with subfolders included or not
* @param folder folder name
* @param includeSubFolder true/false
* @return array of files
*/
public static File[] list(File folder, boolean includeSubFolder) {
if (!folder.isDirectory()) {
return null;
}
File files[] = folder.listFiles();
List<File> list = new ArrayList<File>();
for (File file : files) {
if (file.isDirectory()) {
if (includeSubFolder) {
list.add(file);
}
}
else {
list.add(file);
}
}
if (list.isEmpty()) {
return null;
}
return list.toArray(new File[]{});
}
/*
* TEST
*/
public static void main(String args[]) throws Exception {
File files[] = FileUtils.dirListByExtension(new File("C:/temp"));
for (File file : files) {
System.out.println(file.getName());
}
// to reverse
// List<File> temp = Arrays.asList(files);
// java.util.Collections.reverse(temp);
// files = temp.toArray(new File[]{});
// for (File file : files) {
/// System.out.println(file.getName());
// }
import java.io.*;
import java.text.*;
import java.util.*;
Then
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
System.out.println(Pattern.matches(wildcardToRegex("ABC*"), test));
/*
output :
123ABC
true
true
false
true
false
true
false
true
false
false
*/
It can be useful to have a short version of a long path only for display purpose.
The first version makes a path shorter according to a limit. If the limit is 4, the returned path will contain 4
parts (directories) then ellipse and finally the filename.
ex :
C:\1\2\3\4\5\test.txt == C:\1\2\3\4\...\test.txt
\\server\p1\p2\p3\p4\p5\p6 == \\server\p1\p2\p3\p4\...\p6
http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html == http://p1/p2/p3/p4/.../pb.html
The second accepts a limit corresponding to the total length of the path. If the limit is 20, the path
beginning will be truncated then ellipse and finally the filename. The result is similar to the Win32 API
PathCompactPathExA.
ex :
C:\1\2\3\4\5\test.txt == C:\1\2\3\...test.txt
\\server\p1\p2\p3\p4\p5\p6 == \\server\p1\p2...p6
http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html == http://www...pb.html
private FileUtils() { }
/**
* Return shorter path based on the limited threshold
* ex. C:/1/2/test.txt return C:/1/.../test.txt if threshold is 1
* @param path
* @param threshold
* @return
*/
public static String pathShortener(String path, int threshold) {
if (path.indexOf("/") > 0) {
regex = SHORTENER_SLASH_REGEX;
sep = SHORTENER_SLASH;
}
// drive or protocol
int pos2dots = path.indexOf(":");
if (pos2dots > 0) {
// case c:\ c:/ etc.
sb.append(path.substring(0, pos2dots + 2));
index++;
// case http:// ftp:// etc.
if (path.indexOf(":/") > 0 && pathtemp[0].length() > 2) {
sb.append(SHORTENER_SLASH);
}
}
else {
boolean isUNC = path.substring(0,2).equals(SHORTENER_BACKSLASH_REGEX);
if (isUNC) {
sb.append(SHORTENER_BACKSLASH).append(SHORTENER_BACKSLASH);
}
}
.append(pathtemp[elem - 1]);
}
return sb.toString();
}
return path;
}
/**
* Compact a path into a given number of characters. Similar to the
* Win32 API PathCompactPathExA
* @param path
* @param limit
* @return
*/
public static String pathLengthShortener(String path, int limit) {
System.out.println(pathShortener("C:\\temp"));
System.out.println(pathShortener("C:\\1\\2\\3\\4\\5\\test.txt"));
System.out.println(pathShortener("C:/1/2/test.txt"));
System.out.println(pathShortener("C:/1/2/3/4/5/test.txt"));
System.out.println(pathShortener("\\\\server\\p1\\p2\\p3\\p4\\p5\\p6"));
System.out.println(pathShortener("\\\\server\\p1\\p2\\p3"));
System.out.println
(pathShortener("http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html"));
System.out.println("-----");
System.out.println(pathLengthShortener(t,20));
System.out.println(pathLengthShortener("C:\\temp", 20));
System.out.println(pathLengthShortener("C:\\1\\2\\3\\4\\5\\test.txt", 20));
System.out.println(pathLengthShortener("C:/1/2/testfile.txt", 15));
System.out.println(pathLengthShortener("C:/1/2/3/4/5/test.txt", 15));
System.out.println(pathLengthShortener("\\\\server\\p1\\p2\\p3\\p4\\p5\\p6", 20));
System.out.println
(pathLengthShortener("http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html", 20));
/*
output :
C:\Documents and Settings\All Users\Application Data\Apple Computer\iTunes\...\SC Info.
C:\temp
C:\1\2\3\4\...\test.txt
C:/1/2/test.txt
C:/1/2/3/4/.../test.txt
\\server\p1\p2\p3\p4\...\p6
\\server\p1\p2\p3
http://www.rgagnon.com/p1/p2/p3/.../pb.html
-----
C:\Doc...SC Info.txt
C:\temp
C:\1\2\3\...test.txt
...testfile.txt
C:/1...test.txt
\\server\p1\p2\...p6
http://www...pb.html
*/
}
}
/**
* replace illegal characters in a filename with "_"
* illegal characters :
* : \ / * ? | < >
* @param name
* @return
*/
public static String sanitizeFilename(String name) {
return name.replaceAll("[:\\\\/*?|<>]", "_");
}
This HowTo will only check if a given filename is valid according to the OS rules.
You still need to handle other failures when actually creating the file (e.g. insufficient permissions, lack of
drive space, security restrictions).
import java.io.File;
import java.io.IOException;
//false
System.out.println(FileUtils.isFilenameValid("test.T*T"));
System.out.println(FileUtils.isFilenameValid("test|.TXT"));
System.out.println(FileUtils.isFilenameValid("te?st.TXT"));
System.out.println(FileUtils.isFilenameValid("con.TXT")); // windows
System.out.println(FileUtils.isFilenameValid("prn.TXT")); // windows
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
...
343E0 43 41 54 49 4F 4E 20 44 41 54 41 5C 4D 4F 5A 49 CATION DATA\MOZI
343F0 4C 4C 41 5C 50 52 4F 46 49 4C 45 53 5C 44 45 46 LLA\PROFILES\DEF
34400 41 55 4C 54 5C 43 42 50 4D 53 35 4E 38 2E 53 4C AULT\CBPMS5N8.SL
34410 54 5C 4D 41 49 4C 5C 4D 41 49 4C 5C 54 52 41 53 T\MAIL\MAIL\TRAS
34420 48 0D 0A 20 20 20 20 20 20 54 68 69 73 20 66 69 H.. This fi
34430 6C 65 20 69 73 20 61 20 6D 61 69 6C 62 6F 78 2E le is a mailbox.
34440 20 54 6F 20 61 76 6F 69 64 20 69 6D 70 61 63 74 To avoid impact
...
List the files found in the classpath, the bootclasspath, the extension directory and in a Jar.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* list files in the given directory and subdirs (with recursion)
* @param paths
* @return
*/
public static List<File> getFiles(String paths) {
List<File> filesList = new ArrayList<File>();
for (final String path : paths.split(File.pathSeparator)) {
final File file = new File(path);
if( file.isDirectory()) {
recurse(filesList, file);
}
else {
filesList.add(file);
}
}
return filesList;
}
/**
* List the content of the given jar
* @param jarPath
* @return
* @throws IOException
*/
public static List<String> getJarContent(String jarPath) throws IOException{
List<String> content = new ArrayList<String>();
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> e = jarFile.entries();
while (e.hasMoreElements()) {
JarEntry entry = (JarEntry)e.nextElement();
String name = entry.getName();
content.add(name);
}
return content;
}
list = FileUtils.getFiles(System.getProperty("sun.boot.class.path"));
for (File file: list) {
System.out.println(file.getPath());
}
list = FileUtils.getFiles(System.getProperty("java.ext.dirs"));
for (File file: list) {
System.out.println(file.getPath());
}
}
}
From Wikipedia, the byte order mark (BOM) is a Unicode character used to signal the endianness (byte
order) of a text file or stream. Its code point is U+FEFF. BOM use is optional, and, if used, should appear at
the start of the text stream. Beyond its specific use as a byte-order indicator, the BOM character may also
indicate which of the several Unicode representations the text is encoded in.
To create an UTF8 file with a BOM, open the Windows create a simple text file and save it as utf8.txt with
the encoding UTF-8.
Now if you examine the file content as binary, you see the BOM at the beginning.
import java.io.*;
public class x {
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
The output contains a strange character at the beginning because the BOM is not discarded :
?helloworld
This behaviour is documented in the Java bug database, here and here. There will be no fix for now because
it will break existing tools like javadoc ou xml parsers.
The Apache IO Commons provides some tools to handle this situation. The BOMInputStream class detects
the BOM and, if required, can automatically skip it and return the subsequent byte as the first byte in the
stream.
Or you can do it manually. The next example converts an UTF8 file to ANSI. We check the first line for the
presence of the BOM and if present, we simply discard it.
import java.io.*;
// FEFF because this is the Unicode char represented by the UTF-8 byte order mark (EF BB
public static final String UTF8_BOM = "\uFEFF";
w.close();
r.close();
System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
if (s.startsWith(UTF8_BOM)) {
s = s.substring(1);
}
return s;
}
}
Touch a file
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-touch-a-file.html
import java.io.File;
private FileUtils () {}
...
FileUtils.touch(myFile)
Note that if the given file doesn't exist then it a new empty file is created.
There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about
OpenSource (and free) solutions.
For Java 8 you cannot use the JDBC-ODBC Bridge because it has been removed.
This solution lets you access your Excel worksheet with SQL SELECT statement. The required ODBC
driver is included in a regular Windows installation and the JDBC-ODBC bridge is used to access the Excel
DSN.
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;
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/
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. Latest POI version seems to
support the .XLSX format.
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/
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
Reading values from an XLS with jXLS is very simple. Suppose we have a worksheet with policy numbers
in the first column. We read and process them one by one.
import java.io.File;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
See http://jxls.sourceforge.net/
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/
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");
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.
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);
giffy.setName("giffy");
sheet.insertImage(giffy);
// add to sheet
for(int x=0;x<100;x++) {
fin = new FileInputStream(workingdir + "testImages.png");
ImageHandle jpgy = new ImageHandle(fin, sheet);
jpgy.setName("heart" + x);
// set the random x/y coords of picture
int ix = Math.round((float)((x * (Math.random()*10))));
jpgy.setX(100 + ix);
ix = Math.round((float)((x * (Math.random()*10))));
jpgy.setY(100 + ix);
sheet.insertImage(jpgy);
}
// get png image input stream
fin = new FileInputStream(workingdir + "testImages.jpg");
// add to sheet
ImageHandle pngy = new ImageHandle(fin, sheet);
// set just the x/y coords of picture
pngy.setX(10);
pngy.setY(200);
sheet.insertImage(pngy);
}
catch(Exception e){
System.err.println("testImages failed: " + e.toString());
}
testWrite(tbo, workingdir + "testImagesOut.xls");
WorkBookHandle newbook = new WorkBookHandle
(workingdir + "testImagesOut.xls",0);
System.out.println("Successfully read: " + newbook);
}
See also this HowTo for a way to create a simple XLS without any additional library.
http://www.rgagnon.com/javadetails/../javadetails/java-0586.html
While you can use specialized packages to create native Excel file, an easy way to import data into Excel is
to create an HTML file and embed the date into a TABLE tag. You give to the file the XLS extension and
Excel will do the translation for you!
With a text editor or from a program, create a file named test.xls with this content
<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.
FIrst, we define a POIFSReaderListener, called MacroListener, to analyze a given XLS and record if a
macro is found.
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
boolean macroDetected;
if(event.getPath().toString().startsWith("\\Macros")
|| event.getPath().toString().startsWith("\\_VBA")) {
macroDetected = true;
}
}
}
import java.io.FileInputStream;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
/*
output
Two test files : XLS with macro and XLS without macro
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;
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]);
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You specify the pdf file to be split. Each page is extracted to its own pdf file.
/*
* java SplitPDFFile file.pdf
*
* gives file-001.pdf ... file-nnn.pdf
*
* itext-2.1.5.jar
*/
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
/**
* @param args
*/
public static void main(String[] args) {
try {
String inFile = args[0].toLowerCase();
System.out.println ("Reading " + inFile);
PdfReader reader = new PdfReader(inFile);
int n = reader.getNumberOfPages();
System.out.println ("Number of pages : " + n);
int i = 0;
while ( i < n ) {
String outFile = inFile.substring(0, inFile.indexOf(".pdf"))
+ "-" + String.format("%03d", i + 1) + ".pdf";
System.out.println ("Writing " + outFile);
Document document = new Document(reader.getPageSizeWithRotation(1));
PdfCopy writer = new PdfCopy(document, new FileOutputStream(outFile));
document.open();
PdfImportedPage page = writer.getImportedPage(reader, ++i);
writer.addPage(page);
document.close();
writer.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
/* example :
java SplitPDFFile d:\temp\x\tx.pdf
Reading d:\temp\x\tx.pdf
Number of pages : 3
Writing d:\temp\x\tx-001.pdf
Writing d:\temp\x\tx-002.pdf
Writing d:\temp\x\tx-003.pdf
*/
}
}
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You specify the pdf files to be merge into one.
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PRAcroForm;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.SimpleBookmark;
@SuppressWarnings("unchecked")
public static void main(String[] args) {
try {
if (args.length < 2) {
System.out.println
("Usage: ConcatPDFFiles file1.pdf [file2.pdf... fileN.pdf] out.pdf");
System.exit(1);
}
int pageOffset = 0;
ArrayList master = new ArrayList();
int f = 0;
String outFile = args[args.length - 1];
Document document = null;
PdfCopy writer = null;
while (f < args.length - 1) {
PdfReader reader = new PdfReader(args[f]);
reader.consolidateNamedDestinations();
int n = reader.getNumberOfPages();
List bookmarks = SimpleBookmark.getBookmark(reader);
if (bookmarks != null) {
if (pageOffset != 0) {
SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset,
null);
}
master.addAll(bookmarks);
}
pageOffset += n;
if (f == 0) {
document = new Document(reader.getPageSizeWithRotation(1));
writer = new PdfCopy(document,
new FileOutputStream(outFile));
document.open();
}
PdfImportedPage page;
for (int i = 0; i < n;) {
++i;
page = writer.getImportedPage(reader, i);
writer.addPage(page);
}
PRAcroForm form = reader.getAcroForm();
if (form != null) {
writer.copyAcroForm(reader);
}
f++;
}
if (!master.isEmpty()) {
writer.setOutlines(master);
}
document.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You pass one or many tif files as argument and corresponding PDF are
produced. Multipage TIF are supported. TIF are resized to fit a letter-page dimension.
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
tiff = args[i];
pdf = tiff.substring(0, tiff.lastIndexOf('.') + 1) + "pdf";
Document document = new Document(PageSize.LETTER, 0, 0, 0, 0);
try {
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(pdf));
int pages = 0;
document.open();
PdfContentByte cb = writer.getDirectContent();
RandomAccessFileOrArray ra = null;
int comps = 0;
try {
ra = new RandomAccessFileOrArray(tiff);
comps = TiffImage.getNumberOfPages(ra);
}
catch (Throwable e) {
System.out.println("Exception in " + tiff + " "
+ e.getMessage());
continue;
}
System.out.println("Processing: " + tiff);
for (int c = 0; c < comps; ++c) {
try {
Image img = TiffImage.getTiffImage(ra, c + 1);
if (img != null) {
System.out.println("page " + (c + 1));
img.scalePercent
(7200f / img.getDpiX(), 7200f / img.getDpiY());
document.setPageSize
(new Rectangle(img.getScaledWidth(), img.getScaledHeight()));
img.setAbsolutePosition(0, 0);
cb.addImage(img);
document.newPage();
++pages;
}
}
catch (Throwable e) {
System.out.println("Exception " + tiff + " page "
+ (c + 1) + " " + e.getMessage());
}
}
ra.close();
document.close();
}
catch (Throwable e) {
e.printStackTrace();
}
System.out.println("done");
}
}
}
iText
Using iText HTMLWorker, you can produce PDF version of an HTML document. The document must be
simple. Many things like FORM elements or external images are not supported.
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.html.simpleparser.HTMLWorker; // deprecated
import com.itextpdf.text.pdf.PdfWriter;
e.printStackTrace();
}
}
}
As you can see, the validity of the parsed HTML (using HTMLWorker) is very relax. Closing tags are not
required : <BR> is ok (<BR/> is not mandatory).
HTMLWorker is ok with older iText version but the recommended approach with new iText
(HTMLWorker is now deprecated) is to use the XMLWorker. XMLWorker is stricter since you must send
XHTML document to it.
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
public class HtmlToPDF2 {
// itextpdf-5.4.1.jar http://sourceforge.net/projects/itext/files/iText/
// xmlworker-5.4.1.jar http://sourceforge.net/projects/xmlworker/files/
public static void main(String ... args ) {
try {
Document document = new Document(PageSize.LETTER);
PdfWriter pdfWriter = PdfWriter.getInstance
(document, new FileOutputStream("c://temp//testpdf.pdf"));
document.open();
document.addAuthor("Real Gagnon");
document.addCreator("Real's HowTo");
document.addSubject("Thanks for your support");
document.addCreationDate();
document.addTitle("Please read this");
}
catch (Exception e) {
e.printStackTrace();
}
}
Note :
To get the color on a table cell, you need to use a style because the bgcolor attribute is not supported. By
default, FORM elements are not rendered. Review this document to see what is supported :
http://demo.itextsupport.com/xmlworker/doc.html
As seen in this HowTo, iText can be used to transform an HTML document to PDF. The result is good with
simple HTML but if you get fancy then the result is not so good.
For better result, the Open Source package YAHP (Yet another Html to Pdf converter) is a good choice.
YAHP is based on iText, FlyingSaucer and JTidy.
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// http://www.allcolor.org/YaHPConverter/
import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;
properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
//properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);
converter.convertToPdf(str,
IHtmlToPdfTransformer.A4P,
headerFooterList,
"file:///temp/", // root for relative external CSS and IMAGE
out,
properties);
out.flush();
out.close();
}
}
In the next example, we read an existing HTML file and convert it to a PDF file.
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
// http://www.allcolor.org/YaHPConverter/
import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;
properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
//properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);
converter.convertToPdf(htmlContents,
IHtmlToPdfTransformer.A4P,
headerFooterList,
"file:///temp/html/",
out,
properties);
out.flush();
out.close();
}
}
NOTE : After downloading YAHP (and its dependencies), you still need to build a YAHP.JAR, it's done easily with Eclipse... but you can get it here.
iText
import java.io.FileOutputStream;
document.add(Image.getInstance
(new java.net.URL("http://www.rgagnon.com/images/javahowto.jpg")));
Print a PDF
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-print-a-pdf.html
[Windows only]
You can launch the Acrobat Reader to print a PDF to the default printer.
More infos the "unsupported" command-line switches for the Acrobat reader :
import java.io.IOException;
Runtime.getRuntime().exec(commands);
}
Unfortunately, Acrobat Reader stays opened (but minimized because of the /h switch) after the printing
operation :-(
You can use a special wrapper to force the closing the Acrobat Reader after the print operation. See
http://www.biopdf.com/acrowrap/close_adobe_reader.php (acrowrap.exe).
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.tika.parser.pdf.PDFParser;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/realhowto-vbs-20121221.pdf");
ContentHandler contenthandler = new BodyContentHandler();
Metadata metadata = new Metadata();
PDFParser pdfparser = new PDFParser();
pdfparser.parse(is, contenthandler, metadata, new ParseContext());
System.out.println(contenthandler.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null) is.close();
}
}
}
See also Extract text from HTML, Get Mime Type from a file.
/*
** 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();
}
}
else {
err.print(" 0% ");
}
}
else {
err.println(" (stored 0 %");
}
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();
}
throws IOException {
System.out.println("unzipping " + s);
FileOutputStream out = new FileOutputStream(s);
byte [] b = new byte[512];
int len = 0;
while ( (len=zin.read(b))!= -1 ) {
out.write(b,0,len);
}
out.close();
}
}
Emit a beep
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0001.html
(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.
Emit a tone
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0499.html
//jdk1.3
import javax.sound.sampled.*;
}
}
import java.io.File;
import java.io.FileInputStream;
import javax.sound.sampled.*;
import javax.swing.*;
public AppWithSound() {
initGUI();
}
//jdk1.3
import javax.sound.sampled.*;
import java.util.Random;
sdl.open(af);
sdl.start();
if(i%250 == 0) step += 2;
sdl.write(buf,0,1);
}
Thread.sleep(200);
}
sdl.drain();
sdl.stop();
sdl.close();
}
sdl.close();
}
When a sound is playing, the action is stopped until the sound is finished. To play a sound and keep the
application responding to event, you need to play the sound in a Thread.
import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public AppWithSound2() {
initGUI();
}
if (i % 250 == 0)
step += 2;
sdl.write(buf, 0, 1);
}
Thread.sleep(200);
}
sdl.drain();
sdl.stop();
sdl.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Java Speech API (JSAPI) is not part of the JDK and Sun does not ship an implementation of JSAPI.
Sun porivides the specification and third-parties provide the implementations.
• speech.properties contains the package to provide the JSAPI implementation. Typically, the file is located
in the JRE\lib directory. In this example, I register the TTS package directly.
• You specify the available voices. You have many different ways to do so, see the javadoc at
http://freetts.sourceforge.net/javadoc/com/sun/speech/freetts/VoiceManager.html#getVoices(). In this
example, the available voice is setted with the system property "freetts.voices".
import java.beans.PropertyVetoException;
import java.util.Locale;
import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
SynthesizerModeDesc desc;
Synthesizer synthesizer;
Voice voice;
System.setProperty("freetts.voices",
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
su.init("kevin16");
// high quality
su.doSpeak("Hello world from Real's How To");
su.terminate();
}
}
Related links :
• http://www.ryan-h.com/uncategorized/java-speech-jsapi-freetts/
• http://java.sun.com/products/java-media/speech/forDevelopers/jsapi-doc/javax/speech/package-summary.html
• http://today.java.net/pub/a/today/2006/04/13/vocal-java.html
You can access a sound as defined in the Windows configuration for specific event. The JDK exposed them
as properties and the values for these properties are retrieved with the getDesktopProperty() method on
java.awt.Toolkit. The property related to a sound is a Runnable that plays the current audio clip for that
property.
import java.awt.Toolkit;
System.out.println("Sound 2");
Runnable sound2 =
(Runnable)Toolkit.getDefaultToolkit().getDesktopProperty("win.sound.exclamation");
if(sound2 != null) sound2.run();
*/
Keep in mind that this technique is very specific to Windows and will not work on others OS.
Most database vendors provide a JDBC driver for their products, check the vendor Web site.
• Oracle : web site
• Microsoft SQLServer : web site
• MySQL : web site
There is no JDBC driver for Microsoft Access. While it's possible to use the ODBC-JDBC bridge included
with the JDK, the performance and stability of this solution is not great (and it is not included any more
since JDK8).
A commercial product, called SteelMDB, is a JDBC type 4 driver that allows to perform SQL queries and
other JDBC operations on Microsoft Access database files (MS Access 2000, 2002, 2003, XP versions).
The driver is completely platform-independent and does not require installing additional client or server
software to provide access to MDB files.
http://www.csv-jdbc.com/stels_mdb_jdbc.htm
This HowTo is deprecated. For Java 8 you cannot use the JDBC-ODBC Bridge because it has been
removed.
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 {
JDBC 420
Real's HowTo PDF version
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
("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();
while (rs.next()) {
System.out.println(rs.getString("custName"));
}
rs.close();
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
You need to be aware to the snippet above contains a SQL Injection vulnerability. String concatentation of this form can only be used if you first validate
the fields to include only alphanumeric characters. Even, then it is generally considered bad practice when prepared statements solve this problem more
cleanly. This is especially when you in a Web application environnement.
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 class StringUtils {
public static void main(String args[]) {
System.out.println(StringUtils.sqlQuote("Real's HowTo"));
System.out.println(StringUtils.sqlQuote("HowTo"));
System.out.println(StringUtils.sqlQuote(""));
System.out.println(StringUtils.sqlQuote("Real's HowTo's"));
System.out.println(StringUtils.sqlQuote("'"));
System.out.println(StringUtils.sqlQuote("''"));
/*
output:
Real''s HowTo
HowTo
Real''s HowTo''s
''
''''
*/
}
try {
sql = "INSERT INTO tCust"
+ "(custName) "
+ "VALUES "
+ "(?)";
stmt = theConn.prepareStatement(sql);
stmt.setString(1, "Name with ' are permitted!");
rows = stmt.executeUpdate();
stmt.close();
}
catch (Exception e){
e.printStackTrace();
}
The character "\" (backslash) can be difficult to use in an INSERT statement since "\" is considered as an
escape character in Java (and probably by the database too).
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");
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(*).
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;
pstmt.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
class MyConnection {
Connection dbConn = null;
void connect(String db, String user, String passw) {
try {
Driver d =
(Driver)Class.forName
("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
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();
}
}
}
Retrieve an Image
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0118.html
Insert an Image
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0119.html
Connection conn;
then
cs.setString(2, "");
cs.setString(3, "");
cs.setString(4, parms);
// regsiter ouput parameters
cs.registerOutParameter(5, java.sql.Types.CHAR);
cs.registerOutParameter(6, java.sql.Types.CHAR);
cs.registerOutParameter(7, java.sql.Types.CHAR);
// Procedure execution
ResultSet rs = cs.executeQuery();
int i = 0;
int j = 1;
return cs.getInt(1);
}
Some JDBC driver have limit about how big returned records can be.
First use the getMaxRowSize() and doesMaxRowSizeIncludeBlobs() from the DatabaseMetaData class to
see what the maximum supported by the driver. Then getMaxFieldSize() and setMaxFieldSize() from the
Statement class to adjust if necessary the current maximum value.
// 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");
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 is deprecated. For Java 8 you cannot use the JDBC-ODBC Bridge because it has been
removed.
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!)
It is possible to connect to a database without a User or System DSN. This is useful if you don't have easy
access to a client registry to define the required DSN. Not all JDBC driver support this feature.
// For Access
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String myDB =
"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/data/month.MDB";
DBConn = DriverManager.getConnection(myDB,"","");
// For Excel
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String myDB =
"jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=c:/data/month.xls;"
+ "DriverID=22;READONLY=false";
DriverManager.getConnection(myDB,"","");
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver) ;
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();
}
}
}
[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 (tables.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 {
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));
}
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 '='}");
If you don't want to use JDBC escape sequence then it's possible to use native SQL based on the target
DBMS.
SELECT value FROM vendors WHERE value LIKE '%=_%' ESCAPE '=';
ref : Labo-Oracle.com.
P6Spy
P6Spy is an open source framework for applications that intercept and optionally modify database
statements.
Download at http://p6spy.com/
Proxool
It provides really nice logging facilities with the SQL statement and the running time.
Download at http://proxool.sourceforge.net/
JDBC Logger
JDBC Logger is an Open Source Java tool that intercepts and logs all database statements that use JDBC. It
is intended for developers to monitor SQL statements generated by EJB, Hibernate or any other database
access tool that doesn't display them in clear.
Download at http://jdbclogger.sourceforge.net/
Log4JDBC
Log4jdbc is a Java JDBC driver that can log SQL and/or JDBC calls (and optionally SQL timing
information) for other JDBC drivers
Download at http://code.google.com/p/log4jdbc/
Oracle JDBC
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
When inserting many INSERTs (or DELETE/UPDATE), JDBC provides the addBatch() method to
cumulate the SQL statements. When ready, the whole batch is sent in one shot to minimize the network
traffic. A special attention to the error handling should made.
The performance gain is good. For example, 100 individual INSERTS == 140ms 10 batched INSERTS ==
32ms
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
conn.setAutoCommit(false);
ExecutionTimer t = new ExecutionTimer(); // see this HowTo
int i =0;
t.start();
while (i < 100) {
stmt.addBatch(
"INSERT INTO PROD.COUNTER VALUES "
+ "(\"test\", " + i + ", 0)");
stmt.addBatch();
i++;
}
int[] upCounts = stmt.executeBatch();
conn.commit();
t.end();
System.out.println("Timer : " + t.duration());
stmt.close();
System.out.println("Ok.");
}
}
JDBC provides a way to give a hint about the size of the expected ResultSet.
Statement.setFetchSize() gives a hint about the number of rows that should be fetched from the database
each time new rows are needed. The goal is to reduce unnecessary network round trip.
With Oracle, the default value is 10 (i.e. the Oracle driver will retrieve ResultSets in 10-row chunks)
A JDBC Compliant driver may choose to ignore the setFetchSize(). You should do some testing first to
check if the result is optimal.
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
348831 rows
prefetch == 100
14859
14749
prefetch == 200
13343
13296
prefetch == 500
13891
13812
prefetch == 1000
13078
13078
*/
Handle dates
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0114.html
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());
String query =
"select * from cust where purchase_date <{ d '"
+ sqlDate.toString() + "' }");
With a PreparedStatement, you don't need JDBC escape codes, the JDBC driver will do the job for you.
java.util.Date today =
new java.util.Date();
java.sql.Date sqlToday =
new java.sql.Date(today.getTime());
PreparedStatement p = theConn.prepareStatement
("select * from cust where purchase_date <?");
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' } )");
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) );
It's good idea to use the JDBC escape function instead of using a specific DBMS function. This way, your
code will be portable.
This HowTo is deprecated. For Java 8 you cannot use the JDBC-ODBC Bridge because it has been
removed.
Let's assume we have a worksheet like this
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.*;
Class.forName(DRIVER_NAME);
Connection con = null;
try {
con = DriverManager.getConnection(DATABASE_URL);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery
("select lastname, firstname, id from [Sheet1$]");
while (rs.next()) {
String lname = rs.getString(1);
String fname = rs.getString(2);
int id = rs.getInt(3);
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.
For Java 8 you cannot use the JDBC-ODBC Bridge because it has been removed.
This solution lets you access your Excel worksheet with SQL SELECT statement. The required ODBC
driver is included in a regular Windows installation and the JDBC-ODBC bridge is used to access the Excel
DSN.
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/
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. Latest POI version seems to
support the .XLSX format.
Since it's Jakarta project, POI has a dependencies with other JARs (commons,log4j,etc...).
fileOut.close();
The name was originally an acronym for "Poor Obfuscation Implementation" (ref: Wikipedia).
See http://jakarta.apache.org/poi/
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
Reading values from an XLS with jXLS is very simple. Suppose we have a worksheet with policy numbers
in the first column. We read and process them one by one.
import java.io.File;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
See http://jxls.sourceforge.net/
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/
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");
xlBook.Close(false,null,false);
excel.Quit();
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.
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();
}
(workingdir + "testImages.gif");
// 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.
The JDBC driver for Oracle 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.");
}
}
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = myhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
While it is not to difficult to connect using the example above, it would be nice to connect without having
to specify a server and a port number. Since release 10.2.0.1.0, it's possible to give only a TNSNAMES
entry and the driver extract the required infos (server and port) for the defined TNSNAMES.ORA file. In
order for this to work you must have configured the file TNSNAMES.ORA correctly and set a the java
property oracle.net.tns_admin.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.OracleDriver;
DriverManager.registerDriver(new OracleDriver());
Connection conn = DriverManager.getConnection(url,usr,pwd);
System.out.println("Done..");
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
/*
\\myserver\TNSNAMES_DIR\tnsnames.ora
MYORCL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = orcltest.local)(PORT = 1521))
)
(CONNECT_DATA = (SERVICE_NAME = orcl)(INSTANCE_ROLE=ANY))
)
*/
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.
A Connection Pool is a cache of database connections maintained in memory so that the connections can be
reused when the database receives future requests for data. Connection pools are used to enhance the
performance of executing commands on a database. Various parameters such as number of minimum
connections, maximum connections and idle connections can be set to make sure the connection pool works
well according to the environment it is deployed to work in.
In this example, we have a program with several threads. Each thread makes a connection but the login
process is done only once.
import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.pool.OracleConnectionCacheManager;
import java.util.Properties;
import java.sql.*;
static {
System.out.println("OracleDataSource Initialization");
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.*;
Oracle can generated keys by creating a sequence. This sequence is then incremented with each INSERT to
provides a unique numeric key.
While it's possible to do the INSERT and then a SELECT to RETRIEVE the last sequence, JDBC 3.0
provides a way to tell to the INSERT to return the specified generated keys.
Nice article on the subject : Oracle JDBC: Automatic key generation and retrieval
See this HowTo if you want to log only the SQL statement.
To get Oracle JDBC log output, you must use the oracle driver debug JAR files (in your classpath), which
are indicated with a "_g" in the file name, ex. ojdbc5_g.jar.
Then you need to enable java.util.logging (since Oracle 10/JDK1.4)to see the activities
handlers = java.util.logging.FileHandler
# or can be handlers = java.util.logging.ConsoleHandler
java.util.logging.FileHandler.pattern = c:/myapp/jdbc.log
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# or can be java.util.logging.FileHandler.formatter = java.util.logging.XmlFormatter
oracle.jdbc.driver.level = FINE
If you use the OCI driver, you can enable Net8 tracing on both the client and the server. Keep in mind,
however, that enabling Net8 tracing translates into a substantial performance hit.
To enable client tracing, you add four parameters to your sqlnet.ora file, which is located in your
$ORACLE_HOME\network\admin directory.
TRACE_LEVEL_CLIENT = SUPPORT
TRACE_DIRECTORY_CLIENT = c:\oracle\trace
TRACE_UNIQUE_CLIENT = ON
TRACE_FILE_CLIENT = SESS
0 or OFF
4 or USER
10 or ADMIN
16 or SUPPORT
To turn tracing on and get the most amount of information, specify the following:
TRACE_LEVEL_CLIENT = SUPPORT
To turn tracing off, which you definitely want to do after your debugging session is complete, use 0 or
OFF:
TRACE_LEVEL_CLIENT = OFF
Using this method, you don't need to provide a username/password to Oracle. Kerberos authentication can
take advantage of the user name and password maintained by the operating system to authenticate users to
the database or use another set of user credentials specified by the application.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.net.ano.AnoServices;
javax.security.auth.login.LoginException: KrbException:
KDC has no support for encryption type (14)
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
The v$session view contains session information for each current session.
When connecting with ODBC or OCI, the program column will contain the executable name used to make
the connection. If the connection is made with the Thin Driver,the program is "JDBC Thin Client" (by
default). The good news is that this information can be customized at the connect time to provide a more
interesting name (maximum length = 64 characters).
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
props.setProperty("user","scott");
props.setProperty("password","tiger");
props.setProperty(
OracleConnection.CONNECTION_PROPERTY_THIN_VSESSION_PROGRAM,
"My Java program : " + this.getClass().getName() );
String sql =
"SELECT username, osuser, program, machine " +
"FROM SYS.V_$SESSION " +
"WHERE username IS NOT null ORDER BY logon_time, sid";
Output :
With Oracle, if a CHAR field used in a WHERE clause contains trailing spaces then the trailing spaces
must be there, there is no automatic trimming.
For example, if the "code_value" field is defined as CHAR(10) and the content is "A10" then the real value
is "A10 " and the trailing spaces must be present in the comparaison to have a match.
PreparedStatement ps;
ps = conn.prepareStatement("SELECT desc_value from prod.DICT_VALUES WHERE code_value= ?") ;
ps.setString(1,"A10");
rs = ps.executeQuery();
while (rs.next())
System.out.println("results: " + rs.getString(1));
PreparedStatement ps;
ps = conn.prepareStatement("SELECT desc_value from prod.DICT_VALUES WHERE code_value= ?") ;
ps.setString(1,"A10 ");
rs = ps.executeQuery();
while (rs.next())
System.out.println("results: " + rs.getString(1));
The easy fix is to define the field as a VARCHAR not a CHAR or replace the PreparedStatement with a
Statement.
Statement s;
s= conn.createStatement();
String val = "A10";
String sql ="SELECT desc_value from prod.DICT_VALUES WHERE code_value='" + val + "'" ;
ResultSet rs = s.executeQuery(sql);
while (rs.next())
System.out.println("results: " + rs.getString(1));
To keep a PreparedStatement, you need to add explicitly the trailing spaces or trim the value.
The first try is to trim the value with the rtrim() function.
This is working fine but Oracle will not use the index and probably perform a table scan which is not a
good thing!
Oracle provides an API to make sure that the parameter received is handled as a CHAR value by the
database.
import oracle.jdbc.OraclePreparedStatement;
...
PreparedStatement ps;
The good thing is that we don't need to know the CHAR width of the field, the driver will figure it out for
us but using the special Oracle class can be problem.
A better solution is to instruct the database to add the missing trailing spaces with the rpad() function.
This a better solution because we are not using a special Oracle class and the database will use the index.
• 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"
JNI/JNA 473
Real's HowTo PDF version
#include "JavaHowTo.h"
then from C, we want to call the Java sayHello() method which returns a String :
class JavaHowTo {
SYSTEMTIME st;
GetLocalTime(&st);
st.wHour = hour;
st.wMinute = minutes;
SetLocalTime(&st);
}
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 */
The javap utility can be used on the java.* or your own classes.
Use arrays
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0287.html
JNI provides special functions (relative to the type) to access Java arrays.
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));
}
}
Note that to get the reflection stuff working, the native method (printArrayR) could'nt be static.
class JNIHowTo {
private static native void printArray (int[] t); // print an int[] array
private native void printArrayR (); // print int[] array 'myArray' via reflection
static {
System.loadLibrary("javahowto");
}
The JNI code (tested on 64bit Windows / Java 6u24 64bit using mingw 64bit cross compiler
(x86_64-w64-mingw32-gcc).
#include "JNIHowTo.h"
Load a DLL
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0318.html
[pre JDK1.2]
System.loadLibrary("d:\\directoryX\\subDirY\\MyDll.dll")
In JDK1.2 (or better), if the DLL is in the CLASSPATH then you don't need to specify a PATH. If the DLL is
not in the CLASSPATH then you need to specify the PATH.
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 {
public native void triggerException();
static {
System.loadLibrary("javahowto");
}
}
jht.triggerException();
}
}
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(&vm, (void **)&env, &vm_args);
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);
if (args == 0) {
printf("Out of memory\n");
exit(1);
}
env->CallStaticVoidMethod(cls, mid, args);
return 0;
}
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();
}
[Windows only]
First you need this Java stub (JavaHowTo.java) to provide an interface to the JNI DLL (jni3.dll).
class JavaHowTo {
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;
Clear the console, set color and cursor position (JNI) 486
Real's HowTo PDF version
COORD Home;
static unsigned char EMPTY = 32;
Home.X = 0;
Home.Y = 0;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &strConsoleInfo);
FillConsoleOutputCharacter(hConsole, EMPTY,
strConsoleInfo.dwSize.X * strConsoleInfo.dwSize.X, Home,
hWrittenChars);
SetConsoleCursorPosition(hConsole, Home);
// system("cls"); will do the same as the above!
}
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, &ConsoleInfo);
originalColors = ConsoleInfo.wAttributes;
}
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, originalColors);
}
Clear the console, set color and cursor position (JNI) 487
Real's HowTo PDF version
System.out.print("http://www.rgagnon.com");
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/
JNA (Java Native Access) provides Java programs easy access to native shared libraries (DLLs on Windows)
without writing anything but Java code - no JNI or native code is required.
In this HowTo, we detect if an instance of program is running or not. The following code checks if Excel is
running. It Excel is running, we activate the window and bring it to the front.
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
// https://github.com/twall/jna#readme
// you need 2 jars : jna-3.5.1.jar and platform-3.5.1.jar
This technique looks for the window title. Since my Excel installation is in French then the default sheet name
is Classeur1(in English it would be Sheet1).
Another way is to look for the window class name. For Excel, the class name is XLMAIN.
To search for the class name instead of the window title, change this line :
To determine the class name of a window for a specific program, you can use something like Spy++ (installed
with Visual Studio) or the free alternative WinID.
It is also possible to search for the class name and the title to make the search more precise.
This example will close a running Powerpoint. The idea is to scan the Windows titles and find a match. If
found then the Windows message WinUser.WM_CLOSE is sent to the process using its handle.
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinDef.HWND;
// https://github.com/twall/jna#readme
// you need 2 jars : jna-3.5.1.jar and platform-3.5.1.jar
}
}
You can make the search more precise by specifying the class name as the first parameter. You find the class
name of a specific Windows program with a special utility program like Spy++ or the free alternative WinID.
For PowerPoint, the class name is PP12FrameClass.
You can search by the Windows title only, the class name only or with both.
To close Notepad
If there is a document to be saved you be prompted. To avoid that and discard the current document use the
WM_QUIT message instead of WM_CLOSE.
If you want to kill all running instances, then you can loop until no handle is retrieved.
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinDef.HWND;
// https://github.com/twall/jna#readme
// you need 2 jars : jna-3.5.1.jar and platform-3.5.1.jar
JNA (Java Native Access) provides Java programs easy access to native shared libraries (DLLs on Windows)
without writing anything but Java code - no JNI or native code is required.
In this HowTo, we retrieve the path of some Windows Special Folders : Program Files, Common Documents
and the Desktop.
You can get the others by using the right identifier from the constants defined in the ShlObj interface.
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Shell32;
import com.sun.jna.platform.win32.ShlObj;
import com.sun.jna.platform.win32.WinDef;
// https://github.com/twall/jna#readme
// you need 2 jars : jna-3.5.1.jar and platform-3.5.1.jar
Shell32.INSTANCE.SHGetFolderPath(null,
ShlObj.CSIDL_DESKTOPDIRECTORY, null, ShlObj.SHGFP_TYPE_CURRENT,
pszPath);
System.out.println(Native.toString(pszPath));
Shell32.INSTANCE.SHGetFolderPath(null,
ShlObj.CSIDL_COMMON_DOCUMENTS, null, ShlObj.SHGFP_TYPE_CURRENT,
pszPath);
System.out.println(Native.toString(pszPath));
/*
* output :
* C:\Program Files
* C:\Users\Real_User\Desktop
* C:\Users\Public\Documents
*/
}
}
* Read me *
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0168.html
Mac (old)
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
Mac OSX
Java is pre-installed with Mac OSX.
You need to add the plugin.jar to the classpath (JRE_HOME\lib) for compilation.
When moving the mouse over an image, we want to start an applet (here a simple chronometer), and when the
mouse leave the image, the Applet should stop.
[JAVA APPLET]
import java.applet.*;
import java.awt.*;
public MyThread(JavaChrono a) {
theApplet = a;
}
}
catch(InterruptedException e) { }
}
}
}
[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>
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.*;
if (f == null) {
f = new Frame();
f.setSize(100,100);
f.add(new Label("Hello World"));
f.setVisible(true);
}
}
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.
NOTE: On IE4 or better, you can't call java.* methods directly from Javascript or Jscript. IE javascript can
only access the public methods of an applet (a class derived from java.applet.Applet) but don't have a general
access to other java classes . So the solution is simple, wrap the java.* call in a public method of a "dummy"
Applet.
[Java applet]
import java.awt.*;
import java.applet.*;
public class InJava extends Applet{
public void sayHello() {
Graphics g = getGraphics();
g.drawString("Hello from JAVA!", 10, 10);
}
}
<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>
<SCRIPT>
function getScreenDimension() {
alert("Screen Dimension\r\n width:" +
document.myApplet.getScreenWidth() +
" height:" +
document.myApplet.getScreenHeight() );
}
</SCRIPT>
<FORM>
<INPUT type="button" value="call JAVA"
onClick = "getScreenDimension()">
</FORM>
<APPLET CODE="InJava2.class"
NAME="myApplet"
HEIGHT=100 WIDTH=100>
</APPLET>
</BODY></HTML>
Try it here
NOTE: This for demonstration only. On N4 or IE4, it's better to use screen.height and screen.width properties directly. There is no need for a Java Applet!
NOTE: The first time, there is a delay because the Applet need to load and initialize.
[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).
[Java applet]
import java.awt.*;
import java.applet.*;
public class InJava3 extends Applet{
public int iJava = 123;
public String sJava = "String from JAVA";
return iJava;
}
public String getStringJava() {
return sJava;
}
}
<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.
A Javascript function is called from Java by using the showDocument method. A URL is needed with
"javascript:" as the protocol.
[Java applet]
import java.applet.*;
import java.net.*;
<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.*;
import java.net.URL;
import netscape.javascript.*;
}
}
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>
FirstApplet.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
getAppletContext().showDocument
(new URL(getCodeBase(),
"SecondApplet.html?" + "message="
+ URLEncoder.encode(t.getText())));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
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> '
html += '<PARAM NAME="Message" VALUE="' + theMessage + '"> '
html += '</APPLET>'
document.close()
document.open()
document.write(html)
document.close()
}
</SCRIPT>
</BODY></HTML>
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.
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;
}
</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>
By calling the javascript function from the BODY onLoad handler, we can assume that the Applet is loaded,
initiated and started.
Here a "browser friendly" solution from N. Witteman to check if an Applet can be loaded (or found).
<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>
For best result, never use LiveConnect JSObject in Applet's init() method.
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
installation.
For Java 1.4.2 and later: add plugin.jar to your classpath when compiling. It can be found in the lib directory
of your JRE installation, ex. C:\Program Files\Java\jre1.5.0\lib\plugin.jar
<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();
}
}
}
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function getJavaArray() {
arrayFromJava = document.myApplet.getJavaArray();
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 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
document.search property). And then the parameter extracted is send to another javascript function in the
visible frame.
[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.
[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">
<INPUT TYPE=button VALUE="Send to JAVA" onClick="send2Java();">
</FORM>
<APPLET CODE=SimpleApplet2.class
WIDTH=300
HEIGHT=150>
</APPLET></BODY></HTML>
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.*;
The class to hold a static pointer to SimpleApplet2. This pointer will be used by the InvisibleApplet.
[SimpleAppletRegistered.java]
[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: A Static class can be shared between Applets only if the Applets are coming from the same server and the MAYSCRIPT is not used.
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.
NOTE : 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.rgagnon.com/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";
}
</SCRIPT></HEAD>
<FRAMESET ROWS="35%,65%,*" onLoad="reload_master()">
<FRAME SRC="blank.html" NAME="master">
<FRAME SRC="blank.html" NAME="detail">
<FRAME SRC="../images" NAME="contents" NORESIZE>
</FRAMESET>
</HTML>
blank.html
<HTML<<HEAD><TITLE&glt;
</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>
To compile, make sure that you have the plugin.jar in the classpath (or Eclipse Build Path). This jar is
usually located in [JRE]/lib folder. During runtime, it's already included by the Java plugin so you don't have
to worry about that.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import netscape.javascript.*;
TextField tf;
Button b1;
JSObject win;
b1.addActionListener(this);
add(tf);add(b1);
}
Don't forget the MAYSCRIPT parameter in the APPLET tag, it's required since the Applet is using the
JSObject to interact with the Javascript.
<html>
<head>
<script>
function getUserAgent() {
return navigator.userAgent;
}
</script>
</head><body>
<applet code="GetUserAgent.class" MAYSCRIPT height=100 width=500></Applet>
</body>
</html>
Try it here
You need to parse the returned value to detect browser type. Look at this utility,
http://code.google.com/p/user-agent-utils/ or at this code : http://nerds.palmdrive.net/useragent/code.html to
get the idea.
When serving the HTML containing the Applet, you add the User-Agent as parameter for the Applet.
In a JSP/EL
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.*;
Servlet/JSP 533
Real's HowTo PDF version
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
}
}
out.println("</BODY></HTML>");
}
}
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.servlet.http.*;
response.setHeader("WWW-Authenticate",
"BASIC realm=\"protected-area\"");
}
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&site=java+howto");
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.
import javax.servlet.*;
import javax.servlet.http.*;
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
• Set the "content-length" on the response, otherwise the Acrobat Reader plugin may not work properly,
ex. response.setContentLength(bos.size());
• An additional thing that seems to help some IE browsers is to also have :
response.setHeader("Content-Disposition", "inline;filename=somepdf.pdf");
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
http://www.rgagnon.com/javadetails/../javadetails/java-0363.html
<%
out.print( request.getRemoteAddr() );
out.print( request.getRemoteHost() );
%>
You may not get the real client IP if a the client is behind a proxy, you will get the IP of the proxy and not the
client. However, the proxy may include the requesting client IP in a special HTTP header.
<%
out.print( request.getHeader("x-forwarded-for") );
%>
You can't.
JSP pages were designed for *text* output. The "out" object is a Writer, which means it will play games with
text encoding.
For binary output, like PDF or dynamically generated GIF, it's a better idea to use a servlet.
Having said that, since a JSP will be converted to a servlet, it's possible to modifed the output stream.
[image.jsp]
o.flush();
o.close();// *important* to ensure no more jsp output
return;
%>
There is a trimWhiteSpaces directive that should help to remove the whitespaces form the generated JSP.
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
If you really have a required space in the generated JSP then you need use the HTML non-breaking space
entity : .
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;
java.sql.Connection dbConn = null;
String jcmCacheString = "mycachename";
String msg = "";
try {
jcmCache =
com.sybase.jaguar.jcm.JCM.getCacheByName(jcmCacheString);
dbConn =
jcmCache.getConnection(com.sybase.jaguar.jcm.JCMCache.JCM_WAIT);
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
}
Web Application properties are defined in the WEB-INF/web.xml deployment descriptor (in between the
<webapp> </webapp> tag)
<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.
if (uri.endsWith(".jsp")) {
out.write("<li>"+ uri +"</li>");
out.flush();
RequestDispatcher rd =
getServletContext().getRequestDispatcher(uri);
if (rd == null) {
throw new Error(uri +" - not found");
}
rd.include(request, response);
}
else if (uri.endsWith("/")) {
compileAllJsps(pageContext, out, request, response, uri);
}
}
}
%>
<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";
};
};
compileAllJsps(pageContext, out, req, response, "/");
%>
</ul>
<h4>Done.</h4>
</body> </html>
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.
In this HowTo, the Windows utility NET is executed to get the members of a given group. The JSP
captures the output and to display it as Web page.
out.println("<pre>");
try {
String line;
Process p = Runtime.getRuntime().exec(cmdline);
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
The next example calls a VBSCRIPT to list the Windows groups for a specific user.
Option Explicit
Dim objNetwork, strDomain, strUser, objUser, objGroup, strGroupMemberships
out.println("<pre>");
String line;
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
try {
Process p = Runtime.getRuntime().exec(cmdline);
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream(), "Cp850"));
while ((line = input.readLine()) != null) {
list.add(line);
}
input.close();
}
java.util.Collections.sort(list);
for (String item:list) {
out.println(item);
Launch an external program, capture its output and display itin a JSP 552
Real's HowTo PDF version
}
out.println("</pre>");
%>
As always, special care must be taken if there is a risk that the called program can write something into
stderr (then the process will hang forever).
<jsp-descriptor>
<jsp-param>
<param-name>keepgenerated</param-name>
<param-value>true</param-value>
</jsp-param>
<jsp-param>
<param-name>working-dir</param-name>
<param-value>c:/bea10/user_projects/domains/mydomain/tmp</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;
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 );
}
%>
By default, Weblogic loads a class by asking the parent classloader to load the required class. This can be a
problem, if you have a JAR version in the server LIB directory and your web app requires an another
version.
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>
The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly
specify that certain packages should always be loaded from the application, rather than being loaded by the
system classloader.
The following example specifies that org.apache.log4j.* is loaded from the application, not the system
classloader:
<prefer-application-packages>
<package-name>org.apache.log4j.*</package-name>
</prefer-application-packages>
ref : http://download.oracle.com/docs/cd/E11035_01/wls100/programming/classloading.html#wp1097187
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.
It's possible to obtain a remote connection to a Datasource defined in the application server. In this
example, the connection is made to a Weblogic server so you need wlclient.jar in the classpath.
import java.sql.*;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.sql.DataSource;
env.put("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
env.put("java.naming.provider.url",
"t3://xxxxxxxx-xxxxx.xxx.xxxxx:7101");
InitialContext ctxProxy = new InitialContext(env);
Object dsObj = ctxProxy.lookup(datasourceName);
DataSource ds = (DataSource) PortableRemoteObject.narrow(dsObj,
javax.sql.DataSource.class);
PreparedStatement ps = null;
Connection conn = null;
ResultSet result = null;
try {
conn = ds.getConnection();
String SelectString = "SELECT NAME, ADDRESS FROM EMPLOYEE";
ps = conn.prepareStatement(SelectString);
for (result = ps.executeQuery(); result.next();) {
String data = result.getString(1) + " : " + result.getString(2);
System.out.println(data);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
result.close();
ps.close();
conn.close();
conn = null;
ps = null;
result = null;
}
}
}
The next example, make a remote call to an EJB host in a Weblogic server. You need wlclient and the EJB
client jars in the classpath.
import java.util.Properties;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import com.company.common.myejb.*;
System.out.println(myEJB.doit());
}
}
*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.
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.
Language 560
Real's HowTo PDF version
class MyClass {
MyClass() {
System.out.println
(this.getClass().getName() + " is loaded from " +
this.getClass().getProtectionDomain().getCodeSource().getLocation());
}
}
The output
C:/temp>java LoadingFromWhere
LoadingFromWhere is loaded from file:/C:/temp/
MyClass is loaded from file:/C:/temp/
Other technique
package com.rgagnon;
This technique returns the package too, If the class is in the com.rgagnon package then the output is
package com.rgagnon.howto;
/*
output :
I'm in com.rgagnon.howto.ClassFromStatic class
*/
JDK1.4+
JDK1.5+
While the above snippet is not bad, it is expensive since we need to create an Exception each time we needa
trace.
Now we know how to get the current method. If we need the calling instead instead :
import java.lang.reflect.*;
import java.io.*;
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
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);
}
}
private ClassUtils() {}
}
}
In this HowTo, we instantiate an object from its classname and pass a parameter to the constructor. And
then, we are calling a method dynamically.
try {
String name = "java.lang.String";
String methodName = "toLowerCase";
// create an instance
Object invoker =
constructor.newInstance
(new Object[]{"REAL'S HOWTO"});
System.out.println(result);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
import java.lang.reflect.Field;
@SuppressWarnings("rawtypes")
public static Object getValueOf(Object clazz, String lookingForValue)
throws Exception {
Field field = clazz.getClass().getField(lookingForValue);
Class clazzType = field.getType();
if (clazzType.toString().equals("double"))
return field.getDouble(clazz);
else if (clazzType.toString().equals("int"))
return field.getInt(clazz);
// else other type ...
// and finally
return field.get(clazz);
}
class TestClass {
public double firstValue = 3.1416;
public int secondValue = 42;
public String thirdValue = "Hello world";
}
The ellipsis … means that you can pass 0 or more parameters. If you prefer to force 1 parameter or more
then you can add 1 parameter followed by the VARARGS parameter to the signature.
}
}
The advantage is if you try to call the method with no parameter then the call will fail at compile time and
not runtime.
Java 1.6
This example creates an Hello class source, compiles it and calls a given method.
import java.io.*;
import java.lang.reflect.Method;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
writer.write(
"public class Hello{ \n" +
" public void doit() { \n" +
" System.out.println(\"Hello world\") ;\n" +
" }\n" +
"}"
);
writer.close();
fileManager.setLocation(StandardLocation.CLASS_OUTPUT,
Arrays.asList(new File("/temp")));
// Compile the file
compiler.getTask(null,
fileManager,
null,
null,
null,
fileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile)))
.call();
fileManager.close();
runIt();
}
@SuppressWarnings("unchecked")
public static void runIt() {
try {
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName("Hello");
Object iClass = thisClass.newInstance();
Method thisMethod = thisClass.getDeclaredMethod("doit", params);
thisMethod.invoke(iClass, paramsObj);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
• The tools.jar (located in the [JDK1.6]\lib) must be in the classpath during runtime, it is not included with
the JRE.
• You can compile many sources in one shot.
• The directory used to store the resulting class must be in the classpath if you want to use compiled class. In
Eclipse, you add the directory in the Build Path (as an External Class Folder).
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 myanotherapp"), 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
output :
Hello world!
*/
}
public void doit() {
new InnerClass().sayHello();
}
public void enclosingClassMethod(){
System.out.println("Hello world!");
}
class InnerClass {
public void sayHello() {
TestIt.this.enclosingClassMethod();
}
}
}
or
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 (That's why
the consructor is private). 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.
TheAppFrame {
...
setTitle(APPNAME);
...
}
...
}
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.
Serialize an Object
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0042.html
To serialize an object, it must implements the Serializable interface. The object needs 2 functions with these
signatures
Many standard Java objects already implements the Serializable interface so there is almost nothing to do.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
@SuppressWarnings("unchecked")
public static void main(String args[]) throws IOException, ClassNotFoundException {
ArrayList <String> arraySerialized = new ArrayList<String>();
arraySerialized.add("element 1");
arraySerialized.add("element 2");
arraySerialized.add("element 3");
arraySerialized.add("element 4");
arraySerialized.add("element 5");
System.out.println("ArrayList to be serialized : " + arraySerialized );
System.out.println("serializing the array");
ObjectOutputStream oos = null;
try {
FileOutputStream fout = new FileOutputStream("c:\\temp\\thearraylist.dat");
oos = new ObjectOutputStream(fout);
oos.writeObject(arraySerialized);
}
finally {
if (oos!=null) oos.close();
}
if (ois!=null) ois.close();
}
System.out.println("ArrayList unserialized : " + arrayUnserialized);
}
}
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 be a little bit 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
if (Debug.RELEASE) {
System.out.println("The value of i is " + i);
}
During compilation, since Debug.RELEASE is always true, the code will be present.
When compiling in that environment, the debugging code will be absent from the class file since
Debug.RELEASE is always false.
Have a Singleton
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0355.html
A singleton is a class that can be instantiated only one time in a JVM. Repeated calls always return the
same instance.
private OnlyOne(){}
To use it
/*
output :
i = 0 j= 0
i = 1 j= -1
i = 2 j= -2
i = 3 j= -3
i = 4 j= -4
i = 5 j= -5
i = 6 j= -6
i = 7 j= -7
i = 8 j= -8
i = 9 j= -9
*/
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.List;
...
...
java.awt.List myAwtList = new java.awt.List();
...
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
private ClassUtils() {}
To use it :
String hello="fubar";
double d = Math.PI;
I saw this article (use a generic toString()) and I might have another solution
/**
* Print all properties for a given bean. It's useful for overwriting
* toString method.
*
* @param bean
* Object to get all properties from.
* @param showNulls
* Determine if you wether you want to show null properties or
* not.
* @return String representing bean state.
* @author andres santana
*/
public static String showBean(Object bean, boolean showNulls) {
if (bean == null) return null;
StringBuilder sb =
new StringBuilder(bean.getClass().getName()).append("[");
try {
BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] pd = bi.getPropertyDescriptors();
for (int i = 0; i < pd.length; i++) {
if (!"class".equals(pd[i].getName())) {
Object result = pd[i].getReadMethod().invoke(bean);
if (showNulls || result != null) {
sb.append(pd[i].getDisplayName()).append("=").append(result);
if (i == pd.length - 1) continue;
sb.append(",");
}
}
}
}
catch (Exception ex) { }
return sb.append("]").toString();
}
Use a Object.clone()
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0433.html
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 it, any
modification will be done on the copy, not the original.
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[]) {
int max = 10;
int limit = 5;
int j = 0;
out: {
for (int row=0; row< max; row++ ) {
for (int col=0; col< max; col++ ) {
if( row == limit) break out;
}
j += 1;
}
}
System.out.println(j); // output 5
}
}
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.
enum Simpsons {
HOMER ("Homer"),
MADGE ("Marge"),
MAGGIE ("Maggie"),
BART ("Bart"),
LISA ("Lisa");
/*
output :
Homer
Marge
Maggie
Bart
Lisa
*/
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
private ObjectUtils() {}
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Use a Hashtable
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0027.html
Hashtables are very useful for maintaining a 1-to-1 relationship between Objects. With an arbitary key, you
can retrieve easily an Object. In the following example, we retrieve a String array with a String.
Sort an array
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0008.html
JDK1.4+
case-sensitive
case-insensitive
[ArraySorter.java]
/*
** 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]
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);
}
}
String to Array
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.
public String[] stringtoArray( String s, String sep ) {
// convert a String s to an Array, the elements
Thanks to T. GUIRADO
Array to String
result.append(separator);
result.append(a[i]);
}
}
return result.toString();
}
Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then
it is recommended that StringBuffer be used.
Resize an array
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0431.html
Arrays cannot be resized dynamically. If you want a dynamic data structure with random access, you use a
Collection (Map, ArrayList,...).
If you need to expand, you can use System.arraycopy() method to copy the content of an array to another
one.
import java.lang.reflect.Array;
private ArrayUtils() {}
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);
JDK1.5+
Convert the array to a List and then convert to String. This technique works only with classes and not with
primitives like int or double.
System.out.println(java.util.Arrays.asList(s).toString());
// output
// [a, b, c, d]
}
}
java.util.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 :
Sort an Hashtable
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0478.html
Data in hashtable are not sorted. We extract the keys and sort them.
import java.util.*;
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.
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");
^
C:\ArrayListGeneric.java:25: warning: [unchecked] unchecked conversion
found : java.util.Iterator
required: java.util.Iterator
Iterator it = data.iterator();
^
3 WARNINGS
Since there are only warnings, your class is ready to run but ... it's not bad idea to eliminate the warnings in
production code.
Simply add the expected type (between < and >) after the class.
import java.util.*;
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);
}
}
}
ANT
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.
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()) {
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") 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 {
private static String TEXT_BOOK_NAME = "war-and-peace.txt";
Result :
Sort an HashMap
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0561.html
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
...
Iterator<String> it = sortedset.iterator();
while (it.hasNext()) {
System.out.println (it.next());
}
...
while (it.hasNext()) {
String file = (String)it.next();
}
[Java 5]
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
private MapUtils() {}
System.out.println(MapUtils.getKeysFromValue(map,"Bart"));
}
}
[Java 1.4]
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
private MapUtils() {}
while (it.hasNext()) {
Object o = it.next();
if(hm.get(o).equals(value)) {
list.add(o);
}
}
return list;
}
System.out.println(MapUtils.getKeysFromValue(map,"Bart"));
}
}
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
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at com.rgagnon.howto.Simple.main(Simple.java:20)
*/
}
The trick is to use an Iterator and remove the item with Iterator.remove()
import java.util.ArrayList;
import java.util.Iterator;
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
*/
}
Submitted by T GUIRADO
/**
** This method counts distinct elements from a given position in vector
** containing series of element.
** Arguments : source = vector containing the vectors of elements
** position = which element to search, first position = 0
** count = serie length
**
** ex :
** source = A,B,C D,E,F D,F,G
** length is 3
** from position 0 in each series we have A,D,D
** this method returns 2 because there are 2 distinct elements (A and D)
** from position 2 in each series we have C,F,G
** this method returns 2 because there are 3 distinct elements (C,FandG)
**/
protected synchronized int countDistinctElements
(Vector source,int position,int count){
Vector v = null;
for (int i = 0 ; i < source.size() ; i++) {
boolean isFound = false;
if ( i % count == position ) {
if ( null != v ) {
for (int j = 0 ; j < v.size() ; j++) {
if ( source.elementAt(i).equals(v.elementAt(j) ) ) {
isFound = true;
j = v.size();
}
}
}
if ( !isFound ) {
if ( null == v ) v = new Vector(1, 1);
v.addElement( (String)source.elementAt(i) );
}
i += count - position;
}
}
try {
return v.size();
}
catch ( Exception e ) {
return 0;
}
}
Submitted by bdobby2000
protected static int countDistinctElements ( Vector source, int position, int count )
throws IllegalArgumentException , IndexOutOfBoundsException
{
List list = source.subList(position, position+count);
Set set = new HashSet();
set.addAll(list);
return set.size();
}
List
System.out.println(java.util.Arrays.toString(theSimpsons.toArray()));
/*
output : [Bart, Lisa, Marge, Barney, Homer, Maggie]
*/
Map
import java.util.*;
import java.io.*;
/*
output :
Bart: Bart.jpg
Lisa: Lisa.jpg
Maggie: Maggie.jpg
Homer: Homer.jpg
Barney: Barney.jpg
Marge: Marge.jpg
*/
Initialize a Collection
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0633.html
import java.util.List;
import java.util.ArrayList;
public class InitCollections {
public static void main(String args[]) {
ArrayList<String> list = new ArrayList<String>();
list.add("Bart");
list.add("Lisa");
list.add("Marge");
list.add("Barney");
list.add("Homer");
list.add("Maggie");
dump(list);
}
import java.util.List;
import java.util.ArrayList;
public class InitCollections {
static ArrayList<String> list = new ArrayList<String>();
static {
list.add("Bart");
list.add("Lisa");
list.add("Marge");
list.add("Barney");
list.add("Homer");
list.add("Maggie");
}
public static void main(String args[]) {
dump(list);
}
}
}
import java.util.List;
import java.util.ArrayList;
public class InitCollections {
Use Arrays.asList()
import java.util.List;
import java.util.Arrays;
public class InitCollections {
package com.rgagnon.howto;
import java.util.Arrays;
import java.util.List;
then
package com.rgagnon.howto;
The easy way is to convert the arrays into Lists, add one into another and finally convert back to an array.
import java.util.*;
/*
output : [a, b, c, d, e]
*/
}
}
From there a more versatile method is developped to accept a list of arrays to be merged into one.
int j = 0;
for (String[] array : parms) {
for (String s : array) {
result[j++] = s;
}
}
return result;
}
Using an interface
We put in an array an instance of each implementation. Then we are able to run the desired function by
using the array index.
Using an enum
then
}
}
NOTE : Using this technique, it's possible to simulate "switch ... case" based on a string value.
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.ArrayList;
private CollectionUtils() {}
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
private ListUtils() {}
Order is preserved
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
private ListUtils() {}
@SuppressWarnings("unchecked")
Map to Properties
or simply
Properties to Map
The ini4j is a simple Java API for handling configuration files in Windows .INI format.
http://ini4j.sourceforge.net/
As a bonus, ini4j can deal with variable subsitution, parse .REG file and write or read the registry.
The Apache Commons Configuration package provides the HierarchicalINIConfiguration class to handle
Windows INI file.
http://commons.apache.org/configuration/
Using Properties
The structure of a Properties is very similar to Windows INI file with except that there is no [...] section.
# this a comment
! this a comment too
DBuser=anonymous
DBpassword=&8djsx
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 (Load a properties file), this one (Accentuated characters in
Properties/ResourceBundle file) and finally this one too (Have a multi-line value in a properties file)!
import java.util.Properties;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.net.URL;
/**
* Load a Properties File
* @param propsFile
* @return Properties
* @throws IOException
*/
Load from the startup directory of your application (ex. directory containing the jar)
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.*;
import java.io.*;
class XMLProps {
public static void main(String args[]) {
new XMLProps().doit();
}
p.put("user", "Bob");
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;
Preferences p = Preferences.userRoot();
p.put(REALKEY, "bar");
See also this How-to (Query Windows registry) to access the Windows registry.
With Unix (or Linux), a file is used and you may run into problems if you don't have write access in the
default location for the Preferences storage. See this interesting article and these 2 bugs : 1 2
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
*/
}
}
A common way to use environment variables in a Properties file is to refer to them with the following
syntax :
The regular Properties class can't resolve the real value form the environment variable named
variableName.
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
private PropertiesUtils() {}
Pattern p = Pattern.compile("\\$\\{(\\w+)\\}|\\$(\\w+)");
Matcher m = p.matcher(value);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String envVarName = null == m.group(1) ? m.group(2) : m.group(1);
String envVarValue = System.getenv(envVarName);
m.appendReplacement(sb,
null == envVarValue ? "" : Matcher.quoteReplacement(envVarValue));
}
m.appendTail(sb);
return sb.toString();
}
}
to use it :
NOTE: Apache Commons Lang StrSubstitutor class can be used to do something similar but with Java
System Properties (not OS environment variable) or user-supplied map of values.
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").
Networking 633
Real's HowTo PDF version
import java.net.InetAddress;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
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();
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();
}
}
The output
Windows
A "low-tech" way to get the computer name (can be useful if there is no network card) is to use the
environment variable COMPUTERNAME (at least on modern Windows installation).
[JDK1.4 or less] Pass it to your JVM as java -Dcomputername="%COMPUTERNAME%" ... and then get the
value with System.getProperty("computername")
[JDK1.5 or more] You can extract environment variable directly with System.getenv("COMPUTERNAME")
To get the IP of a client from the server side, see this HowTo.
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 or more
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
Once an application has performed network access (i.e. urlconnection, parsing of xml document with external
references, etc), the DNS settings get cached internally so any subsequent operation will use the previously
read settings to achieve a better performance. There is one cache for successful lookups and one for
unsuccessful lookups. To get the contents of 2 caches, we are using introspection because these are private
elements of the InetAdress object.
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* By introspection, dump the InetAddress internal DNS cache
*
* @param cacheName can be addressCache or negativeCache
* @throws Exception
*/
Output
---------addressCache---------
0.0.0.0 Wed Jul 22 15:41:35 EDT 2015 [0.0.0.0]
stackoverflow.com Wed Jul 22 15:41:35 EDT 2015 [198.252.206.16]
www.google.com Wed Jul 22 15:41:35 EDT 2015 [173.194.123.49, 173.194.123.50, 173.194.123.48, 17
www.rgagnon.com Wed Jul 22 15:41:35 EDT 2015 [72.55.186.40]
---------negativeCache---------
bad.rgagnon.com Wed Jul 22 15:41:15 EDT 2015 [0.0.0.0]
In this HowTo, we saw that is possible to change the default behaviour of DNS caching.
---------addressCache---------
---------negativeCache---------
To cache forever
---------addressCache---------
0.0.0.0 Wed Dec 31 18:59:59 EST 1969 [0.0.0.0]
stackoverflow.com Wed Dec 31 18:59:59 EST 1969 [198.252.206.16]
www.google.com Wed Dec 31 18:59:59 EST 1969 [173.194.123.116, 173.194.123.114, 173.194.123.113,
www.rgagnon.com Wed Dec 31 18:59:59 EST 1969 [72.55.186.40]
---------negativeCache---------
bad.rgagnon.com Wed Dec 31 18:59:59 EST 1969 [0.0.0.0]
The following URL syntax is no longer supported in Internet Explorer or in Windows Explorer after you
install the MS04-004 Cumulative Security Update for Internet Explorer (832894):
http(s)://username:password@server/resource.ext
This change in the default behavior is also implemented by security updates and service packs that were
released after the 832894 security update.
By default, this new default behavior for handling user information in HTTP or HTTPS URLs applies only to
Windows Explorer and Internet Explorer. To use this new behavior in other programs that host the Web
browser control, create a DWORD value named SampleApp.exe, where SampleApp.exe is the name of the
executable file that runs the program. Set the DWORD value's value data to 1 in one of the following registry
keys.
• For all users of the program, set the value in the following registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
• For the current user of the program only, set the value in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
To disable the new default behavior in Windows Explorer and Internet Explorer, create iexplore.exe and
explorer.exe DWORD values in one of the following registry keys and set their value data to 0.
• For all users of the program, set the value in the following registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
• For the current user of the program only, set the value in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
As seen in this HowTo, the sun.misc.BASE64Encoder/Decoder or creating your own Base64 handling are
the more common way to deal with Base64 encoding/decoding.
Here some alternatives which are maybe easier (and safer) to use.
Using javax.mail.internet.MimeUtility
import javax.mail.internet.MimeUtility;
import java.io.*;
private Base64Utils() {}
Apache Commons Codec provides implementations of common encoders and decoders such as Base64,
Hex, Phonetic and URLs.
Download at http://commons.apache.org/codec/
import org.apache.commons.codec.binary.Base64;
// 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();
}
}
}
MiGBase64
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.*;
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.
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.*;
}
if ( line.charAt( 3 ) != '-' ) break;
}
return res;
}
return;
}
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() ) );
// 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
{
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() ) {
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() ) );
// 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.
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.
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;
}
}
Receive email
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0081.html
import java.net.*;
import java.io.*;
System.out.println("*****");
System.out.println(msg);
System.out.println("*****");
}
//
// If the mail was removed from the server
// (see getMail()) then we must COMMIT with
// the "QUIT" command :
// send(out, "QUIT");
//
}
}
catch (Exception e) {
e.printStackTrace();
}
}
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.*;
sendln
(out, "Content-Disposition: attachment;filename=\""+FileName+"\"");
sendln(out, "Content-transfer-encoding: base64\r\n");
MIMEBase64.encode(FileName, out);
sendln(out, "\r\n--" + boundary);
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)
encode "m"
01101101
011011 01
111111 (AND to fill the missing bits)
011011 010000
b Q = = (two paddings are added)
*/
send(out, "\r\n");
linelength = 0;
}
i += 3;
}
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("[email protected]"));
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");
("<h1>This is a test</h1>"
+ "<img src=\"http://www.rgagnon.com/images/jht.gif\">",
"text/html");
message.addRecipient(Message.RecipientType.TO,
new InternetAddress("[email protected]"));
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
The browser accesses these images just as if it were displaying an image in a Web page. Unfortunately,
spammers have used this mechanism as a sneaky way to record who visits their site (and mark your email
as valid). To protect your privacy, many Web-based (and other) email clients don't display images in
HTML emails.
An alternative to placing absolute URLs to images in your HTML is to include the images as attachments
to the email. The HTML can reference the image in an attachment by using the protocol prefix cid: plus the
content-id of the attachment.
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.util.Properties;
class SimpleMail2 {
public static void main(String[] args) throws Exception{
System.out.println("Sending mail...");
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.mymailserver.com");
props.setProperty("mail.user", "myuser");
props.setProperty("mail.password", "mypwd");
//
// This HTML mail have to 2 part, the BODY and the embedded image
//
MimeMultipart multipart = new MimeMultipart("related");
// add it
multipart.addBodyPart(messageBodyPart);
// add it
multipart.addBodyPart(messageBodyPart);
transport.connect();
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
This setting puts the JavaMail classes in debug mode mode to System.out.
To redirect the JavaMail debugging output to a more appropriate log file you can
telnet mymailserver 25
for example, you can detect if your firewall is blocking your connection.
Windows 7
By default, the telnet client is not installed on a Win7 workstation. To installed it, open command shell and
type :
pkgmgr /iu:"TelnetClient"
You can also install it through the Control Panel, see Microsoft Technet.
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("[email protected]"));
transport.connect
(SMTP_HOST_NAME, SMTP_HOST_PORT, SMTP_AUTH_USER, SMTP_AUTH_PWD);
transport.sendMessage(message,
message.getRecipients(Message.RecipientType.TO));
transport.close();
}
}
Even you send to correct credentials, it's possible that you get the
javax.mail.AuthenticationFailedException exception from Gmail. If it's the case, you may need to explicitly
enable "less secure apps" setting in your Gmail account, see
https://support.google.com/accounts/answer/6010255>Answer from Google.
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");
multipart.addBodyPart(messageBodyPart);
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.
http://poi.apache.org/hsmf/
HSMF is the POI Project's pure Java implementation of the Outlook MSG format.
POI 3.6
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
// extract attachment
ByteArrayInputStream fileIn = (ByteArrayInputStream)entry.getValue();
File f = new File("c:/temp", attachmentfilename); // output
OutputStream fileOut = null;
try {
fileOut = new FileOutputStream(f);
byte[] buffer = new byte[2048];
int bNum = fileIn.read(buffer);
while(bNum > 0) {
fileOut.write(buffer);
bNum = fileIn.read(buffer);
}
}
finally {
try {
if(fileIn != null) {
fileIn.close();
}
}
finally {
if(fileOut != null) {
fileOut.close();
}
}
}
}
}
else {
System.out.println("No attachment");
}
}
}
POI 3.7
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import org.apache.poi.hdgf.chunks.Chunk;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.datatypes.Chunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
System.out.println("No attachment");
}
}
}
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.*;
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 <[email protected]>; Sun, 1 Feb 2004 13:25:33 -0500 (EST)
Date: Sun, 01 Feb 2004 13:31:40 -0500
From: real gagnon <[email protected]>
Reply-To: [email protected]
User-Agent: Mozilla/5.0
(Windows; U; Windows NT 5.1; en-US; rv:1.4)
Gecko/20030624 Netscape/7.1 (ax)
X-Accept-Language: en-us, en
MIME-Version: 1.0
To: [email protected]
Subject: Example for HowTo
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
X-UIDL: oP#!!c]^!!1;-!!T@1"!
First you connect to the mail server with POP3 or IMAP protocol to retrieve the emails.
...
folder = store.getDefaultFolder().getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
...
for (int i=0; i < messages.length; ++i) {
Message msg = messages[i];
String subject = msg.getSubject();
processSaveToFile(msg, subject);
...
}
...
Since the subject is used to set the filename, it's not a bad idea to sanitize it to remove illegal characters.
http://www.rgagnon.com/javadetails/../javadetails/java-receive-email-using-imap.html
IMAP presents mail messages as entries in a hierarchy of folders, one of which will be an inbox.
Java Mail comes with Provider implementations for POP3 and IMAP, and the secure versions of those as
POP3S and IMAPS.
This HowTo connects to a Google Mail account with IMAPS. IMAP protocol is more advanced than POP.
With IMAP, you can talk back to the server and sync your changes automatically.
This Howto connects to a server using the IMAPS (Secure, encrypted IMAP) to download messages with
or without attachments and save them into files.
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public ReceiveMailImap() {}
//
// inspired by :
// http://www.mikedesjardins.net/content/2008/03/using-javamail-to-read-and-extract/
//
else {
if (part.isMimeType("text/plain")) {
extension = "txt";
}
else {
// Try to get the name of the attachment
extension = part.getDataHandler().getName();
}
filename = filename + "." + extension;
System.out.println("... " + filename);
out = new FileOutputStream(new File(filename));
in = part.getInputStream();
int k;
while ((k = in.read()) != -1) {
out.write(k);
}
}
}
}
}
}
finally {
if (in != null) { in.close(); }
if (out != null) { out.flush(); out.close(); }
}
}
Java Mail comes with Provider implementations for POP3 and IMAP, and the secure versions of those as
POP3S and IMAPS.
This Howto connects to a server using the POP3S (Secure, encrypted POP3) to download messages with or
without attachments and save them into files.
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
This above snippet reads the HTML page and dumps it to the console.
To trace what is going on at the HTTP protocol level, we can switch the
HttpURLConnection/UrlConnection in debug mode.
You must enable the java-logging mechanism by setting a special property when starting the JVM :
and put in logging.properties file (by default in JRE_HOME\lib) the following property
sun.net.www.protocol.http.HttpURLConnection.level = ALL
Note :
If running from Eclipse, you put the -Djava.util.logging... via the Run configuration dialog -> Arguments
Tab -> VM arguments textarea.
The result is :
URL u =null;
long timestamp = 0;
try {
u = new URL(getDocumentBase(), "test.gif");
URLConnection uc = u.openConnection();
uc.setUseCaches(false);
/*
** use timestamp has a reference, re-open an URLConnection
** to the same file to check if the timestamp is different
** with the getLastModified() method.
*/
timestamp = uc.getLastModified();
}
catch (Exception e) {
e.printStackTrace();
}
}
[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/javase/6/docs/technotes/guides/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 :
System.setProperty("http.proxyHost", "myProxyServer.com");
System.setProperty("http.proxyPort", "80");
Since Java 1.5 you can also pass a java.net.Proxy instance to the openConnection() method:
//Proxy instance, proxy ip = 123.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("123.0.0.1", 8080));
URL url = new URL("http://www.yahoo.com");
HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);
uc.connect();
String page;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((line = in.readLine()) != null){
page.append(line + "\n");
}
System.out.println(page);
You can use the default PROXY as defined by your networking settings.
System.setProperty("java.net.useSystemProxies", "true");
List l = null;
try {
l = ProxySelector.getDefault().select(new URI("http://www.yahoo.com"));
}
catch (URISyntaxException e) {
e.printStackTrace();
}
if (l != null) {
for (Iterator iter = l.iterator(); iter.hasNext() {
java.net.Proxy proxy = (java.net.Proxy) iter.next();
System.out.println("proxy hostname : " + proxy.type());
InetSocketAddress addr = (InetSocketAddress) proxy.address();
if (addr == null) {
System.out.println("No Proxy");
}
else {
System.out.println("proxy hostname : " + addr.getHostName());
System.out.println("proxy port : " + addr.getPort());
}
}
}
One way is to use the HTTP property "Proxy-Authorization" with a username:password base64 encoded.
System.setProperty("http.proxyHost", "myProxyServer.com");
System.setProperty("http.proxyPort", "80");
URL url=new URL("http://someserver/somepage");
URLConnection uc = url.openConnection ();
String encoded = new String
(Base64.base64Encode(new String("username:password").getBytes()));
uc.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
uc.connect();
The following example dumps the content of a URL but before we identify ourself to the proxy.
import java.net.*;
import java.io.*;
// PROXY
System.setProperty("http.proxyHost","proxy.mydomain.local") ;
System.setProperty("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.
// PROXY
System.setProperty("http.proxyHost","proxy.mydomain.local") ;
System.setProperty("http.proxyPort", "80") ;
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new
PasswordAuthentication("mydomain\\username","password".toCharArray());
}});
Bypass a Proxy
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.*;
}
return encodedString;
}
}
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.
Use of the sun.* package is "discouraged" by sun and not formally supported. Those classes can be missing
in your JDK release.
Check this HowTo for a more official way to encode/decode to/from Base64.
Talk to a CGI/Servlet
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0082.html
From the client point of view, there is no difference talking to CGI or Servlet. There is two ways to send a
request to a CGI. The GET method contains encoded parameters in the URL. A typical URL talking to CGI
using the GET method would be:
new URL("http://www.server.com/cgi-bin/acgi.pl?name=real&site=java+howto");
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.
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.
*
/**
* 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;
while ((hdrKey = urlConn.getHeaderFieldKey(i)) != null) {
if (hdrKey.equals("Set-Cookie")) {
hdrString = urlConn.getHeaderField(i);
StringTokenizer st = new StringTokenizer(hdrString,",");
while (st.hasMoreTokens()) {
String s = st.nextToken();
aCookie = s.substring(0, s.indexOf(";"));
// aCookie = hdrString.substring(0, s.indexOf(";"));
int j = aCookie.indexOf("=");
if (j != -1) {
if (!theCookies.containsKey(aCookie.substring(0, j))){
// if the Cookie do not already exist then when keep it,
// you may want to add some logic to update
// the stored Cookie instead. thanks to rwhelan
theCookies.put
(aCookie.substring(0, j),aCookie.substring(j + 1));
if (printCookies){
System.out.println("Reading Key: "
+ aCookie.substring(0, j));
/**
* 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
* @param printCookies Print or not the result
*/
public void addCookie(String _key, String _val, boolean printCookies){
if (!theCookies.containsKey(_key)){
theCookies.put(_key,_val);
if (printCookies){
System.out.println("Adding Cookie: ");
System.out.println(" " + _key + " = " + _val);
}
}
}
}
import java.io.IOException;
import java.net.URL;
import java.util.Scanner;
private NetUtils() {}
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).
java.security.Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());
System.setProperty
("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
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:
HTTPS protocol is supported since JDK1.4 (AFAIK), you have nothing special to do.
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
However, you can have a problem if the server certificate is self-signed by a testing certification authority
(CA) which is not in trusted CAs of Java on the client side. An exception like
The fix is to add the self signed certificate to trusted CAs on the client side. You do that by updating the
CACERT file in the your JRE_HOME/lib directory.
Or you can override the check and accept an untrusted certificate (with the risk coming with it!).
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
/*
* end of the fix
*/
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)");
Upload a file
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0543.html
To upload a file to a server you need something on the server side to accept the file, you can't do it with
client-side code only. A simple way to use the HTML tag in a FORM
File to upload:
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.
A special regular expression is used to strip out anything between a < and > .
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.
Using javax.swing.text.html.HTMLEditorKit
In most cases, the HTMLEditorKit is used with a JEditorPane text component but it can be also used
directly to extract text from an HTML page.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.MutableAttributeSet;
Remove HTML tags from a file to extract only the TEXT 708
Real's HowTo PDF version
}
public void handleStartTag(Tag tag, MutableAttributeSet attribute, int pos) { }
public void handleEndTag(Tag t, final int pos) { }
public void handleSimpleTag(Tag t, MutableAttributeSet a, final int pos) { }
public void handleComment(final char[] data, final int pos) { }
public void handleError(final java.lang.String errMsg, final int pos) { }
};
parserDelegator.parse(reader, parserCallback, true);
return list;
}
Note that the HTMLEditorKit can be easily confused if the HTML to be parsed is not well-formed.
This is maybe the best solution (if the choosen parser is good !).
There are many parsers available on the net. In this HowTo, I will use the OpenSource package Jsoup.
Jsoup is entirely self contained and has no dependencies which is a good thing.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.io.BufferedReader;
import org.jsoup.Jsoup;
Remove HTML tags from a file to extract only the TEXT 709
Real's HowTo PDF version
("C:/RealHowTo/topics/java-language.html");
System.out.println(HTMLUtils.extractText(reader));
}
}
Apache Tika
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/java-x.html");
ContentHandler contenthandler = new BodyContentHandler();
Metadata metadata = new Metadata();
Parser parser = new AutoDetectParser();
parser.parse(is, contenthandler, metadata, new ParseContext());
System.out.println(contenthandler.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null) is.close();
}
}
}
See Extract text from a PDF using Apache Tika, Get Mime Type from a file.
Remove HTML tags from a file to extract only the TEXT 710
Real's HowTo PDF version
Using javax.swing.text.html.HTMLEditorKit
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.HTML.Attribute;
import javax.swing.text.MutableAttributeSet;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
// href ...
for (Element link : links) {
result.add(link.attr("abs:href"));
}
// img ...
for (Element src : media) {
result.add(src.attr("abs:src"));
}
ServiceGen is an utility to generate a client module to access a web service hosted by BEA WLS.
This example use a generated client to call the function list of a Web Service.
import com.company.webservices.client.Commonwebservices;
import com.company.webservices.client.CommonwebservicesPort;
import com.company.webservices.client.Commonwebservices_Impl;
A typical output :
URL : http://server.company.local:80/commonWS/commonwebservices
Headers :
Content-Length: [459]
SOAPAction: [""]
Content-Type: [text/xml; charset=utf-8]
URL : http://server.company.local:80/commonWS/commonwebservices
Response Code :200
Headers :
Date=Mon, 17 Aug 2009 14:36:29 GMT
Server=Microsoft-IIS/6.0
X-Powered-By=Servlet/2.5 JSP/2.1
Cache-Control=no-cache="set-cookie"
Content-Length=1211
Content-Type=text/xml; charset=ISO-8859-1
Set-Cookie=JSESSIONID=BJYXKJqfFC7nl9TMgYkJg9DpL5kZ1nTQy2M8v1BXJnT1R8n1DhfX!-1553076658; pat
Envelope :
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Header></env:Header>
<env:Body env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:listResponse xmlns:m="http://company.local/common">
<result xsi:type="xsd:string">\\company.local\fonc_sas, \\company.local\unit_sas, \\company.l
</result></m:listResponse></env:Body></env:Envelope>
<!-------------------- END RESPONSE TO CLIENT ----------->
\\company.local\fonc_sas, \\company.local\unit_sas, \\company.local\prod_sas
If you need authentication to access the WSDL then it's possible to do something like this :
String wsdlUri =
"http://myusername:[email protected]/commonWS/commonwebservices?WSDL";
You have a web service, generated with JAX-WS or something else. You have the required client class but
you need to provide a username/password. This can done easily with the help of the
java.net.Authenticator. In this snippet, we are using an anonymous Authenticator to pass the credentials.
import java.net.Authenticator;
import java.net.PasswordAuthentication;
WLS uses its own HTTP protocol implementation, so the above technique won't work, a 401 return code is
always returned.
So if from Weblogic, you need to call a Web service and identify yourself using HTTP BASIC then you
need to make sure to use the Sun's HTTP implementation, not the default and "push" the credentials.
import javax.xml.ws.BindingProvider;
...
URL url;
if (wsUrl.startsWith("https")) {
url = new URL(null, svcUrl, new sun.net.www.protocol.https.Handler());
}
else {
url = new URL(null, svcUrl, new sun.net.www.protocol.http.Handler());
}
((BindingProvider)engine).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "usernam
((BindingProvider)engine).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "passwor
Since Java 1.6, there's a built-in HTTP server included with the JDK.
The HttpServer provides a simple high-level Http server API, which can be used to build embedded HTTP
servers.
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
/*
* a simple static http server
*/
public class SimpleHttpServer {
Compile and execute. To access the local server, open a browser at http://localhost:8000/test.
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.Headers;
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read
and write. It is used primarily to transmit data between a server and web application, as an alternative to
XML.
JSON structures are easy to manipulate from Java. The required libraries are now included in the Java EE 7
specification.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
import java.io.StringReader;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
// https://jsonp.java.net/download.html
public class Json1 {
String jsonString = "{" +
" \"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 25," +
" \"address\" : { " +
" \"streetAddress\": \"21 2nd Street\"," +
" \"city\": \"New York\"," +
" \"state\": \"NY\"," +
" \"postalCode\": \"10021\"" +
" }," +
" \"phoneNumber\": [" +
" { \"type\": \"home\", \"number\": \"212 555-1234\" }," +
" { \"type\": \"fax\", \"number\": \"646 555-4567\" }" +
" ]" +
"}";
reader.close();
System.out.println(object.getString("firstName") + " " + object.getString("lastName"))
System.out.println(object.getJsonObject("address").getString("city")) ;
/*
output :
John Smith
New York
*/
}
}
import javax.json.Json;
import javax.json.JsonObject;
To call the REST service, we will use the HTTPClient module from Apache.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
• https://jsonp.java.net/download.html
• http://hc.apache.org/downloads.cgi
For the demonstration, we call http://jsonplaceholder.typicode.com/ which is Fake Online REST API for
Testing and Prototyping.
The first example calls jsonplaceholder.typicode.com/posts/1 to get the first message. From the response,
we extract the id and the title.
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit ...eveniet architecto"
}
import java.io.InputStreamReader;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
Now we call jsonplaceholder.typicode.com/posts which returns a message list of 100 elements. From the
response, we iterate the returned array to display the id and the title.
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
import java.io.InputStreamReader;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
output
id : 1
title : sunt aut facere repellat provident occaecati excepturi optio reprehende
...
id : 100
title : at nam consequatur ea labore ea harum
Done.
*/
}
finally {
if (reader != null) reader.close();
if (client != null) client.close();
if (response != null) response.close();
System.out.println("Done.");
}
}
}
import java.io.InputStream;
import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
//https://jsonp.java.net/download.html
//http://hc.apache.org/downloads.cgi
+ response.getStatusLine().getStatusCode());
}
InputStream is = response.getEntity().getContent();
JsonParser parser = Json.createParser(is);
while (parser.hasNext()) {
Event e = parser.next();
if (e == Event.KEY_NAME) {
switch (parser.getString()) {
case "id":
parser.next();
System.out.print(parser.getString());
System.out.print(": ");
break;
case "title":
parser.next();
System.out.println(parser.getString());
System.out.println("---------");
break;
}
}
}
/*
output :
1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
-------------
2: qui est esse
---------
...
99: temporibus sit alias delectus eligendi possimus magni
---------
100: at nam consequatur ea labore ea harum
---------
Done.
*/
}
finally {
if (client != null) client.close();
if (response != null) response.close();
System.out.println("Done.");
}
}
}
It's possible to do it by hand by calling the jasonobject.get[type] and the corresponding DTO/POJO set
methods. But it is easier to use a library to handle the finer details. One library which is nice is GSON.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
import java.io.InputStreamReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import com.google.gson.Gson;
// https://jsonp.java.net/download.html
// http://hc.apache.org/downloads.cgi
// http://search.maven.org/#artifactdetails|com.google.code.gson|gson|2.3.1|jar
import com.google.gson.Gson;
// http://search.maven.org/#artifactdetails|com.google.code.gson|gson|2.3.1|jar
By default, when you make a request to URL, the response is not compressed.
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
}
}
Length : 21740
<!DOCTYPE HTML>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<LINK REL="SHORTCUT ICON" HREF="http://www.rgagnon.com/favicon.ico">
<META NAME="description"
Content="Real's JAVA JAVASCRIPT WSH and PowerBuilder How-to pages with useful cod
<META NAME="keywords"
Content="java,javascript,wsh,vbscript,how-to,powerbuilder">
...
By setting the Request Header "Accept" to "gzip", we are telling to the server that we want the response to
be compressed if possible with the GZIP compression scheme. If it's not supported by the server then the
response will be sent as plain text.
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
Now the response length is 4865 but the content is not readable because we need to uncompress it!
Length : 4865
j¼Eðßô[è^úðGR¾vø
...
We add a check to determine if the response is compressed or not to use the appropriate InputStream
because the web server is by no means obliged to use any compression method - this depends on the
internal settings of the web server.
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.zip.GZIPInputStream;
while (true) {
int ch = reader.read();
if (ch==-1) {
break;
}
System.out.print((char)ch);
}
}
}
Length : 4865
<!DOCTYPE HTML>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<LINK REL="SHORTCUT ICON" HREF="http://www.rgagnon.com/favicon.ico">
<META NAME="description"
Content="Real's JAVA JAVASCRIPT WSH and PowerBuilder How-to pages with useful cod
<META NAME="keywords"
Content="java,javascript,wsh,vbscript,how-to,powerbuilder">
...
NOTE: proxyHost, proxyPort are deprecated. you have to prefix them with "http.".
NOTE: Those properties are documented here :
http://java.sun.com/javase/6/docs/technotes/guides/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 :
System.setProperty("http.proxyHost", "myProxyServer.com");
System.setProperty("http.proxyPort", "80");
Since Java 1.5 you can also pass a java.net.Proxy instance to the openConnection() method:
//Proxy instance, proxy ip = 123.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("123.0.0.1", 8080));
URL url = new URL("http://www.yahoo.com");
HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);
uc.connect();
String page;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((line = in.readLine()) != null){
page.append(line + "\n");
}
System.out.println(page);
You can use the default PROXY as defined by your networking settings.
System.setProperty("java.net.useSystemProxies", "true");
List l = null;
try {
l = ProxySelector.getDefault().select(new URI("http://www.yahoo.com"));
}
catch (URISyntaxException e) {
e.printStackTrace();
}
if (l != null) {
for (Iterator iter = l.iterator(); iter.hasNext() {
java.net.Proxy proxy = (java.net.Proxy) iter.next();
System.out.println("proxy hostname : " + proxy.type());
InetSocketAddress addr = (InetSocketAddress) proxy.address();
if (addr == null) {
System.out.println("No Proxy");
}
else {
System.out.println("proxy hostname : " + addr.getHostName());
System.out.println("proxy port : " + addr.getPort());
}
}
}
One way is to use the HTTP property "Proxy-Authorization" with a username:password base64 encoded.
System.setProperty("http.proxyHost", "myProxyServer.com");
System.setProperty("http.proxyPort", "80");
URL url=new URL("http://someserver/somepage");
URLConnection uc = url.openConnection ();
String encoded = new String
(Base64.base64Encode(new String("username:password").getBytes()));
uc.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
uc.connect();
The following example dumps the content of a URL but before we identify ourself to the proxy.
import java.net.*;
import java.io.*;
System.out.println("**************");
URLUtils.dump("https://www.paypal.com");
System.out.println("**************");
}
// PROXY
System.setProperty("http.proxyHost","proxy.mydomain.local") ;
System.setProperty("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.
// PROXY
System.setProperty("http.proxyHost","proxy.mydomain.local") ;
System.setProperty("http.proxyPort", "80") ;
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new
PasswordAuthentication("mydomain\\username","password".toCharArray());
}});
Bypass a Proxy
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.
Ping a server
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0093.html
It's not possible to really "ping" a machine to check if it's alive or not (it's a long story, but to keep it short I
will just say that the Socket class is not low-level enough for that operation). But we can emulate a ping by
talking the "echo port". On a server, the echo port is always port 7. We write a string to that port and the
server will echo the string.
import java.io.*;
import java.net.*;
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.*;
}
catch (IOException e) {
System.err.println("Unable to reach web.mit.edu");
}
}
}
isReachable() will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to
establish a TCP connection on port 7 (Echo) of the destination host. But most Internet sites have disabled
the service or blocked the requests (except some university web sites like the example above) .
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.*;
By using the setSoLinger() method, you can explicitly set a delay before a reset is sent, giving more time
for data to be read or send, or you can specify a delay of zero, meaning a reset will be sent as soon as the
java.net.Socket.close() method is invoked. You can possibly increase performance with a delay of zero.
Note that if a linger time is set to zero, then any unsent packets are thrown away when the socket is closed
otherwise the close() method blocks while waiting the specified number of seconds for the data to be sent,
and acknowledgements to be received.
The java.net.Socket.setSoLinger() method accepts as parameters a boolean and an int. The boolean flag
activates or deactivates the SO_LINGER option, and the int controls the delay time (in seconds, max
65535).
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());
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public final static int SOCKET_PORT = 13267; // you may change this
public final static String FILE_TO_SEND = "c:/temp/source.pdf"; // you may change this
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public final static int SOCKET_PORT = 13267; // you may change this
public final static String SERVER = "127.0.0.1"; // localhost
public final static String
FILE_TO_RECEIVED = "c:/temp/source-downloaded.pdf"; // you may change this, I give a
// different name because i don't
// overwrite the one used by serv
public final static int FILE_SIZE = 6022386; // file size temporary hard coded
// should bigger than the file to be downloade
// receive file
byte [] mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File " + FILE_TO_RECEIVED
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
To try it, first you start the server. You make sure that the file to be sent (as specified in SimpleFileServer)
exists! Then you execute the client module.
To download a file, a simpler and better way is to use the built-in JDK HTTP server, see this HowTo
To check if a document is present in a Sharepoint library, we are using the REST API provided by
Microsoft. All we need is the Apache HttpComponents library to make the call.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* check if a document exists in a sharepoint library
*/
public static void main(String[] args) throws Exception{
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false))
.build();
See also :
To delete a document in a Sharepoint library, we are using the REST API provided by Microsoft.
All we need is the Apache HttpComponents library to make the call.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* delete a file in a sharepoint library
*/
public static void main(String[] args) throws Exception{
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false))
.build();
//
// 204 No Content
// The server successfully processed the request, but is not returning any con
// Usually used as a response to a successful delete request.
// other
// we have a problem
}
}
See also :
To retrieve or download a document from a Sharepoint library, we are using the REST API
provided by Microsoft. All we need is the Apache HttpComponents.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* download a file from a sharepoint library
*/
public static void main(String[] args) throws Exception{
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false))
.build();
See also :
To store or upload a document into a Sharepoint library, we are using the REST API provided by
Microsoft. All we need is the Apache HttpComponents library.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
import java.io.File;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
}
else if (rc == HttpStatus.SC_OK) {
System.out.println(file + " is copied (original overwritten)");
}
else {
throw new Exception("Problem while copying " + file
+ " reason " + reason + " httpcode : " + rc);
}
}
finally {
if (response2 != null) response2.close();
}
return;
}
}
See also :
You can access the public folders from Microsoft Exchange by calling the Exchange Web Services
(EWS). An Open Source library is available to allow Java program to easily call thoses services,
ews-java-api. You can get a ready to use jar at the Sonatype OSS repository. Be sure to get all the
dependencies! With Maven, use this POM :
<dependency>
<groupId>com.microsoft.ews-java-api</groupId>
<artifactId>ews-java-api</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
to connect
to navigate, you position yourself level by level. You can save each item of a folder as EML file.
EML is the format used by Exchange and can be opened by Outlook or any mail client and be
parsed by JavaMail .
For example, we want to go in the folder \level1\level2, then save the first 5 items as EML files.
// search for a specific folder and then list the first 5 item
FolderView view = new FolderView(10);
SearchFilter filter = new SearchFilter.ContainsSubstring(FolderSchema.DisplayName, "l
FindFoldersResults findResults = service.findFolders(WellKnownFolderName.PublicFolder
// save .eml
for (Item item : findResults3.getItems()) {
System.out.println("!! " + item.getSubject());
String subject = item.getSubject();
item.load(new PropertySet(ItemSchema.MimeContent));
MimeContent mc = item.getMimeContent();
// it may be a good idea to sanitize a little bit the filename to remove illega
// see this HowTo
FileOutputStream fs = new FileOutputStream("c:/temp/" + subject + ".eml");
to delete
service.close();
System.out.println("Done.");
In this HowTo, EWS was used to access the public folders but you can use it to send/receive
regular mail or create appointment/task. See
https://github.com/OfficeDev/ews-java-api/blob/master/readme.md for more details.
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/
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.
https://com4j.dev.java.net/
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
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.
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, normal, and optional task in
different colors. Tis a great way to document your Ant build file.
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 ...
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.
Launch4J
http://launch4j.sourceforge.net/
Launch4j is a cross-platform tool for wrapping Java applications distributed as jars in lightweight Windows
native executables. The executable can be configured to search for a certain JRE version or use a bundled one.
CSVPrinter/CSVParser/ExcelCSVPrinter/ExcelCSVParser
http://ostermiller.org/utils/CSV.html
opencsv
ServingXML
Super CSV
This CSV reader/writer makes it easy to read/write objects/maps/string lists with automatic type
conversion and constraint checking.
http://supercsv.sourceforge.net/
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
CSVFile
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.
http://flatpack.sourceforge.net/
CSVJDBC
CsvJdbc is a simple read-only JDBC driver that uses Comma Separated Value (CSV) files as database
tables.
http://csvjdbc.sourceforge.net/
FFP
FFP - Flat file parsing library, is used to parse text files where lines can be interpreted according to
positional patterns. The library can handle both multi-line formats and files containing lines have
different known formats ("mixed format" files).
http://jffp.sourceforge.net/
XSLT
XSLT is built-in in the JDK, you need to create your own transformation in a XSL file. Transform
XML into CSV using XSLT
There are many solutions to read or write Excel spreadsheets from Java. This HowTo is only about
OpenSource (and free) solutions.
For Java 8 you cannot use the JDBC-ODBC Bridge because it has been removed.
This solution lets you access your Excel worksheet with SQL SELECT statement. The required
ODBC driver is included in a regular Windows installation and the JDBC-ODBC bridge is used to
access the Excel DSN.
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/
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. Latest POI
version seems to support the .XLSX format.
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/
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
Reading values from an XLS with jXLS is very simple. Suppose we have a worksheet with policy
numbers in the first column. We read and process them one by one.
import java.io.File;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
See http://jxls.sourceforge.net/
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/
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");
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.
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++) {
// 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");
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.
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
JAD is good but out-dated, the new class format introduced with JDK1.5 is not well supported.
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
JD - Java decompiler
The Java Decompiler project aims to develop tools in order to decompile and analyze Java 5 byte
code and the later versions.
Also available is JD-GUI, a standalone graphical utility that displays Java source codes of .class files,
and JD-Eclipse, a plug-in for the Eclipse platform.
http://java.decompiler.free.fr/
JarPlug
By default, the support for viewing and editing JAR file in Eclipse is very limited.
http://jar-plug.sourceforge.net/
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/
Fat Jar
The Fat Jar Eclipse Plug-In is a Deployment-Tool which deploys an Eclipse java-project into one
executable jar.
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
http://poi.apache.org/hsmf/
HSMF is the POI Project's pure Java implementation of the Outlook MSG format.
POI 3.6
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
// extract attachment
ByteArrayInputStream fileIn = (ByteArrayInputStream)entry.getValue();
File f = new File("c:/temp", attachmentfilename); // output
OutputStream fileOut = null;
try {
fileOut = new FileOutputStream(f);
byte[] buffer = new byte[2048];
int bNum = fileIn.read(buffer);
while(bNum > 0) {
fileOut.write(buffer);
bNum = fileIn.read(buffer);
}
}
finally {
try {
if(fileIn != null) {
fileIn.close();
}
}
finally {
if(fileOut != null) {
fileOut.close();
}
}
}
}
}
else {
System.out.println("No attachment");
}
}
}
POI 3.7
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import org.apache.poi.hdgf.chunks.Chunk;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.datatypes.Chunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
fileOut.write(buffer);
bNum = fileIn.read(buffer);
}
}
finally {
try {
if(fileIn != null) {
fileIn.close();
}
}
finally {
if(fileOut != null) {
fileOut.close();
}
}
}
}
}
else {
System.out.println("No attachment");
}
}
}
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.*;
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).
http://jpoller.sourceforge.net/
A general purpose Java component to enable polling on directories and aysnchronously notify client
code of incoming files. It's instrumented via JMX and controllable (also) via a JMX agent, like JBoss'
JMX console.
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).
https://github.com/twall/jna#readme
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
http://johannburkard.de/blog/programming/java/Call-native-methods-in-a-DLL-from-Java-without-JNI.html
In this blog entry, the package NativeCall is used to call the Windows API to get notification about
modification in given folder.
Java 7
Java 7 provides a mechanism to get notification on file change without polling (WatchService).
To clear the screen, you can use many System.out.println();, that's about it!
While it is possible to use the DOS ANSI.SYS driver with Windows 9x and make old JVM use it ... it
won't work with modern Windows installations. Windows NT (or better) CMD.EXE does not support
Fortunately many Open Source solutions are coming to the rescue and Jansi and JCurses are two of
them.
Jansi
Jansi is a small java library that allows you to use ANSI escape sequences to format your console
output which works even on Windows.
import org.fusesource.jansi.AnsiConsole;
NOTE: Check this "old" text file to have an overview of ANSI Escape Sequences.
The above example shows that it's possible to use ANSI codes directly but Jansi provides a neat
mechanism to help building the required ANSI sequence.
JCurses
The Java Curses Library (JCurses) is a library for developing text terminal based applications using
Java programming language. It is implemented as a Windowing toolkit similar to AWT, but built
upon the UNIX "curses" windowing system.
JCurses works on Unix and Windows (32 bit only, on a 64-bit OS you need to use JCurses with a
32-bit JVM).
This example will display a character-based window with a label, a textfield and a button (don't click
with you mouse, use the keyboard!).
import jcurses.system.*;
import jcurses.widgets.*;
import jcurses.util.*;
import jcurses.event.*;
button.setShortCut('q');
button.addListener(this);
window.addListener((WindowListener) this);
window.show();
}
sometime it may be to strict. Hopefully, there is a way to disable Checkstyle checking for a certain
area to ebable to reach to the glory of having a Checkstyle == 0 ;-)
<module name="Checker">
<property name="severity" value="warning"/>
<property name="localeLanguage" value="fr"/>
<module name="SuppressionCommentFilter"/>
<module name="TreeWalker">
<module name="FileContentsHolder"/>
...
<module name="HideUtilityClassConstructor"/>
</module>
</module>
In this example, we want the disable it because we don't want to get the warning for the missing
Javadoc tags for the getter/setter methods.
//CHECKSTYLE:OFF
public void setDriverFileName(String driverFileName) { this.driverFileName = driverFileNa
public String getDriverFileName () { return this.driverFileName;}
//CHECKSTYLE:ON
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;
over.endText();
// adding a page from another document
PdfReader reader2 = new PdfReader("SimpleAnnotations1.pdf");
under = stamp.getUnderContent(1);
under.addTemplate
(stamp.getImportedPage(reader2, 3), 1, 0, 0, 1, 0, 0);
// closing PdfStamper will generate the new PDF file
stamp.close();
}
catch (Exception de) {
de.printStackTrace();
}
}
}
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");
output.open();
output.addAuthor("RealHowTo");
output.addSubject(args[0]);
output.addTitle(args[0]);
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You specify the pdf file to be split. Each page is extracted to its own pdf
file.
/*
* java SplitPDFFile file.pdf
*
* gives file-001.pdf ... file-nnn.pdf
*
* itext-2.1.5.jar
*/
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
/**
* @param args
*/
public static void main(String[] args) {
try {
String inFile = args[0].toLowerCase();
System.out.println ("Reading " + inFile);
PdfReader reader = new PdfReader(inFile);
int n = reader.getNumberOfPages();
System.out.println ("Number of pages : " + n);
int i = 0;
while ( i < n ) {
String outFile = inFile.substring(0, inFile.indexOf(".pdf"))
+ "-" + String.format("%03d", i + 1) + ".pdf";
System.out.println ("Writing " + outFile);
Document document = new Document(reader.getPageSizeWithRotation(1));
PdfCopy writer = new PdfCopy(document, new FileOutputStream(outFile));
document.open();
PdfImportedPage page = writer.getImportedPage(reader, ++i);
writer.addPage(page);
document.close();
writer.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
/* example :
java SplitPDFFile d:\temp\x\tx.pdf
Reading d:\temp\x\tx.pdf
Number of pages : 3
Writing d:\temp\x\tx-001.pdf
Writing d:\temp\x\tx-002.pdf
Writing d:\temp\x\tx-003.pdf
*/
}
}
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You specify the pdf files to be merge into one.
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PRAcroForm;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.SimpleBookmark;
@SuppressWarnings("unchecked")
public static void main(String[] args) {
try {
if (args.length < 2) {
System.out.println
("Usage: ConcatPDFFiles file1.pdf [file2.pdf... fileN.pdf] out.pdf");
System.exit(1);
}
int pageOffset = 0;
ArrayList master = new ArrayList();
int f = 0;
String outFile = args[args.length - 1];
Document document = null;
PdfCopy writer = null;
while (f < args.length - 1) {
PdfReader reader = new PdfReader(args[f]);
reader.consolidateNamedDestinations();
int n = reader.getNumberOfPages();
List bookmarks = SimpleBookmark.getBookmark(reader);
if (bookmarks != null) {
if (pageOffset != 0) {
SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset,
null);
}
master.addAll(bookmarks);
}
pageOffset += n;
if (f == 0) {
document = new Document(reader.getPageSizeWithRotation(1));
writer = new PdfCopy(document,
new FileOutputStream(outFile));
document.open();
}
PdfImportedPage page;
for (int i = 0; i < n;) {
++i;
page = writer.getImportedPage(reader, i);
writer.addPage(page);
}
PRAcroForm form = reader.getAcroForm();
if (form != null) {
writer.copyAcroForm(reader);
}
f++;
}
if (!master.isEmpty()) {
writer.setOutlines(master);
}
document.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
This HowTo is based on the iText package. You need a recent version (ex. 2.*)
This a command line utility. You pass one or many tif files as argument and corresponding PDF are
produced. Multipage TIF are supported. TIF are resized to fit a letter-page dimension.
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
catch (Throwable e) {
System.out.println("Exception " + tiff + " page "
+ (c + 1) + " " + e.getMessage());
}
}
ra.close();
document.close();
}
catch (Throwable e) {
e.printStackTrace();
}
System.out.println("done");
}
}
}
iText
Using iText HTMLWorker, you can produce PDF version of an HTML document. The document
must be simple. Many things like FORM elements or external images are not supported.
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.html.simpleparser.HTMLWorker; // deprecated
import com.itextpdf.text.pdf.PdfWriter;
As you can see, the validity of the parsed HTML (using HTMLWorker) is very relax. Closing tags are
not required : <BR> is ok (<BR/> is not mandatory).
HTMLWorker is ok with older iText version but the recommended approach with new iText
(HTMLWorker is now deprecated) is to use the XMLWorker. XMLWorker is stricter since you must
send XHTML document to it.
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
public class HtmlToPDF2 {
// itextpdf-5.4.1.jar http://sourceforge.net/projects/itext/files/iText/
// xmlworker-5.4.1.jar http://sourceforge.net/projects/xmlworker/files/
public static void main(String ... args ) {
try {
Document document = new Document(PageSize.LETTER);
PdfWriter pdfWriter = PdfWriter.getInstance
(document, new FileOutputStream("c://temp//testpdf.pdf"));
document.open();
document.addAuthor("Real Gagnon");
document.addCreator("Real's HowTo");
document.addSubject("Thanks for your support");
document.addCreationDate();
document.addTitle("Please read this");
Note :
To get the color on a table cell, you need to use a style because the bgcolor attribute is not supported.
By default, FORM elements are not rendered. Review this document to see what is supported :
http://demo.itextsupport.com/xmlworker/doc.html
As seen in this HowTo, iText can be used to transform an HTML document to PDF. The result is
good with simple HTML but if you get fancy then the result is not so good.
For better result, the Open Source package YAHP (Yet another Html to Pdf converter) is a good
choice. YAHP is based on iText, FlyingSaucer and JTidy.
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// http://www.allcolor.org/YaHPConverter/
import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;
properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
//properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);
converter.convertToPdf(str,
IHtmlToPdfTransformer.A4P,
headerFooterList,
"file:///temp/", // root for relative external CSS and IMAGE
out,
properties);
out.flush();
out.close();
}
}
In the next example, we read an existing HTML file and convert it to a PDF file.
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
// http://www.allcolor.org/YaHPConverter/
import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;
properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
//properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);
converter.convertToPdf(htmlContents,
IHtmlToPdfTransformer.A4P,
headerFooterList,
"file:///temp/html/",
out,
properties);
out.flush();
out.close();
}
}
NOTE : After downloading YAHP (and its dependencies), you still need to build a YAHP.JAR, it's done easily with Eclipse... but you can get it
here.
iText
import java.io.FileOutputStream;
document.add(Image.getInstance
(new java.net.URL("http://www.rgagnon.com/images/javahowto.jpg")));
Print a PDF
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-print-a-pdf.html
[Windows only]
You can launch the Acrobat Reader to print a PDF to the default printer.
More infos the "unsupported" command-line switches for the Acrobat reader :
http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/intro_to_sdk/DeveloperFAQ.pdf (page
27).
import java.io.IOException;
Runtime.getRuntime().exec(commands);
}
Unfortunately, Acrobat Reader stays opened (but minimized because of the /h switch) after the
printing operation :-(
You can use a special wrapper to force the closing the Acrobat Reader after the print operation. See
http://www.biopdf.com/acrowrap/close_adobe_reader.php (acrowrap.exe).
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.tika.parser.pdf.PDFParser;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/realhowto-vbs-20121221.pdf");
ContentHandler contenthandler = new BodyContentHandler();
Metadata metadata = new Metadata();
PDFParser pdfparser = new PDFParser();
See also Extract text from HTML, Get Mime Type from a file.
In this HowTo, we check if we found some resource reference, if found then the page is not blank.
The xext step is to get the content as a byte array. We compare the size of content with a threshold
value. This value depends on how the PDF is produced. For example, a Word document converted in
PDF (with CutePDF) shows that a blank page has a size of 156 bytes. So my threshold value in this
context is 160. Obviously, this method can produce false positive match and you need to test and
re-test before setting this value!
A nice extra step would be that to extract the content as text, do a trim() and check if the result is empty or not ... this is left as an exercise to the
reader for now ;-).
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.io.RandomAccessSourceFactory;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
try {
r = new PdfReader(source);
// deprecated
// RandomAccessFileOrArray raf
// = new RandomAccessFileOrArray(pdfSourceFile);
// itext 5.4.1
rasf = new RandomAccessSourceFactory();
raf = new RandomAccessFileOrArray(rasf.createBestSource(source));
document = new Document(r.getPageSizeWithRotation(1));
writer = new PdfCopy(document, new FileOutputStream(destination));
document.open();
PdfImportedPage page = null;
if (!noFontsOrImages) {
byte bContent [] = r.getPageContent(i,raf);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
bs.write(bContent);
System.out.println
(i + bs.size() + " > BLANK_THRESHOLD " + (bs.size() > BLANK_THRESH
if (bs.size() > BLANK_THRESHOLD) {
page = writer.getImportedPage(r, i);
writer.addPage(page);
}
}
}
}
finally {
if (document != null) document.close();
if (writer != null) writer.close();
if (raf != null) raf.close();
if (r != null) r.close();
}
}
Encrypt a password
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0400.html
Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length
hash value.
A One-way hash function computes a number from a given data. There is no way to decrypt that number to
retrieve its original value. The only way is to compute again the same value and check if the result is the same
than the previouly computed one.
In this scenario, the user sends a password to the server (through a secure connection). The server computes
the computed hash code with the stored hash, if it's the same then the password is correct. The password is
never stored in the database.
Security 792
Real's HowTo PDF version
The output is :
If an automated task needs to log in then you must provide a username/password. Since it's an automated task
you can retrieve the username/password from something like a properties file. A security best practice is to
never store a password in plain text, you must encrypt it using an appropriate algorithm. The javax.crypto
package provides those algorithms and AES is one of them. To retrieve the original value from an encrypted
string, you need to use a secret key habitually stored in a different location than the user/password file.
In this scenario, a process gets its user and password from a properties file. The password is crypted, the
process uses a "key" stored in a different secure location to decrypt the password. The password is sent to the
server for authentication by comparing the computed hash of the received password with the hash code stored
for this user in the database.
In this HowTo, a key file is created during the encryption process if the specified key file is not found.
import java.io.File;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* encrypt a value and generate a keyfile
* if the keyfile is not found then a new one is created
* @throws GeneralSecurityException
* @throws IOException
*/
public static String encrypt(String value, File keyFile)
throws GeneralSecurityException, IOException
{
if (!keyFile.exists()) {
KeyGenerator keyGen = KeyGenerator.getInstance(CryptoUtils.AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
FileWriter fw = new FileWriter(keyFile);
fw.write(byteArrayToHexString(sk.getEncoded()));
fw.flush();
fw.close();
}
/**
* decrypt a value
* @throws GeneralSecurityException
* @throws IOException
*/
public static String decrypt(String message, File keyFile)
throws GeneralSecurityException, IOException
{
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(CryptoUtils.AES);
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(hexStringToByteArray(message));
return new String(decrypted);
}
p1.put("user", "Real");
String encryptedPwd = CryptoUtils.encrypt(clearPwd, new File(KEY_FILE));
p1.put("pwd", encryptedPwd);
p1.store(new FileWriter(PWD_FILE), "");
// ==================
Properties p2 = new Properties();
p2.load(new FileReader(PWD_FILE));
encryptedPwd = p2.getProperty("pwd");
System.out.println(encryptedPwd);
System.out.println
(CryptoUtils.decrypt(encryptedPwd, new File(KEY_FILE)));
}
}
Create a checksum
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0416.html
MD5 digests have been widely used in the software world to provide some assurance that a downloaded file
has not been altered. A user can compare a published MD5 sum with the checksum of a downloaded file.
import java.io.*;
import java.security.MessageDigest;
// ref :
// http://www.apache.org/dist/
// tomcat/tomcat-5/v5.5.17/bin
// /apache-tomcat-5.5.17.exe.MD5
// 0bb2827c5eacf570b6064e24e0e6653b *apache-tomcat-5.5.17.exe
}
catch (Exception e) {
e.printStackTrace();
}
}
}
The next example is used to create a .chk file which contains a MD5 checksum of a given file. The same
program is used to check if a file has been altered by looking at previously generated .chk file and compared
with current checksum of the given file.
import java.security.*;
import java.io.*;
//
// 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]");
}
}
e.printStackTrace();
return 0;
}
}
is.read(chk2);
The java.util.zip package can be used to create a checksum. However the CRC32 is not a very strong way to
make sure that a file is not altered.
import java.io.*;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
However, MD5 is not secure anymore because researchers have proven that it is possible to manipulate the
original data to get the same MD5 as the original. The alternative is to use SHA-1 which is on 160-bits (MD5
is 128-bits). It's still not perfect but it is better than MD5.
import java.io.*;
import java.security.MessageDigest;
return complete.digest();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
MD5 or SHA1 checksum can be used to validate a password without passing the actual password.
In application :
will print the current user. You can't use this technique to secure your application since it is very to spoof.
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 and the server are
configured correcty (SSO).
Even if the application server do not support NTLM protocol, it is possible to use it to extract the Windows
username. From the server, we ask the browser to identify the current user, and "by hand", we extract the
response from the answer.
The browser client must support NT Challenge authentification mechanism (IE does).
This is a quick HACK to extract the username! There is no security into this. Beware...
[username.jsp]
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')
The following URL syntax is no longer supported in Internet Explorer or in Windows Explorer after you
install the MS04-004 Cumulative Security Update for Internet Explorer (832894):
http(s)://username:password@server/resource.ext
This change in the default behavior is also implemented by security updates and service packs that were
released after the 832894 security update.
By default, this new default behavior for handling user information in HTTP or HTTPS URLs applies only to
Windows Explorer and Internet Explorer. To use this new behavior in other programs that host the Web
browser control, create a DWORD value named SampleApp.exe, where SampleApp.exe is the name of the
executable file that runs the program. Set the DWORD value's value data to 1 in one of the following registry
keys.
• For all users of the program, set the value in the following registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
• For the current user of the program only, set the value in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
To disable the new default behavior in Windows Explorer and Internet Explorer, create iexplore.exe and
explorer.exe DWORD values in one of the following registry keys and set their value data to 0.
• For all users of the program, set the value in the following registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
• For the current user of the program only, set the value in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\
Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
A separate thread is used to send to the console the backspace character to erase the last-typed character.
import java.io.*;
import java.awt.*;
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 &&
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.
Good document on the subject : XSS (Cross Site Scripting) Prevention Cheat Sheet
This regex function removes the obvious code to inject unwanted scripting.
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/.
You have to be careful. You don't want to remove legitimate string. An input like "prescription" can be
become "preion" if the filter is too strict!
Based on a policy file, you allow only certain tags and discard everything else.
The idea is to sanitize a string before displaying it a user. This is done by replacing supicious characters by
the corresponding entity.
The JSTL taglib provides the tag <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.
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<c:set var="test" scope="session">
<script>
alert("hello")
</script>
</c:set>
This JSP will not display the script code and the browser execute it.
With JSF, the tag <h:outputtext ... > provides the same protection.
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.*;
TextField password;
MyLogin(Frame frame){
super(frame, "Welcome", true);
setLayout(new FlowLayout());
username = new TextField(15);
password = new TextField(15);
password.setEchoChar('*');
add(new Label("User :"));
add(username);
add(new Label("Password :"));
add(password);
addOKCancelPanel();
createFrame();
pack();
setVisible(true);
}
void addOKCancelPanel() {
Panel p = new Panel();
p.setLayout(new FlowLayout());
createButtons( p );
add( p );
}
void createButtons(Panel p) {
p.add(ok = new Button("OK"));
ok.addActionListener(this);
p.add(can = new Button("Cancel"));
can.addActionListener(this);
}
void createFrame() {
Dimension d = getToolkit().getScreenSize();
setLocation(d.width/4,d.height/3);
}
<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>
The Java plugin refuses to run unsigned applets, starting with version 1.7u51. It shows the message
"Application blocked by security settings", and no visible option to override this limitation.
To allow unsigned applets, you need to create a whitelist. If the unsigned applet is coming from one the
websites specified in the whitelist then its execution will be permitted.
Manually
The whitelist is simple text file called exception.sites containing one URL per line.
For example, to allow the unsigned applets from rgagnon.com to execute, the file exception.sites will have
this line :
http://www.rgagnon.com
Go to this page to do a test with an unsigned applet. You will still have one security popup to click before
Solve "Application blocked by security settings" message with unsigned Applet 811
Real's HowTo PDF version
The Java Control Panel is not in the Control Panel of Windows any more, instead it is now in the Start
Menu as "Configure Java" (java).
Click on "add" for each site you want to add to exception list.
The above procedure can be cumbersome, especially in the enterprise environment since it is specific for
one user. It is easier to have one global whitelist and make sure that every users are using it.
You declare the common location of the exception list in "Deployment Properties" file located in
%windir%\Sun\Java\Deployment\deployment.properties. If this .properties file doesn't
exist then you need to create it.
ex:
deployment.user.security.exception.sites=C:/Windows/Sun/Java/Deployment/exception.sites
Note :
An interesting page on the subject with some possible issues for Firefox or Chrome.
*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.
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.
integer to String :
int i = 42;
String str = Integer.toString(i);
or
String str = "" + i
double to String :
long to String :
String/Number 814
Real's HowTo PDF version
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);
char to String
String s = String.valueOf('c');
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, use 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.
/**
* @param s source string
* @param toMatch target character(s)
* @param boolean true=keep false=strip
**/
public static String cleanUp
( String s, String sToMatch, boolean isToKeep ) {
The String class offers the replaceAll() method that can be used with String or char (JDK1.4+).
System.out.println(
"@*1#^2$@!34#5ajs67>?<{8_(9SKJDH".replaceAll("\\D", ""));
// output : 123456789
If your project already depends on Apache Commons then StringUtils provides many methods to manipulate
String objects, no need to reinvent the wheel!
import org.apache.commons.lang.StringUtils;
...
foo = StringUtils.replace(foo, "bar", "baz");
// replace in foo the occurrence of bar" by "baz"
To remove a character :
String.replaceAll() replaces each substring of this String that matches the given regular expression with the
given replacement. Remember that StringreplaceAll() returns a new String so keep the result!
[JDK1.4]
// replace all
String result = text.replaceAll("(?:hello world)", "bonjour le monde");
System.out.println(result);
/*
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. 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.
Since replaceAll() is based on a regex expression, it is very easy to make the substituion case insensitive.
[ < JDK1.4]
String,replaceAll() is not available with Java version older than 1.4, you need to code the substitution. This
snippet provides a simple replacesAll() equivalent.
"Tokenize" a string
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0015.html
import java.util.StringTokenizer;
...
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.
import java.util.*;
/**
* This class wraps a standard java.util.StringTokenizer, but provides
* an additional mode of operation (NO_CONSECUTIVE_DELIMS).
*
*/
public class EnhancedStringTokenizer implements Enumeration {
public static final int NO_RETURN_DELIMS = 0;
public static final int RETURN_DELIMS = 1;
public static final int NO_CONSECUTIVE_DELIMS = 2;
protected int Mode = NO_CONSECUTIVE_DELIMS;
*/
public EnhancedStringTokenizer(String str) {
setMode(this.NO_RETURN_DELIMS);
st = new StringTokenizer(str);
}
/**
* 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.
*/
public EnhancedStringTokenizer
(String str, String delim, boolean returnDelims) {
if (returnDelims) {
setMode(RETURN_DELIMS);
}
else {
setMode(NO_RETURN_DELIMS);
}
setDelimiter(delim);
st = new StringTokenizer(str, delim, returnDelims);
}
/**
* 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;
}
}
getRemainder().indexOf(getDelimiter(), intIndex);
if (intIndex != -1) {
String retValue =
getRemainder().substring(0, intIndex);
setRemainder(getRemainder().substring(intIndex + 1));
return retValue;
}
else {
if (getRemainder().length() > 0) {
String retValue = getRemainder();
setRemainder("");
return retValue;
}
else {
throw new NoSuchElementException();
}
}
default :
return st.nextElement();
}
}
return retValue;
}
else {
if (getRemainder().length() > 0) {
String retValue = getRemainder();
setRemainder("");
return retValue;
}
else {
throw new NoSuchElementException();
}
}
default :
return st.nextToken();
}
}
See also this HowTo to split a given String into an array based on a specific separator.
For JDK1.4+, you may want to look at the String.split() method. See this HowTo.
The String class has a split() (since 1.4) method that will return a String array.
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 :
// good
System.out.println
(java.util.Arrays.toString(testString.split("\\.")));
// output : [Real, How, To]
}
}
And
// good
System.out.println
(java.util.Arrays.toString(testString.split("\\|")));
The special character needs to be escaped with a "\" but since "\" is also a special character in Java, you need
to escape it again with another "\" !
The result does not include the empty strings between the "|" separator. To keep the empty strings :
See split(String.int).
System.out.println
(java.util.Arrays.toString("".split("")));
// output : []
System.out.println
(java.util.Arrays.toString(" ".split(" ")));
// output : []
System.out.println
(java.util.Arrays.toString(" ".split(" ")));
// output : []
System.out.println
(java.util.Arrays.toString(" s ".split(" ")));
// output : [, s]
}
}
System.out.println
(java.util.Arrays.toString(testString.split(" ")));
// output : [Real, , How, To]
}
}
We have an extra element. The fix is to specify a regular expression to match one or more spaces.
System.out.println
(java.util.Arrays.toString(testString.split("\\s+")));
// output : [Real, How, To]
}
}
Since String.split() is based on regular expression, you can make some complex operations with a simple call!
String testString = "{RealHowto}{java-0438.html}{usage of String.split()}";
System.out.println
(java.util.Arrays.toString(testString.split("[{}]")));
// output : [, RealHowto, , java-0438.html, , usage of String.split()]
// note : extra empty elements :-(
To split a long string into into fixed-length parts. In this example, we split in groups of 3 characters :
String testString = "012345678901234567890";
System.out.println
(java.util.Arrays.toString(testString.split("(?<=\\G.{3})")));
// output : [012, 345, 678, 901, 234, 567, 890]
(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:
StringBuilder (JDK1.5)
The StringBuilder class, introduced in J2SE 5.0, differs from StringBuffer in that it is unsynchronized. When
only a single thread at a time will access the object (the most common case), using a StringBuilder is more
efficient than using a StringBuffer.
The code
[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.
private BlankRemover () {}
*/
}
import java.util.regex.Pattern;
...
boolean startsWithDigitOrUpper(String s) {
return Pattern.compile("^[A-Z0-9]").matcher(s).find();
}
[JDK 1.5]
Since 1.5, String.format() can be used to left/right pad a given string.
// pad with " " to the right to the given length (n)
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
// pad with " " to the left to the given length (n)
public static String padLeft(String s, int n) {
return String.format("%1$" + n + "s", s);
}
/* output
Howto *
Howto*
*/
}
These one-liners are useful to pad to a fix length with a given character.
/* output
*****howto
howto*****
*/
/* output
howto
*****
*/
[JDK1.4 or less]
/**
* Pads a String <code>s</code> to take up <code>n</code>
* characters, padding with char <code>c</code> on the
* left (<code>true</code>) or on the right (<code>false</code>).
* Returns <code>null</code> if passed a <code>null</code>
* String.
**/
public static String paddingString(String s, int n, char c, boolean paddingLeft) {
if (s == null) {
return s;
}
int add = n - s.length(); // may overflow int size... should not be a problem in real life
if(add <= 0){
return s;
}
StringBuffer str = new StringBuffer(s);
char[] ch = new char[add];
Arrays.fill(ch, c);
if(paddingLeft){
str.insert(0, ch);
}
else {
str.append(ch);
}
return str.toString();
}
[JDK1.4]
import java.util.regex.Pattern;
import java.util.regex.Matcher;
...
// 4 different combinaisons
Pattern CRLF = Pattern.compile("(\r\n|\r|\n|\n\r)");
Matcher m = CRLF.matcher(myString);
if (m.find()) {
newString = m.replaceAll("<br>");
}
or use the String.replaceAll(regex,replacement) method which is doing basically the same thing.
The following snippets remove from a String accented letters and replace them by their regular ASCII
equivalent.
These can be useful before inserting data into a database to made sorting easier.
Using java.text.Normalizer
We are calling the normalize(). If we pass à, the method returns a + ` . Then using a regular expression, we
clean up the string to keep only valid US-ASCII characters.
import java.text.Normalizer;
import java.util.regex.Pattern;
Using String.replaceAll()
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
}
}
The String.indexOf()
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.
As a bonus, here a method to convert a given string to uppercase with no accent. This can be useful in a
database field to simplify name searching with accent or not.
return sb.toString();
}
JDK1.4
NOTE : Since this is Swing class, it is designed to be used in conjunction with a JFormattedTextField.
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");
System.out.println(s);
// output : Welcome Real's HowTo at http://www.rgagnon.com
System.out.printf
("Welcome %s at %s", "Real's HowTo", "http://www.rgagnon.com");
As you can see, it is now possible to call a method with a variable number of parameters. But it is also
possible to use an array (with the new String.format()).
You can use this new feature to quickly format strings into table :
System.out.format(String.format(format, (Object[])ex));
}
}
Output:
To align numbers :
Output :
123.45
99.00
23.20
45.00
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.
java.text.MessageFormat is a very powerful API, you should study the javadoc to see all the possibilities.
In this code, we have 2 strings, "état" and "famille". We expect that "état" is before "famille". But
String.compareTo() will return that "famille" is before "état".
class Test {
public static void main(String args[]) {
String s1 = "état";
String s2 = "famille";
import java.text.Collator;
String s1 = "état";
String s2 = "famille";
// Collator c = Collator.getInstance(java.util.Locale.FRANCE);
Collator c = Collator.getInstance();
c.setStrength(Collator.PRIMARY);
if (c.compare(s1, s2) < 0) {
// s2 lexicographically follows s1
System.out.println("ok " + s1 + " < " + s2);
}
}
/*
output :
ok état < famille
*/
Equality
To compare without taking into account the presence of accentued so that "é" == "e", we use a Collator.
import java.text.Collator;
// import java.util.Locale;
Unquote a String
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0522.html
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.
else {
int ci = 0xffff & c;
if (ci < 160 )
// nothing special only 7 Bit
sb.append(c);
else {
// Not 7 Bit use the unicode system
sb.append("&#");
sb.append(new Integer(ci).toString());
sb.append(';');
}
}
}
}
return sb.toString();
}
Using HashMap
import java.util.*;
private StringUtils() {}
htmlEntities.put("Ù","Ù"); htmlEntities.put("û","û");
htmlEntities.put("Û","Û") ; htmlEntities.put("ü","ü");
htmlEntities.put("Ü","Ü") ; htmlEntities.put(" "," ");
htmlEntities.put("©","\u00a9");
htmlEntities.put("®","\u00ae");
htmlEntities.put("€","\u20a0");
}
/*
Here the original recursive version.
It is fine unless you pass a big string then a Stack Overflow is possible :-(
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, i + 1); // recursive call
}
}
}
return source;
}
M. McNeely Jr. has sent a version with do...while()loop which is more robust.
Thanks to him!
*/
boolean continueLoop;
int skip = 0;
do {
continueLoop = false;
i = source.indexOf("&", skip);
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 = source.substring(0, i)
+ value + source.substring(j + 1);
continueLoop = true;
}
else if (value == null){
skip = i+1;
continueLoop = true;
}
}
}
} while (continueLoop);
return source;
}
/*
output ((Windows DOS Shell):
© 2007 Réal Gagnon <www.rgagnon.com>
-->
© 2007 Réal Gagnon <www.rgagnon.com>
*/
}
}
Using Array
private StringUtils() {}
{ "©" , "\u00a9" } ,
{ "®" , "\u00ae" } ,
{ "€" , "\u20a0" }
};
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) {
s = s.substring(0 , i)
+ htmlEscape[k][1] + s.substring(j + 1);
return unescapeHTML(s, i); // recursive call
}
}
}
return s;
}
/*
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_HTML.
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
A different (and simpler) approach is to take a given string and check if it's possible to encode it into ASCII.
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
/*
* output :
* Réal isPureAscii() : false
* Real isPureAscii() : true
*/
}
}
Another way is to use a regular expression, see this Javascript HowTo for a hint!
A special regular expression is used to strip out anything between a < and > .
Remove HTML tags from a file to extract only the TEXT 854
Real's HowTo PDF version
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.
Using javax.swing.text.html.HTMLEditorKit
In most cases, the HTMLEditorKit is used with a JEditorPane text component but it can be also used directly
to extract text from an HTML page.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.MutableAttributeSet;
Remove HTML tags from a file to extract only the TEXT 855
Real's HowTo PDF version
Note that the HTMLEditorKit can be easily confused if the HTML to be parsed is not well-formed.
This is maybe the best solution (if the choosen parser is good !).
There are many parsers available on the net. In this HowTo, I will use the OpenSource package Jsoup.
Jsoup is entirely self contained and has no dependencies which is a good thing.
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.io.BufferedReader;
import org.jsoup.Jsoup;
Remove HTML tags from a file to extract only the TEXT 856
Real's HowTo PDF version
Apache Tika
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/java-x.html");
ContentHandler contenthandler = new BodyContentHandler();
Metadata metadata = new Metadata();
Parser parser = new AutoDetectParser();
parser.parse(is, contenthandler, metadata, new ParseContext());
System.out.println(contenthandler.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null) is.close();
}
}
}
See Extract text from a PDF using Apache Tika, Get Mime Type from a file.
Remove HTML tags from a file to extract only the TEXT 857
Real's HowTo PDF version
Using javax.swing.text.html.HTMLEditorKit
import java.io.IOException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.HTML.Attribute;
import javax.swing.text.MutableAttributeSet;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
// href ...
for (Element link : links) {
result.add(link.attr("abs:href"));
}
// img ...
for (Element src : media) {
result.add(src.attr("abs:src"));
}
A faster way
import java.io.UnsupportedEncodingException;
private StringUtils () {}
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...
*/
}
}
As seen in this HowTo, the sun.misc.BASE64Encoder/Decoder or creating your own Base64 handling are the
more common way to deal with Base64 encoding/decoding.
Here some alternatives which are maybe easier (and safer) to use.
Using javax.mail.internet.MimeUtility
import javax.mail.internet.MimeUtility;
import java.io.*;
private Base64Utils() {}
System.out.println(new String(res1));
byte res2[] = Base64Utils.decode(res1);
System.out.println("");
System.out.println( java.util.Arrays.toString(res1) + " string --> "
+ new String(res2));
/*
* output
* realhowto base64 ->
* [99, 109, 86, 104, 98, 71, 104, 118, 100, 51, 82, 118]
* cmVhbGhvd3Rv
* [99, 109, 86, 104, 98, 71, 104, 118, 100, 51, 82, 118]
* string --> realhowto
*/
}
Apache Commons Codec provides implementations of common encoders and decoders such as Base64, Hex,
Phonetic and URLs.
Download at http://commons.apache.org/codec/
import org.apache.commons.codec.binary.Base64;
// 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();
}
}
}
MiGBase64
private StringUtils() {}
/*
justify a string,
here only left justification is implemented
*/
public static String justifyLeft( int width,String st) {
StringBuffer buf = new StringBuffer(st);
int lastspace = -1;
int linestart = 0;
int i = 0;
formatted_string = StringUtils.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
*/
}
}
It can be useful to have a short version of a long path only for display purpose.
The first version makes a path shorter according to a limit. If the limit is 4, the returned path will contain 4
parts (directories) then ellipse and finally the filename.
ex :
C:\1\2\3\4\5\test.txt == C:\1\2\3\4\...\test.txt
\\server\p1\p2\p3\p4\p5\p6 == \\server\p1\p2\p3\p4\...\p6
http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html == http://p1/p2/p3/p4/.../pb.html
The second accepts a limit corresponding to the total length of the path. If the limit is 20, the path beginning
will be truncated then ellipse and finally the filename. The result is similar to the Win32 API
PathCompactPathExA.
ex :
C:\1\2\3\4\5\test.txt == C:\1\2\3\...test.txt
\\server\p1\p2\p3\p4\p5\p6 == \\server\p1\p2...p6
http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html == http://www...pb.html
private FileUtils() { }
/**
* Return shorter path based on the limited threshold
* ex. C:/1/2/test.txt return C:/1/.../test.txt if threshold is 1
* @param path
* @param threshold
* @return
*/
public static String pathShortener(String path, int threshold) {
if (path.indexOf("/") > 0) {
regex = SHORTENER_SLASH_REGEX;
sep = SHORTENER_SLASH;
}
// drive or protocol
int pos2dots = path.indexOf(":");
if (pos2dots > 0) {
/**
* Compact a path into a given number of characters. Similar to the
* Win32 API PathCompactPathExA
* @param path
* @param limit
* @return
*/
public static String pathLengthShortener(String path, int limit) {
int i = 0;
for (; i < limit ; i++) {
if (pathArray[pathindex - i] != '/' && pathArray[pathindex - i] != '\\') {
shortPathArray[shortpathindex - i] = pathArray[pathindex - i] ;
}
else {
break;
}
}
// check how much space is left
int free = limit - i;
System.out.println(pathShortener("C:\\temp"));
System.out.println(pathShortener("C:\\1\\2\\3\\4\\5\\test.txt"));
System.out.println(pathShortener("C:/1/2/test.txt"));
System.out.println(pathShortener("C:/1/2/3/4/5/test.txt"));
System.out.println(pathShortener("\\\\server\\p1\\p2\\p3\\p4\\p5\\p6"));
System.out.println(pathShortener("\\\\server\\p1\\p2\\p3"));
System.out.println
(pathShortener("http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html"));
System.out.println("-----");
System.out.println(pathLengthShortener(t,20));
System.out.println(pathLengthShortener("C:\\temp", 20));
System.out.println(pathLengthShortener("C:\\1\\2\\3\\4\\5\\test.txt", 20));
System.out.println(pathLengthShortener("C:/1/2/testfile.txt", 15));
System.out.println(pathLengthShortener("C:/1/2/3/4/5/test.txt", 15));
System.out.println(pathLengthShortener("\\\\server\\p1\\p2\\p3\\p4\\p5\\p6", 20));
System.out.println
(pathLengthShortener("http://www.rgagnon.com/p1/p2/p3/p4/p5/pb.html", 20));
/*
output :
C:\Documents and Settings\All Users\Application Data\Apple Computer\iTunes\...\SC Info.tx
C:\temp
C:\1\2\3\4\...\test.txt
C:/1/2/test.txt
C:/1/2/3/4/.../test.txt
\\server\p1\p2\p3\p4\...\p6
\\server\p1\p2\p3
http://www.rgagnon.com/p1/p2/p3/.../pb.html
-----
C:\Doc...SC Info.txt
C:\temp
C:\1\2\3\...test.txt
...testfile.txt
C:/1...test.txt
\\server\p1\p2\...p6
http://www...pb.html
*/
}
}
You "ellipse" a String when you want to display a long String using a shorter representation because of the
available space.
private StringUtils() { }
/*
* output :
* Real's HowTo @ www.rgagnon.com
* Real's Ho...on.com
* Real's HowTo @ ...
*/
}
}
Unicode has a special character to show an ellipsis (to use one character instead of 3) :
Draw a string to an Image and then examine the Image created and output " ", "#" or "*" depending of the
pixel value.
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
Output is :
######*** ## ## ## ##
#########* ## ## ## ##
## **#* ## ** ## ##
## *#* ## ** ## ##
## *#* ******* ******* ## ** ****** ## ## ******* *#*
## **#* *#####** *######* ## *######* ## ## **#####** ***
########** *#** **#* *#****#* ## *#****#* ########### *#** **#* *#*
######*** *#* *#* #* ## *#* ########### *#* *#* *#*
## **** *#######* ****## ## *##**** ## ## *#* *#* *#*
## *#** *#######* **###### ## ***###** ## ## *# #* *#**
## *#* *#* *#****## ## ****#* ## ## *#* *#* ****
## *##* *#* *#* *## ## *#* ## ## *#* *#* *#*
## *#* *#** **#* *#* **##* ## *#****#* ## ## *#** **#* *#*
## **#* **#####** *#######* ## *######* ## ## **#####** *#
## *#* ******* *******#* ## ****** ## ## ******* *#
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 :
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);
char to String
String s = String.valueOf('c');
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, use 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.
Round a double
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0016.html
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.0.2
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.1
import java.text.*;
public class DemoNumber {
public static void main(String args[]) {
double d = 123456.78;
DecimalFormat df = new DecimalFormat("#####0.00");
System.out.println(df.format(d));
}
}
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.0.2
double power=(int)(Math.log(num)/Math.log(10));
if(power < 0) power--;
double fraction=num/Math.pow(10,power);
fraction=round(fraction,places);
if(power > 0) sign="+";
result += fraction + "e" + sign + power;
return result;
}
double power_of_ten = 1;
while (decimalPlace-- > 0) power_of_ten *= 10.0;
return Math.round(value * power_of_ten) / power_of_ten;
}
JDK1.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
jdk1.5+
Using String.format()
*/
String format = String.format("%%0%dd", digits);
return String.format(format, n);
}
jdk1.2+
Using DecimalFormat.format()
import java.util.Arrays;
import java.text.DecimalFormat;
pre-jdk1.1
JDK1.1, Random.nextInt() returns the next pseudorandom, uniformly distributed int value from this random
number generator's sequence.
JDK1.2, Random.nextInt(n) returns a pseudorandom, uniformly distributed int value between 0 (inclusive)
and n (exclusive).
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));
System.out.println(unsignedByteToInt(b2));
System.out.println(unsignedByteToInt(b3));
/*
127
-128
-1
127
128
255
*/
}
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;
" seventeen",
" eighteen",
" nineteen"
};
private EnglishNumberToWords() {}
// 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:
tradBillions = "";
break;
case 1 :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
break;
default :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
}
String result = tradBillions;
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));
/*
*** 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"
};
private FrenchNumberToWords() {}
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;
String tradMille;
tradMille = convertLessThanOneThousand(lesMille);
resultat = resultat + tradMille;
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.
import java.math.BigDecimal;
...
System.out.println
(BigDecimal.valueOf(1.33).subtract(BigDecimal.valueOf(1.3)));
if (x % 2 == 0) {
// even
}
if (x % 2 != 0) {
// odd
}
if (( x & 1 ) == 0) {
// even
}
if (( x & 1 ) != 0) {
// odd
}
System.out.println(f.length());
System.out.println(bytesToMeg(f.length()) + " Mb");
}
Validate a number
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0599.html
private NumberUtils() {}
// 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
*/
}
}
Using java.rmi.dgc.VMID
java.rmi.dgc.VMID can generate an identifier. Each new VMID is unique for all Java virtual machines
under the following conditions:
• 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
Using java.util.UUID
Using java.util.concurrent.AtomicLong
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;
private NumberUtils() {}
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.ParseException;
private NumberUtils() {}
/*
* 0.5
* 0.6666666666666666
* 0.6666666666666666
* 0.8
* 0.3333333333333333
*/
}
}
import java.util.Locale;
private NumberUtils() { }
/*
* Ordinal (depends on the current locale)
* French or english support
*/
public static String getOrdinal(int number) {
if (Locale.getDefault().getLanguage().equals("fr")) {
return NumberUtils.getOrdinalFr(number);
}
else {
return NumberUtils.getOrdinalEn(number);
}
}
/*
output (english)
0th
1st
2nd
3rd
4th
5th
10th
11th
12th
13th
14th
20th
21st
22nd
...
*/
}
}
}
*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.
Swing 902
Real's HowTo PDF version
UIManager.put("Label.font",new Font("Serif",Font.ITALIC,12));
Swing UI default
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.
The trick is to fool Swing by setting the property os.name to a different value than real one to enable the use
of "forbidden" LookAndFeel.
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");
Use a Timer
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0220.html
In this example, a JMenu, JToolbar and JButtons on a JFrame are sharing common ActionEvent handlers.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
ShareAction() {
createMenu();
createToolBar();
createButtons();
pack();
file.add(saveAction);
file.add(quitAction);
setJMenuBar(mb);
}
}
}
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
* (may not work with some LAF or built-in icon, use with caution!)
* 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);
ti.setImageAutoSize(true);
return ti;
}
int h = icon.getIconHeight();
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
Graphics2D g = image.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return image;
}
}
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.*;
JTextField field1;
JPanel panel;
public CloseOrNot() {
super( "CloseOrNot Frame" );
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
panel = new JPanel();
field1 = new JTextField( 10 );
panel.add( new JLabel("type yes to close the Frame "));
panel.add( field1 );
getContentPane().add( "Center", panel );
addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
field1.requestFocus();
}
public void windowClosing( WindowEvent e ){
if (field1.getText().equals("yes")) {
if (JOptionPane.showConfirmDialog
(null,"Are you sure ?")==JOptionPane.YES_OPTION) {
setVisible(false);
dispose();
}
}
}
} );
pack();
setVisible( true );
}
Maximize a JFrame
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0479.html
import java.awt.*;
import javax.swing.*;
// this.setMaximizedBounds(env.getMaximumWindowBounds());
this.setExtendedState(this.getExtendedState() | this.MAXIMIZED_BOTH);
}
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 ([email protected]);
* William Denniss has edited the code, improving its customizability
*
* In breif, this class captures all output to the system and prints it in
* a frame. You can choose weither or not you want to catch errors, log
* them to a file and more.
* For more details, read the constructor method description
*/
// 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.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.awt.*;
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");
tp.setPage(url);
...
to set an anchor, you get the URL then add the "#anchor".
...
URL url = getClass().getResource("contents.html");
tp.setPage(new URL(url.toExternalForm() + "#section42"));
...
Use a JOptionPane
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0376.html
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/*
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();
button.setActionCommand("fr");
button.addActionListener(this);
group.add(button);
add(button);
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");
}
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
}
}
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");
}
Localize a JFileChooser
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0299.html
Modern Swing release have now built-in ready-to-use translations for the JFileChooser. The language is
choosen based on the current Locale. So you don't have to do anything to display the JFileChooser in the
right language.
The user interface elements provided by the J2SE Runtime Environment 5.0, include Swing dialogs,
messages written by the runtime environment to the standard output and standard error streams, as well as
messages produced by the tools provided with the JRE. These user interface elements are localized into the
following languages:
Language Locale ID
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.*;
ButtonGroup group;
Locale locale;
String msg ;
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
examine the Swing sources to get these values or check
http://www.gargoylesoftware.com/papers/plafdiff.html for
a list of them.
*/
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
}
}
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(): "
+ chooser.getCurrentDirectory());
System.out.println("getSelectedFile() : "
+ chooser.getSelectedFile());
}
else {
System.out.println("No Selection!");
}
}
frame.setVisible(true);
}
}
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 javax.swing.JFrame;
import javax.swing.JLabel;
frame.setAlwaysOnTop( true );
frame.setLocationByPlatform( true );
frame.add(new JLabel(" Always visible") );
frame.pack();
frame.setVisible(true);
}
}
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JLabel;
javax.swing.JOptionPane.showConfirmDialog((java.awt.Component)
null, "Found : " + gs.length, "screen detected ?",
javax.swing.JOptionPane.DEFAULT_OPTION);
import javax.swing.JFrame;
import javax.swing.JDialog;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
getContentPane().add(textfield);
button = new JButton("foo");
getContentPane().add(button);
button.setEnabled(false);
document = textfield.getDocument();
document.addDocumentListener
(new JButtonStateController(button));
}
}
JButtonStateController(JButton b) {
button = b;
}
The following class will help a JTextField to filter numeric or alphanumeric characters.
import javax.swing.*;
import javax.swing.text.*;
LOWERCASE + UPPERCASE;
public static final String NUMERIC =
"0123456789";
public static final String FLOAT =
NUMERIC + ".";
public static final String ALPHA_NUMERIC =
ALPHA + NUMERIC;
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 (###)
###-#### for a telephone number, and it will not accept any input that doesn't follow that format.
import java.awt.Container;
import javax.swing.*;
import javax.swing.text.*;
import java.text.ParseException;
It's also possible to provide simple validation. For example, specify a field to accept only numeric with a
minimum and a maximum value. If the input is not valid then a warning beep is produced.
import java.awt.Container;
import javax.swing.*;
import javax.swing.text.*;
import java.text.ParseException;
f.setSize(300, 100);
f.pack();
f.setVisible(true);
}
}
import com.sun.java.swing.text.*;
JTextFieldLimit(int limit) {
super();
this.limit = limit;
}
import java.awt.*;
import javax.swing.*;
JLabel label1;
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.*;
...
...
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;
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());
}
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
JTextComponent.KeyBinding[] newBindings = {
new JTextComponent.KeyBinding(
KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK),
DefaultEditorKit.beepAction),
new JTextComponent.KeyBinding(
KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK),
DefaultEditorKit.beepAction),
new JTextComponent.KeyBinding(
KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK),
DefaultEditorKit.beepAction)
};
Keymap k = myTextField.getKeymap();
JTextComponent.loadKeymap(k, newBindings, myTextField.getActions());
myFrame.add(myTextField);
myFrame.addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
myTextField.requestFocus();
}
public void windowActivated( WindowEvent e ){
boolean focus = myTextField.requestFocusInWindow();
if(focus){
System.out.println("Focus successful");
}
else{
System.out.println("Focus unsuccessful");
}
}
}
);
myFrame.setVisible(true);
}
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;
}
Then we define how the node would be shown in the Tree. This is done by implementing a Renderer class.
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
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;
}
}
The next step is building the JTree in a JPanel. We use a datafile to define the Tree nodes. Since this Tree is
designed to be used in Applet, we must pass a JApplet reference to be able to read some parameters passed
via the HTML PARAM tags.
import 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();
}
}
try {
initTreeIcons();
targetFrame = parentApplet.getParameter("targetframe");
URL urlFile =
new URL(parentApplet.getCodeBase(),
parentApplet.getParameter("datafile"));
st.quoteChar('"');
st.eolIsSignificant(false);
st.parseNumbers();
//
// datafile structure <level> <label> <link> <image1> <image2>
//
while ((token = st.nextToken()) != StreamTokenizer.TT_EOF ) {
// get level
value = new Double(st.nval).intValue();
if (!rootDone) {
// do the root first
token = st.nextToken();
strValue = st.sval;
token = st.nextToken();
lnkValue = st.sval;
rsn = new RealSwingNode(strValue, "", null, null);
node = new DefaultMutableTreeNode(rsn, true);
rootNode = node;
rootDone = true;
}
else {
token = st.nextToken(); strValue = st.sval;
token = st.nextToken(); lnkValue = st.sval;
token = st.nextToken(); image1idx = Integer.parseInt(st.sval);
token = st.nextToken(); image2idx = Integer.parseInt(st.sval);
rsn = new RealSwingNode
(strValue, lnkValue, treeIcons[image1idx],
treeIcons[image2idx]);
node = new DefaultMutableTreeNode(rsn, true);
if (value >= oldvalue) {
if (value==oldvalue) {
// *** sibling
if (currentNode.equals(rootNode))
rootNode.add(node);
else {
DefaultMutableTreeNode dmtn =
(DefaultMutableTreeNode)currentNode.getParent();
dmtn.add(node);
}
}
else {
// *** child
currentNode.add(node);
}
}
else {
// *** new branch, must get back to the right level
while (value < oldvalue) {
currentNode =
(DefaultMutableTreeNode)currentNode.getParent();
oldvalue--;
}
DefaultMutableTreeNode dmtn =
(DefaultMutableTreeNode)currentNode.getParent();
if (dmtn.equals(rootNode))
rootNode.add(node);
else
dmtn.add(node);
}
}
currentNode = node;
oldvalue = value;
}
tree.addTreeSelectionListener(this);
tsm = tree.getSelectionModel();
tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
add(new JScrollPane(tree),"Center");
}
String rootImage;
String pathImages;
String leaveImagesList;
Vector leaveImage = new Vector();
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);
}
System.out.println("end initImage()");
}
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]
Here the HTML used to test the Tree. Since there is almost no error checking, all PARAM tags are
required.
<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.*;
node1.add(node2);
root.add(node3);
node3.add(node4);
setLayout(new BorderLayout());
tree = new JTree(root);
add(new JScrollPane((JTree)tree),"Center");
}
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 java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
}
}
}
);
}
public void actionPerformed(ActionEvent ae) {
DefaultMutableTreeNode dmtn, node;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
import javax.swing.tree.*;
Traverse a JTree
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0313.html
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());
}
cc = model.getChildCount(o);
for( int i=0; i < cc; i++) {
Object child = model.getChild(o, i );
if (model.isLeaf(child))
System.out.println(child.toString());
else {
System.out.print(child.toString()+"--");
walk(model,child );
}
}
}
}
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
(new TreeWillExpandListener() {
public void treeWillExpand(TreeExpansionEvent e) { }
public void treeWillCollapse(TreeExpansionEvent e)
throws ExpandVetoException {
throw new ExpandVetoException(e, "you can't collapse this JTree");
}
});
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+]
If you want to use the more regular - and + sign to collapse or expand a tree node.
Example
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
getContentPane().add(panel,"Center");
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowCloser());
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.table.JTableHeader;
SimpleJTable() {
Object[][] cellData = {
{"row1-col1", "row1-col2"},
{"row2-col1", "row2-col2"},
{"row3-col1", "row3-col2"},
{"row4-col1", "row4-col2"},
{"row5-col1", "row5-col2"}};
}
public static void main(String ... arg) {
SimpleJTable mainFrame = new SimpleJTable();
mainFrame.setVisible( true );
}
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.event.*;
import java.awt.*;
}
public void setValueAt(Object aValue, int row, int column) {
data[row][column] = aValue;
}
};
aTable.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2){
System.out.println(" double click" );
}
}
} );
}
if (!e.getValueIsAdjusting()) {
selRows = aTable.getSelectedRows();
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.*;
StringTokenizer st2 =
new StringTokenizer(aLine, "|");
while(st2.hasMoreTokens())
data.addElement(st2.nextToken());
}
br.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
return colName;
}
[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.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);
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;
File f = new File(file);
lastModified = f.lastModified(); // original timestamp
t.start();
}
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.*;
public TableHideColumn() {
JFrame frame = new JFrame("Table");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
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);
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");
JScrollPane myScrollPane;
JTable 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(){
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);
}
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.getContentPane().add(panel,"Center");
frame.setSize(200,200);
frame.setVisible(true);
}
}
Sort a JList
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0218.html
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.text.Collator;
// import java.util.Locale;
public SortJList(){
Vector data;
setLayout(new BorderLayout());
list = new JList();
list.setModel(new DefaultListModel());
add(new JScrollPane(list),"Center");
add(jb1 = new JButton("Add"), "West");
add(jb2 = new JButton("Sort"), "East");
add(tf = new JTextField(), "North");
jb1.addActionListener(this);
jb2.addActionListener(this);
}
dlm.addElement
((Object) tf.getText());
}
else {
// sort
dlm = (DefaultListModel) list.getModel();
int numItems = dlm.getSize();
String[] a = new String[numItems];
for (int i=0;i<numItems;i++){
a[i] = (String)dlm.getElementAt(i);
}
sortArray(Collator.getInstance(),a);
// Locale loc = Locale.FRENCH;
// sortArray(Collator.getInstance(loc), (String[])a);
for (int i=0;i<numItems;i++) {
dlm.setElementAt(a[i], i);
}
}
}
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.setBackground(myColor)
Bold/UnBold a JLabel
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0349.html
Font f = label.getFont();
// bold
label.setFont(f.deriveFont(f.getStyle() | Font.BOLD));
// unbold
// toggle bold
label.setFont(f.deriveFont(f.getStyle() ^ Font.BOLD));
Multi-line JLabel
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0315.html
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.
Underline in Swing
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0326.html
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);
Update a JLabel
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0392.html
myLabel.setText("Real's HowTo");
SwingUtilities.updateComponentTreeUI(myLabel);
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
timer.setInitialDelay(0);
timer.start();
}
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
import java.io.*;
import javax.swing.*;
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.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.filechooser.*;
String s = "c:/windows/regedit.exe";
JFileChooser chooser = new JFileChooser();
javax.swing.Box.createGlue() will create a "greedy" component: when it is added to a container it takes all
remaining horizontal and vertical space. Adding such a glue component to the menubar will cause
remaining menus/components to 'flow' to the right.
import javax.swing.*;
import java.awt.event.*;
class RightJMenuBar {
public static void main(String args[]) {
new RightJMenuBar().doit();
}
// 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);
}
We use the PipedOutputStream/PipedInputStream duo. When these streams are connected together what is
written in the PipedOutputStream can be read in PipedInputStream. That connection acts like a queue (FIFO).
Pipeline Thread
+----------+ +----------+
| thread A | --- > | thread B |
+----------+ +----------+
(PRODUCE) (CONSUME)
[ProduceData.java]
import java.io.*;
[ConsumeData.java]
import java.io.*;
Thread 999
Real's HowTo PDF version
this.is = is;
Thread t = new Thread(this);
t.start();
}
[SendProduction.java]
import java.io.*;
SendProduction(OutputStream os) {
super(os);
this.output = os;
}
[ReceiveProduction.java]
import java.io.*;
InputStream input;
ReceiveProduction(InputStream is) {
super(is);
this.input = is;
}
[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
+----------+ +----------+
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;
}
public synchronized int atomicRead(byte[] x) {
try {
read(x, 0, atom);
}
catch (Exception e) {
e.printStackTrace();
return -1;
}
return 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.*;
new ReceiveProduction(as);
new ReceiveProduction(as);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
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.
catch (Exception e) {
e.printStackTrace();
}
}
}
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();
}
System.out.println
("\007Being ticked " + Calendar.getInstance().getTime());
}
}
}
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
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
int delay;
DelayedMethod(AnnoyingPopUps myObj) {
this.myObj = myObj;
this.delay = 2000;
}
NOTE: Check this How-to to achieve to same goal by using the Timer object.
JDK1.3 introduces a way to execute a process at regular interval (java.util.Timer and java.util.TimerTask).
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();
}
catch (Exception e){
e.printStackTrace();
}
Iterator it = data.iterator();
while (it.hasNext()) it.next();
}
}
}
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)
at RW$Consumer.run(RW.java:26)
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; }
//System.out.println
// (Thread.currentThread().getName()+": " + value );
/*
do something with value
*/
value = queue.take();
}
}
catch (Exception e) {
System.out.println
(Thread.currentThread().getName() + " " + e.getMessage());
}
}
}
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.");
}
}
Using java.rmi.dgc.VMID
java.rmi.dgc.VMID can generate an identifier. Each new VMID is unique for all Java virtual machines under
the following conditions:
• 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
Using java.util.UUID
Using java.util.concurrent.AtomicLong
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).
Using java.rmi.dgc.VMID
java.rmi.dgc.VMID can generate an identifier. Each new VMID is unique for all Java virtual machines under
the following conditions:
• 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 :
Varia 1020
Real's HowTo PDF version
Code :
Output :
d578271282b42fce:-2955b56e:107df3fbc96:-8000
d578271282b42fce:-2955b56e:107df3fbc96:-7fff
d578271282b42fce:-2955b56e:107df3fbc96:-7ffe
Using java.util.UUID
Using java.util.concurrent.AtomicLong
import java.util.concurrent.AtomicLong;
return nextId.getAndIncrement();
}
}
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.
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
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";
Get the hard disk serial number or Motherboard Serial number 1022
Real's HowTo PDF version
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result += line;
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
return result.trim();
}
This serial number is created by the OS where formatting the drive and it's not the manufacturer serial
number. It's unique, because it is created on the fly based on the current time information. AFAIK, there is no
API that return that the manufacturer SN. At best, the SN of the HD firmware can be read but this will involve
some very low-level API calls. Keep in mind that even if you get that number, there is no warranty that it will
be unique since each manufacturer can assign the SN as they wish.
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
Get the hard disk serial number or Motherboard Serial number 1023
Real's HowTo PDF version
Sort an array 1
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0008.html
JDK1.4+
case-sensitive
case-insensitive
[ArraySorter.java]
/*
** 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]
Sort an array 2
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0343.html
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 (String s : words) {
w.write(s + " ");
}
w.flush();
w.close();
}
catch(Exception e){
e.printStackTrace();
}
The output is :
Before :
Réal Real Raoul Rico
After :
java.util.Arrays.sort(words);
by
java.util.Arrays.sort(words, java.text.Collator.getInstance(java.util.Locale.FRENCH));
// or
// java.util.Arrays.sort(words, java.text.Collator.getInstance());
Before :
Réal Real Raoul Rico
After :
Raoul Real Réal Rico
import java.util.Locale;
import java.text.Collator;
...
Locale loc = Locale.FRENCH;
sortArray(Collator.getInstance(loc), words);
...
Do a selection sort
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0009.html
import java.util.*;
import java.io.*;
*/
public static boolean validSSN(String ssn) {
if (isNumber(ssn)) {
try {
int checksum = 0;
int j = ssn.length();
int [] digit = new int[j];
for (int i=0; i < ssn.length(); i++)
digit[i] = Integer.valueOf("" + ssn.charAt(i)).intValue();
// Add odd digits except the last one
int total_odd = 0;
for (int i=0; i < digit.length-1; i+=2)
checksum += digit[i];
// Multiply by 2 even digits,
// if result > 9 then div and mod by 10,
// add the results to the checksum
// else
// add result to the checksum
int k = 0;
for (int i=0; i < digit.length; i+= 2) {
if (i < digit.length-1) {
k = digit[i+1] * 2;
if (k>9) k = (k-10) + 1;
// total_even += k;
checksum += k;
}
}
/**
* Check if number is valid
*/
public static boolean isNumber(String n) {
try {
double d = Double.valueOf(n).doubleValue();
return true;
}
catch (NumberFormatException e) {
e.printStackTrace();
return false;
}
}
/*
** 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
*/
public static boolean validCC(String number)
throws Exception {
int CardID;
if ( (CardID = getCardID(number)) != -1)
return validCCNumber(number);
return false;
}
/**
* 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
*/
else if (digit2.equals("36") || digit2.equals("38") ||
(digit3.compareTo("300")>=0 && digit3.compareTo("305")<=0)) {
if (number.length() == 14)
valid = DINERS_CLUB;
}
}
return valid;
/* ----
** 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();
return false;
}
}
/*
** 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());
}
}
The output
C:/temp>java LoadingFromWhere
LoadingFromWhere is loaded from file:/C:/temp/
MyClass is loaded from file:/C:/temp/
Other technique
package com.rgagnon;
This technique returns the package too, If the class is in the com.rgagnon package then the output is
System.out.println(ClassUtils.getClassName(java.awt.Frame.class));
System.out.println(ClassUtils.getFullClassName(java.awt.Frame.class));
System.out.println(ClassUtils.getPackageName(java.awt.Frame.class));
System.out.println("----");
System.out.println(ClassUtils.getClassName(ClassUtils.class));
System.out.println(ClassUtils.getFullClassName(ClassUtils.class));
System.out.println(ClassUtils.getPackageName(ClassUtils.class));
System.out.println("----");
java.util.Calendar cal = java.util.Calendar.getInstance();
System.out.println(ClassUtils.getClassName(cal.getClass()));
System.out.println(ClassUtils.getFullClassName(cal.getClass()));
System.out.println(ClassUtils.getPackageName(cal.getClass()));
}
}
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);
}
}
4: return
Note this is very low-level optimization, the gain in performance is not very significative, the class is little
bit smaller.
Self-replicating programs
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0344.html
A self replicating programs (also known as Quine) is computer program which prints its own listing!
First example
"System.out.println(s.substring(0,62)+c+s+c+s.substring(62));}}";
System.out.println(s.substring(0,62)+c+s+c+s.substring(62));}}
Second example
Third example
author Daniel Pitts
[Q.java]
A curiosity
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0356.html
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.
A curiosity 1041
Real's HowTo PDF version
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)
public class Homework{public static void main (String[] OoO) {for (int
oOo=0;oOo<OoO.length;++oOo) main (OoO [oOo]);} public static void main
(String oOo){String Oo0="9876543210"; long o0o=oOo.length()*Oo0.length
();for(int OoO=oOo.length();--OoO>=0;) {int O0O=Oo0.indexOf(oOo.charAt
(OoO));o0o-=O0O<0?012:++O0O;} main(oOo,o0o);} public static void main(
String Oo0,long oOo){System.out.print("Sum of digits in ");for(int O0O
=0;O0O<Oo0.length();++O0O)System.out.print(Oo0.charAt(O0O));System.out
.print(" = ");System.out.println(oOo);}}
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 curiosity 1042
Real's HowTo PDF version
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.
From SO
Common Bugs
Current version of this HowTo :
http://www.rgagnon.com/javadetails/../javadetails/java-0361.html
1:
int x = 0;
2:
int i = 0;
if (i = 0){
System.out.println("Won't print, why ?");
}
3:
4:
import java.util.List;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
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();
}
}
}
These examples use the Rhino Javascript engine bundled with Java 6.
import java.util.Arrays;
import java.util.List;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
output :
*** Java object to Javascript
Homer
Bart
Marge
Maggie
Lisa
*** Javascript object to Java
Moe
Barney
Ned
*/
The next example uses an external file containing the javascript code. The .JS file is loaded from the
classpath.
[scripting02.js]
importPackage(java.util);
var listObject = {
list2 : Arrays.asList
(['Moe', 'Barney', 'Ned']),
getList2 : function() {
return listObject.list2;
}
};
import java.io.InputStreamReader;
import java.util.List;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
}
}
System.out.println("***");
// call a javascript function to retrieve an object
if (engine instanceof Invocable){
Invocable engineInv = (Invocable)engine;
Object obj = engine.get("listObject");
Object list2 = engineInv.invokeMethod(obj, "getList2");
if (list2 != null) {
for (String s : (List<String>) list2) {
System.out.println(s);
}
}
}
}
}
/*
output :
Homer
Bart
Marge
Maggie
Lisa
***
Moe
Barney
Ned
*/
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;
}
if (lock == null) {
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.
.scf is a special file that contains a command for the Windows Explorer.
This command file can be localized for Windows in a different language, for the french Windows, it's
"Bureau.scf". It may be a good to make a copy of it under a different (and known) name and location.
import java.io.*;
fw.close();
}
pb2.showProgress = false;
System.out.println("\nDone " + j);
}
}
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
XML 1055
Real's HowTo PDF version
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.
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.
XHTML (Extensible Hypertext Markup Language) is a reformulation of HTML 4.0 as an application of the
XML.
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>
Read me 1056
Real's HowTo PDF version
</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.*;
import java.net.*;
import java.io.*;
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>
</howto>
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]
// jdk1.4.1
import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;
// using DOM
public class HowtoListerDOM {
public static void main(String[] args) {
File file = new File("howto.xml");
try {
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
}
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.*;
" </employee>" +
" <employee>" +
" <name>Sara</name>" +
" <title>Clerk</title>" +
" </employee>" +
"</data>";
try {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
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
<table>
<xsl:for-each select="data/guynamedbruce">
<tr>
<td>
<xsl:value-of select="FirstName"/>
</td>
<td>
<xsl:value-of select="LastName"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
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;
in.close();
closeXML();
}
catch (Exception e) { e.printStackTrace(); }
}
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);
}
transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
// we want to pretty format the XML output
// note : this is broken in jdk1.5 beta!
transformer.setOutputProperty
("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//
transformer.transform(domSource, out);
/*
get the XML in a String
java.io.StringWriter sw = new java.io.StringWriter();
StreamResult sr = new StreamResult(sw);
transformer.transform(domSource, sr);
return sw.toString();
*/
}
}
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();
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) {
}
}
}
transformer.setOutputProperty
("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//
java.io.StringWriter sw = new java.io.StringWriter();
StreamResult sr = new StreamResult(sw);
transformer.transform(domSource, sr);
return sw.toString();
}
}
class AccessCon {
public static Connection getConnection() throws Exception {
Driver d = (Driver)Class.forName
("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
Connection c = DriverManager.getConnection
("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:/tech97.mdb");
return c;
/*
To use an already defined ODBC Datasource :
*/
}
}
[J2SE 1.5]
<?xml version="1.0"?>
<howto>
<topic name="Java">
<url>http://www.rgagnon.com/topics/java-xml.html</url>
</topic>
<topic name="PowerBuilder">
<url>http://www.rgagnon.com/topics/pb-common.html</url>
<url>http://www.rgagnon.com/topics/pb-pfc.html</url>
</topic>
<topic name="Javascript">
<url>http://www.rgagnon.com/topics/js-language.html</url>
</topic>
<topic name="VBScript">
<url>http://www.rgagnon.com/topics/wsh-vbs.html</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;
If your XML is in a String (not in a File) then you need to get an InputStream from it.
import java.io.ByteArrayInputStream;
import java.io.InputStream;
...
You may need to pass the required encoding to the String.getBytes() method. See this HowTo
If we want the Handle text value then we don't need to retrieve the NODESET, only the TEXT.
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
...
...
One last example. Suppose we have an XML file containing SQL Statements.
<queries>
<query id="getUserByName">select * from users where name=?</query>
<query id="getUserByEmail">select * from users where email=?</query>
</queries>
To retrieve a SELECT
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
This can be useful to reduce the size of a file or before writting a message to a queue or the network.
System.out.println("");
/*
output :
<tag>test 3</tag>
<tag>test 4</tag>
<tag>test 3</tag><tag>test 4</tag>
*/
}
}
One drawback is that the spaces inside tags are stripped too. The following example preserves those spaces
inside a tag.
/*
output :
<tag>test 1</tag> <tag>test 2</tag> <tag> </tag>
<tag>test 1</tag><tag>test 2</tag><tag> </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);
}
transformer.transform(domSource, out);
}
}
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
</topic>
</howto>
import java.io.IOException;
// DOM
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
// SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
private XMLUtils() {}
builder.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING : " + e.getMessage()); // do nothing
}
reader.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING : " + e.getMessage()); // do nothing
}
System.out.println(XMLUtils.validateWithDTDUsingDOM("c:/temp/howto.xml"));
System.out.println(XMLUtils.validateWithDTDUsingSAX("c:/temp/howto.xml"));
/*
output :
true
true
*/
}
}
NOTES :
• The DOM is faster than SAX but DOM reads the entire structure in memory so the memory consumption is
bigger.
• DTD is the old way to validate an XML structure. The preferred way is to use an XML schema (XSD)
which provides a more complete validation process.
• To validate using an XML Schema (XSD), see this HowTo
<xs:element name="howto">
<xs:complexType>
<xs:sequence>
<xs:element name="topic" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="url" type="httpURI"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="httpURI">
<xs:restriction base="xs:anyURI">
<xs:pattern value="http://.*" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
The code (using SAX parser) to validate an XML file using a given external XSD.
import java.io.IOException;
// SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
private XMLUtils() {}
The code (using DOM parser) to validate an XML file using the referenced XSD :
import java.io.IOException;
// DOM
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
private XMLUtils() {}
builder.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING: " + e.getMessage()); // do nothing
}
);
builder.parse(new InputSource(xml));
return true;
}
catch (ParserConfigurationException pce) {
throw pce;
}
catch (IOException io) {
throw io;
}
catch (SAXException se){
return false;
}
}
The code (using SAX parser) to validate an XML file using the referenced XSD :
import java.io.IOException;
// SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
private XMLUtils() {}
This HowTo uses the built-in XML parser, you can switch JAXP in debug mode by passing a special
switch on the JVM command-line.
NOTES :
• The DOM is faster than SAX but DOM reads the entire structure in memory so the memory consumption is
bigger.
• See http://en.wikibooks.org/wiki/XML_Schema for more infos about XSD.
• To validate using an DTD, see this HowTo.
The following lists the range of valid XML characters. Any character not in the range is not allowed.
Hexidecimal Decimal
#x9 #9
#xA #10
#xD #13
#x20-#xD7FF #32-#55295
#xE000-#xFFFD #57344-#65533
#x10000-#x10FFFF #10000-#1114111
any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
ref : http://www.w3.org/TR/REC-xml/#charsets.
The exception to this rule is that CDATA sections may contain any character, including ones not in the above range.
For example, if data is coming from a Cut&Paste operation from a Microsoft Word document, you may end
up with 0x1a characters. Later, when the XML data is parsed, an Exception "hexadecimal value 0x1A, is an
invalid character" will be thrown.
The following methods will remove all invalid XML characters from a given string (the special handling of
a CDATA section is not supported).
Using Regex
);
return xmlInvalidChars.matcher(xml).replaceAll("");
}
char current;
You disable the automatic output escaping and use the & entity to build the actual entity.
<P><span style="border-style:solid;border-width:1px;">
<a href="{link}">
<xsl:text disable-output-escaping="yes">&nbsp;&rArr;</xsl:text>
Read the article</a>.
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</span>
</P>
will produce
<?xml version="1.0"?>
<howto>
<topic id="1">
<title>Java</title>
<url>http://www.rgagnon.com/topics/java-io.html</url>
</topic>
<topic id="2">
<title>XML</title>
<url>http://www.rgagnon.com/topics/java-xml.html</url>
</topic>
<topic id="3">
<title>Javascript</title>
<url>http://www.rgagnon.com/topics/js-language.html</url>
</topic>
<topic id="4">
<title>VBScript</title>
<url>http://www.rgagnon.com/topics/wsh-vbs.html</url>
</topic>
</howto>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
topic,title,url
<xsl:for-each select="//topic">
<xsl:value-of select="@id" />
<xsl:value-of select="concat(',' , title, ',' , url,'
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
package com.rgagnon.howto;
import org.w3c.dom.Document;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
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.transform.stream.StreamSource;
The result is
[howoto.csv]
topic,title,url
1,Java,http://www.rgagnon.com/topics/java-io.html
2,XML,http://www.rgagnon.com/topics/java-xml.html
3,Javascript,http://www.rgagnon.com/topics/js-language.html
4,VBScript,http://www.rgagnon.com/topics/wsh-vbs.html
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 2.0
<rss version="2.0">
<channel>
<title>Real's HowTo</title>
<description>Updates of useful code examples for Java</description>
<link>http://www.rgagnon.com/howto.html</link>
<pubDate>23 May 2007 00:00:00 GMT</pubDate>
<image>
<title>Real's HowTo</title>
<width>144</width>
<height>41</height>
<link>http://www.rgagnon.com/howto.html</link>
<url>http://www.rgagnon.com/images/realhowto-left.jpg</url>
</image>
<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>
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.
<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>[email protected]</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>
Creating a 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;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.text.SimpleDateFormat;
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>
</item>
</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;
return pubdate;
}
public void setPubDate(String pubdate) {
this.pubdate = pubdate;
}
}
package com.rgagnon.howto.rss;
this.pubDate = pubDate;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
}
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(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)</descript
<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);
RSS-UTIL.TLD
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.
<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>
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read
and write. It is used primarily to transmit data between a server and web application, as an alternative to
XML.
JSON structures are easy to manipulate from Java. The required libraries are now included in the Java EE 7
specification.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
import java.io.StringReader;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
// https://jsonp.java.net/download.html
public class Json1 {
String jsonString = "{" +
" \"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 25," +
" \"address\" : { " +
" \"streetAddress\": \"21 2nd Street\"," +
" \"city\": \"New York\"," +
" \"state\": \"NY\"," +
" \"postalCode\": \"10021\"" +
" }," +
" \"phoneNumber\": [" +
" { \"type\": \"home\", \"number\": \"212 555-1234\" }," +
" { \"type\": \"fax\", \"number\": \"646 555-4567\" }" +
" ]" +
"}";
import javax.json.Json;
import javax.json.JsonObject;
To call the REST service, we will use the HTTPClient module from Apache.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
• https://jsonp.java.net/download.html
• http://hc.apache.org/downloads.cgi
For the demonstration, we call http://jsonplaceholder.typicode.com/ which is Fake Online REST API for
Testing and Prototyping.
The first example calls jsonplaceholder.typicode.com/posts/1 to get the first message. From the response,
we extract the id and the title.
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit ...eveniet architecto"
}
import java.io.InputStreamReader;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
Now we call jsonplaceholder.typicode.com/posts which returns a message list of 100 elements. From the
response, we iterate the returned array to display the id and the title.
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit ...eveniet architecto"
}
...
{
"userId": 10,
"id": 100,
"title": "at nam consequatur ea labore ea harum",
"body": "cupiditate quo est a modi nesciunt ... ratione error aut"
}
]
import java.io.InputStreamReader;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.InputStream;
import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
//https://jsonp.java.net/download.html
//http://hc.apache.org/downloads.cgi
InputStream is = response.getEntity().getContent();
JsonParser parser = Json.createParser(is);
while (parser.hasNext()) {
Event e = parser.next();
if (e == Event.KEY_NAME) {
switch (parser.getString()) {
case "id":
parser.next();
System.out.print(parser.getString());
System.out.print(": ");
break;
case "title":
parser.next();
System.out.println(parser.getString());
System.out.println("---------");
break;
}
}
}
/*
output :
1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
-------------
2: qui est esse
---------
...
99: temporibus sit alias delectus eligendi possimus magni
---------
100: at nam consequatur ea labore ea harum
---------
Done.
*/
}
finally {
if (client != null) client.close();
if (response != null) response.close();
System.out.println("Done.");
}
}
}
It's possible to do it by hand by calling the jasonobject.get[type] and the corresponding DTO/POJO set
methods. But it is easier to use a library to handle the finer details. One library which is nice is GSON.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
import java.io.InputStreamReader;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import com.google.gson.Gson;
// https://jsonp.java.net/download.html
// http://hc.apache.org/downloads.cgi
// http://search.maven.org/#artifactdetails|com.google.code.gson|gson|2.3.1|jar
import com.google.gson.Gson;
// http://search.maven.org/#artifactdetails|com.google.code.gson|gson|2.3.1|jar
json : {"userid":1111,"id":2222,"title":"foo","body":"bar"}
Done.
*/
}
}