Differences Between  AWT and Swing

Even the simplest Swing components have capabilities far beyond what the AWT components offer:

     Swing lets you specify which look and feel your program's GUI uses. By contrast, AWT components always have
     the look and feel of the native platform.

     Another interesting feature is that Swing components with state use models to keep the state. A JSlider, for
     instance, uses a BoundedRangeModel object to hold its current value and range of legal values. Models are set
     up automatically, so you don't have to deal with them unless you want to take advantage of the power they can
     give you.

     If you're used to using AWT components, you need to be aware of a few gotchas when using Swing components:



Tip:    To view the containment hierarchy for any frame or dialog, click its border to select it, and then
          press Control-Shift-F1. A list of the containment hierarchy will be written to the standard output
          stream.


How Painting Works

    When a Swing GUI needs to paint itself -- whether for the first time, in response to becoming unhidden, or because it needs to reflect a change in the program's state -- it starts with the highest component that needs to be repainted and works its way down the containment hierarchy. This process is orchestrated by the AWT painting system, and made more efficient and smooth by the Swing repaint manager and double-buffering code.

     Swing components generally repaint themselves whenever necessary. When you invoke the setText method on a component, for example, the component should automatically repaint itself and, if appropriate, resize itself. If it doesn't, it's a bug. The workaround is to invoke the repaint method on the component to request that the component be scheduled for painting. If the component's size or position needs to change but doesn't do so  automatically, you should invoke revalidate upon the component before invoking repaint.

      Like event-handling code, painting code executes on the event-dispatching thread. While an event is being handled, no painting will occur. Similarly, if a painting operation takes a long time, no events will be handled during that time.

     For smoothness, Swing painting is double-buffered by default -- performed to an offscreen buffer and then flushed to the screen once finished. It might slightly help performance if you make a Swing component opaque, so  that the Swing painting system can know not to paint anything behind the component. To make a Swing component opaque, invoke setOpaque(true) on the component.



Swing and Threads

The Single-Thread Rule : Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.

Realized: A Swing component that's a top-level window is realized by having one of these methods invoked on it:
setVisible(true), show, or pack. Once a window is realized, all the components that it contains are realized.
Another way to realize a component is to add it to a container that's already realized.

Two JComponent methods are safe to call from any thread: repaint and revalidate.
These methods queue requests to be executed on the event-dispatching thread.
Also, it's always safe to call the addListenerTypeListener and removeListenerTypeListener methods.
The add/remove operations have no effect on an event dispatch that's under way.

The SwingUtilities class provides two methods to help you run code in the event-dispatching thread:

     invokeLater
          Requests that some code be executed in the event-dispatching thread. This method returns immediately,
          without waiting for the code to execute.

     invokeAndWait
          Acts like invokeLater, except that this method waits for the code to execute. As a rule, you should use
          invokeLater rather than this method.



More Swing Features:

JComponent : All non-top level swing components starting with J are subclass of JComponent class. It provides features like tooltip text, border, configurable L&F, Double Buffering etc.
Icons : Swing components such as JButton and JLabel can have images represented by Icon Objects.
Actions : If you want multiple objects to share state and data information during action event, use Action objects.
Pluggable Look and Feel : A Single program can have any one of several L&F. It can be chosen by the end user or set programmatically set.
Support Assistive Technologies: Swing API comes with in built support for Assistive Technologies.
Separate Data and State Models: All noncontainer Swing Components have a underlying model. JButton has a ButtonModel which stores information like - Keyboard Mnemonic, enabled state or not, selected, pressed and so.
Some Swing Component can have more than one underlying models. For example JList has ListModel which contains the List's contents and ListSelectionModel which contains information about its list selection.
Working with models directly is more efficient and faster.



JComponent Class

The JComponent class extends java.awt.Container class. There are some classes like Box.Filler which are not top-level container and that do not subclass JComponent.

Important methods include : setToolTipText, setBorder, registerKeyboardAction(specify a KeyStroke Object), putClientProperty, getClientProperty (properties for use by Layout Managers), setPreferredSize, setMinimumSize, setMaximumSize, setAlignmentX, setAlignmentY (setter methods: Component class provides getter methods), setOpaque, isOpaque etc



Top Level Containers: JFrame, JApplet, JDialog, JWindow

Each top-level container has a containment hierarchy of its own.

Top-Level container has a content-pane that contains all the visible components of the top-level container. It is an intermediate container that inherits from JComponent class with a BorderLayout layout Manager. getContentPane returns a Container object and not a JComponent object. Generally an opaque JComponent , such as JPanel, is constructed to contain all the visible components and set as the content pane with setContentPane.

In theory all top-level container can have a JMenuBar. But generally a JFrame or a JApplet has JMenuBar. Use setJMenuBar.

All top-level container has a RootPane that supports the content pane, menubar, Layered pane and Glass Pane.
It is used to intercept mouse click or paint over multiple components.

The layered pane directly contains the menu bar and content pane, and enables Z-ordering of other components you might add. The glass pane is often used to intercept input events occurring over the top-level container, and can also be used to paint over multiple components.



JFrame Class

     JFrame extends from java.awt.Frame.

     By default, when the user closes a frame onscreen, the frame is hidden. Although invisible, the frame still exists and
     the program can make it visible again. If you want different behavior, then you need to either register a window
     listener that handles window-closing events, or you need to specify default close behavior using the
     setDefaultCloseOperation method. You can even do both.

     The argument to setDefaultCloseOperation must be one of the following values, which are defined in the
     WindowConstants interface (which JFrame implements):

If the default close operation is to dispose the frame and also a window event listener is registered that checks if the frame is the last one and if so exits the application, then in such condition the window event listener is invoked first.

API: createRootPane, setRootPane, getRootPane, getGlassPane, setGlassPane, setLayeredPane, getLayeredPane, setContentPane, getContentPane, setJMenuBar, getJMenuBar, setDefaultCloseOperation etc



JDialog Class

     Extends the java.awt.Dialog class.

     Every dialog is dependent on a frame. When that frame is destroyed, so are its dependent dialogs. When the
     frame is iconified, its dependent dialogs disappear from the screen. When the frame is deiconified, its dependent
     dialogs return to the screen. The AWT automatically provides this behavior.

     A dialog can be modal. When a modal dialog is visible, it blocks user input to all other windows in the program.
     The dialogs that JOptionPane provides are modal. To create a non-modal dialog, you must use the JDialog
     class directly.

     JOptionPane class

     It is a container that automatically creates a JDialog and put itself to the contentpane of the JDialog. It is Modal.

     JOptionPane's icon support lets you easily specify which icon the dialog displays. You can use a custom icon, no
     icon at all, or any one of four standard JOptionPane icons (question, information, warning, and error). Each look
     and feel has its own versions of the four standard icons.

     JOptionPane API:
 
