Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Swing Chapter 17. (Advanced topics) Trees. Easy for reading, Click here!

Custom Search
Swing Chapter 17. (Advanced topics) Trees. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 3/7 



Previous Page Previous Page (2/7) - Next Page (4/7) Next Page
Subpages: 1. JTree 
2.
Basic JTree example 
3.
Directories tree: part I - Dynamic node retrieval 
4. Directories tree: part II - Popup menus and programmatic navigation 
5. Directories tree: part III - Tooltips 
6. JTree and XML documents 
7. Custom editors and renderers 

17.3  Directories tree: part I - dynamic node retrieval

The example in this section uses the JTree component to display and navigate through a tree of directories located on drives accessible from the user's machine. We will show how to build a custom tree cell renderer as well as create and insert tree nodes dynamically.

The main problem encountered in building this application is the fact that it is not practical to read all directories for all accessible drives before displaying our tree component. This would take an extremely long time. To deal with this issue we initially display only the roots (i.e. disk partitions or network drives), and then dynamically expand the tree as the user navigates through it. This requires the use of threads and SwingUtilities.invokeLater() for thread-safe updating of our tree.

Figure 17.3 Dynamic, threaded directories tree with custom cell renderer and angled line style.

<<file figure17-3.gif>>

The Code: FileTree1.java

see \Chapter17\2

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

import javax.swing.*;

import javax.swing.tree.*;

import javax.swing.event.*;

public class FileTree1 extends JFrame

{

  public static final ImageIcon ICON_COMPUTER =

    new ImageIcon("computer.gif");

  public static final ImageIcon ICON_DISK =

    new ImageIcon("disk.gif");

  public static final ImageIcon ICON_FOLDER =

    new ImageIcon("folder.gif");

  public static final ImageIcon ICON_EXPANDEDFOLDER =

    new ImageIcon("expandedfolder.gif");

  protected JTree  m_tree;

  protected DefaultTreeModel m_model;

  protected JTextField m_display;

  public FileTree1() {

    super("Directories Tree");

    setSize(400, 300);

    DefaultMutableTreeNode top = new DefaultMutableTreeNode(

      new IconData(ICON_COMPUTER, null, "Computer"));

    DefaultMutableTreeNode node;

      File[] roots = File.listRoots();

    for (int k=0; k<roots.length; k++) {

      node = new DefaultMutableTreeNode(

        new IconData(ICON_DISK,

        null, new FileNode(roots[k])));

      top.add(node);

      node.add( new DefaultMutableTreeNode(

      new Boolean(true)));

    }

    m_model = new DefaultTreeModel(top);

    m_tree = new JTree(m_model);

    m_tree.getSelectionModel().setSelectionMode(

      TreeSelectionModel.SINGLE_TREE_SELECTION);

    m_tree.putClientProperty("JTree.lineStyle", "Angled");

    TreeCellRenderer renderer = new IconCellRenderer();

    m_tree.setCellRenderer(renderer);

    m_tree.addTreeExpansionListener(new DirExpansionListener());

    m_tree.addTreeSelectionListener(new DirSelectionListener());

    m_tree.setShowsRootHandles(true);

    m_tree.setEditable(false);

    JScrollPane s = new JScrollPane();

    s.getViewport().add(m_tree);

    getContentPane().add(s, BorderLayout.CENTER);

    m_display = new JTextField();

    m_display.setEditable(false);

    getContentPane().add(m_display, BorderLayout.NORTH);

    WindowListener wndCloser = new WindowAdapter() {

      public void windowClosing(WindowEvent e) {

        System.exit(0);

      }

    };

    addWindowListener(wndCloser);

    setVisible(true);

  }

  DefaultMutableTreeNode getTreeNode(TreePath path) {

    return (DefaultMutableTreeNode) (path.getLastPathComponent());

  }

  FileNode getFileNode(DefaultMutableTreeNode node) {

    if (node == null)

      return null;

    Object obj = node.getUserObject();

    if (obj instanceof IconData)

      obj = ((IconData)obj).getObject();

    if (obj instanceof FileNode)

      return (FileNode)obj;

    else

      return null;

  }

  // Make sure expansion is threaded and updating the tree model

  // only occurs within the event dispatching thread.

  class DirExpansionListener implements TreeExpansionListener

  {

