Creating TreeTables in Swing


From:http://www.comp.nus.edu.sg/~cs3283/ftp/Java/swingConnect/tech_topics/tables_trees_2/tables_trees_2.html


Creating TreeTables: Part 2
Completing the Example Program


This article builds on the JTreeTable example that was introduced in "Creating TreeTables in Swing,"  the previous article in this section. Before reading this article, please read the previous one.


By Scott Violet and Kathy Walrath

tree_table_thumb_wideFor the sake of simplicity, the example program presented in "Creating TreeTables in Swing" was a bare-bones program with a few shortcomings. This article presents an expanded and enhanced example program, renamed TreeTable II,  that fixes the shortcomings of the original example and adds a few new features of its own.

In the Source Code section of this article, you´ll get a chance to view the rest of the program´s code. You´ll also get an opportunity to download a zipped version of the complete program and its resources.

This article has three major sections:

What´s New in TreeTable II

In last month´s issue of The Swing Connection, the "Creating TreeTables in Swing" article showed how to create a combination of a Tree and a Table -- a component capable of both expanding and contracting rows, as well as showing multiple columns of data. The article concluded with a example application, named TreeTableExample0, which displayed a working TreeTable browser that you can use to browse a local file system

As you can see by examining the JTreeTable.java file, this article´s version of the JTreeTable class is much improved over the version of the same class presented in "Creating TreeTables in Swing." Before, colors and row heights weren't consistent between the tree and the table. Also, keyboard navigation was awkward. Two other shortcomings, which weren't noticeable due to the previous example's simplicity, were that the tree's selection model didn't track changes properly and the GUI wouldn't be updated if the tree data changed.

We substantially changed the behavior of the example to show off the capabilities of new, improved JTreeTable. TreeTable II behaves rather like the UNIX command du, or the NEXTSTEP example DarkForest. The basic functionality changes are that the size of a directory is now the total size of all its children, and you can update the size data and inspect multiple directory hierarchies. We also added the ability to change the look and feel while TreeTable II is running.

Another difference from the previous source code is that we now use the new Swing package structure (javax.swing, rather thancom.sun.java.swing). You can run the example with either JDK 1.2 (RC1 or a compatible release) or with JDK 1.1 + JFC 1.1 (Swing 1.1 Beta 3 or a compatible version).

Here are the fixes we added to overcome shortcomings of the previous example:

Here are the features we added to implement new functionality:



Coordinating colors and row height

To coordinate colors and row height, we overrode two methods (updateUI and setRowHeight) in both the JTree subclass (JTreeTable.TreeTableCellRenderer) and the JTable subclass (JTreeTable). The code in the updateUI methods makes the table use the tree's default foreground and background colors, and the tree use the table's selection colors. The setRowHeight methods ensure that when the row height of the tree or table is changed, the row height of the other object (table or tree) is changed to be exactly the same.



Improving keyboard navigation

In the previous version, the tree could get the keyboard focus. Once it did, the tree handled all key events. This gave an odd feeling in that you could not tab out of the tree to select other cells in the table, nor use the left/right arrow keys as you normally could in a table.

In the new version, the TableCellEditor's isCellEditable method always returns false, so the tree never gets the focus. If the argument to isCellEditable is a MouseEvent, then isCellEditable forwards the mouse event to the tree. This lets the tree handle the mouse event as it normally would, without ever having focus. This change fixes the focus problem, and as a side effect enables autoscrolling to the new selection.



Updating the table in response to tree events

