树这东西给用户的感觉极为方便但给程序员带来很大的麻烦它是swing中最麻烦的控件之一树要弄的好非常麻烦图标的美化层次的划分各种事件的处理……对于初学者来说就不要太讲究样式下面举个粗糙的例子eg
public class SimpleJTree
{
JFrame jf = new JFrame(简单树)
JTree tree;
//定义几个初始节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode(中国)
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode(广东)
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode(广西)
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode(佛山)
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode(汕头)
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode(桂林)
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode(南宁)
public void init()
{
//通过add方法建立树节点之间的父子关系
guangdongadd(foshan)
guangdongadd(shantou)
guangxiadd(guilin)
guangxiadd(nanning)
rootadd(guangdong)
rootadd(guangxi)
//以根节点创建树
tree = new JTree(root)
//默认连线
//treeputClientProperty(JTreelineStyle Angeled)
//没有连线
treeputClientProperty(JTreelineStyle None)
//水平分隔线
//treeputClientProperty(JTreelineStyle Horizontal)
//设置是否显示根节点的展开/折叠图标默认是false
treesetShowsRootHandles(true)
//设置节点是否可见默认是true
treesetRootVisible(true)
jfadd(new JScrollPane(tree))
jfpack()
jfsetDefaultCloseOperation(JFrameEXIT_ON_CLOSE)
jfsetVisible(true)
}
public static void main(String[] args)
{
new SimpleJTree()init()
}
}
拖动编辑树节点也是树的基本功能下面就在上面例子的基础上加上这些功能eg
public class EditJTree
{
JFrame jf;
JTree tree;
//上面JTree对象对应的model
DefaultTreeModel model;
//定义几个初始节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode(中国)
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode(广东)
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode(广西)
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode(佛山)
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode(汕头)
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode(桂林)
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode(南宁)
//定义需要被拖动的TreePath
TreePath movePath;
JButton addSiblingButton = new JButton(添加兄弟节点)
JButton addChildButton = new JButton(添加子节点)
JButton deleteButton = new JButton(删除节点)
JButton editButton = new JButton(编辑当前节点)
public void init()
{
guangdongadd(foshan)
guangdongadd(shantou)
guangxiadd(guilin)
guangxiadd(nanning)
rootadd(guangdong)
rootadd(guangxi)
jf = new JFrame(树)
tree = new JTree(root)
//获取JTree对应的TreeModel对象
model = (DefaultTreeModel)treegetModel()
//设置JTree可编辑
treesetEditable(true)
MouseListener ml = new MouseAdapter()
{
//按下鼠标时候获得被拖动的节点
public void mousePressed(MouseEvent e)
{
//如果需要唯一确定某个节点必须通过TreePath来获取
TreePath tp = treegetPathForLocation(egetX() egetY())
if (tp != null)
{
movePath = tp;
}
}
//鼠标松开时获得需要拖到哪个父节点
public void mouseReleased(MouseEvent e)
{
//根据鼠标松开时的TreePath来获取TreePath
TreePath tp = treegetPathForLocation(egetX() egetY())
if (tp != null && movePath != null)
{
//阻止向子节点拖动
if (movePathisDescendant(tp) && movePath != tp)
{
JOptionPaneshowMessageDialog(jf 目标节点是被移动节点的子节点无法移动!
非法操作 JOptionPaneERROR_MESSAGE )
return;
}
//既不是向子节点移动而且鼠标按下松开的不是同一个节点
else if (movePath != tp)
{
Systemoutprintln(tpgetLastPathComponent())
//add方法可以先将原节点从原父节点删除再添加到新父节点中
((DefaultMutableTreeNode)tpgetLastPathComponent())add(
(DefaultMutableTreeNode)movePathgetLastPathComponent())
movePath = null;
treeupdateUI()
}
}
}
};
treeaddMouseListener(ml)
JPanel panel = new JPanel()
addSiblingButtonaddActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//获取选中节点
DefaultMutableTreeNode selectedNode
= (DefaultMutableTreeNode) treegetLastSelectedPathComponent()
//如果节点为空直接返回
if (selectedNode == null) return;
//获取该选中节点的父节点
DefaultMutableTreeNode parent
= (DefaultMutableTreeNode)selectedNodegetParent()
//如果父节点为空直接返回
if (parent == null) return;
//创建一个新节点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(新节点)
//获取选中节点的选中索引
int selectedIndex = parentgetIndex(selectedNode)
//在选中位置插入新节点
modelinsertNodeInto(newNode parent selectedIndex + )
//下面代码实现显示新节点(自动展开父节点)
//获取从根节点到新节点的所有节点
TreeNode[] nodes = modelgetPathToRoot(newNode)
//使用指定的节点数组来创建TreePath
TreePath path = new TreePath(nodes)
//显示指定TreePath
treescrollPathToVisible(path)
}
})
paneladd(addSiblingButton)
addChildButtonaddActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//获取选中节点
DefaultMutableTreeNode selectedNode
= (DefaultMutableTreeNode) treegetLastSelectedPathComponent()
//如果节点为空直接返回
if (selectedNode == null) return;
//创建一个新节点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(新节点)
//直接通过model来添加新节点则无需通过调用JTree的updateUI方法
//modelinsertNodeInto(newNode selectedNode selectedNodegetChildCount())
//直接通过节点添加新节点则需要调用tree的updateUI方法
selectedNodeadd(newNode)
//下面代码实现显示新节点(自动展开父节点)
TreeNode[] nodes = modelgetPathToRoot(newNode)
TreePath path = new TreePath(nodes)
treescrollPathToVisible(path)
treeupdateUI()
}
})
paneladd(addChildButton)
deleteButtonaddActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
DefaultMutableTreeNode selectedNode
= (DefaultMutableTreeNode) treegetLastSelectedPathComponent()
if (selectedNode != null && selectedNodegetParent() != null)
{
//删除指定节点
modelremoveNodeFromParent(selectedNode)
}
}
})
paneladd(deleteButton)
editButtonaddActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
TreePath selectedPath = treegetSelectionPath()
if (selectedPath != null)
{
//编辑选中节点
treestartEditingAtPath(selectedPath)
}
}
})
paneladd(editButton)
jfadd(new JScrollPane(tree))
jfadd(panel BorderLayoutSOUTH)
jfpack()
jfsetDefaultCloseOperation(JFrameEXIT_ON_CLOSE)
jfsetVisible(true)
}
public static void main(String[] args)
{
new EditJTree()init()
}
}
最后讲下如何修饰tree的图标主要是通过拓展TreeCellRenderer来实现eg
public class ExtendsDefaultTreeCellRenderer
{
JFrame jf = new JFrame(根据节点类型定义图标)
JTree tree;
//定义几个初始节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeROOT 数据库导航))
DefaultMutableTreeNode salaryDb = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeDATABASE 公司工资数据库))
DefaultMutableTreeNode customerDb = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeDATABASE 公司客户数据库))
//定义salaryDb的两个子节点
DefaultMutableTreeNode employee = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeTABLE 员工表))
DefaultMutableTreeNode attend = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeTABLE 考勤表))
//定义customerDb的一个子节点
DefaultMutableTreeNode contact = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeTABLE 联系方式表))
//定义employee的三个子节点
DefaultMutableTreeNode id = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeINDEX 员工ID))
DefaultMutableTreeNode name = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeCOLUMN 姓名))
DefaultMutableTreeNode gender = new DefaultMutableTreeNode(
new NodeData(DBObjectTypeCOLUMN 性别))
public void init()throws Exception
{
//通过add方法建立树节点之间的父子关系
rootadd(salaryDb)
rootadd(customerDb)
salaryDbadd(employee)
salaryDbadd(attend)
customerDbadd(contact)
employeeadd(id)
employeeadd(name)
employeeadd(gender)
//以根节点创建树
tree = new JTree(root)
//设置该JTree使用自定义的节点绘制器
treesetCellRenderer(new MyRenderer())
//设置是否显示根节点的展开/折叠图标默认是false
treesetShowsRootHandles(true)
//设置节点是否可见默认是true
treesetRootVisible(true)
//设置使用Windows风格外观
UIManagersetLookAndFeel(comsunjavaswingplafwindowsWindowsLookAndFeel)
//更新JTree的UI外观
SwingUtilitiesupdateComponentTreeUI(tree)
jfadd(new JScrollPane(tree))
jfpack()
jfsetDefaultCloseOperation(JFrameEXIT_ON_CLOSE)
jfsetVisible(true)
}
public static void main(String[] args) throws Exception
{
new ExtendsDefaultTreeCellRenderer()init()
}
}
//定义一个NodeData类用于封装节点数据
class NodeData
{
public int nodeType;
public String nodeData;
public NodeData(int nodeType String nodeData)
{
thisnodeType = nodeType;
thisnodeData = nodeData;
}
public String toString()
{
return nodeData;
}
}
//定义一个接口该接口里包含数据库对象类型的常量
interface DBObjectType
{
int ROOT = ;
int DATABASE = ;
int TABLE = ;
int COLUMN = ;
int INDEX = ;
}
class MyRenderer extends DefaultTreeCellRenderer
{
//初始化个图标
ImageIcon rootIcon = new ImageIcon(icon/rootgif)
ImageIcon databaseIcon = new ImageIcon(icon/databasegif)
ImageIcon tableIcon = new ImageIcon(icon/tablegif)
ImageIcon columnIcon = new ImageIcon(icon/columngif)
ImageIcon indexIcon = new ImageIcon(icon/indexgif)
public Component getTreeCellRendererComponent(JTree tree Object value
boolean sel boolean expanded boolean leaf int row boolean hasFocus)
{
//执行父类默认的节点绘制操作
supergetTreeCellRendererComponent(tree value sel expanded leaf row hasFocus)
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
NodeData data = (NodeData)nodegetUserObject()
//根据数据节点里的nodeType数据决定节点图标
ImageIcon icon = null;
switch(datanodeType)
{
case DBObjectTypeROOT:
icon = rootIcon;
break;
case DBObjectTypeDATABASE:
icon = databaseIcon;
break;
case DBObjectTypeTABLE:
icon = tableIcon;
break;
case DBObjectTypeCOLUMN:
icon = columnIcon;
break;
case DBObjectTypeINDEX:
icon = indexIcon;
break;
}
//改变图标
thissetIcon(icon)
return this;
}
}