    public void treeExpanded(TreeExpansionEvent event) {

      final DefaultMutableTreeNode node = getTreeNode(

        event.getPath());

      final FileNode fnode = getFileNode(node);

      Thread runner = new Thread() {

        public void run() {

          if (fnode != null && fnode.expand(node)) {

            Runnable runnable = new Runnable() {

              public void run() {

                m_model.reload(node);

              }

            };

            SwingUtilities.invokeLater(runnable);

          }

        }

      };

      runner.start();

    }

    public void treeCollapsed(TreeExpansionEvent event) {}

  }

  class DirSelectionListener implements TreeSelectionListener

  {

    public void valueChanged(TreeSelectionEvent event) {

      DefaultMutableTreeNode node = getTreeNode(event.getPath());

        FileNode fnode = getFileNode(node);

        if (fnode != null)

          m_display.setText(fnode.getFile().getAbsolutePath());

        else

          m_display.setText("");

    }

  }

  public static void main(String argv[]) { new FileTree1(); }

}

class IconCellRenderer extends JLabel implements TreeCellRenderer

{

  protected Color m_textSelectionColor;

  protected Color m_textNonSelectionColor;

  protected Color m_bkSelectionColor;

  protected Color m_bkNonSelectionColor;

  protected Color m_borderSelectionColor;

  protected boolean m_selected;

  public IconCellRenderer() {

    super();

    m_textSelectionColor = UIManager.getColor(

      "Tree.selectionForeground");

    m_textNonSelectionColor = UIManager.getColor(

      "Tree.textForeground");

    m_bkSelectionColor = UIManager.getColor(

      "Tree.selectionBackground");

    m_bkNonSelectionColor = UIManager.getColor(

      "Tree.textBackground");

    m_borderSelectionColor = UIManager.getColor(

      "Tree.selectionBorderColor");

    setOpaque(false);

  }

  public Component getTreeCellRendererComponent(JTree tree,

   Object value, boolean sel, boolean expanded, boolean leaf,

   int row, boolean hasFocus)        

  {

    DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;

    Object obj = node.getUserObject();

    setText(obj.toString());

    if (obj instanceof Boolean)

      setText("Retrieving data...");

    if (obj instanceof IconData) {

      IconData idata = (IconData)obj;

      if (expanded)

        setIcon(idata.getExpandedIcon());

      else

        setIcon(idata.getIcon());

    }

    else

      setIcon(null);

    setFont(tree.getFont());

    setForeground(sel ? m_textSelectionColor :

      m_textNonSelectionColor);

    setBackground(sel ? m_bkSelectionColor :

      m_bkNonSelectionColor);

    m_selected = sel;

    return this;

  }

  public void paintComponent(Graphics g) {

    Color bColor = getBackground();

    Icon icon = getIcon();

    g.setColor(bColor);

    int offset = 0;

    if(icon != null && getText() != null)

      offset = (icon.getIconWidth() + getIconTextGap());

    g.fillRect(offset, 0, getWidth() - 1 - offset,

      getHeight() - 1);

    if (m_selected) {

      g.setColor(m_borderSelectionColor);

      g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);

    }

    super.paintComponent(g);

  }

}

class IconData

{

  protected Icon   m_icon;

  protected Icon   m_expandedIcon;

  protected Object m_data;

  public IconData(Icon icon, Object data) {

    m_icon = icon;

    m_expandedIcon = null;

    m_data = data;

  }

  public IconData(Icon icon, Icon expandedIcon, Object data) {

    m_icon = icon;

    m_expandedIcon = expandedIcon;

    m_data = data;

  }

  public Icon getIcon() { return m_icon; }

  public Icon getExpandedIcon() {

    return m_expandedIcon!=null ? m_expandedIcon : m_icon;

  }

  public Object getObject() { return m_data; }

  public String toString() { return m_data.toString(); }

}

class FileNode

{

  protected File m_file;

  public FileNode(File file) { m_file = file; }

  public File getFile() { return m_file; }

  public String toString() {

    return m_file.getName().length() > 0 ? m_file.getName() :

      m_file.getPath();

  }

