<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FSwing_Components%2FTreeTable</id>
		<title>Java/Swing Components/TreeTable - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FSwing_Components%2FTreeTable"/>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Swing_Components/TreeTable&amp;action=history"/>
		<updated>2026-04-19T03:15:00Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Swing_Components/TreeTable&amp;diff=8221&amp;oldid=prev</id>
		<title>Admin: 1 версия</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Swing_Components/TreeTable&amp;diff=8221&amp;oldid=prev"/>
				<updated>2010-06-01T06:56:39Z</updated>
		
		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Версия 06:56, 1 июня 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Swing_Components/TreeTable&amp;diff=8220&amp;oldid=prev</id>
		<title> в 18:01, 31 мая 2010</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Swing_Components/TreeTable&amp;diff=8220&amp;oldid=prev"/>
				<updated>2010-05-31T18:01:46Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== JTreeTable component ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
/*&lt;br /&gt;
 * The contents of this file are subject to the Sapient Public License&lt;br /&gt;
 * Version 1.0 (the &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
 * with the License. You may obtain a copy of the License at&lt;br /&gt;
 * http://carbon.sf.net/License.html.&lt;br /&gt;
 *&lt;br /&gt;
 * Software distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; basis,&lt;br /&gt;
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for&lt;br /&gt;
 * the specific language governing rights and limitations under the License.&lt;br /&gt;
 *&lt;br /&gt;
 * The Original Code is The Carbon Component Framework.&lt;br /&gt;
 *&lt;br /&gt;
 * The Initial Developer of the Original Code is Sapient Corporation&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * @(#)JTreeTable.java    1.2 98/10/27&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright 1997, 1998 by Sun Microsystems, Inc.,&lt;br /&gt;
 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.&lt;br /&gt;
 * All rights reserved.&lt;br /&gt;
 *&lt;br /&gt;
 * This software is the confidential and proprietary information&lt;br /&gt;
 * of Sun Microsystems, Inc. (&amp;quot;Confidential Information&amp;quot;).  You&lt;br /&gt;
 * shall not disclose such Confidential Information and shall use&lt;br /&gt;
 * it only in accordance with the terms of the license agreement&lt;br /&gt;
 * you entered into with Sun.&lt;br /&gt;
 */&lt;br /&gt;
import java.awt.ruponent;&lt;br /&gt;
import java.awt.Dimension;&lt;br /&gt;
import java.awt.Graphics;&lt;br /&gt;
import java.awt.event.MouseEvent;&lt;br /&gt;
import java.util.EventObject;&lt;br /&gt;
import javax.swing.AbstractCellEditor;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.JTree;&lt;br /&gt;
import javax.swing.ListSelectionModel;&lt;br /&gt;
import javax.swing.LookAndFeel;&lt;br /&gt;
import javax.swing.SwingUtilities;&lt;br /&gt;
import javax.swing.UIManager;&lt;br /&gt;
import javax.swing.event.ListSelectionEvent;&lt;br /&gt;
import javax.swing.event.ListSelectionListener;&lt;br /&gt;
import javax.swing.event.TreeExpansionEvent;&lt;br /&gt;
import javax.swing.event.TreeExpansionListener;&lt;br /&gt;
import javax.swing.event.TreeModelEvent;&lt;br /&gt;
import javax.swing.event.TreeModelListener;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
import javax.swing.table.TableCellEditor;&lt;br /&gt;
import javax.swing.table.TableCellRenderer;&lt;br /&gt;
import javax.swing.tree.DefaultTreeCellRenderer;&lt;br /&gt;
import javax.swing.tree.DefaultTreeSelectionModel;&lt;br /&gt;
import javax.swing.tree.TreeCellRenderer;&lt;br /&gt;
import javax.swing.tree.TreeModel;&lt;br /&gt;
import javax.swing.tree.TreePath;&lt;br /&gt;
/**&lt;br /&gt;
 * This example shows how to create a simple JTreeTable component,&lt;br /&gt;
 * by using a JTree as a renderer (and editor) for the cells in a&lt;br /&gt;
 * particular column in the JTable.&lt;br /&gt;
 *&lt;br /&gt;
 * @version 1.2 10/27/98&lt;br /&gt;
 *&lt;br /&gt;
 * @author Philip Milne&lt;br /&gt;
 * @author Scott Violet&lt;br /&gt;
 */&lt;br /&gt;
