【前言】
这篇文章是接上一篇文章的。
【jtree】
jtree也是其中一个比较难明白的控件。
jtree也是数模分离的,需要自定义一个模型,然后再自定义显示方式---您也可以选择使用默认的显示方式,假如您可以忍受。
下面一段代码是对jtree进行初始化的:
public void _initTreeList(){
treeItemInfo _t_tableInfo= new treeItemInfo();
treeItemInfo _t_viewInfo=new treeItemInfo();
treeItemInfo _t_procInfo=new treeItemInfo();
_t_tableInfo.icon="table3.png";
_t_tableInfo.itemType="";
_t_tableInfo.name="数据表";
_t_viewInfo.icon="view_icon.png";
_t_viewInfo.itemType="";
_t_viewInfo.name="视图";
_t_procInfo.icon="database_active.png";
_t_procInfo.itemType="";
_t_procInfo.name="存储过程";
_treeRoot=new DefaultMutableTreeNode();
treeItemInfo t1=new treeItemInfo();
t1.icon="sitemap.png";
t1.name="详细信息";
t1.itemType="";
_treeRoot.setUserObject(t1);
_tableTreeNode=new DefaultMutableTreeNode(_t_tableInfo);
_viewTreeNode=new DefaultMutableTreeNode(_t_viewInfo);
_procTreeNode=new DefaultMutableTreeNode(_t_procInfo);
_treeRoot.add(_tableTreeNode);
_treeRoot.add(_viewTreeNode);
_treeRoot.add(_procTreeNode);
//_dbTree=new JTree(new DefaultMutableTreeNode[]{_tableTreeNode,_viewTreeNode,_procTreeNode});
_treeModel=new DefaultTreeModel(_treeRoot);
_dbTree.setModel(_treeModel);
_dbTree.setRootVisible(false);
//_dbTree.setPreferredSize(new Dimension(150, 25));
_dbTree.setCellRenderer(new dbDetailCell());
}
对应于每一个item的数据模型是:
/**
* 针对树形的数据模型
* */
class treeItemInfo{
public String name;
public String itemType;
public String icon;
public String toString(){
return this.name;
}
}
让我来解释一下:
首先,定义一个包含默认行为的_treeRoot 根节点(DefaultMutableTreeNode),然后将我们的treeiteminfo对象塞进去。
然后就是不停向treeRoot下面塞子节点了,我只是塞了三个节点(现在还没有子节点),分别是:“数据表”,“视图”,“存储过程”,我也定义了不同的icon,方便自定义渲染方式时候使用。
好了我们继续,下面是设置模型,setmodel
new DefaultTreeModel(_treeRoot);
为上面那个,继续,设置根节点不可见,设置渲染方式为自定义。
下面看看自定义的渲染方式:
/**
* 自定义tree的显示方式
* **/
class dbDetailCell implements TreeCellRenderer{
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
// TODO Auto-generated method stub
//DynamicUtilTreeNode dUtilTreeNode=(DynamicUtilTreeNode)value;
DefaultMutableTreeNode treeNode=(DefaultMutableTreeNode)value;
Object object=treeNode.getUserObject();
//setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
JPanel cPanel=new JPanel();
cPanel.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
if(leaf==false){
ImageIcon cOpened;
if(expanded==true){
cOpened=appConfig.getResourceIcon("arrow_state_blue_expanded.png", 16 , 16);
cPanel.add(new JLabel(cOpened));
}
else{
cOpened=appConfig.getResourceIcon("arrow_state_blue_right.png", 16 , 16);
cPanel.add(new JLabel(cOpened));
}
}
else{
/*
JLabel lb1=new JLabel();
lb1.setPreferredSize(new Dimension(16, 16));
cPanel.add(lb1);
*/
}
if(object instanceof treeItemInfo){
treeItemInfo tItemInfo=(treeItemInfo)object;
ImageIcon icon= appConfig.getResourceIcon(tItemInfo.icon, 20, 20);
JLabel l1=new JLabel(icon);
l1.setText(tItemInfo.name);
cPanel.add(l1);
}
else{
ImageIcon icon=appConfig.getResourceIcon("stock_unknown.png",20,20);
JLabel l1=new JLabel(icon);
l1.setText(value.toString());
cPanel.add(l1);
}
if (selected) {
cPanel.setBackground(Utils.str2color("#90e3f2"));
setBackground(Utils.str2color("#90e3f2"));
// setBorder(new )
//setForeground(Color.red);
//setBackground(tree.getse);
//setForeground(tree.getSelectionForeground());
}
else {
cPanel.setBackground(tree.getBackground());
cPanel.setForeground(tree.getForeground());
setBackground(tree.getBackground());
setForeground(tree.getForeground());
}
cPanel.setEnabled(tree.isEnabled());
cPanel.setFont(tree.getFont());
cPanel.setOpaque(true);
// cPanel.setPreferredSize(new Dimension(150, 40));
return cPanel;
}}
我自定义了一个jpanel,假如下面有节点的话,就在前面显示三角图标,然后再根据icon参数来设置第二个图标,最后设置文字。
渲染方式说完,现在看看如何动态添加删除节点及更新UI。
public void _BindTreeList(){
DBRecordInfo recordInfo= (DBRecordInfo) _dbList.getSelectedValue();
_tableTreeNode.removeAllChildren();
_viewTreeNode.removeAllChildren();
_procTreeNode.removeAllChildren();
CodeGen.DAL.ConnectionDAL cDal=new ConnectionDAL();
ConnectionModel cmodel=cDal.getRecord(recordInfo.recordId);
System.out.println(""+cmodel.title);
MSSQLProvider sProvider=new MSSQLProvider(cmodel.serverip , cmodel.account, cmodel.pwd, cmodel.database);
List<String> tableNames= sProvider.getTableNames();
List<String> procNamesList=sProvider.getProcNames();
//表
for (String name1 : tableNames) {
treeItemInfo tInfo=new treeItemInfo();
tInfo.icon="table16.png";
tInfo.itemType="table";
tInfo.name=name1;
_tableTreeNode.add(new DefaultMutableTreeNode(tInfo));
}
//存储过程
//表
for (String name1 : procNamesList) {
treeItemInfo tInfo=new treeItemInfo();
tInfo.icon="database.png";
tInfo.itemType="procedure";
tInfo.name=name1;
_procTreeNode.add(new DefaultMutableTreeNode(tInfo));
}
_dbTree.setModel(_treeModel);
_dbTree.updateUI();
}
值得主意的是:
最后的更新Ui是需要:setmodel一次,然后再updateUI。
【获取选中的记录】
DefaultMutableTreeNode treeNode=(DefaultMutableTreeNode) _dbTree.getLastSelectedPathComponent();
treeItemInfo myitemInfo= (treeItemInfo) treeNode.getUserObject();