MORE COMPLEX SWING
Swing provides you with a huge selection of components that you can use in your GUI, each with a very wide range of properties and methods available. The JComponent abstract class is subclassed (directly or indirectly) to ..
JButton JMenuItem JCheckBoxMenuItem JMenu JRadioButtonMenuItem JToggleButton JCheckBox JRadioButton JColorChooser JComboBox JFileChooser JInternalFrame JLabel JLayeredPane JDesktopPane JToolTip JMenuBar JOptionPane JPanel JPopupMenu JProgressBar JRootPane JScrollBar JScrollPane JSeparator JSlider JSplitPane JTabbedPane JTable JToolBar JList JTree JViewport
We'll choose just two of these for a further look in this module; you'll very much "get the idea" from these components, and then be able to make good use of the others from documentation and books available elsewhere (have a look at our library - we have complete books on Swing).
THE JTREE COMPONENT
JTrees are used to display hierarchical trees and to navigate around them; you could use them for a directory structure, to navigate a set of object inheritances, or (at just two levels) to navigate around school classes, and the students who are in each class.
This is Java, so using a JTree is all about using Objects of different types. The Author has found that most textbooks give sophisticated examples that seem better suited to showing how clever the programmer who wrote them was than to helping the newcomer; we'll take a different approach here.
Let's start by looking at the structure - here's a piece of code that sets up the simplest possible JTree:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDemoSetup extends JPanel {
public static void main (String [] args) {
JFrame frame = new JFrame("First JTree");
Container cp = frame.getContentPane();
frame.setSize(180,90);
frame.setVisible(true);
DefaultMutableTreeNode Node = new DefaultMutableTreeNode("Top Level");
DefaultTreeModel Behind = new DefaultTreeModel(Node);
JTree simple = new JTree(Behind);
cp.add(simple);
}
}
and here is the result of running it:
As we would expect, we've created an empty tree, and when we display it, it contains nothing. But at least we have the initial structure in place.
What are the elements?
We create NODES that are going to be placed into a TREE, which is then placed into a JTREE Swing component. You can create your own classes for nodes and trees, or (as we've done here) that extend abstract classes (or implement interfaces) .... or, as we've done here, use the default ones that are provided by Swing.
Let's add some Nodes to our tree:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDemo2 extends JPanel {
public static void main (String [] args) {
String [][] DataSample = { {"numbers","one","two","three"},
{"fruit","apple","orange","banana","cherry","tomato"},
{"desserts","pie","pudding"} };
JFrame frame = new JFrame("First JTree");
Container cp = frame.getContentPane();
DefaultMutableTreeNode Node = new DefaultMutableTreeNode("Top Level");
DefaultTreeModel Behind = new DefaultTreeModel(Node);
for (int i=0; i<DataSample.length; i++) {
DefaultMutableTreeNode Kid = new DefaultMutableTreeNode(DataSample[0]);
Behind.insertNodeInto(Kid,Node,i);
for (int j=1; j<DataSample.length; j++) {
DefaultMutableTreeNode GKid = new DefaultMutableTreeNode(DataSample[j]);
Behind.insertNodeInto(GKid,Kid,j-1);
}
}
JTree simple = new JTree(Behind);
cp.add(simple);
frame.setSize(180,290);
frame.setVisible(true);
}
}
You'll note that the default classes are doing a lot of work for you here; if you add Children to a node, then the Icon changes from a "file" Icon to a directory Icon, and the opening and closing of the "directories" is all taken care of for you too.
Further methods are available to allow you to change the icons in use, to select whether or not multiple branches can be open at the same time, and so forth.
By default, the text displayed alongside each Object is the result of running the "toString" method on that Object, so that information can be changed as the application is run and the JTree is refreshed. If you write a TreeCellRenderer, you can change this default behaviour.
Since the JTree can shrink and grow in height, it's likely that you'll want to include it in a JScrollPane component so that you don't start loosing vital branches and leaves off the bottom of your window.
And you'll also want to be adding event handling so that you can make use of your JTree for making selections.
To finish off this introduction to the JTree, here's an example that selects all the image files (.gif and .jpgs) in subdirectories of a directory named on the command line, and offers them in a tree. To keep the code simpler, all our application does with the selections is display them in a Text area, but this application could be extended to give you details of each of the images you select, a "thumbnail", and much more.
How does it run? ...
import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
// Complete example of JTree to explore images held in subdirectories
// of a given base directory
public class ImageExplorer extends JPanel {
static Vector Selected;
static TextArea Display;
public static void main (String [] args) {
Selected = new Vector();
JFrame frame = new JFrame("Image Explorer");
Container cp = frame.getContentPane();
cp.setLayout(new GridLayout(1,2));
DefaultMutableTreeNode Node = new DefaultMutableTreeNode(args[0]);
DefaultTreeModel Behind = new DefaultTreeModel(Node);
String [] Directories = (new File(args[0])).list();
int level1 = 0;
for (int i=0; i<Directories.length; i++) {
File CurrentDir = new File(args[0] + "/" + Directories);
if (CurrentDir.isDirectory()) {
DefaultMutableTreeNode Kid = new DefaultMutableTreeNode(Directories);
Behind.insertNodeInto(Kid,Node,level1++);
int level2 = 0;
String [] Contents = (CurrentDir.list());
for (int j=0; j<Contents.length; j++) {
if (Contents[j].endsWith("jpg") || Contents[j].endsWith("gif")) {
String CurrentObj = CurrentDir + "/" +Contents[j];
DefaultMutableTreeNode GKid = new DefaultMutableTreeNode(CurrentObj);
Behind.insertNodeInto(GKid,Kid,level2++);
}
}
}
}
JTree simple = new JTree(Behind);
simple.setFont(new Font("TimesRoman", Font.PLAIN, 10));
JScrollPane Scroll = new JScrollPane();
(Scroll.getViewport()).add(simple);
TreeSelectionListener tsl = new TreeSelectionListener() {
// Inner class - tree selection listener
public void valueChanged(TreeSelectionEvent evt) {
TreePath Follow = evt.getPath();
Selected.add(Follow);
String thistime = Follow.getLastPathComponent().toString();
Display.append(thistime+"\n");
}
// End of inner class definition
};
simple.addTreeSelectionListener(tsl);
Display = new TextArea("Where have you been?\n\n");
cp.add(Scroll);
cp.add(Display);
frame.setSize(600,300);
frame.setVisible(true);
}
}
THE JTABLE COMPONENT
We'll finish this introduction to Swing with a little on the JTable Component. The JTable Swing Component is used for displaying and editing Tabular Data.
Here's a table:
and the code that generated it:
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class TableDemo extends JPanel {
public static void main (String [] args) {
String [][] DataSample = { {"one","two","three","four"},
{"apple","orange","banana","cherry"},
{"potato","carrot","pea","brocolli"},
{"dessert","pie","pudding","sweet"} };
String [] tops = {"001","002","003","004"};
JFrame frame = new JFrame("First JTree");
Container cp = frame.getContentPane();
Vector overall = new Vector();
Vector titles = new Vector();
for (int i=0; i<DataSample.length; i++) {
Vector row = new Vector();
for (int j=0; j<DataSample.length; j++) {
row.add(DataSample[j]);
}
overall.add(row);
titles.add(tops);
}
JTable SampleTable = new JTable(overall,titles);
SampleTable.setFont(new Font("TimesRoman", Font.PLAIN, 18));
cp.add(SampleTable);
frame.setSize(380,200);
frame.setVisible(true);
}
}
In our first example, we've used a Vector of Vectors, since there's a convenience constructor that takes that as its parameter; that's just one of 8 constructors that are available. Just as there were TreeModel Objects used in JTrees, so you'll use TableModel objects in JTables, and you'll very often place your table in a JScrollPane. This should all start to look hideously familiar ...
See also
Swing classes