public class JTreeTable extends JTable {&lt;br /&gt;
    /** A subclass of JTree. */&lt;br /&gt;
    protected TreeTableCellRenderer tree;&lt;br /&gt;
    public JTreeTable(TreeTableModel treeTableModel) {&lt;br /&gt;
    super();&lt;br /&gt;
    // Create the tree. It will be used as a renderer and editor.&lt;br /&gt;
    tree = new TreeTableCellRenderer(treeTableModel);&lt;br /&gt;
    // Install a tableModel representing the visible rows in the tree.&lt;br /&gt;
    super.setModel(new TreeTableModelAdapter(treeTableModel, tree));&lt;br /&gt;
    // Force the JTable and JTree to share their row selection models.&lt;br /&gt;
    ListToTreeSelectionModelWrapper selectionWrapper = new&lt;br /&gt;
                            ListToTreeSelectionModelWrapper();&lt;br /&gt;
    tree.setSelectionModel(selectionWrapper);&lt;br /&gt;
    setSelectionModel(selectionWrapper.getListSelectionModel());&lt;br /&gt;
    // Install the tree editor renderer and editor.&lt;br /&gt;
    setDefaultRenderer(TreeTableModel.class, tree);&lt;br /&gt;
    setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());&lt;br /&gt;
    // No grid.&lt;br /&gt;
    setShowGrid(false);&lt;br /&gt;
    // No intercell spacing&lt;br /&gt;
    setIntercellSpacing(new Dimension(0, 0));&lt;br /&gt;
    // And update the height of the trees row to match that of&lt;br /&gt;
    // the table.&lt;br /&gt;
    if (tree.getRowHeight() &amp;lt; 1) {&lt;br /&gt;
        // Metal looks better like this.&lt;br /&gt;
        setRowHeight(18);&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Overridden to message super and forward the method to the tree.&lt;br /&gt;
     * Since the tree is not actually in the component hieachy it will&lt;br /&gt;
     * never receive this unless we forward it in this manner.&lt;br /&gt;
     */&lt;br /&gt;
    public void updateUI() {&lt;br /&gt;
    super.updateUI();&lt;br /&gt;
    if(tree != null) {&lt;br /&gt;
        tree.updateUI();&lt;br /&gt;
    }&lt;br /&gt;
    // Use the tree&amp;quot;s default foreground and background colors in the&lt;br /&gt;
    // table.&lt;br /&gt;
        LookAndFeel.installColorsAndFont(this, &amp;quot;Tree.background&amp;quot;,&lt;br /&gt;
                                         &amp;quot;Tree.foreground&amp;quot;, &amp;quot;Tree.font&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    /* Workaround for BasicTableUI anomaly. Make sure the UI never tries to&lt;br /&gt;
     * paint the editor. The UI currently uses different techniques to&lt;br /&gt;
     * paint the renderers and editors and overriding setBounds() below&lt;br /&gt;
     * is not the right thing to do for an editor. Returning -1 for the&lt;br /&gt;
     * editing row in this case, ensures the editor is never painted.&lt;br /&gt;
     */&lt;br /&gt;
    public int getEditingRow() {&lt;br /&gt;
        return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 :&lt;br /&gt;
            editingRow;&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Overridden to pass the new rowHeight to the tree.&lt;br /&gt;
     */&lt;br /&gt;
    public void setRowHeight(int rowHeight) {&lt;br /&gt;
        super.setRowHeight(rowHeight);&lt;br /&gt;
    if (tree != null &amp;amp;&amp;amp; tree.getRowHeight() != rowHeight) {&lt;br /&gt;
            tree.setRowHeight(getRowHeight());&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the tree that is being shared between the model.&lt;br /&gt;
     */&lt;br /&gt;
    public JTree getTree() {&lt;br /&gt;
    return tree;&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * A TreeCellRenderer that displays a JTree.&lt;br /&gt;
     */&lt;br /&gt;
    public class TreeTableCellRenderer extends JTree implements&lt;br /&gt;
             TableCellRenderer {&lt;br /&gt;
    /** Last table/tree row asked to renderer. */&lt;br /&gt;
    protected int visibleRow;&lt;br /&gt;
    public TreeTableCellRenderer(TreeModel model) {&lt;br /&gt;
        super(model);&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * updateUI is overridden to set the colors of the Tree&amp;quot;s renderer&lt;br /&gt;
     * to match that of the table.&lt;br /&gt;
     */&lt;br /&gt;
    public void updateUI() {&lt;br /&gt;
        super.updateUI();&lt;br /&gt;
        // Make the tree&amp;quot;s cell renderer use the table&amp;quot;s cell selection&lt;br /&gt;
        // colors.&lt;br /&gt;
        TreeCellRenderer tcr = getCellRenderer();&lt;br /&gt;
        if (tcr instanceof DefaultTreeCellRenderer) {&lt;br /&gt;
        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer)tcr);&lt;br /&gt;
        // For 1.1 uncomment this, 1.2 has a bug that will cause an&lt;br /&gt;
        // exception to be thrown if the border selection color is&lt;br /&gt;
        // null.&lt;br /&gt;
        // dtcr.setBorderSelectionColor(null);&lt;br /&gt;
        dtcr.setTextSelectionColor(UIManager.getColor&lt;br /&gt;
                       (&amp;quot;Table.selectionForeground&amp;quot;));&lt;br /&gt;
        dtcr.setBackgroundSelectionColor(UIManager.getColor&lt;br /&gt;
                        (&amp;quot;Table.selectionBackground&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Sets the row height of the tree, and forwards the row height to&lt;br /&gt;
     * the table.&lt;br /&gt;
     */&lt;br /&gt;
    public void setRowHeight(int rowHeight) {&lt;br /&gt;
        if (rowHeight &amp;gt; 0) {&lt;br /&gt;
        super.setRowHeight(rowHeight);&lt;br /&gt;
        if (JTreeTable.this != null &amp;amp;&amp;amp;&lt;br /&gt;
            JTreeTable.this.getRowHeight() != rowHeight) {&lt;br /&gt;
            JTreeTable.this.setRowHeight(getRowHeight());&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * This is overridden to set the height to match that of the JTable.&lt;br /&gt;
     */&lt;br /&gt;
    public void setBounds(int x, int y, int w, int h) {&lt;br /&gt;
        super.setBounds(x, 0, w, JTreeTable.this.getHeight());&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Sublcassed to translate the graphics such that the last visible&lt;br /&gt;
     * row will be drawn at 0,0.&lt;br /&gt;
     */&lt;br /&gt;
    public void paint(Graphics g) {&lt;br /&gt;
        g.translate(0, -visibleRow * getRowHeight());&lt;br /&gt;
        super.paint(g);&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * TreeCellRenderer method. Overridden to update the visible row.&lt;br /&gt;
     */&lt;br /&gt;
    public Component getTableCellRendererComponent(JTable table,&lt;br /&gt;
                               Object value,&lt;br /&gt;
                               boolean isSelected,&lt;br /&gt;
                               boolean hasFocus,&lt;br /&gt;
                               int row, int column) {&lt;br /&gt;
        if(isSelected)&lt;br /&gt;
        setBackground(table.getSelectionBackground());&lt;br /&gt;
        else&lt;br /&gt;
        setBackground(table.getBackground());&lt;br /&gt;
        visibleRow = row;&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * TreeTableCellEditor implementation. Component returned is the&lt;br /&gt;
     * JTree.&lt;br /&gt;
     */&lt;br /&gt;
     class TreeTableCellEditor extends AbstractCellEditor implements&lt;br /&gt;
             TableCellEditor {&lt;br /&gt;
    public Component getTableCellEditorComponent(JTable table,&lt;br /&gt;
                             Object value,&lt;br /&gt;
                             boolean isSelected,&lt;br /&gt;
                             int r, int c) {&lt;br /&gt;
        return tree;&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Overridden to return false, and if the event is a mouse event&lt;br /&gt;
     * it is forwarded to the tree.&amp;lt;p&amp;gt;&lt;br /&gt;
     * The behavior for this is debatable, and should really be offered&lt;br /&gt;
     * as a property. By returning false, all keyboard actions are&lt;br /&gt;
     * implemented in terms of the table. By returning true, the&lt;br /&gt;
     * tree would get a chance to do something with the keyboard&lt;br /&gt;
     * events. For the most part this is ok. But for certain keys,&lt;br /&gt;
     * such as left/right, the tree will expand/collapse where as&lt;br /&gt;
     * the table focus should really move to a different column. Page&lt;br /&gt;
     * up/down should also be implemented in terms of the table.&lt;br /&gt;
     * By returning false this also has the added benefit that clicking&lt;br /&gt;
     * outside of the bounds of the tree node, but still in the tree&lt;br /&gt;
     * column will select the row, whereas if this returned true&lt;br /&gt;
     * that wouldn&amp;quot;t be the case.&lt;br /&gt;
     * &amp;lt;p&amp;gt;By returning false we are also enforcing the policy that&lt;br /&gt;
     * the tree will never be editable (at least by a key sequence).&lt;br /&gt;
     */&lt;br /&gt;
    public boolean isCellEditable(EventObject e) {&lt;br /&gt;
        if (e instanceof MouseEvent) {&lt;br /&gt;
        for (int counter = getColumnCount() - 1; counter &amp;gt;= 0;&lt;br /&gt;
             counter--) {&lt;br /&gt;
            if (getColumnClass(counter) == TreeTableModel.class) {&lt;br /&gt;
            MouseEvent me = (MouseEvent)e;&lt;br /&gt;
            MouseEvent newME = new MouseEvent(tree, me.getID(),&lt;br /&gt;
                   me.getWhen(), me.getModifiers(),&lt;br /&gt;
                   me.getX() - getCellRect(0, counter, true).x,&lt;br /&gt;
                   me.getY(), me.getClickCount(),&lt;br /&gt;
                                   me.isPopupTrigger());&lt;br /&gt;
            tree.dispatchEvent(newME);&lt;br /&gt;
            break;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
    public Object getCellEditorValue() {&lt;br /&gt;
      // TODO Auto-generated method stub&lt;br /&gt;
      return null;&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel&lt;br /&gt;
     * to listen for changes in the ListSelectionModel it maintains. Once&lt;br /&gt;
     * a change in the ListSelectionModel happens, the paths are updated&lt;br /&gt;
     * in the DefaultTreeSelectionModel.&lt;br /&gt;
     */&lt;br /&gt;
    class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel {&lt;br /&gt;
    /** Set to true when we are updating the ListSelectionModel. */&lt;br /&gt;
    protected boolean         updatingListSelectionModel;&lt;br /&gt;
    public ListToTreeSelectionModelWrapper() {&lt;br /&gt;
        super();&lt;br /&gt;
        getListSelectionModel().addListSelectionListener&lt;br /&gt;
                                (createListSelectionListener());&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the list selection model. ListToTreeSelectionModelWrapper&lt;br /&gt;
     * listens for changes to this model and updates the selected paths&lt;br /&gt;
     * accordingly.&lt;br /&gt;
     */&lt;br /&gt;
    ListSelectionModel getListSelectionModel() {&lt;br /&gt;
        return listSelectionModel;&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * This is overridden to set &amp;lt;code&amp;gt;updatingListSelectionModel&amp;lt;/code&amp;gt;&lt;br /&gt;
     * and message super. This is the only place DefaultTreeSelectionModel&lt;br /&gt;
     * alters the ListSelectionModel.&lt;br /&gt;
     */&lt;br /&gt;
    public void resetRowSelection() {&lt;br /&gt;
        if(!updatingListSelectionModel) {&lt;br /&gt;
        updatingListSelectionModel = true;&lt;br /&gt;
        try {&lt;br /&gt;
            super.resetRowSelection();&lt;br /&gt;
        }&lt;br /&gt;
        finally {&lt;br /&gt;
            updatingListSelectionModel = false;&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
        // Notice how we don&amp;quot;t message super if&lt;br /&gt;
        // updatingListSelectionModel is true. If&lt;br /&gt;
        // updatingListSelectionModel is true, it implies the&lt;br /&gt;
        // ListSelectionModel has already been updated and the&lt;br /&gt;
        // paths are the only thing that needs to be updated.&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Creates and returns an instance of ListSelectionHandler.&lt;br /&gt;
     */&lt;br /&gt;
    protected ListSelectionListener createListSelectionListener() {&lt;br /&gt;
        return new ListSelectionHandler();&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * If &amp;lt;code&amp;gt;updatingListSelectionModel&amp;lt;/code&amp;gt; is false, this will&lt;br /&gt;
     * reset the selected paths from the selected rows in the list&lt;br /&gt;
     * selection model.&lt;br /&gt;
     */&lt;br /&gt;
    protected void updateSelectedPathsFromSelectedRows() {&lt;br /&gt;
        if(!updatingListSelectionModel) {&lt;br /&gt;
        updatingListSelectionModel = true;&lt;br /&gt;
        try {&lt;br /&gt;
            // This is way expensive, ListSelectionModel needs an&lt;br /&gt;
            // enumerator for iterating.&lt;br /&gt;
            int        min = listSelectionModel.getMinSelectionIndex();&lt;br /&gt;
            int        max = listSelectionModel.getMaxSelectionIndex();&lt;br /&gt;
            clearSelection();&lt;br /&gt;
            if(min != -1 &amp;amp;&amp;amp; max != -1) {&lt;br /&gt;
            for(int counter = min; counter &amp;lt;= max; counter++) {&lt;br /&gt;
                if(listSelectionModel.isSelectedIndex(counter)) {&lt;br /&gt;
                TreePath     selPath = tree.getPathForRow&lt;br /&gt;
                                            (counter);&lt;br /&gt;
                if(selPath != null) {&lt;br /&gt;
                    addSelectionPath(selPath);&lt;br /&gt;
                }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        finally {&lt;br /&gt;
            updatingListSelectionModel = false;&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Class responsible for calling updateSelectedPathsFromSelectedRows&lt;br /&gt;
     * when the selection of the list changse.&lt;br /&gt;
     */&lt;br /&gt;
    class ListSelectionHandler implements ListSelectionListener {&lt;br /&gt;
        public void valueChanged(ListSelectionEvent e) {&lt;br /&gt;
        updateSelectedPathsFromSelectedRows();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * The contents of this file are subject to the Sapient Public License&lt;br /&gt;
 * Version 1.0 (the &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
 * with the License. You may obtain a copy of the License at&lt;br /&gt;
 * http://carbon.sf.net/License.html.&lt;br /&gt;
 *&lt;br /&gt;
 * Software distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; basis,&lt;br /&gt;
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for&lt;br /&gt;
 * the specific language governing rights and limitations under the License.&lt;br /&gt;
 *&lt;br /&gt;
 * The Original Code is The Carbon Component Framework.&lt;br /&gt;
 *&lt;br /&gt;
 * The Initial Developer of the Original Code is Sapient Corporation&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * TreeTableModel.java&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.&lt;br /&gt;
 *&lt;br /&gt;
 * This software is the confidential and proprietary information of Sun&lt;br /&gt;
 * Microsystems, Inc. (&amp;quot;Confidential Information&amp;quot;).  You shall not&lt;br /&gt;
 * disclose such Confidential Information and shall use it only in&lt;br /&gt;
 * accordance with the terms of the license agreement you entered into&lt;br /&gt;
 * with Sun.&lt;br /&gt;
 *&lt;br /&gt;
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE&lt;br /&gt;
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br /&gt;
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt;
 * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES&lt;br /&gt;
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING&lt;br /&gt;
 * THIS SOFTWARE OR ITS DERIVATIVES.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
/**&lt;br /&gt;
 * TreeTableModel is the model used by a JTreeTable. It extends TreeModel&lt;br /&gt;
 * to add methods for getting inforamtion about the set of columns each&lt;br /&gt;
 * node in the TreeTableModel may have. Each column, like a column in&lt;br /&gt;
 * a TableModel, has a name and a type associated with it. Each node in&lt;br /&gt;
 * the TreeTableModel can return a value for each of the columns and&lt;br /&gt;
 * set that value if isCellEditable() returns true.&lt;br /&gt;
 *&lt;br /&gt;
 * @author Philip Milne&lt;br /&gt;
 * @author Scott Violet&lt;br /&gt;
 */&lt;br /&gt;
 interface TreeTableModel extends TreeModel&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the number ofs availible column.&lt;br /&gt;
     */&lt;br /&gt;
    public int getColumnCount();&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the name for column number &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;.&lt;br /&gt;
     */&lt;br /&gt;
    public String getColumnName(int column);&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the type for column number &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;.&lt;br /&gt;
     */&lt;br /&gt;
    public Class getColumnClass(int column);&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns the value to be displayed for node &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt;,&lt;br /&gt;
     * at column number &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;.&lt;br /&gt;
     */&lt;br /&gt;
    public Object getValueAt(Object node, int column);&lt;br /&gt;
    /**&lt;br /&gt;
     * Indicates whether the the value for node &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt;,&lt;br /&gt;
     * at column number &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt; is editable.&lt;br /&gt;
     */&lt;br /&gt;
    public boolean isCellEditable(Object node, int column);&lt;br /&gt;
    /**&lt;br /&gt;
     * Sets the value for node &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt;,&lt;br /&gt;
     * at column number &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;.&lt;br /&gt;
     */&lt;br /&gt;
    public void setValueAt(Object aValue, Object node, int column);&lt;br /&gt;
}&lt;br /&gt;
 /*&lt;br /&gt;
  * The contents of this file are subject to the Sapient Public License&lt;br /&gt;
  * Version 1.0 (the &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
  * with the License. You may obtain a copy of the License at&lt;br /&gt;
  * http://carbon.sf.net/License.html.&lt;br /&gt;
  *&lt;br /&gt;
  * Software distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; basis,&lt;br /&gt;
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for&lt;br /&gt;
  * the specific language governing rights and limitations under the License.&lt;br /&gt;
  *&lt;br /&gt;
  * The Original Code is The Carbon Component Framework.&lt;br /&gt;
  *&lt;br /&gt;
  * The Initial Developer of the Original Code is Sapient Corporation&lt;br /&gt;
  *&lt;br /&gt;
  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * @(#)TreeTableModelAdapter.java    1.2 98/10/27&lt;br /&gt;
  *&lt;br /&gt;
  * Copyright 1997, 1998 by Sun Microsystems, Inc.,&lt;br /&gt;
  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.&lt;br /&gt;
  * All rights reserved.&lt;br /&gt;
  *&lt;br /&gt;
  * This software is the confidential and proprietary information&lt;br /&gt;
  * of Sun Microsystems, Inc. (&amp;quot;Confidential Information&amp;quot;).  You&lt;br /&gt;
  * shall not disclose such Confidential Information and shall use&lt;br /&gt;
  * it only in accordance with the terms of the license agreement&lt;br /&gt;
  * you entered into with Sun.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * This is a wrapper class takes a TreeTableModel and implements&lt;br /&gt;
  * the table model interface. The implementation is trivial, with&lt;br /&gt;
  * all of the event dispatching support provided by the superclass:&lt;br /&gt;
  * the AbstractTableModel.&lt;br /&gt;
  *&lt;br /&gt;
  * @version 1.2 10/27/98&lt;br /&gt;
  *&lt;br /&gt;
  * @author Philip Milne&lt;br /&gt;
  * @author Scott Violet&lt;br /&gt;
  */&lt;br /&gt;
  class TreeTableModelAdapter extends AbstractTableModel&lt;br /&gt;
 {&lt;br /&gt;
     JTree tree;&lt;br /&gt;
     TreeTableModel treeTableModel;&lt;br /&gt;
     public TreeTableModelAdapter(TreeTableModel treeTableModel, JTree tree) {&lt;br /&gt;
         this.tree = tree;&lt;br /&gt;
         this.treeTableModel = treeTableModel;&lt;br /&gt;
     tree.addTreeExpansionListener(new TreeExpansionListener() {&lt;br /&gt;
         // Don&amp;quot;t use fireTableRowsInserted() here; the selection model&lt;br /&gt;
         // would get updated twice.&lt;br /&gt;
         public void treeExpanded(TreeExpansionEvent event) {&lt;br /&gt;
           fireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
             public void treeCollapsed(TreeExpansionEvent event) {&lt;br /&gt;
           fireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
     });&lt;br /&gt;
     // Install a TreeModelListener that can update the table when&lt;br /&gt;
     // tree changes. We use delayedFireTableDataChanged as we can&lt;br /&gt;
     // not be guaranteed the tree will have finished processing&lt;br /&gt;
     // the event before us.&lt;br /&gt;
     treeTableModel.addTreeModelListener(new TreeModelListener() {&lt;br /&gt;
         public void treeNodesChanged(TreeModelEvent e) {&lt;br /&gt;
         delayedFireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
         public void treeNodesInserted(TreeModelEvent e) {&lt;br /&gt;
         delayedFireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
         public void treeNodesRemoved(TreeModelEvent e) {&lt;br /&gt;
         delayedFireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
         public void treeStructureChanged(TreeModelEvent e) {&lt;br /&gt;
         delayedFireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
     });&lt;br /&gt;
     }&lt;br /&gt;
     // Wrappers, implementing TableModel interface.&lt;br /&gt;
     public int getColumnCount() {&lt;br /&gt;
     return treeTableModel.getColumnCount();&lt;br /&gt;
     }&lt;br /&gt;
     public String getColumnName(int column) {&lt;br /&gt;
     return treeTableModel.getColumnName(column);&lt;br /&gt;
     }&lt;br /&gt;
     public Class getColumnClass(int column) {&lt;br /&gt;
     return treeTableModel.getColumnClass(column);&lt;br /&gt;
     }&lt;br /&gt;
     public int getRowCount() {&lt;br /&gt;
     return tree.getRowCount();&lt;br /&gt;
     }&lt;br /&gt;
     protected Object nodeForRow(int row) {&lt;br /&gt;
     TreePath treePath = tree.getPathForRow(row);&lt;br /&gt;
     return treePath.getLastPathComponent();&lt;br /&gt;
     }&lt;br /&gt;
     public Object getValueAt(int row, int column) {&lt;br /&gt;
     return treeTableModel.getValueAt(nodeForRow(row), column);&lt;br /&gt;
     }&lt;br /&gt;
     public boolean isCellEditable(int row, int column) {&lt;br /&gt;
          return treeTableModel.isCellEditable(nodeForRow(row), column);&lt;br /&gt;
     }&lt;br /&gt;
     public void setValueAt(Object value, int row, int column) {&lt;br /&gt;
     treeTableModel.setValueAt(value, nodeForRow(row), column);&lt;br /&gt;
     }&lt;br /&gt;
     /**&lt;br /&gt;
      * Invokes fireTableDataChanged after all the pending events have been&lt;br /&gt;
      * processed. SwingUtilities.invokeLater is used to handle this.&lt;br /&gt;
      */&lt;br /&gt;
     protected void delayedFireTableDataChanged() {&lt;br /&gt;
     SwingUtilities.invokeLater(new Runnable() {&lt;br /&gt;
         public void run() {&lt;br /&gt;
         fireTableDataChanged();&lt;br /&gt;
         }&lt;br /&gt;
     });&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
/*&lt;br /&gt;
 * The contents of this file are subject to the Sapient Public License&lt;br /&gt;
 * Version 1.0 (the &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
 * with the License. You may obtain a copy of the License at&lt;br /&gt;
 * http://carbon.sf.net/License.html.&lt;br /&gt;
 *&lt;br /&gt;
 * Software distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; basis,&lt;br /&gt;
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for&lt;br /&gt;
 * the specific language governing rights and limitations under the License.&lt;br /&gt;
 *&lt;br /&gt;
 * The Original Code is The Carbon Component Framework.&lt;br /&gt;
 *&lt;br /&gt;
 * The Initial Developer of the Original Code is Sapient Corporation&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.&lt;br /&gt;
 */&lt;br /&gt;
package org.sape.carbon.services.swing.treetable;&lt;br /&gt;
/*&lt;br /&gt;
 * @(#)AbstractTreeTableModel.java    1.2 98/10/27&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright 1997, 1998 by Sun Microsystems, Inc.,&lt;br /&gt;
 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.&lt;br /&gt;
 * All rights reserved.&lt;br /&gt;
 *&lt;br /&gt;
 * This software is the confidential and proprietary information&lt;br /&gt;
 * of Sun Microsystems, Inc. (&amp;quot;Confidential Information&amp;quot;).  You&lt;br /&gt;
 * shall not disclose such Confidential Information and shall use&lt;br /&gt;
 * it only in accordance with the terms of the license agreement&lt;br /&gt;
 * you entered into with Sun.&lt;br /&gt;
 */&lt;br /&gt;
import javax.swing.event.EventListenerList;&lt;br /&gt;
import javax.swing.event.TreeModelEvent;&lt;br /&gt;
import javax.swing.event.TreeModelListener;&lt;br /&gt;
import javax.swing.tree.TreePath;&lt;br /&gt;
/**&lt;br /&gt;
 * @version 1.2 10/27/98&lt;br /&gt;
 * An abstract implementation of the TreeTableModel interface, handling the list&lt;br /&gt;
 * of listeners.&lt;br /&gt;
 * @author Philip Milne&lt;br /&gt;
 */&lt;br /&gt;
public abstract class AbstractTreeTableModel implements TreeTableModel {&lt;br /&gt;
    protected Object root;&lt;br /&gt;
    protected EventListenerList listenerList = new EventListenerList();&lt;br /&gt;
    public AbstractTreeTableModel(Object root) {&lt;br /&gt;
        this.root = root;&lt;br /&gt;
    }&lt;br /&gt;
    //&lt;br /&gt;
    // Default implmentations for methods in the TreeModel interface.&lt;br /&gt;
    //&lt;br /&gt;
    public Object getRoot() {&lt;br /&gt;
        return root;&lt;br /&gt;
    }&lt;br /&gt;
    public boolean isLeaf(Object node) {&lt;br /&gt;
        return getChildCount(node) == 0;&lt;br /&gt;
    }&lt;br /&gt;
    public void valueForPathChanged(TreePath path, Object newValue) {}&lt;br /&gt;
    // This is not called in the JTree&amp;quot;s default mode: use a naive implementation.&lt;br /&gt;
    public int getIndexOfChild(Object parent, Object child) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; getChildCount(parent); i++) {&lt;br /&gt;
        if (getChild(parent, i).equals(child)) {&lt;br /&gt;
            return i;&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    return -1;&lt;br /&gt;
    }&lt;br /&gt;
    public void addTreeModelListener(TreeModelListener l) {&lt;br /&gt;
        listenerList.add(TreeModelListener.class, l);&lt;br /&gt;
    }&lt;br /&gt;
    public void removeTreeModelListener(TreeModelListener l) {&lt;br /&gt;
        listenerList.remove(TreeModelListener.class, l);&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.  The event instance&lt;br /&gt;
     * is lazily created using the parameters passed into&lt;br /&gt;
     * the fire method.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireTreeNodesChanged(Object source, Object[] path,&lt;br /&gt;
                                        int[] childIndices,&lt;br /&gt;
                                        Object[] children) {&lt;br /&gt;
        // Guaranteed to return a non-null array&lt;br /&gt;
        Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
        TreeModelEvent e = null;&lt;br /&gt;
        // Process the listeners last to first, notifying&lt;br /&gt;
        // those that are interested in this event&lt;br /&gt;
        for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
            if (listeners[i]==TreeModelListener.class) {&lt;br /&gt;
                // Lazily create the event:&lt;br /&gt;
                if (e == null)&lt;br /&gt;
                    e = new TreeModelEvent(source, path,&lt;br /&gt;
                                           childIndices, children);&lt;br /&gt;
                ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.  The event instance&lt;br /&gt;
     * is lazily created using the parameters passed into&lt;br /&gt;
     * the fire method.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireTreeNodesInserted(Object source, Object[] path,&lt;br /&gt;
                                        int[] childIndices,&lt;br /&gt;
                                        Object[] children) {&lt;br /&gt;
        // Guaranteed to return a non-null array&lt;br /&gt;
        Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
        TreeModelEvent e = null;&lt;br /&gt;
        // Process the listeners last to first, notifying&lt;br /&gt;
        // those that are interested in this event&lt;br /&gt;
        for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
            if (listeners[i]==TreeModelListener.class) {&lt;br /&gt;
                // Lazily create the event:&lt;br /&gt;
                if (e == null)&lt;br /&gt;
                    e = new TreeModelEvent(source, path,&lt;br /&gt;
                                           childIndices, children);&lt;br /&gt;
                ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.  The event instance&lt;br /&gt;
     * is lazily created using the parameters passed into&lt;br /&gt;
     * the fire method.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireTreeNodesRemoved(Object source, Object[] path,&lt;br /&gt;
                                        int[] childIndices,&lt;br /&gt;
                                        Object[] children) {&lt;br /&gt;
        // Guaranteed to return a non-null array&lt;br /&gt;
        Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
        TreeModelEvent e = null;&lt;br /&gt;
        // Process the listeners last to first, notifying&lt;br /&gt;
        // those that are interested in this event&lt;br /&gt;
        for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
            if (listeners[i]==TreeModelListener.class) {&lt;br /&gt;
                // Lazily create the event:&lt;br /&gt;
                if (e == null)&lt;br /&gt;
                    e = new TreeModelEvent(source, path,&lt;br /&gt;
                                           childIndices, children);&lt;br /&gt;
                ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.  The event instance&lt;br /&gt;
     * is lazily created using the parameters passed into&lt;br /&gt;
     * the fire method.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireTreeStructureChanged(Object source, Object[] path,&lt;br /&gt;
                                        int[] childIndices,&lt;br /&gt;
                                        Object[] children) {&lt;br /&gt;
        // Guaranteed to return a non-null array&lt;br /&gt;
        Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
        TreeModelEvent e = null;&lt;br /&gt;
        // Process the listeners last to first, notifying&lt;br /&gt;
        // those that are interested in this event&lt;br /&gt;
        for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
            if (listeners[i]==TreeModelListener.class) {&lt;br /&gt;
                // Lazily create the event:&lt;br /&gt;
                if (e == null)&lt;br /&gt;
                    e = new TreeModelEvent(source, path,&lt;br /&gt;
                                           childIndices, children);&lt;br /&gt;
                ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    //&lt;br /&gt;
    // Default impelmentations for methods in the TreeTableModel interface.&lt;br /&gt;
    //&lt;br /&gt;
    public Class getColumnClass(int column) { return Object.class; }&lt;br /&gt;
   /** By default, make the column with the Tree in it the only editable one.&lt;br /&gt;
    *  Making this column editable causes the JTable to forward mouse&lt;br /&gt;
    *  and keyboard events in the Tree column to the underlying JTree.&lt;br /&gt;
    */&lt;br /&gt;
    public boolean isCellEditable(Object node, int column) {&lt;br /&gt;
         return getColumnClass(column) == TreeTableModel.class;&lt;br /&gt;
    }&lt;br /&gt;
    public void setValueAt(Object aValue, Object node, int column) {}&lt;br /&gt;
&lt;br /&gt;
    // Left to be implemented in the subclass:&lt;br /&gt;
    /*&lt;br /&gt;
     *   public Object getChild(Object parent, int index)&lt;br /&gt;
     *   public int getChildCount(Object parent)&lt;br /&gt;
     *   public int getColumnCount()&lt;br /&gt;
     *   public String getColumnName(Object node, int column)&lt;br /&gt;
     *   public Object getValueAt(Object node, int column)&lt;br /&gt;
     */&lt;br /&gt;
}&lt;br /&gt;
/*&lt;br /&gt;
 * The contents of this file are subject to the Sapient Public License&lt;br /&gt;
 * Version 1.0 (the &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
 * with the License. You may obtain a copy of the License at&lt;br /&gt;
 * http://carbon.sf.net/License.html.&lt;br /&gt;
 *&lt;br /&gt;
 * Software distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; basis,&lt;br /&gt;
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for&lt;br /&gt;
 * the specific language governing rights and limitations under the License.&lt;br /&gt;
 *&lt;br /&gt;
 * The Original Code is The Carbon Component Framework.&lt;br /&gt;
 *&lt;br /&gt;
 * The Initial Developer of the Original Code is Sapient Corporation&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
import java.util.EventObject;&lt;br /&gt;
import javax.swing.CellEditor;&lt;br /&gt;
import javax.swing.event.CellEditorListener;&lt;br /&gt;
import javax.swing.event.ChangeEvent;&lt;br /&gt;
import javax.swing.event.EventListenerList;&lt;br /&gt;
public class AbstractCellEditor implements CellEditor {&lt;br /&gt;
    protected EventListenerList listenerList = new EventListenerList();&lt;br /&gt;
    public Object getCellEditorValue() { return null; }&lt;br /&gt;
    public boolean isCellEditable(EventObject e) { return true; }&lt;br /&gt;
    public boolean shouldSelectCell(EventObject anEvent) { return false; }&lt;br /&gt;
    public boolean stopCellEditing() { return true; }&lt;br /&gt;
    public void cancelCellEditing() {}&lt;br /&gt;
    public void addCellEditorListener(CellEditorListener l) {&lt;br /&gt;
    listenerList.add(CellEditorListener.class, l);&lt;br /&gt;
    }&lt;br /&gt;
    public void removeCellEditorListener(CellEditorListener l) {&lt;br /&gt;
    listenerList.remove(CellEditorListener.class, l);&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireEditingStopped() {&lt;br /&gt;
    // Guaranteed to return a non-null array&lt;br /&gt;
    Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
    // Process the listeners last to first, notifying&lt;br /&gt;
    // those that are interested in this event&lt;br /&gt;
    for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
        if (listeners[i]==CellEditorListener.class) {&lt;br /&gt;
        ((CellEditorListener)listeners[i+1]).editingStopped(new ChangeEvent(this));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
    /*&lt;br /&gt;
     * Notify all listeners that have registered interest for&lt;br /&gt;
     * notification on this event type.&lt;br /&gt;
     * @see EventListenerList&lt;br /&gt;
     */&lt;br /&gt;
    protected void fireEditingCanceled() {&lt;br /&gt;
    // Guaranteed to return a non-null array&lt;br /&gt;
    Object[] listeners = listenerList.getListenerList();&lt;br /&gt;
    // Process the listeners last to first, notifying&lt;br /&gt;
    // those that are interested in this event&lt;br /&gt;
    for (int i = listeners.length-2; i&amp;gt;=0; i-=2) {&lt;br /&gt;
        if (listeners[i]==CellEditorListener.class) {&lt;br /&gt;
        ((CellEditorListener)listeners[i+1]).editingCanceled(new ChangeEvent(this));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;/div&gt;</summary>
			</entry>

	</feed>