  public boolean expand(DefaultMutableTreeNode parent) {

    DefaultMutableTreeNode flag =

      (DefaultMutableTreeNode)parent.getFirstChild();

    if (flag==null)      // No flag

      return false;

    Object obj = flag.getUserObject();

    if (!(obj instanceof Boolean))

      return false;      // Already expanded

    parent.removeAllChildren();  // Remove Flag

    File[] files = listFiles();

    if (files == null)

      return true;

    Vector v = new Vector();

    for (int k=0; k<files.length; k++) {

      File f = files[k];

      if (!(f.isDirectory()))

        continue;

      FileNode newNode = new FileNode(f);

      boolean isAdded = false;

      for (int i=0; i<v.size(); i++) {

        FileNode nd = (FileNode)v.elementAt(i);

        if (newNode.compareTo(nd) < 0) {

          v.insertElementAt(newNode, i);

          isAdded = true;

          break;

        }

      }

      if (!isAdded)

      v.addElement(newNode);

    }

    for (int i=0; i<v.size(); i++) {

      FileNode nd = (FileNode)v.elementAt(i);

      IconData idata = new IconData(FileTree1.ICON_FOLDER,

        FileTree1.ICON_EXPANDEDFOLDER, nd);

      DefaultMutableTreeNode node =

        new DefaultMutableTreeNode(idata);

      parent.add(node);

      if (nd.hasSubDirs())

        node.add(new DefaultMutableTreeNode(

          new Boolean(true) ));

    }

    return true;

  }

  public boolean hasSubDirs() {

    File[] files = listFiles();

    if (files == null)

      return false;

    for (int k=0; k<files.length; k++) {

      if (files[k].isDirectory())

        return true;

    }

    return false;

  }

  public int compareTo(FileNode toCompare) {

    return  m_file.getName().compareToIgnoreCase(

      toCompare.m_file.getName() );

  }

  protected File[] listFiles() {

    if (!m_file.isDirectory())

      return null;

    try {

      return m_file.listFiles();

    }

    catch (Exception ex) {

      JOptionPane.showMessageDialog(null,

        "Error reading directory "+m_file.getAbsolutePath(),

        "Warning", JOptionPane.WARNING_MESSAGE);

          return null;

    }

  }

}

Understanding the Code

Class FileTree1

Four custom icons are loaded as static ImageIcon variables: ICON_COMPUTER, ICON_DISK, ICON_FOLDER, and ICON_EXPANDEDFOLDER, and three instance variables are declared:

JTree m_tree: tree component to display directory nodes.

DefaultTreeModel m_model: tree model to manage nodes.

JTextField m_display: component to display selected directory (acts as a status bar).

The FileTree1 constructor creates and initializes all GUI components. A root node "Computer" hosts child nodes for all disk partitions and network drives in the system. These nodes encapsulate Files retrieved with the static File.listRoots() method (a valuable addition to the File class in Java 2). Note that IconData objects (see below) encapsulate Files in the tree. Also note that each newly created child node immediately receives a child node containing a Boolean user object. This Boolean object allows us to display an expanding message for nodes when they are in the process of being expanded. Exactly how we expand them will be explained soon enough.

We then create a DefaultTreeModel and pass our "Computer" node as the root. This model is used to instantiate our JTree object:

    m_model = new DefaultTreeModel(top);

    m_tree = new JTree(m_model);

We then set the lineStyle client property so that angled lines will represent the edges between parent and child nodes:

    m_tree.putClientProperty("JTree.lineStyle", "Angled");

We also use a custom tree cell renderer, as well as a tree exapansion listener and a tree selection listener, (each of which in detail below): IconCellRenderer, DirExpansionListener, and DirSelectionListener respectively.

The actual contents of our tree nodes represent directories. Each node is a DefaultMutableTreeNode with an IconData user object. Each user object is an instance of IconData, and each IconData contains an instance of FileNode. Each FileNode contain a java.io.File object. Thus we have a four layered nested structure:

DefaultMutableTreeNode is used for each node to represent a directory or disk (as well as the "Computer" root node). When we retrieve a node at the end of a given TreePath, using the getLastPathComponent() method, we are provided with an instance of this class.

IconData (see below) sits inside DefaultMutableTreeNode and provides custom icons for our tree cell renderer, and encapsulation of a FileNode object. IconData can be retrieved using DefaultMutableTreeNode's getUserObject() method. Note that we need to cast the returned Object to an IconData instance.

FileNode (see below) sits inside IconData and encapsulates a File objects. A FileNode can be retrieved using IconData's getObject() method, also requireing a subsequent cast.

A File object sits inside a FileNode and can be retrieved using FileNode's getFile() method.

Figure 17.2 illustrates this structure.

