| You are receiving this e-mail {e-mail address} because you elected to receive e-mail from Sun Microsystems, Inc. To update your communications preferences, please see the link at the bottom of this message. We respect your privacy and post our privacy policy prominently on our Web site http://sun.com/privacy/ |
![]() |
||||||
|
||||||
|
This monthly newsletter provides a way for you to learn the basics of
the Java programming language, discover new resources, and keep
up-to-date on the latest additions to Sun Developer Network's New to
Java Programming Center.
You can receive future issues of this newsletter in HTML or text: http://developer.java.sun.com/subscription/ Note: For the code to compile in this issue of Fundamentals, you need to use the JDK 5.0 software. http://java.sun.com/j2se/1.5.0/download.jsp |
||
| Contents | ||
| Java Programming Language Basics | ||
|
Formatting Basics with JFormattedTextField by John Zukowski
The JFormattedTextField provides support for the input of
formatted text. When the component is created, you define a mask for
the input. That mask can be in the form of a java.text.Format object,
as an AbstractFormatter, as an AbstractFormatterFactory, or in the form
as an actual value, like a Date.
The system provides several abstract formatters for you to work with, depending upon the type of data you want a user to input. For instance, the NumberFormatter is available to enter numbers and the
DateFormatter is available for entering dates. There is also a
MaskFormatter for describing input with edit strings, like "XXX-XX-XXX"
for a US social security number. If you want different display and edit
formats, that's where the AbstractFormatterFactory comes into play.
For a JFormattedTextField, the validation magic is controlled
by the focusLostBehavior property. This can be set to one of four
values: COMMIT, COMMIT_OR_REVERT, REVERT, or PERSIST. When the
component loses focus, you'll get one of four behaviors, the default
being COMMIT_OR_REVERT. What COMMIT_OR_REVERT means is when the
component loses focus, automatically call the commitEdit method
internally. This parses the component's contents and throws a
ParseException on error, reverting the contents to the most recent
valid value. The COMMIT setting works similarly, but leaves the invalid
contents within the field, allowing the user to modify the setting. A
REVERT setting always reverts the value, while PERSIST essentially does
nothing. When set to PERSIST, you should manually call commitEdit
yourself to see if the contents are valid before using the contents.
For starters, let's use the JFormattedTextField to accept
input that should be internationalized. This includes all forms of
dates, times, and numbers, basically, anything whose format can be
acquired form a DateFormat or NumberFormat object. If, instead, you
provide a Date object or Number subclass to the JFormattedTextField
constructor, the component passes the input String to the constructor
of that object type to do the input validation. Instead, you should
work with the InternationalFormatter class in the java.swing.text
package by passing a DateFormat or NumberFormat into the constructor.
This allows you to specify long vs. short form for dates and times, and
currency, percentage, floats, and integers for numbers.
To demonstrate, the example below accepts date and time input. From top to bottom, the inputs are short date format for default locale, full date format for US English, medium date format for Italian, day of week in French, and short time format for the default locale. To start the program in a different locale, you can set the user.language and user.country settings from the command line with a command similar to the following: java -Duser.language=fr -Duser.country=FR DateInputSample, though this
only alters the valid input for those formats without a specific locale
set.
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.text.*;
import java.util.*;
public class DateInputSample {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Date/Time Input");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label;
JFormattedTextField input;
JPanel panel;
BoxLayout layout =
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
frame.setLayout(layout);
Format shortDate =
DateFormat.getDateInstance(DateFormat.SHORT);
label = new JLabel("Short date:");
input = new JFormattedTextField(shortDate);
input.setValue(new Date());
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format fullUSDate =
DateFormat.getDateInstance(DateFormat.FULL, Locale.US);
label = new JLabel("Full US date:");
input = new JFormattedTextField(fullUSDate);
input.setValue(new Date());
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format mediumItalian =
DateFormat.getDateInstance(DateFormat.MEDIUM,
Locale.ITALIAN);
label = new JLabel("Medium Italian date:");
input = new JFormattedTextField(mediumItalian);
input.setValue(new Date());
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format dayOfWeek = new SimpleDateFormat("E", Locale.FRENCH);
label = new JLabel("French day of week:");
input = new JFormattedTextField(dayOfWeek);
input.setValue(new Date());
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format shortTime =
DateFormat.getTimeInstance(DateFormat.SHORT);
label = new JLabel("Short date:");
input = new JFormattedTextField(shortTime);
input.setValue(new Date());
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
java.text.NumberFormat
class, instead of the DateFormat. The localization that can be done
here is with the getCurrencyInstance, getInstance,
getIntegerInstance, getNumberInstance, and getPercentInstance methods.
The NumberFormat class deals with the placement of the necessary
commas, periods, percent signs, and so forth. While inputting the
numbers, extra characters like commas for thousands aren't required.
The component naturally adds them after the fact where appropriate.
The listing here shows the resulting program. Each input field
starts with a value of 2424.50. Notice the position of decimal
points and commas and how it differs from locale to locale.
Properly set, your users won't have to worry. In the case of the
integer version, the input value is rounded. When setting the
contents of a JFormattedTextField, use the setValue method, not
the setText method. This will ensure the text contents are
validated.
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.text.*;
import java.util.*;
public class NumberInputSample {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Number Input");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Font font = new Font("SansSerif", Font.BOLD, 16);
JLabel label;
JFormattedTextField input;
JPanel panel;
BoxLayout layout =
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
frame.setLayout(layout);
Format currency =
NumberFormat.getCurrencyInstance(Locale.UK);
label = new JLabel("UK Currency:");
input = new JFormattedTextField(currency);
input.setValue(2424.50);
input.setColumns(20);
input.setFont(font);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format general = NumberFormat.getInstance();
label = new JLabel("General/Instance:");
input = new JFormattedTextField(general);
input.setValue(2424.50);
input.setColumns(20);
input.setFont(font);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format integer =
NumberFormat.getIntegerInstance(Locale.ITALIAN);
label = new JLabel("Italian integer:");
input = new JFormattedTextField(integer);
input.setValue(2424.50);
input.setColumns(20);
input.setFont(font);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
Format number =
NumberFormat.getNumberInstance(Locale.FRENCH);
label = new JLabel("French Number:");
input = new JFormattedTextField(number);
input.setValue(2424.50);
input.setColumns(20);
input.setFont(font);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
label = new JLabel("Raw Number:");
input = new JFormattedTextField(2424.50);
input.setColumns(20);
input.setFont(font);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
JFormattedTextField examples here
initializes the component with a double. The value 2424.50 is
auto-boxed into a Double object. There's nothing wrong with passing an
object to the constructor. Playing with the input field though will
reveal some irregularities while entering values. It seems to always
start with one decimal point, even though more input digits are
accepted. Instead of using a Format object to go from text to Object
and back, the Double constructor that accepts a String is used instead.
When you pass in a java.text.Format object to the
JFormattedTextField constructor, this internally is mapped to either a
DateFormatter or NumberFormatter object. Both of these are subclasses
of the InternationalFormatter class. The inner class named
JFormattedTextField.AbstractFormatterFactory manages the use of the
formatter objects within JFormattedTextField. The factory will
install() the formatter as the user enters the JFormattedTextField and
uninstall() it upon departure, ensuring the formatter is active in only
one text field at a time. These install and uninstall methods are
inherited by the formatter classes from the
JFormattedTextField.AbstractFormatter, superclass of all formatters.
Beyond numbers and dates, the JFormattedTextField supports
user input following a pattern or mask. For instance, if an input field
is a social security number (SSN), it has a typical pattern of number,
number, number, dash, number, number, dash, number, number, number,
number. With the help of the MaskFormatter class, you can specify the
mask using characters found in the following table. So, an SSN would be
created with a formatter of new MaskFormatter("###'-##'-####"). The
apostrophes in the mask mean the character after each is treated
literally, in this case as a dash. You have the option of passing this
formatter to the JFormattedTextField constructor, or configuring the
text field with the setMask method.
CHARACTER DESCRIPTIONTo demonstrate, the following class includes two JFormattedTextField components, one to accept US social security
numbers, and the other US-formatted phone numbers. The SSN field starts
with an initial value, while the phone number doesn't.
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.text.*;
import java.util.*;
public class MaskInputSample {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Mask Input");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label;
JFormattedTextField input;
JPanel panel;
MaskFormatter formatter;
BoxLayout layout =
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
frame.setLayout(layout);
try {
label = new JLabel("SSN");
formatter = new MaskFormatter("###'-##'-####");
input = new JFormattedTextField(formatter);
input.setValue("123-45-6789");
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
} catch (ParseException e) {
System.err.println("Unable to add SSN");
}
try {
label = new JLabel("US Phone");
formatter = new MaskFormatter("'(###')' ###'-####");
input = new JFormattedTextField(formatter);
input.setColumns(20);
panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(label);
panel.add(input);
frame.add(panel);
} catch (ParseException e) {
System.err.println("Unable to add Phone");
}
frame.pack();
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
MaskFormatter does provide some customization options. By
default, the formatter is in overwrite mode, so as you type, the
entered digits will replace each number/space in the input field. Set
the overwriteMode property to false to disable this. Typically this
isn't necessary, though for entering long dates it can be helpful. If
you wish to have a different character as the placeholder character,
before a position is filled in mask, set the placeholderCharacter
property of the MaskFormatter.
|
||
| Making Sense of the Java Classes & Tools | ||
|
Security Tools These security tools help you set security policies on your system and create applications that can work within the scope of security policies set at remote sites. Tool Name Brief Description keytool Manage keystores and certificates. jarsigner Generate and verify JAR signatures. policytool GUI tool for managing policy files.These security tools help you obtain, list, and manage Kerberos tickets.
|
|||||||||
| Java Bits | ||
|
Version 1.5.0 or 5.0? by Sun Staff Both version numbers 1.5.0 and 5.0 are used to identify this release of the Java 2 Platform Standard Edition. Version 5.0 is the product version, while 1.5.0 is the developer version. The number 5.0 is used to better reflect the level of maturity, stability, scalability and security of the J2SE. The number 5.0 was arrived at by dropping the leading 1. from 1.5.0. Where you might have expected to see 1.5.0, it is now 5.0, and where it was 1.5, it is now 5. Version 5.0 Used in Platform and Product Names Version 5.0 is used in the platform and product names as given in this table:
Due to significant popularity within the Java developer community, the development kit has reverted back to the name JDK from Java 2 SDK (or J2SDK), and the runtime environment has reverted back to JRE from J2RE. Notice that JDK stands for J2SE Development Kit to distinguish it from the J2EE Development Kit. The name Java Development Kit is no longer used, and has not been officially used since 1.1, prior to the advent of J2EE and J2ME. As before, the 2 in Java 2 Platform Standard Edition indicates the second generation Java platform, introduced with J2SE 1.2. This generation number is also used with J2EE and J2ME. Version 1.5.0 Used by Developers J2SE also keeps the version number 1.5.0, or 1.5, in some places that are visible only to developers, or where the version number is parsed by programs. As mentioned, 1.5.0 refers to exactly the same platform and products numbered 5.0. Version numbers 1.5.0 and 1.5 are used at:
|
||||||||||
| Concurrent Programming with J2SE 5.0 | ||
|
By Qusay H. Mahmoud Java is a multithreaded programming language that makes programming with threads easier, by providing built-in language support for threads. The built-in primitives however, such as synchronized blocks, Object.wait, and Object.notify, are insufficient for many programming tasks. This leads developers to implement their own high-level synchronization facilities, but given the difficulty of concurrency issues, their implementations may not be correct, efficient, or high quality. The Java 2 Platform, Standard Edition release 5.0 (J2SE 5.0), which is also known as Tiger, has provided a new path to multithreading in the Java programming language. The original mechanisms for coordinating threads with wait and notify are now enhanced with new and sophisticated mechanisms for working with threads. The new mechanisms are part of the java.util.concurrent package, which offers a standard set of concurrency utilities that will ease the task of developing multithreaded applications and servers. In addition, such standards will improve the quality of such applications. The package has been defined through the Java Community Process as JSR 166: Concurrency Utilities. This article provides an overview and an introductory tutorial to the new concurrency mechanisms that have been added to J2SE 5.0. It helps developers get started using the new java.util.concurrent package and its subpackages. Limitations of Built-in Synchronization in J2SE 1.4.x When writing multithread applications, the issues that may create difficulties are related to data synchronization; these are the errors that make design harder, and such errors are hard to detect. Built-in synchronization (methods and blocks) are fine for many lock-based applications, but they do have their own limitations, such as:
Read the rest of this article |
||
| What's New on java.net | ||
|
The Java Extension Mechanism by Thomas Künneth A huge number of publicly available packages extends the functionality of the Java core platform. Some of them provide access to features of the underlying operating system that are not available through the standard class library, such as missing GUI components, or reader and writer classes for important file formats. Others are exciting technologies in their own right, like Spring, Hibernate or Struts. Sometimes installing them is a bit tricky, requiring you to modify the class path of your application or tweak options passed to the Java launcher. Others utilize a handy feature called the Java Extension Mechanism. Libraries loaded through the extension mechanism can be accessed by any Java program without further prerequisites besides copying some files to certain directories. This article explains how the Extension Mechanism works and discusses the steps required to implement your own so-called optional packages. The Class Path The virtual machine uses the concept of a class path, which is a set of directories and .zip or .jar archives. To find classes (as well as other resources like properties files, images, or audio content) the Java runtime looks in all locations specified in the class path to find the required resource. Early versions of Java relied heavily on an environment variable called CLASSPATH that stored these locations. It is easy to modify
this variable, perhaps too easy: setting the class path this way
turned out to be error-prone, as changes usually affected other
applications. Another shortcoming of this approach was the missing
distinction between user (third-party) and system classes. Today
there is no need to use the CLASSPATH environment variable.
Since Java 1.2, the virtual machine has distinguished between three types of classes: bootstrap classes, extension classes, and user classes. Each type has its own individual search path that can be modified separately. All three parts together make up the class path. It is worth mentioning, however, that the user class path is commonly referred to as simply "the class path." The difference between extension classes and user classes may not be clear at first sight, as they both are implemented by third-party developers, and hence do not belong to the core Java classes. The difference is that user classes do not take advantage of the extension mechanism. Additionally, the way that extension classes are found by the virtual machine is different. The boot class path specifies where core system classes are searched. The system property sun.boot.class.path stores these locations. It
generally should not be necessary to change them, but there is a
non-standard option of the Java launcher, -Xbootclasspath, that
allows you to use alternative core system classes.
How User Classes Are Found The user class path specifies where user classes and resources are searched. A simple program consisting of one class called Test is invoked through: java Test This assumes you use the standard Java launcher. The class path defaults to the current directory, so Test is found easily (if the current directory contains Test.class).
A program consisting of two .jars (the main application in MyApp.jar and a set of utility classes in MyUtils.zip) is invoked
through:
java -classpath MyApp.jar;MyUtils.zip myapp.MyAppMain
The path separator is ; on Windows, while UNIX variants like Mac OS X and Linux use : instead. Using -classpath completely overrides the default setting; therefore,
the current directory is not part of the class path. Consequently,
to access classes that are not part of the specified .jar or .zip
archives, the directory containing them must be added to the user
class path with the -classpath option.
Sharing .jar Archives It is common practice to have a Main-Class: attribute in the main
application .jar's manifest file so the application can be launched
by typing java -jar MyApp.jar. In this case, the .jar file is the
source for all user classes. Any other class path option is ignored.
To gain access to classes and resources stored in utility class .jars, you must add a Class-Path: attribute to your application's
manifest file. Its value contains a space-delimited list of
relative URLs referencing libraries your application wishes to use.
These URLs are assumed to point to directories if they end with the
/ character. Otherwise they are assumed to refer to .jars.
To share a library among multiple projects, you could add its location to the class paths of these programs using -classpath or
Class-Path: in the manifest file of each program. This can be a
cumbersome task if several projects are involved. If we used the
old-style CLASSPATH environment variable, it would have been
sufficient to append the location of the library--no need to
explicitly reference it with each application wishing to use it.
But there must be a similar feature in recent Java versions,
right?
Read the rest of this article |
||
| What's New in the New to Java Technology Center | ||
|
Updated Articles Articles in the New to Java Technology Programming Center have been updated to reflect newer operating systems, and the latest J2SE software download. Make sense of many Java technologies and acronyms with Unraveling Java Terminology and the Java Concept Map, and learn how to set up the lastest Java platform software using Getting Started as a guide: |
||
| Sun's Java Technology Courses Special Offer | ||
|
For a limited time, register for one of our five most popular Java technology training courses to be eligible to receive one of our five most requested giveaway items. Qualifying Java Technology Courses
Offer is good while quantities last. There are limited quantities of each of the 5 items. If the item you want is no longer available you will have to choose from the remaining items. |
||
| For More Information | ||
| Downloading the Java 2 Platform | ||
|
For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the J2SE development kit. |
||
|
Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: fundamentals_newsletter@sun.com
Find archived issues of the following Java technology developer newsletters or manage your current newsletter subscriptions: https://softwarereg.sun.com/registration/developer/en_US/subscriptions Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:
IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies: http://www.sun.com/share/text/termsofuse.html http://www.sun.com/privacy/ http://developer.java.sun.com/berkeley_license.html © 2005 Sun Microsystems, Inc. All Rights Reserved. For information on Sun's trademarks see: http://sun.com/suntrademarks Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. To update your Sun subscription preferences or unsubscribe to Sun news services, click here or use this link https://softwarereg.sun.com/registration/developer/en_US/subscriptions Sun Microsystems, Inc. 10 Network Circle, MPK10-209 Menlo Park, CA 94025 US |