JTree and JButton in node.

Helo.
I've a question regarding JTree component. I was wondering if it is possible at all.
I want to build JTree component with JButton(JPanel) in each node, for example:
RootNode
|
---String [JButton][JButton]
|
---String [JButton][JButton]
Is there possibility to put JPanel into children node.
Maybe anyone did do this before?
Thanks in advance for any help.
Regards

This is possible. You'll have to take a look at TreeCellRenderer and TreeCellEditor, and maybe the tutorial at http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html . Basically, both interfaces allow you to return arbitrary components for rendering / editing tree nodes. The default implementation is based on JLabels, but you can use complex panels with multiple child components as well.

Similar Messages

  • JTree and selected tree node

    I am allowing the user to search for a node in a JTree. I can find the node and progamatically expand and select the node. What I would like to do next is find the x,y coordinates of this selected node so I can use Robot to move the mouse to this node. I have hover help which is chock full of information in HTML describing this node, however, the user now is required to move the cursor to this selected node to see the hover help.
    Any help would be appreciated.

    Hi ,
    try this
    jlabel.setIcon( null ) ;

  • Reload JTree and keep expanded nodes

    Hi all,
    I have spent some time looking around on this, found some useful stuff, but I still cannot seem to get a result.
    Here is my situation:
    I have a JTree for a GUI desktop app. I build the tree from a database file. The user has the ability to refresh the tree to keep it in sync with any database changes. The problem is that when I refresh, all the nodes that were previously expanded are now collapsed again.
    Having looked around, I have seen a lot of JTree.expandRow() answers, but I don't want to use expandRow, as the rows will changes according to any db changes.
    I thought a good solution would be to trap any expand or collapse events and for each either add or remove the TreePath for the relevant node onto a List. When the users refreshes the tree, I thought I could run through the list and expand any TreeNodes I find. I also found someone advocating such an approach in another thread. BUT - it doesn't work for me Here is the code for my refresh. Any help/advice, greatly appreciated.
    Thanks in advance,
    Steve
    private void refreshBrowser(){
            System.out.println("Refresh browser - Started");       
            rootTreeNode.removeAllChildren(); // remove all nodes from root
            loadBrowserData(); // This method loads nodes from a database
             Iterator<TreePath> TPI = objectTreePaths.iterator(); // run throught my saved paths
            while (TPI.hasNext()) {
                TreePath yTreePath = TPI.next();           
                browserTree.expandPath(yTreePath); // Expand each found path
            treeModel.reload(); // model changed - reload it.
            System.out.println("Refresh browser - Complete");       
        }

    Here is my situation:
    I have a JTree for a GUI desktop app. I build the
    tree from a database file. The user has the ability
    to refresh the tree to keep it in sync with any
    database changes. The problem is that when I refresh,
    all the nodes that were previously expanded are now
    collapsed again.
    Having looked around, I have seen a lot of
    JTree.expandRow() answers, but I don't want to use
    expandRow, as the rows will changes according to any
    db changes.you could use:
    JTee.scrollPathToVisible(path);
    Where path is obtained in this way from a DefaultMutableTreeNode (TreeNode):
    TreePath path = new TreePath(((DefaultMutableTreeNode)node).getPath());
    I thought a good solution would be to trap any expand
    or collapse events and for each either add or remove
    the TreePath for the relevant node onto a List. When
    the users refreshes the tree, I thought I could run
    through the list and expand any TreeNodes I find. I
    also found someone advocating such an approach in
    another thread. BUT - it doesn't work for me When you perform a JTree.reload() call, it will collapse each node.
    My advice is to call JTree.reload() and then call JTree.scrollPathToVisible(path) for each TreeNode previously expanded.
    Hope this can help,
    regards

  • How to retrieve the nodes from the Database on JTree and many more

    I am facing a problem with JTree. I want to retrieve all the nodes from the MS-Access database on the Frame(i.e. Frame will display the JTree), then I also want to perform function like Edit, insert , delete and Drag and Drop opeartion on the JTree and the database should also updated accordingly.
    So, if you have any idea or if you have some code to look for then please send it to me.

    I am facing a problem with JTree. I want to retrieve all the nodes from the MS-Access database on the Frame(i.e. Frame will display the JTree), then I also want to perform function like Edit, insert , delete and Drag and Drop opeartion on the JTree and the database should also updated accordingly
    pls give me code

  • Focus Problem with JTree and Menus

    Hi all,
    I have a problem with focus when editing a JTree and selecting a menu. The problem occurs when the user single clicks on a node, invoking the countdown to edit. If the user quickly clicks on a menu item, the focus will go to the menu item, but then when the countdown finishes, the node now has keyboard focus.
    Below is code to reproduce the problem. Click on the node, hover for a little bit, then quickly click on the menu item.
    How would I go about fixing the problem? Thanks!
    import java.awt.Container;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeModel;
    public class MyTree extends JTree {
         public MyTree(DefaultTreeModel treemodel) {
              setModel(treemodel);
              setRootVisible(true);
         public static void main(String[] args) {
              JFrame frame = new JFrame();
              JMenuBar bar = new JMenuBar();
              JMenu menu = new JMenu("Test");
              JMenuItem item = new JMenuItem("Item");
              menu.add(item);
              bar.add(menu);
              frame.setJMenuBar(bar);
              Container contentPane = frame.getContentPane();
              contentPane.setLayout(new GridLayout(1, 2));
              DefaultMutableTreeNode root1 = new DefaultMutableTreeNode("Root");
              root1.add(new DefaultMutableTreeNode("Root2"));
              DefaultTreeModel model = new DefaultTreeModel(root1);
              MyTree tree1 = new MyTree(model);
              tree1.setEditable(true);
              tree1.setCellEditor(
                   new ComponentTreeCellEditor(
                        tree1,
                        new ComponentTreeCellRenderer()));
              tree1.setRowHeight(0);
              contentPane.add(tree1);
              frame.pack();
              frame.show();
    import java.awt.FlowLayout;
    import java.util.EventObject;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultTreeCellEditor;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeCellEditor;
    import javax.swing.tree.TreeCellRenderer;
    public class ComponentTreeCellEditor
         extends DefaultTreeCellEditor
         implements TreeCellEditor {
         private String m_oldValue;
         private TreeCellRenderer m_renderer = null;
         private DefaultTreeModel m_model = null;
         private JPanel m_display = null;
         private JTextField m_field = null;
         private JTree m_tree = null;
         public ComponentTreeCellEditor(
              JTree tree,
              DefaultTreeCellRenderer renderer) {
              super(tree, renderer);
              m_renderer = renderer;
              m_model = (DefaultTreeModel) tree.getModel();
              m_tree = tree;
              m_display = new JPanel(new FlowLayout(FlowLayout.LEFT));
              m_field = new JTextField();
              m_display.add(new JLabel("My Label "));
              m_display.add(m_field);
         public java.awt.Component getTreeCellEditorComponent(
              JTree tree,
              Object value,
              boolean isSelected,
              boolean expanded,
              boolean leaf,
              int row) {
              m_field.setText(value.toString());
              return m_display;
         public Object getCellEditorValue() {
              return m_field.getText();
          * The edited cell should always be selected.
          * @param anEvent the event that fired this function.
          * @return true, always.
         public boolean shouldSelectCell(EventObject anEvent) {
              return true;
          * Only edit immediately if the event is null.
          * @param event the event being studied
          * @return true if event is null, false otherwise.
         protected boolean canEditImmediately(EventObject event) {
              return (event == null);
    }

    You can provide a cell renderer to the JTree to paint the checkBox.
    The following code checks or unchecks the box with each click also:
    _tree.setCellRenderer(new DefaultTreeCellRenderer()
      private JCheckBox checkBox = null;
      public Component getTreeCellRendererComponent(JTree tree,
                                                    Object value,
                                                    boolean selected,
                                                    boolean expanded,
                                                    boolean leaf,
                                                    int row,
                                                    boolean hasFocus)
        // Each node will be drawn as a check box
        if (checkBox == null)
          checkBox  = new JCheckBox();
          checkBox .setBackground(tree.getBackground());
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
        checkBox.setText(node.getUserObject().toString());
        checkBox.setSelected(selected);
        return checkBox;
    });

  • Jtree: "check if tree node is a folder"  not wrkin

    Hi, I have a JTree and If a folder does not has any file, it displays as file not folder. Is there any way to fix it. I want to represent an empty folder as folder not file. here is the code. Thanks for help.
    if(!f.isDirectory()) {
         System.out.println("FILE - " + f.getName());
         DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
         node.add(child);
         else {
         DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
              node.add(child);
         File fList[] = f.listFiles();
         for(int i = 0; i < fList.length; i++)
         getList(child, fList);

    Sorry for not formatting the code:
    here is the code again:
    public void getDirectories()
         getList(root, new File("c:/FIST/Projects/"));
           KeyStroke ks = KeyStroke.getKeyStroke("ctrl A");
           tree.getInputMap().put(ks, "none");
    public void getList(DefaultMutableTreeNode node, File f)
         if(!f.isDirectory())
    DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
                int i=child.getLevel();
                if(i==0)
                    node.add(child);
         else {
                  DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
                 node.add(child);
                  File fList[] = f.listFiles();
                  for(int i = 0; i  < fList.length; i++)
                      getList(child, fList);

  • Drag and Drop between JTree and another component

    Hi,
    I have searched the forum for answer to this question but am not sure I found something similar to this. So, please help me out on this.
    I have a JTree and a JPanel, which basically shows images (as thumbnails) for the child nodes of one node in the tree heirarchy.
    I need to be able to drag and drop components from the JPanel to the JTree and vice versa, and of course, when you drop them on the tree, they should go under the correct node.
    I am using Swing 1.4.1, and have successfully implemented DnD in the JTree itself. But I am a little unclear about the DnD between the tree and the panel.
    Would really appreciate if someone could throw some light on this.
    Thanks a lot,
    Sri.

    Hi clairesheridan,
    thanks for your response. Your answer would have helped me if I was using JDK 1.3 but I am try to use the Swing API in jdk1.4.1, in which you have to set a transferhandler etc.
    Please let me know if you have any ideas or solutions.
    Thanks,
    sriharmya.

  • Drag and Drop between JTree and Labels in 2 different panes

    Hi,
    I am using JDK 1.4.1 and am trying to implement Drag n Drop between a JTree and JLabels with ImageIcons, both on different panes.
    I got the DnD working fine on the tree. but i cant get to drag and drop the label from the other pane, on the Jtree as a node. I am getting confused with the DataFlavors, and also wonder if there is something else that i have to do for DnD between 2 panes. Can someone give me any leads on this, please? The Panes I am talking about are splitpanes.
    thanks,
    Sri.

    hey thanks Dennis!! I was hoping you would respond to my question, as I have seen a lot of your replies. yes, the example you gave would be helpful. but i am trying to implement this in 1.4.1, with the new drag and drop in swing. and i am getting confused wiht theh data flavors etc.
    my problem at hand is :
    I have a tree on the left pane. i can drag and drop the nodes on the tree itself. (i already did that...no problem). I have Jlabels with imageicons (actually wrapper classes with labels and imageicons) on the right pane. i have to be able to drag these labels to the tree such that they form a node.
    I have one class the NodeSelection class which extends TransferHandler and implements Transferable. i was able to do DnD for the tree using this. I customized the importData method in this.I thought that i can just use the same class to create the transferhandler and transferable, and just use a different implementation for the importData method if the data being dragged is from the label.
    well, my thoughts and ideas were ok...but i can implement it...so they must be wrong ;-)
    Can u please suggest another way to do this. I have a deadline to meet and am stuck here :-( any suggestions or tips or hints would be very helpful and appreciated!!
    Thanks,
    Sri.

  • JTree adding to expanded nodes

    Hey,
    I'm writing a program that contains a JTree with two parent nodes and child nodes that are added/removed on demand.
    Basically I can't add child nodes while the parent node is expanded. Following the code it actually does add it, just does not update the display.
    I've tried validate/repaint/anything I could find that may be of some help with no luck.
    Any ideas?
    Thanks in advance :)

    What do you think about the library I created which
    addresses this issue?
    Denis Krukovsky
    http://dotuseful.sourceforge.net/
    I looked at your site and spent 20 minutes trying to figure out why your classes are useful. It's not at all clear why someone should use them. I also looked over your previous posts, but you never seem to explain why someone should use them.

  • JTree: Updating a single node

    I have a Jtree and need, during the course of the apps execution, update the information in the tree, specifically change the icons of individual nodes. setLeafIcon() allows you to change the icon for the entire model, but I just need to change it for individual nodes. anyone else implement this or have any ideas?
    thanks.
    -karl

    ok, i still can't get it working, though im closer.
    my problem is that i use a wrapper node(AdapterNode) to wrap Node objects. Inside the AdapterNode is an icon field that gets initialized, then changed dynamically during the execution of the app. Through debuggin over the past 13 hours(ugh), i've found my root problem: the JTree re-renders ALL of its nodes everytime an event is fired. When this happens, it recurses down the tree, and reinitializes all of my icons. (The icons get initialized in the AdapterNode constructor. there is not other place to do this because of the recursion)
    I notice that 2 event listeners get registered with my custom TreeModel.
    I was thinking about setting a boolean flag for an initial render of the tree, then mark it false and have it update only specific nodes. any suggestions?
    thanks.
    -karl

  • JTree: Problems updating the nodes size

    Hi,
    I'm trying to update the content of a JTree and I wonder how it
    really works, since the paint() method doesn't seem to call the
    renderer.
    My situation: Imagine a JPanel splited in two by a JSplitPane. In
    the left is the tree. Each node in the tree shows two panels, one
    aligned to the left, and another to the right. I need that the panel
    containing the two use all the available space in the left part of the
    Split panel.
    My solution: I pass the left JPanel to the tree renderer, so that
    it can get the width from it (inside the
    getTreeCellRendererComponent()) to build the return JPanel with the
    correct size. My logic is that since each time you move the JSplitPane
    the JTree paint() method is invoked the renderer can return the
    correct JPanel with the correct size that will be painted then in the
    screen.
    My problem: Doens't work. When I render the tree, the renderer is
    invoked, but it doesn't change its size (I can change the color based on the width, but not the node size). Only when I collapse & expand a node, it correctly takes into account the .setPreferredSize() and returns the JPanel with the correct size.
    The only way I found to update the tree involves to catch the
    JSplitPane event and call updateUI() in the tree, something that, I
    think, it's certainly not the correct way to do it.
    Any explanation of why this doesn't work would be really great. Any
    pointer to a web resource explaining in deep how Swing components work (specially the JTree) would be a godsend.
    Thanks,
    - Juancho

    My situation: Imagine a JPanel splited in two by a JSplitPane. Got it.
    In the left is the tree. In the left side of the JSplitPane is a JTree.
    Each node in the tree shows two panels,Maybe... on the right side of the JSplitPane are two Panels in which the data depends on which node is selected in the JTree???
    Maybe... you have a custom TreeCellRenderer which displays a pair of panels in place of the standard JLabel???
    one aligned to the left, and another to the right. To the left of what??? To the right of what???
    I need that the panel containing the two use all the available
    space in the left part of the Split panel.Panel containing the two what??? I thought the left part of the SplitPanel contained a JTree???

  • JTree and JPanel

    I have an application in which I have two separate dialog boxes that have multiple tabs (Panels) on them to set program options. I would like to update this UI to have a single dialog box that has a JTree on the left hand side of the dialog and have it update the Panel on the right hand side of the dialog. I am not 100% certain of how to achieve this. There are 2 issues
    1) How to I update the panel corresponding to the node clicked in the JTree. I assume I need to add a listener so when a node is clicked I need to update the JPanel.
    2) I assume that I do not want to create/destroy each JPanel associated with each JTree entry whenever a node is clicked. This would imply creating all JPanels when the dialog box is created. Do I create another JPanel/ScrollPane for the right hand side of the dialog box as a container and add these individual JPanels to it?
    The Dialog box looks similar to
    LHS RHS
    JTree JPanel (changes based on JTree node selected)
    The JTree looks similar to the following:
    Options
       Global
          Connections
          Storage Options
       Session
          Filters
          ListsTIA

    mperemsky5 wrote:
    Ok, I have many panels in the application. Each panel is a different layout and contains information pertinent to that specific feature.
    Panel A = All Connection Information
    Panel B = All Log File Information
    Pancel C = All Proxy Information
    If I click on node A in the JTree I want Panel A to be displayed on the RHS of the dialog box. If I click node B I want Panel B to be displayed on the RHS of the dialog box. Remember, all the Panels are different and have different inputs, so this is not simply a matter of having a single form on the RHS and updating values in the form.
    I have added a mouse click listener to the JTree to retrieve which node of the tree has been clicked (still working on deciphering which node in the tree). When this listener is called, it needs to display the Panel associated with that node.
    Since I want the overall dialog box to remain the same size (say 600 x 400), I need Panels A,B,... to be displayed in the same size area on the RHS of the dialog box (say 300 x 400). Do I need to create a Panel that is 300x400 and add A, B, ... to that panel to ensure that they all display in the same location/size in the dialog box.
    If this is not clear, what part is unclear?Okay gotcha. That sounds like a job for CardLayout then. Check out the link I posted earlier. Also, the link I posted to the Tree tutorial shows you how to figure out which node was clicked.

  • Catch the image of JTree and save it as a file

    There is an JTree and it has a few nodes.
    And there, I want to capture both the image of JTree and
    the images of it's child nodes as they show in screen.
    if possible, I want to capture image of all expanded nodes in tree and
    save them as jpg file.
    I try to capture the Image of JTree from JTree.createImage() method.
    and I also tried to capture the images of child nodes
    from JTree.getComponents() and capture images all of child nodes as they were.
    I,however,get to know the method
    Component.createImage() doesn't return the image that shows in screen as it was.
    could anybody tell me the answer?

    Hi,
    don't know if I got you right, but what you want is a "screenshot" of the JTree, right ?
    Try to paint the JTree in a BufferedImage and encode this as JPEG or whatever.
    BufferedImage theImage = new BufferedImage(
          owner.getWidth(), owner.getHeight(), BufferedImage.TYPE_INT_RGB);
          Graphics g = theImage.createGraphics();
          g.setClip( 0, 0, owner.getWidth(), owner.getHeight());
          owner.paint( g);owner is your JTree or any other component you want.
    Hope that helped.

  • JTree - make visible new node

    I have added a new DefaultMutableTreeNode, as follows, to a JTree:
    DefaultMutableTreeNode root;
    jTree = new JTree(root);
    DefaultTreeModel treeModel = new DefaultTreeModel(root);
    DefaultMutableTreeNode node = new DefaultMutableTreeNode();
    treeModel.insertNodeInto(node, root, root.getChildCount());
    now I want to display this new node in the JTree at run time (i.e. JTree updates and displays new node within GUI).
    (the JTree is within a JScrollPane).
    I have tried methods makeVisible(.), setPathToVisible(.) without success.
    What is the easiest way to do this?
    thanks in advance.

    I've used JTree.scrollPathToVisible(TreePath)

  • One model for JTree and JTable

    Hi.
    Is it possible for a JTree and a JTable to share one model?
    Thank you

    Hope u r not using Comonent TreeTable
    If u have Tree & Table different components, just want to have a common model then u can try this,
    It is nothing but default implementation given in DefaultTableModel
    public class MyTreeTableModel extends DefaultTreeModel implements TableModel, Serializable {
    protected Vector dataVector;
    /** List of listeners */
    protected EventListenerList listenerList = new EventListenerList();
    /** The <code>Vector</code> of column identifiers. */
    protected Vector columnIdentifiers;
    public MyTreeTableModel(TreeNode root) {
    this(root, false);
    // constructor for TreeModel only
    public MyTreeTableModel(TreeNode root, boolean asksAllowsChildren) {
    super(root, asksAllowsChildren);
    // constructor for TableModel only
    public MyTreeTableModel() {
    this(0, 0);
    private static Vector newVector(int size) {
    Vector v = new Vector(size);
    v.setSize(size);
    return v;
    // constructor for TableModel only
    public MyTreeTableModel(int rowCount, int columnCount) {
    this(newVector(columnCount), rowCount);
    // constructor for TableModel only
    public MyTreeTableModel(Vector columnNames, int rowCount) {
    super(null);
    setDataVector(newVector(rowCount), columnNames);
    // constructor for TableModel only
    public MyTreeTableModel(Object[] columnNames, int rowCount) {
    this(convertToVector(columnNames), rowCount);
    // constructor for TableModel only
    public MyTreeTableModel(Vector data, Vector columnNames) {
    super(null);
    setDataVector(data, columnNames);
    // constructor for TableModel only
    public MyTreeTableModel(Object[][] data, Object[] columnNames) {
    super(null);
    setDataVector(data, columnNames);
    * Returns a default name for the column using spreadsheet conventions:
    * A, B, C, ... Z, AA, AB, etc. If <code>column</code> cannot be found,
    * returns an empty string.
    * @param column the column being queried
    * @return a string containing the default name of <code>column</code>
    private String getDefaultColumnName(int column) {
    String result = "";
    for (; column >= 0; column = column / 26 - 1) {
    result = (char)((char)(column%26)+'A') + result;
    return result;
    * Returns a column given its name.
    * Implementation is naive so this should be overridden if
    * this method is to be called often. This method is not
    * in the <code>TableModel</code> interface and is not used by the
    * <code>JTable</code>.
    * @param columnName string containing name of column to be located
    * @return the column with <code>columnName</code>, or -1 if not found
    public int findColumn(String columnName) {
    for (int i = 0; i < getColumnCount(); i++) {
    if (columnName.equals(getColumnName(i))) {
    return i;
    return -1;
    * Returns <code>Object.class</code> regardless of <code>columnIndex</code>.
    * @param columnIndex the column being queried
    * @return the Object.class
    public Class getColumnClass(int columnIndex) {
    return Object.class;
    // Managing Listeners
    * Adds a listener to the list that's notified each time a change
    * to the data model occurs.
    * @param     l          the TableModelListener
    public void addTableModelListener(TableModelListener l) {
    listenerList.add(TableModelListener.class, l);
    * Removes a listener from the list that's notified each time a
    * change to the data model occurs.
    * @param     l          the TableModelListener
    public void removeTableModelListener(TableModelListener l) {
    listenerList.remove(TableModelListener.class, l);
    * Returns an array of all the table model listeners
    * registered on this model.
    * @return all of this model's <code>TableModelListener</code>s
    * or an empty
    * array if no table model listeners are currently registered
    public TableModelListener[] getTableModelListeners() {
    return (TableModelListener[])listenerList.getListeners(
    TableModelListener.class);
    // Fire methods
    * Notifies all listeners that all cell values in the table's
    * rows may have changed. The number of rows may also have changed
    * and the <code>JTable</code> should redraw the
    * table from scratch. The structure of the table (as in the order of the
    * columns) is assumed to be the same.
    public void fireTableDataChanged() {
    fireTableChanged(new TableModelEvent(this));
    * Notifies all listeners that the table's structure has changed.
    * The number of columns in the table, and the names and types of
    * the new columns may be different from the previous state.
    * If the <code>JTable</code> receives this event and its
    * <code>autoCreateColumnsFromModel</code>
    * flag is set it discards any table columns that it had and reallocates
    * default columns in the order they appear in the model. This is the
    * same as calling <code>setModel(TableModel)</code> on the
    * <code>JTable</code>.
    public void fireTableStructureChanged() {
    fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
    * Notifies all listeners that rows in the range
    * <code>[firstRow, lastRow]</code>, inclusive, have been inserted.
    * @param firstRow the first row
    * @param lastRow the last row
    public void fireTableRowsInserted(int firstRow, int lastRow) {
    fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
    TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
    * Notifies all listeners that rows in the range
    * <code>[firstRow, lastRow]</code>, inclusive, have been updated.
    * @param firstRow the first row
    * @param lastRow the last row
    public void fireTableRowsUpdated(int firstRow, int lastRow) {
    fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
    TableModelEvent.ALL_COLUMNS, TableModelEvent.UPDATE));
    * Notifies all listeners that rows in the range
    * <code>[firstRow, lastRow]</code>, inclusive, have been deleted.
    * @param firstRow the first row
    * @param lastRow the last row
    public void fireTableRowsDeleted(int firstRow, int lastRow) {
    fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
    TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
    * Notifies all listeners that the value of the cell at
    * <code>[row, column]</code> has been updated.
    * @param row row of cell which has been updated
    * @param column column of cell which has been updated
    public void fireTableCellUpdated(int row, int column) {
    fireTableChanged(new TableModelEvent(this, row, row, column));
    * Forwards the given notification event to all
    * <code>TableModelListeners</code> that registered
    * themselves as listeners for this table model.
    * @param e the event to be forwarded
    public void fireTableChanged(TableModelEvent e) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners==TableModelListener.class) {
    ((TableModelListener)listeners[i+1]).tableChanged(e);
    * Returns an array of all the objects currently registered
    * as <code><em>Foo</em>Listener</code>s
    * upon this <code>AbstractTableModel</code>.
    * <code><em>Foo</em>Listener</code>s are registered using the
    * <code>add<em>Foo</em>Listener</code> method.
    * <p>
    * You can specify the <code>listenerType</code> argument
    * with a class literal,
    * such as
    * <code><em>Foo</em>Listener.class</code>.
    * For example, you can query a
    * model <code>m</code>
    * for its table model listeners with the following code:
    * <pre>TableModelListener[] tmls = (TableModelListener[])(m.getListeners(TableModelListener.class));</pre>
    * If no such listeners exist, this method returns an empty array.
    * @param listenerType the type of listeners requested; this parameter
    * should specify an interface that descends from
    * <code>java.util.EventListener</code>
    * @return an array of all objects registered as
    * <code><em>Foo</em>Listener</code>s on this component,
    * or an empty array if no such
    * listeners have been added
    * @exception ClassCastException if <code>listenerType</code>
    * doesn't specify a class or interface that implements
    * <code>java.util.EventListener</code>
    public EventListener[] getListeners(Class listenerType) {
    return listenerList.getListeners(listenerType);
    * Returns the <code>Vector</code> of <code>Vectors</code>
    * that contains the table's
    * data values. The vectors contained in the outer vector are
    * each a single row of values. In other words, to get to the cell
    * at row 1, column 5: <p>
    * <code>((Vector)getDataVector().elementAt(1)).elementAt(5);</code><p>
    * @return the vector of vectors containing the tables data values
    public Vector getDataVector() {
    return dataVector;
    private static Vector nonNullVector(Vector v) {
    return (v != null) ? v : new Vector();
    * Replaces the current <code>dataVector</code> instance variable
    * with the new Vector of rows, <code>dataVector</code>.
    * <code>columnIdentifiers</code> are the names of the new
    * columns. The first name in <code>columnIdentifiers</code> is
    * mapped to column 0 in <code>dataVector</code>. Each row in
    * <code>dataVector</code> is adjusted to match the number of
    * columns in <code>columnIdentifiers</code>
    * either by truncating the <code>Vector</code> if it is too long,
    * or adding <code>null</code> values if it is too short.
    * <p>Note that passing in a <code>null</code> value for
    * <code>dataVector</code> results in unspecified behavior,
    * an possibly an exception.
    * @param dataVector the new data vector
    * @param columnIdentifiers the names of the columns
    public void setDataVector(Vector dataVector, Vector columnIdentifiers) {
    this.dataVector = nonNullVector(dataVector);
    this.columnIdentifiers = nonNullVector(columnIdentifiers);
    justifyRows(0, getRowCount());
    fireTableStructureChanged();
    * Replaces the value in the <code>dataVector</code> instance
    * variable with the values in the array <code>dataVector</code>.
    * The first index in the <code>Object[][]</code>
    * array is the row index and the second is the column index.
    * <code>columnIdentifiers</code> are the names of the new columns.
    * @param dataVector          the new data vector
    * @param columnIdentifiers     the names of the columns
    public void setDataVector(Object[][] dataVector, Object[] columnIdentifiers) {
    setDataVector(convertToVector(dataVector), convertToVector(columnIdentifiers));
    * Equivalent to <code>fireTableChanged</code>.
    * @param event the change event
    public void newDataAvailable(TableModelEvent event) {
    fireTableChanged(event);
    // Manipulating rows
    private void justifyRows(int from, int to) {
    // Sometimes the MyTreeTableModel is subclassed
    // instead of the AbstractTableModel by mistake.
    // Set the number of rows for the case when getRowCount
    // is overridden.
    dataVector.setSize(getRowCount());
    for (int i = from; i < to; i++) {
    if (dataVector.elementAt(i) == null) {
    dataVector.setElementAt(new Vector(), i);
    ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
    * Ensures that the new rows have the correct number of columns.
    * This is accomplished by using the <code>setSize</code> method in
    * <code>Vector</code> which truncates vectors
    * which are too long, and appends <code>null</code>s if they
    * are too short.
    * This method also sends out a <code>tableChanged</code>
    * notification message to all the listeners.
    * @param e this <code>TableModelEvent</code> describes
    * where the rows were added.
    *                    If <code>null</code> it assumes
    * all the rows were newly added
    public void newRowsAdded(TableModelEvent e) {
    justifyRows(e.getFirstRow(), e.getLastRow() + 1);
    fireTableChanged(e);
    * Equivalent to <code>fireTableChanged</code>.
    * @param event the change event
    public void rowsRemoved(TableModelEvent event) {
    fireTableChanged(event);
    * Obsolete as of Java 2 platform v1.3. Please use <code>setRowCount</code> instead.
    * Sets the number of rows in the model. If the new size is greater
    * than the current size, new rows are added to the end of the model
    * If the new size is less than the current size, all
    * rows at index <code>rowCount</code> and greater are discarded. <p>
    * @param rowCount the new number of rows
    public void setNumRows(int rowCount) {
    int old = getRowCount();
    if (old == rowCount) {
    return;
    dataVector.setSize(rowCount);
    if (rowCount <= old) {
    fireTableRowsDeleted(rowCount, old-1);
    else {
    justifyRows(old, rowCount);
    fireTableRowsInserted(old, rowCount-1);
    * Sets the number of rows in the model. If the new size is greater
    * than the current size, new rows are added to the end of the model
    * If the new size is less than the current size, all
    * rows at index <code>rowCount</code> and greater are discarded. <p>
    public void setRowCount(int rowCount) {
    setNumRows(rowCount);
    * Adds a row to the end of the model. The new row will contain
    * <code>null</code> values unless <code>rowData</code> is specified.
    * Notification of the row being added will be generated.
    * @param rowData optional data of the row being added
    public void addRow(Vector rowData) {
    insertRow(getRowCount(), rowData);
    * Adds a row to the end of the model. The new row will contain
    * <code>null</code> values unless <code>rowData</code> is specified.
    * Notification of the row being added will be generated.
    * @param rowData optional data of the row being added
    public void addRow(Object[] rowData) {
    addRow(convertToVector(rowData));
    * Inserts a row at <code>row</code> in the model. The new row
    * will contain <code>null</code> values unless <code>rowData</code>
    * is specified. Notification of the row being added will be generated.
    * @param row the row index of the row to be inserted
    * @param rowData optional data of the row being added
    * @exception ArrayIndexOutOfBoundsException if the row was invalid
    public void insertRow(int row, Vector rowData) {
    dataVector.insertElementAt(rowData, row);
    justifyRows(row, row+1);
    fireTableRowsInserted(row, row);
    * Inserts a row at <code>row</code> in the model. The new row
    * will contain <code>null</code> values unless <code>rowData</code>
    * is specified. Notification of the row being added will be generated.
    * @param row the row index of the row to be inserted
    * @param rowData optional data of the row being added
    * @exception ArrayIndexOutOfBoundsException if the row was invalid
    public void insertRow(int row, Object[] rowData) {
    insertRow(row, convertToVector(rowData));
    private static int gcd(int i, int j) {
    return (j == 0) ? i : gcd(j, i%j);
    private static void rotate(Vector v, int a, int b, int shift) {
    int size = b - a;
    int r = size - shift;
    int g = gcd(size, r);
    for(int i = 0; i < g; i++) {
    int to = i;
    Object tmp = v.elementAt(a + to);
    for(int from = (to + r) % size; from != i; from = (to + r) % size) {
    v.setElementAt(v.elementAt(a + from), a + to);
    to = from;
    v.setElementAt(tmp, a + to);
    * Moves one or more rows from the inlcusive range <code>start</code> to
    * <code>end</code> to the <code>to</code> position in the model.
    * After the move, the row that was at index <code>start</code>
    * will be at index <code>to</code>.
    * This method will send a <code>tableChanged</code> notification
    * message to all the listeners. <p>
    * <pre>
    * Examples of moves:
    * <p>
    * 1. moveRow(1,3,5);
    * a|B|C|D|e|f|g|h|i|j|k - before
    * a|e|f|g|h|B|C|D|i|j|k - after
    * <p>
    * 2. moveRow(6,7,1);
    * a|b|c|d|e|f|G|H|i|j|k - before
    * a|G|H|b|c|d|e|f|i|j|k - after
    * <p>
    * </pre>
    * @param start the starting row index to be moved
    * @param end the ending row index to be moved
    * @param to the destination of the rows to be moved
    * @exception ArrayIndexOutOfBoundsException if any of the elements
    * would be moved out of the table's range
    public void moveRow(int start, int end, int to) {
    int shift = to - start;
    int first, last;
    if (shift < 0) {
    first = to;
    last = end;
    else {
    first = start;
    last = to + end - start;
    rotate(dataVector, first, last + 1, shift);
    fireTableRowsUpdated(first, last);
    * Removes the row at <code>row</code> from the model. Notification
    * of the row being removed will be sent to all the listeners.
    * @param row the row index of the row to be removed
    * @exception ArrayIndexOutOfBoundsException if the row was invalid
    public void removeRow(int row) {
    dataVector.removeElementAt(row);
    fireTableRowsDeleted(row, row);
    // Manipulating columns
    * Replaces the column identifiers in the model. If the number of
    * <code>newIdentifier</code>s is greater than the current number
    * of columns, new columns are added to the end of each row in the model.
    * If the number of <code>newIdentifier</code>s is less than the current
    * number of columns, all the extra columns at the end of a row are
    * discarded. <p>
    * @param newIdentifiers vector of column identifiers. If
    *                    <code>null</code>, set the model
    * to zero columns
    public void setColumnIdentifiers(Vector columnIdentifiers) {
    setDataVector(dataVector, columnIdentifiers);
    * Replaces the column identifiers in the model. If the number of
    * <code>newIdentifier</code>s is greater than the current number
    * of columns, new columns are added to the end of each row in the model.
    * If the number of <code>newIdentifier</code>s is less than the current
    * number of columns, all the extra columns at the end of a row are
    * discarded. <p>
    * @param newIdentifiers array of column identifiers.
    *                    If <code>null</code>, set
    * the model to zero columns
    public void setColumnIdentifiers(Object[] newIdentifiers) {
    setColumnIdentifiers(convertToVector(newIdentifiers));
    * Sets the number of columns in the model. If the new size is greater
    * than the current size, new columns are added to the end of the model
    * with <code>null</code> cell values.
    * If the new size is less than the current size, all columns at index
    * <code>columnCount</code> and greater are discarded.
    * @param columnCount the new number of columns in the model
    public void setColumnCount(int columnCount) {
    columnIdentifiers.setSize(columnCount);
    justifyRows(0, getRowCount());
    fireTableStructureChanged();
    * Adds a column to the model. The new column will have the
    * identifier <code>columnName</code>, which may be null. This method
    * will send a
    * <code>tableChanged</code> notification message to all the listeners.
    * This method is a cover for <code>addColumn(Object, Vector)</code> which
    * uses <code>null</code> as the data vector.
    * @param columnName the identifier of the column being added
    public void addColumn(Object columnName) {
    addColumn(columnName, (Vector)null);
    * Adds a column to the model. The new column will have the
    * identifier <code>columnName</code>, which may be null.
    * <code>columnData</code> is the
    * optional vector of data for the column. If it is <code>null</code>
    * the column is filled with <code>null</code> values. Otherwise,
    * the new data will be added to model starting with the first
    * element going to row 0, etc. This method will send a
    * <code>tableChanged</code> notification message to all the listeners.
    * @param columnName the identifier of the column being added
    * @param columnData optional data of the column being added
    public void addColumn(Object columnName, Vector columnData) {
    columnIdentifiers.addElement(columnName);
    if (columnData != null) {
    int columnSize = columnData.size();
    if (columnSize > getRowCount()) {
    dataVector.setSize(columnSize);
    justifyRows(0, getRowCount());
    int newColumn = getColumnCount() - 1;
    for(int i = 0; i < columnSize; i++) {
    Vector row = (Vector)dataVector.elementAt(i);
    row.setElementAt(columnData.elementAt(i), newColumn);
    else {
    justifyRows(0, getRowCount());
    fireTableStructureChanged();
    * Adds a column to the model. The new column will have the
    * identifier <code>columnName</code>. <code>columnData</code> is the
    * optional array of data for the column. If it is <code>null</code>
    * the column is filled with <code>null</code> values. Otherwise,
    * the new data will be added to model starting with the first
    * element going to row 0, etc. This method will send a
    * <code>tableChanged</code> notification message to all the listeners.
    public void addColumn(Object columnName, Object[] columnData) {
    addColumn(columnName, convertToVector(columnData));
    // Implementing the TableModel interface
    * Returns the number of rows in this data table.
    * @return the number of rows in the model
    public int getRowCount() {
    return dataVector.size();
    * Returns the number of columns in this data table.
    * @return the number of columns in the model
    public int getColumnCount() {
    return columnIdentifiers.size();
    * Returns the column name.
    * @return a name for this column using the string value of the
    * appropriate member in <code>columnIdentifiers</code>.
    * If <code>columnIdentifiers</code> does not have an entry
    * for this index, returns the default
    * name provided by the superclass
    public String getColumnName(int column) {
    Object id = null;
    // This test is to cover the case when
    // getColumnCount has been subclassed by mistake ...
    if (column < columnIdentifiers.size()) {
    id = columnIdentifiers.elementAt(column);
    return (id == null) ? getDefaultColumnName(column)
    : id.toString();
    * Returns true regardless of parameter values.
    * @param row the row whose value is to be queried
    * @param column the column whose value is to be queried
    * @return true
    public boolean isCellEditable(int row, int column) {
    return true;
    * Returns an attribute value for the cell at <code>row</code>
    * and <code>column</code>.
    * @param row the row whose value is to be queried
    * @param column the column whose value is to be queried
    * @return the value Object at the specified cell
    * @exception ArrayIndexOutOfBoundsException if an invalid row or
    * column was given
    public Object getValueAt(int row, int column) {
    Vector rowVector = (Vector)dataVector.elementAt(row);
    return rowVector.elementAt(column);
    * Sets the object value for the cell at <code>column</code> and
    * <code>row</code>. <code>aValue</code> is the new value. This method
    * will generate a <code>tableChanged</code> notification.
    * @param aValue the new value; this can be null
    * @param row the row whose value is to be changed
    * @param column the column whose value is to be changed
    * @exception ArrayIndexOutOfBoundsException if an invalid row or
    * column was given
    public void setValueAt(Object aValue, int row, int column) {
    Vector rowVector = (Vector)dataVector.elementAt(row);
    rowVector.setElementAt(aValue, column);
    fireTableCellUpdated(row, column);
    // Protected Methods
    * Returns a vector that contains the same objects as the array.
    * @param anArray the array to be converted
    * @return the new vector; if <code>anArray</code> is <code>null</code>,
    *                    returns <code>null</code>
    protected static Vector convertToVector(Object[] anArray) {
    if (anArray == null) {
    return null;
    Vector v = new Vector(anArray.length);
    for (int i=0; i < anArray.length; i++) {
    v.addElement(anArray[i]);
    return v;
    * Returns a vector of vectors that contains the same objects as the array.
    * @param anArray the double array to be converted
    * @return the new vector of vectors; if <code>anArray</code> is
    *                    <code>null</code>, returns <code>null</code>
    protected static Vector convertToVector(Object[][] anArray) {
    if (anArray == null) {
    return null;
    Vector v = new Vector(anArray.length);
    for (int i=0; i < anArray.length; i++) {
    v.addElement(convertToVector(anArray[i]));
    return v;

Maybe you are looking for