Advanced+Swing

=Swing Overview= Swing did not exist in the early days of Java. Rather, it was a response to deficiencies present in Java’s original GUI subsystem: the Abstract Window Toolkit (AWT). The AWT defines a basic set of components that support a usable, but limited graphical interface. One reason for the limited nature of the AWT is that it translates its various visual components into their corresponding, platform-specific equivalents, or peers. This means that the look and feel of an AWT component is defined by the platform, not by Java. Because the AWT components use native code resources, they are referred to as heavyweight. The use of native peers led to several problems. First, because of differences between operating systems, a component might look, or even act, differently on different platforms. This potential variability threatened the overarching philosophy of Java: write once, run anywhere. Second, the look and feel of each component was fixed (because it is defined by the platform) and could not be (easily) changed. Third, the use of heavyweight components caused some frustrating restrictions. For example, a heavyweight component is always rectangular and opaque. Not long after Java’s original release, it became apparent that the limitations and restrictions present in the AWT were sufficiently serious that a better approach was needed. The solution was Swing. Introduced in 1997, Swing was included as part of the Java Foundation Classes (JFC). Swing was initially available for use with Java 1.1 as a separate library. However, beginning with Java 1.2, Swing (and the rest of the JFC) was fully integrated into Java. Swing addresses the limitations associated with the AWT’s components through the use of two key features: lightweight components and a pluggable look and feel. Although they are largely transparent to the programmer, these two features are at the foundation of Swing’s design philosophy and the reason for much of its power and flexibility. Let’s look at each. With very few exceptions, Swing components are lightweight. This means that a component is written entirely in Java. It does not rely on platform-specific peers. Lightweight components have some important advantages, including efficiency and flexibility. For example, a lightweight component can be transparent, which enables non-rectangular shapes. Furthermore, because lightweight components do not translate into platform-specific peers, the look and feel of each component is determined by Swing, not by the underlying operating system. This means that each component will work in a consistent manner across all platforms.

Components and Containers
A Swing GUI consists of two key items: components and containers. However, this distinction is mostly conceptual because all containers are also components. The difference between the two is found in their intended purpose. As the term is commonly used, a component is an independent visual control, such as a push button or text field. A container holds a group of components. Thus, a container is a special type of component that is designed to hold other components. Furthermore, in order for a component to be displayed, it must be held within a container. Thus, all Swing GUIs will have at least one container. Because containers are components, a container can also hold other containers. This enables Swing to define what is called a containment hierarchy, at the top of which must be a top-level container.

Components
In general, Swing components are derived from the JComponent class. JComponent provides the functionality that is common to all components. For example, JComponent supports the pluggable look and feel. JComponent inherits the AWT classes Container and Component. Thus, a Swing component is built on and compatible with an AWT component. All of Swing’s components are represented by classes defined within the package javax.swing.

The following table shows the class names for Swing components:



Containers
Swing defines two types of containers. The first are top-level containers: JFrame, JApplet, JWindow, and JDialog. These containers do not inherit JComponent. They do, however, inherit the AWT classes Component and Container. Unlike Swing’s other components, which are lightweight, the top-level containers are heavyweight. This makes the top-level containers a special case in the Swing component library. As the name implies, a top-level container must be at top of a containment hierarchy. A top-level container is not contained within any other container. Furthermore, every containment hierarchy must begin with a top-level container. The one most commonly used for applications is JFrame. The one used for applets is JApplet. The second type of containers supported by Swing is lightweight containers. Lightweight containers do inherit JComponent. Examples of lightweight containers are JPanel, JScrollPane, and JRootPane. Lightweight containers are often used to collectively organize and manage groups of related components because a lightweight container can be contained within another container. Thus, you can use lightweight containers to create subgroups of related controls that are contained within an outer container.