As the previous article explained, TreeTableModelAdapter is used to share the TreeTableModel (the table's data model) between the JTree and JTable. The previous version of TreeTableModelAdapter did not implement TreeModelListener, which meant that changes in the TreeTableModel would not be propagated to the UI. This didn't matter in the previous example, since the tree's contents didn't change after the tree was visible.

The current version of TreeTableModelAdapter registers a TreeModelListener on the TreeTableModel. The listener's methods fire TableModelEvents so that the UI will update when the tree is updated. This enables TreeTable II's Reload feature.



Making the tree track the visible selection

In the previous version, the JTable referenced the ListSelectionModel from the DefaultTreeSelectionModel. As DefaultTreeSelectionModel does not listen for changes in its ListSelectionModel, this could result in an inconsistent state. The ListSelectionModel would have one thing selected and the TreeSelectionModel would reference another set of paths as being selected.

This version defines a new subclass of DefaultTreeSelectionModel, called JTreeTable.ListToTreeSelectionModelWrapper, that listens for changes in its ListSelectionModel. When the ListSelectionModel changes, JTreeTable.ListToTreeSelectionModelWrapper updates its paths so that the two models remain in sync. This didn't matter in the previous example, since no code queried the tree for its selection state. Implementing this feature enables detecting the selected tree paths, which is necessary for commands such as Reload that work on the current selection.



Reloading data

By selecting a directory and then choosing the File > Reload menu item, you cause that directory to be rechecked.

Links, by default, aren't initially descended. To load the contents of a link, select the link and then choose the Reload menu item.



Inspecting a new root directory

With the File > Open command, you bring up a file chooser from which you can choose a directory. A new frame appears that shows a tree-table that has the specified directory as its root.



Dynamically changing the look and feel

By choosing any of the menu items in the Options menu, you can dynamically change the look and feel. You have the choice of three look-and-feel options: Metal (the Java Look and Feel), CDE/Motif Look and Feel, and Windows Look and Feel (which works only on computers that normally use the corresonding look and feel).

Note that if you're using Swing with JDK 1.1, you must be sure that the appropriate look-and-feel archive files are in the class path. For example, if you might use the CDE/Motif Look and Feel, then the class path must include motif.jar. For the Windows Look and Feel, the class path must include windows.jar. The Java Look and Feel (Metal) is already included in swing.jar.



Dynamically sorting rows

When all the children of the topmost directory have been loaded, they are sorted again by total size. This sorting generates aTreeStructureChange event, which has the effect of causing any expanded children of the topmost directory to collapse.



Using a background thread

To avoid freezing the UI, calculating the total size is done in a background thread. Because Swing is not thread safe, data-ready notifications (accomplished by firing TreeModelEvents) can't be done in the background thread. Instead, TreeTable II uses theSwingUtilities.invokeLater() method to make the event-firing code be executed in the event dispatch thread.

A new background thread is used for each data-loading cycle. First, all of the children of the tree's root are loaded and made available. Then a new thread is spawned that recursively loads the descendants of each child of the tree's root directory. Each time all the descendants of one of the tree root's children have been loaded, a TreeModelEvent is generated.



Source Code

The list of files for TreeTable II is almost the same as for the old example. The differences are that FileSystemModel.java has been renamed to FileSystemModel2.java to reflect its drastically different implementation, and TreeTableExample0.java has been renamed toTreeTableExample2.java. Here are the source files for the new example:

src.zip

  • Contains all of the TreeTable II source files.

AbstractCellEditor.java

  • No significant changes. A subclass of CellEditorapi that handles the list of listeners, providing a base class for cell editors.

AbstractTreeTableModel.java

  • No significant changes. Provides a base class for TreeTableModels; handles the list of listeners.

FileSystemModel2.java

  • Now implements sorting, getting total size of directories, and background thread. FileSystemModel2 extends AbstractTreeTableModel.

JTreeTable.java

  • Changed to improve selection coordination between tree and table, use a better row height, use better colors, support switching the look and feel, and improve navigability. Includes these classes: 

    • JTreeTable (extends JTableapi) 
       
    • JTreeTable.TreeTableCellRenderer (extends JTreeapi
       
    • JTreeTable.TreeTableCellEditor (extends AbstractCellEditor implements TableCellEditorapi
       
    • JTreeTable.ListToTreeSelectionModelWrapper (extends DefaultTreeSelectionModelapi)

MergeSort.java

No significant changes. Implements a sorting algorithm.

TreeTableExample2.java

Modified as necessary to create the new GUI and hook everything together. Contains the main method that creates and runs the TreeTable II example.

TreeTableModel.java

No significant changes. A TreeModelapi subinterface that describes the kind of data that can be drawn by a TreeTable.

TreeTableModelAdapter.java

Now installs a TreeModelListenerapi to fire events to the table after the tree has been updated. TreeTableModelAdapter implements the TableModelapi interface, given both a TreeTableModel and a JTree.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值