Figure 17.2 Nested structure of our tree nodes.

<<file figure17-2.gif>>

To keep things simple, two helper methods are provided to work with these encapsulated nodes: getTreeNode() retrieves a DefaultMutableTreeNode from a given TreePath, and getFileNode() retrieves the FileNode (or null) from a DefaultMutableTreeNode. We will see where these methods are needed soon enough.

Class FileTree1.DirExpansionListener

This inner class implements TreeExpansionListener to listen for tree expansion events. When a node is expanded, method treeExpanded() retrieves the FileNode instance for that node, and, if it's not null, calls the expand() method on it (see below). This is wrapped in a separate thread because it can often be a very time consuming process and we do not want the application to freeze. Inside this thread, once expand() has completed, we need to update the tree model with any new nodes retrieved. As we learned in chapter 2, updating the state of a component should only occur within the event dispatching thread. For this reason we wrap the call to reload() in a Runnable and send it the event dispatching queue using SwingUtilities.invokeLater():

    Runnable runnable = new Runnable() {

      public void run() {

        m_model.reload(node);

      }

    };

    SwingUtilities.invokeLater(runnable);

As we will see below in our discussion of IconCellRenderer, by placing a Boolean user object in a dummy child node of each non-expanded node, we allow a certain String to be displayed while a node is in the process of being expanded. In our case, "Retreiving data..." is shown below a node until finished expanding.

Class FileTree1.DirSelectionListener

This inner class implements TreeSelectionListener to listen for tree selection events. When a node is selected, the valueChanged() method extracts the FileNode instance contained in that node, and, if it is not null, displays the absolute path to that directory in the m_display text field.

Class IconCellRenderer

This class implements the TreeCellRenderer interface and extends JLabel. The purpose of this renderer is to display custom icons and access FileNodes contained in IconData instances.

First we declare five Colors and retrieve them from the current look-and-feel in use through UIManager's getColor() method. The getTreeCellRendererComponent() method is then implemented to set the proper text and icon (retrieved from the underlying IconData object). If the user object happens to be a Boolean, this signifies that a node is in the process of being expanded:

        if (obj instanceof Boolean)

          setText("Retrieving data...");

The reason we do this is slightly confusing. In the FileNode expand() method (see below), when each new node is added to our tree it receives a node containing a Boolean user object only if the corresponding directory has sub-directories. When we click on this node, the Boolean child will be immediately shown, and we also generate an expansion event that is received by our DirExpansionListener. As we discussed above, this listener extracts the encapsulated FileNode and calls the FileNode expand() method on it. The child node containing the Boolean object is removed before all new nodes are added. Until this update occurs, the JTree will display the Boolean child node, in effect telling us that the expansion is not complete yet. So, if our cell renderer detects a Boolean user object, we simply display "Recieving data..." for its text.

The paintComponent() method is overridden to fill the text background with the appropriate color set in the getTreeCellRendererComponent() method. Fortunately we don't need to explicitly draw the text and icon because we have extended JLabel, which can do this for us.

Class IconData

Instances of this class are used as our DefaultMutableTreeNode user data objects, and they encapsulate a generic Object m_data and two Icons for use by IconCellRenderer. These icons can be retrieved with our getIcon() and getExpandedIcon() methods. The icon retrieved with getExpandedIcon() represents an expanded folder, and the icon retrieved with getIcon() represents a collapsed/non-expanded folder. Note that the toString() method invokes toString() on the m_data object. In our example this object is either a FileNode, in the case of an expanded folder, or a Boolean, in the case of a non-expanded folder.

Class FileNode

This class encapsulates a File object, which is in turn encapsulated in an IconData object in a DefaultMutableTreeNode.

As we discussed above, the toString() method determines the text to be displayed in each tree cell containing a FileNode. It returns File.getName() for regular directories and File.getPath() for partitions.

The most interesting and complex method of this class is expand(), which attempts to expand a node by dynamically inserting new DefaultMutableTreeNode's corresponding to each sub-directory. This method returns true if nodes are added, and false otherwise. First we need to discuss the mechanism of dynamically reading information (of any kind) into a tree:

Before we add any new node to the tree, we must determine somehow whether or not it has children (we don't need a list of children yet, just a yes or no answer).

If a newly created node has children, a fake child to be used as a flag will be added to it. This will signify that the parent node has not been expanded.

When a node is expanded, its list of children is examined. Three situations are possible:

No children. This node is a leaf and cannot be expanded (remember, we've checked previously whether or not any newly created node has children).

One flag child is present. That node has children which have not been added yet. So we create these children (depending on the nature of the tree) and add new nodes to the parent node.

One or more non-flag children are present. This node has already been processed, so expand it as usual.

Method FileNode.expand() implements this dynamic tree expansion strategy, and takes a parent node as parameter. In the process of expansion it also alphabetically sorts each node for a more organized display structure. Initially this method checks the first child of the given parent node:

    DefaultMutableTreeNode flag =

      (DefaultMutableTreeNode)parent.getFirstChild();

    if (flag==null)      // No flag

      return false;

    Object obj = flag.getUserObject();

    if (!(obj instanceof Boolean))

      return false;    // Already expanded

    parent.removeAllChildren();  // Remove Flag

If no child is found, it can only mean that this node was already checked and was found to be a true leaf (a directory with no sub-directories). If this isn't the case then we extract the associated data object and check whether it is an instance of Boolean, i.e. it is a flag child. If yes, the flag child is removed and our method proceeds to add nodes corresponding to each sub-directory. Otherwise we conclude that this node has already been processed and return, allowing it to be expanded as usual.

We process a newly expanded node by retrieving an array of File objects representing files contained in the corresponding directory:

    File[] files = listFiles();

    if (files == null)

      return true;

If the contents have been successfully read, we check for sub-directories and create new FileNodes for each:

    Vector v = new Vector();

    for (int k=0; k<files.length; k++) {

      File f = files[k];

      if (!(f.isDirectory()))

        continue;

      FileNode newNode = new FileNode(f);

To perform alphabetical sorting of child nodes we store them in a temporary collection Vector v, and iterate through our array of Files, inserting them accordingly

      boolean isAdded = false;

      for (int i=0; i<v.size(); i++) {

        FileNode nd = (FileNode)v.elementAt(i);

        if (newNode.compareTo(nd) < 0) {

          v.insertElementAt(newNode, i);

          isAdded = true;

           break;

        }

      }

      if (!isAdded)

      v.addElement(newNode);

    }

We then wrap each newly created FileNode object in an IconData to bind them with folder icons, and add the sorted nodes to the given parent node. At the same time, flags are added to new nodes if they contain any sub-directories themselves (this is checked by the hasSubDirs() method):

    for (int i=0; i<v.size(); i++) {

      FileNode nd = (FileNode)v.elementAt(i);

      IconData idata = new IconData(FileTree1.ICON_FOLDER,

      FileTree1.ICON_EXPANDEDFOLDER, nd);

      DefaultMutableTreeNode node = new

        DefaultMutableTreeNode(idata);

      parent.add(node);

      if (nd.hasSubDirs())

        node.add(new DefaultMutableTreeNode(

          new Boolean(true) ));

    }

    return true;

The rest of FileNode class implements three methods which do not require much explanation at this point:

boolean hasSubDirs() returns true if this directory has sub-directories and false otherwise.

int compareTo(FileNode toCompare) returns the result of the alphabetical comparison of this directory with another given as parameter.

File[] listFiles() reads a list of contained flies in this directory. If an exception occurs (possible while reading from a floppy disk or network drive) this method displays a warning message and returns null.

Running the Code

Figure 17.3 shows our directory tree at work. Note the use of custom icons for partition roots. Try selecting various directories and note how the selected path is reflected at the top of the frame in our status bar. Also note that when expanding large directories "Retrieving data.." will be displayed underneath the corresponding node. Because we have properly implemented multithreading, we can go off and expand other directories while this one is being processed. Also not that the tree is always updated correctly when the expanding procedure completes because we have made sure to only change its state in the event dispatching thread using invokeLater().

UI Guideline : When to use connecting lines

Angled connecting lines (or edges ) add visual noise and clutter to a tree display. Reduced visual clutter aiding recognition and comprehension is a clear advantage to leaving them out of the design. So when is it appropriate to have them included?

Include the line edges when it is likely that:

(a) several nodes may be expanded at one time and/or

(b) the data set is very large and a node may expand off the bottom of the screen and perhaps several screens deep. In this case the introduction of the lines, helps to give the viewer a clear picture of how many layers deep in the hierarchy they are viewing and makes it easier to trace back to the original root node.



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy