how to store JTree data hierarchically in mysql database from netbeans. I am new to this topics so I need a program and tables you are using in database . for ex:

 Items |-shoes |-shirts |-half shirt |-sarees

when i click on add button it should add nodes to parent node(items node)such that the child node should be visible on tree and should be saved in database also

is that possible? am still new at java so will appreciate the help or direction

I wonder if you still need help on this?

Anyway, I will tell you some steps I have used to manipulate JTree

Every node in JTree is a DefaultMutableTreeNode object.

Use DefaultMutableTreeNode.add(Object userObject) function to add a node under a node hierachycally .

To get Object under the DefaultMutableTreeNode, call DefaultMutableTreeNode.getUserObject() funtion

Function Object.toString() is used to display text in JTree GUI, so you have to @Override toString() to get your expected string

About how to save in DB, I cannot tell everything here as it is long. You can refer to this link http://www.vogella.com/articles/MySQLJava/article.html

Whether this help you or not, I still hope to have some reputation point :) LOL

Comments
Good contribution - here are some rep. points!

+1 without

Function Object.toString() is used to display text in JTree GUI, so you have to @Override toString() to get your expected string

What's wrong with that? Looks like sound advice to me (given that the type of the nodes has not been specified)

Edited 3 Years Ago by JamesCherrill

+1 without

Function Object.toString() is used to display text in JTree GUI, so you have to @Override toString() to get your expected string

Is there any problem if I override that? really want to see your explanation :)

by ignoring - really want to see your explanation :),

  • toString isn't about good practicies(Java=>6),

  • why is there, any reason to distribute Object (already displayed in View) and with toString??

  • read Oracle tutorial Concepts: Editors and Renderers (valid for all JCOmponents that implementets renderers concept) about data types, why to restrict view to String, whats happend in the case that there is allowed TreeCellEditor, you 'll parse "1" to int, etc,

  • node doesn't required this value (I think that wrong habbits by default caused by copy-paste from oudated code depots),

  • different will be situations for path (prepared array), there required how is defined underlaying array (simple Vector or Vector<Object>),

_________________________________________________

  • sure could be usefull for preparing value ToolTip (a few bugs here about unacceptable delay, required dirty hack == my view)

  • or JTree based on 2D array that to display narrative/general description, but DefaultTreeModel stores/retruns association or ID

  • JTree isn't my cup of Java, (all renderers concept was changed in Java6) I love JTable/JComboBox/JTextComponents, there is my area

Edited 3 Years Ago by mKorbel

this sentence missing important points

  1. for Swing

  2. use WildCard instead of, because models in Swing to accepts general data types,

  3. use todays arrays (quite not possible for JTree, because there isn't AbstractTreeModel in API, nor to see good custom, then you are reduced to use only Vector<Object>)

_________________________

I'd have to search code about JTree, there you can to test that I'm tried to talking about

booking code example, nice, quite too old, outdated, from java2s.com :-)

edit - DefaultXxxRenderer is the class responsible for configuring the display all data types correct way, this Renderer is there presented without requirent to override ...,

.

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

public class JCheckBoxJTreeEditor {
private JFrame frame = new JFrame("CheckBox Tree");
    public JCheckBoxJTreeEditor() {        
        CheckBoxNode accessibilityOptions[] = {
            new CheckBoxNode(
            "Move system caret with focus/selection changes", false),
            new CheckBoxNode("Always expand alt text for images", true)};
        CheckBoxNode browsingOptions[] = {
            new CheckBoxNode("Notify when downloads complete", true),
            new CheckBoxNode("Disable script debugging", true),
            new CheckBoxNode("Use AutoComplete", true),
            new CheckBoxNode("Browse in a new process", false)};
        Vector accessVector = new NamedVector("Accessibility", accessibilityOptions);
        Vector browseVector = new NamedVector("Browsing", browsingOptions);
        Object rootNodes[] = {accessVector, browseVector};
        Vector rootVector = new NamedVector("Root", rootNodes);
        JTree tree = new JTree(rootVector);
        CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
        tree.setCellRenderer(renderer);
        tree.setCellEditor(new CheckBoxNodeEditor(tree));
        tree.setEditable(true);
        JScrollPane scrollPane = new JScrollPane(tree);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane);
        frame.setSize(400, 250);
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JCheckBoxJTreeEditor();
            }
        });
    }
}

class CheckBoxNodeRenderer implements TreeCellRenderer {

    private JCheckBox leafRenderer = new JCheckBox();
    private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
    private Color selectionBorderColor, selectionForeground, selectionBackground,
            textForeground, textBackground;

    protected JCheckBox getLeafRenderer() {
        return leafRenderer;
    }

    public CheckBoxNodeRenderer() {
        Font fontValue;
        fontValue = UIManager.getFont("Tree.font");
        if (fontValue != null) {
            leafRenderer.setFont(fontValue);
        }
        Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
        leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
        selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
        selectionForeground = UIManager.getColor("Tree.selectionForeground");
        selectionBackground = UIManager.getColor("Tree.selectionBackground");
        textForeground = UIManager.getColor("Tree.textForeground");
        textBackground = UIManager.getColor("Tree.textBackground");
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
            boolean expanded, boolean leaf, int row, boolean hasFocus) {

        Component returnValue;
        if (leaf) {
            String stringValue = tree.convertValueToText(value, selected, expanded,
                    leaf, row, false);
            leafRenderer.setText(stringValue);
            leafRenderer.setSelected(false);
            leafRenderer.setEnabled(tree.isEnabled());
            if (selected) {
                leafRenderer.setForeground(selectionForeground);
                leafRenderer.setBackground(selectionBackground);
            } else {
                leafRenderer.setForeground(textForeground);
                leafRenderer.setBackground(textBackground);
            }
            if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
                Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
                if (userObject instanceof CheckBoxNode) {
                    CheckBoxNode node = (CheckBoxNode) userObject;
                    leafRenderer.setText(node.getText());
                    leafRenderer.setSelected(node.isSelected());
                }
            }
            returnValue = leafRenderer;
        } else {
            returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value,
                    selected, expanded, leaf, row, hasFocus);
        }
        return returnValue;
    }
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

    private CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
    private ChangeEvent changeEvent = null;
    private JTree tree;

    public CheckBoxNodeEditor(JTree tree) {
        this.tree = tree;
    }

    @Override
    public Object getCellEditorValue() {
        JCheckBox checkbox = renderer.getLeafRenderer();
        CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText(), checkbox.isSelected());
        return checkBoxNode;
    }

    @Override
    public boolean isCellEditable(EventObject event) {
        boolean returnValue = false;
        if (event instanceof MouseEvent) {
            MouseEvent mouseEvent = (MouseEvent) event;
            TreePath path = tree.getPathForLocation(mouseEvent.getX(),
                    mouseEvent.getY());
            if (path != null) {
                Object node = path.getLastPathComponent();
                if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
                    DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
                    Object userObject = treeNode.getUserObject();
                    returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
                }
            }
        }
        return returnValue;
    }

    @Override
    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected,
            boolean expanded, boolean leaf, int row) {
        Component editor = renderer.getTreeCellRendererComponent(tree, value, true,
                expanded, leaf, row, true);
        ItemListener itemListener = new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent itemEvent) {
                if (stopCellEditing()) {
                    fireEditingStopped();
                }
            }
        };
        if (editor instanceof JCheckBox) {
            ((JCheckBox) editor).addItemListener(itemListener);
        }
        return editor;
    }
}

class CheckBoxNode {

    private String text;
    private boolean selected;

    public CheckBoxNode(String text, boolean selected) {
        this.text = text;
        this.selected = selected;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean newValue) {
        selected = newValue;
    }

    public String getText() {
        return text;
    }

    public void setText(String newValue) {
        text = newValue;
    }

    /*@Override
    public String toString() {
        return getClass().getName() + "[" + text + "/" + selected + "]";
    }*/
}

class NamedVector extends Vector {

    private String name;

    public NamedVector(String name) {
        this.name = name;
    }

    public NamedVector(String name, Object elements[]) {
        this.name = name;
        for (int i = 0, n = elements.length; i < n; i++) {
            add(elements[i]);
        }
    }

    @Override
    public String toString() {
        return "[" + name + "]";
    }
}

Edited 3 Years Ago by mKorbel

Thanks for the clarificatio mKorbel.

There's no doubt that is the way to go for complete control or for difficult cases, but personally I would be happy to live with the simple default behaviour of displaying the object's toString() in 95% of cases.

@JamesCherrill

  • you are welcome

  • but I'm think that this is right way, or am I wrong ??? (enum can be replaced with all of todays arrays or JDBC), this is my view about standard renderings concept, then there no required any Abstract Whatever

  • note for ToolTip is required to test for if is leaf

.

import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

public class EnumWithStandardJTree {

    private JFrame frame;
    private JTree tree;

    public EnumWithStandardJTree() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Days");
        for (DaysOfTheWeek dotw : DaysOfTheWeek.values()) {
            root.add(new DefaultMutableTreeNode(dotw));
        }
        final DefaultTreeModel model = new DefaultTreeModel(root);
        tree = new JTree(model);
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);
        ToolTipManager.sharedInstance().registerComponent(tree);
        tree.setCellRenderer(new MyTreeCellRenderer());
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(150, 100);
        frame.add(new JScrollPane(tree));
        frame.pack();
        frame.setVisible(true);
    }

    public enum DaysOfTheWeek {

        MONDAY("MondayXxx", "MON", "First day of the work week."), TUESDAY("Tuesday", "TUE", "Second day of the work week");
        // etc ...
        private final String fullName;
        private final String abbrvName;
        private final String description;

        private DaysOfTheWeek(String fullName, String abbrvName, String description) {
            this.fullName = fullName;
            this.abbrvName = abbrvName;
            this.description = description;
        }

        public String getFullName() {
            return fullName;
        }

        public String getAbbrvName() {
            return abbrvName;
        }

        public String getDescription() {
            return description;
        }
    }

    public class MyTreeCellRenderer extends DefaultTreeCellRenderer {

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            Component cell = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            if (value instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode) value).getUserObject() instanceof DaysOfTheWeek) {
                ((JLabel) cell).setText(((DaysOfTheWeek) ((DefaultMutableTreeNode) value).getUserObject()).getFullName());
                ((JLabel) cell).setToolTipText("is selected -  " + selected + " ,  " + "is expanded -  " + expanded + " ,  "
                        + "is leaf -  " + leaf + " ,  FullName -  " + ((DaysOfTheWeek) ((DefaultMutableTreeNode) value).getUserObject()).getFullName()
                        + " , AbbrvName -  " + ((DaysOfTheWeek) ((DefaultMutableTreeNode) value).getUserObject()).getAbbrvName()
                        + " , Description -  " + ((DaysOfTheWeek) ((DefaultMutableTreeNode) value).getUserObject()).getDescription());
            }
            return cell;
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new EnumWithStandardJTree();
            }
        });
    }
}

mKorbel - that code makes complete sense to me. You want to display something other than the default toString() in the cells, and you want to set a custom tooltip on each cell, so a small custom tree cell renderer is how I would do it also.
But now I think we should go back to beginner-level code, in which case I think Tu Dinh's advice (make sure your node objects have a sensible toString()) is good advice to give a beginner.

This article has been dead for over six months. Start a new discussion instead.