=Tables= The JTable component is the standard Swing component for displaying two-dimensional data in the form of a grid. The JTable component relies on numerous support classes for its inner workings. For the JTable, the support classes are found in the javax.swing.table package. The cells within the JTable can be selected by row, column, row and column, or individual cell. It's the responsibility of the current ListSelectionModel settings to control the selection within a table. The display of the different cells within a table is the responsibility of the TableCellRenderer; the DefaultCellRenderer offers one such implementation of the TableCellRenderer interface in a JLabel subclass. Managing the data stored in the cells is accomplished through an implementation of the TableModel interface. The AbstractTableModel provides the basics of an implementation of the interface without any data storage. By comparison, the DefaultTableModel encapsulates the TableModel interface and uses a Vector of Vector objects for the data storage. You extend AbstractTableModel if you need a different type of storage than the kind supplied by the DefaultTableModel; for instance, if you already had the data in your own data structure. The TableColumnModel interface and the DefaultTableColumnModel implementation of the interface manage the table's data as a series of columns. They work together with the TableColumn class to allow for greater flexibility in manipulating individual columns. For example, you can store columns of data in the TableModel in an order that's different from the display order within the JTable. The TableColumnModel manages a second ListSelectionModel to control table column selection. At the top of every column is a column header. By default, the TableColumn class relies on the JTableHeader class to render a text column header. Nevertheless, you must embed the JTable in a scroll pane to see the default header. Cells within a JTable can be editable. If a cell is editable, how the editing works depends on the TableCellEditor implementation, such as the DefaultCellEditor implementation, which extends from AbstractCellEditor. In addition, no classes exist to handle individual rows. Rows must be manipulated on a cell-by-cell basis. Behind the scenes, the JTable uses the SizeSequence utility class to deal with variable height rows; you won't need to manipulate it yourself. There are additional interrelationships among the elements used by the JTable component. The JTable has many properties, 40 in all. These 40 are in addition to the many properties inherited from the JComponent, Container, and Component classes.

The code below will use a couple of different Swing classes, and each one will provide us with different tools: JFrame : this will create the Frame of the GUI. JScrollPane: this one will make it possible for us to resize the GUI. JList: whenever a selection is made, the ListSelectionEvent are fired. The method valueChanged in the interface ListSelectionListener is called whenever a new selection has been made

//**Code sample 1: Filename: WordCupGroups.java**// code format="java" import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener;

public class WordCupGroups {

public static void main(String[] a) { JFrame frame = new JFrame("World Cup Groups"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JTable table;

String[] columnTitles = { "Group A", " Group B", " Group C", " Group D", "Group E", "Group F", "Group G", "Group H" }; Object[][] rowData = { { "South Africa", "Argentina", "England", "Germany", "Netherlands","Italy","Brazil","Spain" }, { "Mexico", "Nigeria", "USA", "Australia", "Denmark","Paraguay","Korea DPR","Switzerland" }, { "Uruguay", "Korea Republic", "Algeria", "Serbia", "Japan","New Zeland","Ivory Coast","Honduras" }, { "France", "Greece", "Slovenia", "Gana", "Cameroon","Slovakia","Portugal","Chile" }};

table = new JTable(rowData, columnTitles); table.setCellSelectionEnabled(true); ListSelectionModel cellSelectionModel = table.getSelectionModel; cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

cellSelectionModel.addListSelectionListener(new ListSelectionListener {     public void valueChanged(ListSelectionEvent e) {        String selectedData = null;        int[] selectedRow = table.getSelectedRows;        int[] selectedColumns = table.getSelectedColumns;        for (int i = 0; i < selectedRow.length; i++) {          for (int j = 0; j < selectedColumns.length; j++) {            selectedData = (String) table.getValueAt(selectedRow[i], selectedColumns[j]);          }        }        System.out.println("Selected: " + selectedData);      }    }); frame.add(new JScrollPane(table)); frame.setSize(700, 150); frame.setVisible(true); } }

code

// Output 1: //
In the output below we can see how it will look right after we run the program. The Table will appear in the predetermined size of (700,150). Also each column will have the same width, even though the entire name of the country does not show, as we can see with Group B's third country "Korea Republic".

// Output 2: //
In the output below we can see that we enlarged the Group B column. That will cause the other columns to shrink, so we can go ahead and enlarge the entire GUI by left clicking and holding on the corner of the GUI, and moving to the desired size.

// Output 3: //
As we can see below, we can change the name of the teams and it will be replaced by the new one. That was done by using the ListSelectionEvent.

=Drag and Drop= Drag-and-drop support allows a user to highlight something in one program or area of the screen, select it, and relocate it to another program or area of the screen. For example, in Microsoft Word, you can select a paragraph and drag it to a new location. As Java has evolved, not only has the printing support changed with nearly every release, but so has the drag-and-drop support. The last major change in drag-and-drop support happened with the J2SE 1.4 release. Prior releases had support that was extremely difficult to use, especially to get proper drag-and-drop behavior for complex (nontext) types. The JDK 5.0 version adds some bug fixes and enhancements to drag-and-drop support. You can implement drag-and-drop within your Java program in three ways:
 * For the components that come with built-in support, just enable it by calling their setDragEnabled method with an argument of true. Those components are JColorChooser, JFileChooser, JList, JTable, JTree, and all the subclasses of JTextComponent, except JPasswordField.
 * For components without built-in support, you typically just need to configure the TransferHandler for that component.
 * You can also go directly to the classes found in the java.awt.dnd package. Thanks to the built-in support and configurability, this approach is rarely necessary.

Built-in Drag-and-Drop Support
The table below shows the components that offer built-in support for drag-and-drop. Initially, only dropping is enabled for the components that support it, but after calling setDragEnabled(true) for the component in question, you can enable dragging, too, if it's supported. The drag-and-drop capabilities of the Java platform involve the underlying java.awt.datatransfer package to move data around. Classes in this package allow you to describe the type of data to transfer.

For the JColorChooser component, what you drag is a java.awt.Color object. The other oddball of the bunch is the JFileChooser, where you literally drag a java.io.File object around and drop it into a drop target. If the drop target doesn't support working with File objects, a string representing the path is dropped instead.

TransferHandler Class
The magic of drag-and-drop happens because of the java.swing.TransferHandler class, introduced with the J2SE 1.4 release. "What's magical about it?" you might ask. With this class, you can pick which property you would like to be transferable in a drag-and-drop operation. When you call setDragEnabled(true) to tell a component to support the drag gesture, the component asks the installed TransferHandler what to transfer. If you don't like the default object being transferred, you can call the setTransferHandler method of the component, passing in an appropriate replacement. You can also call setTransferHandler when you want to enable drag-and-drop support for a component that doesn't come with support built in.

//**Code sample 2: Filename: ReplaceSomeone.java**// code format="java" import java.awt.BorderLayout; import java.awt.Rectangle; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.ItemEvent; import java.awt.event.ItemListener;

import javax.swing.DefaultListModel; import javax.swing.DropMode; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.TransferHandler;

public class ReplaceSomeone { public static void main(String[] args) { JPanel north = new JPanel; north.add(new JLabel("Replace a person:")); JTextField field = new JTextField(10); field.setDragEnabled(true); north.add(field);

final DefaultListModel listModel = new DefaultListModel; listModel.addElement("Watson"); listModel.addElement("Carlos"); listModel.addElement("Charles"); listModel.addElement("John"); listModel.addElement("Justin"); listModel.addElement("Ronaldo"); listModel.addElement("Peter");

final JList list = new JList(listModel); list.setDragEnabled(true);

list.setTransferHandler(new TransferHandler {     public boolean canImport(TransferHandler.TransferSupport support) {        if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {          return false;        }        JList.DropLocation dl = (JList.DropLocation) support.getDropLocation;        if (dl.getIndex == -1) {          return false;        } else {          return true;        }      }

public boolean importData(TransferHandler.TransferSupport support) { if (!canImport(support)) { return false; }

Transferable transferable = support.getTransferable; String data; try { data = (String) transferable.getTransferData(DataFlavor.stringFlavor); } catch (Exception e) { return false; }

JList.DropLocation dl = (JList.DropLocation) support.getDropLocation; int index = dl.getIndex; if (dl.isInsert) { listModel.add(index, data); } else { listModel.set(index, data); }

// Scroll to display the element that was dropped Rectangle r = list.getCellBounds(index, index); list.scrollRectToVisible(r); return true; }   });    JScrollPane center = new JScrollPane;    center.setViewportView(list);

list.setDropMode(DropMode.ON); JPanel cp = new JPanel; cp.setLayout(new BorderLayout); cp.add(north, BorderLayout.NORTH); cp.add(center, BorderLayout.CENTER); JFrame frame = new JFrame; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(cp); frame.pack; frame.setVisible(true); }

code

// Output 1: //
In the output below we have the main output with a JTextField, so we can input a name for later be used to substitute any other names on the list.

// Output 2: //
Below we use the JTextField to input the name Jacob, later we will drap and drop the name in the place of the name "Ronaldo"

// Output 3: //
Below we see the final result, as we used the list.setDragEnabled to drag the name "Jacob" into the position that the name "Ronaldo" was previously located, and we use the JList.DropLocation to drop the name "Jacob" into that position.

Advanced Swing Wrap Up
Swing is one of the most fun, and useful parts of Java. Today, whenever we think about any application, we always have a visual image of how the application will run. Swing will provide us with a lot of tools to make our application look more professional and user friendly.

Database **SWING**  Conclusion


 * Chapters **