Method Purpose
int showMessageDialog(Component, Object) 
int showMessageDialog(Component, Object, String, int) 
int showMessageDialog(Component, Object, String, int,
Icon) 
Show a one-button, modal dialog that gives the user some information. The arguments specify (in order) the parent   component, message, title, message type, and icon for the  dialog.
int showOptionDialog(Component, Object, String, int, int,Icon, Object[], Object Show a customized modal dialog. The arguments specify (in order) the parent component, message, title, option type, message type, icon, options, and initial value for the dialog.
int showConfirmDialog(Component, Object) 
int showConfirmDialog(Component, Object, String, int) 
int showConfirmDialog(Component, Object, String, int,
int) 
int showConfirmDialog(Component, Object, String, int,
int, Icon) 
A modal dialog that ask the user  a question. The arguments specify (in order) the parent   component, message, title, message type, and icon for the  dialog.
String showInputDialog(Object) 
String showInputDialog(Component, Object) 
String showInputDialog(Component, Object, String, int) 
String showInputDialog(Component, Object, String, int,
Icon, Object[], Object) 
Show a modal dialog that prompts the user for input. The single-argument version specifies just the message, with the parent component assumed to be null. The arguments for the other versions specify (in order) the parent component, message, title, message type, icon, options, and initial value for the dialog

Description of arguments in the above methods:

    Component parentComponent
          The first argument to each showXxxDialog method is always the parent component, which must be a
          frame, a component inside a frame, or null. If you specify a frame, then the dialog will appear over the
          center of the frame, and depend on that frame. If you specify a component inside a frame, then the dialog
          will appear over the center of that component, and depend on that component's frame. If you specify null,
          then the look and feel picks an appropriate position for the dialog -- generally the center of the screen, and
          the dialog doesn't depend on any visible frame.

          The JOptionPane constructors do not include this argument. Instead, you specify the parent frame when
          you create the JDialog that contains the JOptionPane, and you use the JDialog
          setLocationRelativeTo method to set the dialog's position.

     Object message
          This required argument specifies what the dialog should display in its main area. Generally, you specify a
          string, which results the dialog displaying a label with the specified text. You can split the message over
          several lines by putting newline (\n) characters inside the message string. For example:

               "Complete the sentence:\n \"Green eggs and...\""

     String title
          The title of the dialog.

     int optionType
          Specifies the set of buttons that appear at the bottom of the dialog. Choose from one of the following
          standard sets: DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION,
          OK_CANCEL_OPTION.

     int messageType
          This argument determines the icon displayed in the dialog. Choose from one of the following values:
          PLAIN_MESSAGE (no icon), ERROR_MESSAGE, INFORMATION_MESSAGE,
          WARNING_MESSAGE,   QUESTION_MESSAGE.

     Icon icon
          The icon to display in the dialog.

     Object[] options
          Further specifies the option buttons to appear at the buttom of the dialog. Generally, you specify an array of
          strings for the buttons. See Customizing Button Text in a Standard Dialog for more information.

     Object initialValue
          Specifies the default value to be selected.

Knowing User's Response:

The showMessageDialog, showConfirmDialog, and showOptionDialog methods return an integer indicating the user's choice. The values for this integer are YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION, and CLOSED_OPTION. Except for CLOSED_OPTION, each option corresponds to the button the user pressed. When CLOSED_OPTION is returned, it indicates that the user closed the dialog window explicitly, rather than by choosing a button inside the option pane.

Customized Dialog:

1. Create a JOptionPane like ... new JOptionPane(mesg,optionType, OptionType)
2. Create a JDialog
3. set the JOptionPane of step1 as the contentPane of the JDialog of step2
4. To override the default behaviour of a JOptionPane getting closed as the user chooses an option, register a PropertyChageListener to the JDialog. Get  propertyName and handle it according to your requirments.



JApplet Class
java.awt.Applet used getImage to get an Image object. JApplet uses ImageIcon to create an image icon from an image-URL, instead.

If the browser is Swing enabled an html file with <APPLET>tag can be used to run an applet. If the browser does not support swing, java plug-in must be used and the applet should be specified using <OBJECT> tag ot <EMBED> tag. There are tools that generates this new tags from <APPLET> tag.


Intermediate Swing Containers:

DeskTop Pane is a specialized Layered Pane intermediate container that is used to contain JInternalFrame.

JPanel Class
The Layout manager can be specified at instantiation time as an argument to the constructor or by using the setLayout method.



JScrollPane Class

You can change a scroll pane's client dynamically by calling the setViewportView method. Note that
JScrollPane has no corresponding getViewportView method, so you should cache the client object in a
variable if you need to refer to it later.
JScrollPane uses an instance of JViewPort to manage its visible region. It uses instances of JScrollBar to manage scrolling.

ScrollPane policy
The scroll bar policy of the horizontal and vertical scroll bars can be specified at creation time or set dynamically:

   JScrollPane(Component, vertPolicy, horiPolicy)
   JScrollPane(vertPolicy, horiPolicy)

   OR

  setHorizontalScrollBarPolicy(int)
  setVerticalScrollBarPolicy(int)

In above the int values can be one of the following constants defined in the ScrollPaneConstants Interface:
VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED, VERTICAL_SCROLLBAR_ALWAYS,  HORIZONTAL_SCROLLBAR_ALWAYS, VERTICAL_SCROLLBAR_NEVER,  HORIZONTAL_SCROLLBAR_NEVER

Custom Decorations
The area drawn by a scroll pane consists of up to nine parts: the center, four sides, and four corners. The center is
the only component that is always present in all scroll panes. Besides scroll bars, the sides can contain column and
row headers. A corner component is visible only if both sides that intersect at that corner contain visible
components.

API: setColumnHeaderView(Component), setRowHeaderView(Component), setCorner(JScrollPane.XXX_XXX_CORNER, Component)

Scroll-Savvy Client
To customize the way that a client component interacts with its scroll pane, you can make the component
implement the Scrollable interface. By implementing Scrollable, a client can specify both the size of the
viewport used to view it and the amount to scroll for clicks on the different controls on a scroll bar.

The Scrollable interface includes the following methods:

All these methods returns an integral value of pixels.

Lists, Tables, textComponents, and trees implements the scrollable interface.

Sizing the Scroll Pane
By default the size of a scroll pane is the preferred size of it nine components.
If the size of the client is fized then having a scroll pane is redundant. To get the scroll bars, in such as case, is to set the preferred size of the scroll pane or its container.
Scroll-savvy clients implements Scrollable interface and provides methods that the scroll pane uses to determine it scrolling behaviour. Scroll-savvy class like lists, tables provides methods the programmer can call to set the values returned by the methods of the Scrollable interface.

Dynamically Changing Client's Size
Step 1. Reset the preferred size of the client
Step 2. revalidate the client

API: setViewportView, setViewportBorder etc

Scrolling methods in other class : setVisibleRowCount (JList, JTree), setPreferredScrollableViewportSize (JTable) etc.



JSplitPane Class

JSplitPane([orientation],[boolean],[component1,component2])
orientation : JSplitPane.HORIZONTAL_SPLIT, JSplitPane.VERTICAL_SPLIT
boolean : Determines whether the component repaints as the user drags the split pane.

setOneTouchExpandable, setDividerSize, setDividerLocation, setOrientation, setLeftComponent, setRightComponent, setTopComponent, setBottomComponent



JTabbedPane Class

JTabbedPane([int]) : The int specfies constants from SwingConstants interface : TOP, BOTTOM, LEFT, RIGHT
addTab(TabLabelText, [Icon], component,[toolTipText]), setSelectedIndex(int) -- index starts from 0



JToolBar Class

It uses BoxLayout as its layout manager and hence can have its components call setAlignmentX, setAlignmentY etc.

API: JToolBar(), add(Component), add(Action), addSeparatot(), setFloatable(boolean) etc



JInternalFrame Class

The internal frame is implemented with platform-independent code and hence has more features than normal frames. It can specify the window decorations for resizing, iconifying, and maximizing. Internal frames cannot be root of a containment hierarchy. It does not generate windows event and generates Internal Frame events. Internal frame supports root pane and hence realizing GUI in internal frame is similar to that of normal frame.

Important rules while using internal frames:
- It is usually contained in a LayeredPane as JDeskTopPane.
- By default the internal frame has 0 size and must be set using pack, setSize or setBounds
- set the location in within its container using setLocation or setBounds
- to add components to an internal frame add it to the content pane of the internal frame
- to allow just outline drawing at the time of dragging use : internalframecontainer.setClientProperty("JDesktopPane.fragMode", "outline")

API: setJMenuBar, setDefaultCloseOperation, addInternalFrameListener, moveToFront, moveToBack etc



JLayeredPane Class

All containers with root pane supports a JLayeredPane.
There are 2 main classes of Layered Pane : JLayeredPane and its sublcass JDesktopPane.

A Layered Pane does not have default layout manager. This is because all existing managers lays out components as if all of them are in a single layer.

Depth: The higher the value higher the depth.
Position: The higher the value lower the depth with the same layer. If there are n components in a layer, the position ranges from 0 to n-1. -1 is same as n-1. For example when n=3 we have:

API: JLayeredPane(), add(Component,[depthasInteger],[positioninsamelayerasInt]), setLayer(Component, depthasInt, [positionasInt]), setPosition(Component, positionasInt), moveToFront(Component), moveToBack(Component) etc

If in add method depth is not specified it is assumed to be 0. If position is not specified then it is same n-1.
The setPosition and moveTo.. are methods for the same layer.



JRootPane Class

The JRootPane uses a JLayeredPane instance:

The description of each of this layers are shown below:
 
Layer Name Value Description
FRAME_CONTENT_LAYER new Integer(-30000)  This layer is used to position the frame's content pane and
menu bar. Most programs won't use this. The root pane
adds the menu bar and content pane to its layered pane at
this depth. 
DEFAULT_LAYER new Integer(0)  Most components go in this layer. If you don't specify a
component's depth, the layered pane puts it at this depth. 
PALETTE_LAYER  new Integer(100) This layer is useful for floating toolbars and palettes.
MODAL_LAYER new Integer(200) Modal internal-frame dialogs would belong in this layer.
POPUP_LAYER new Integer(300)  Popups go in this layer because they need to appear above
just about everything. 
DRAG_LAYER  new Integer(400)  Move a component to this layer when dragging. Return the
component to its regular layer when dropped.