- 浏览: 11154 次
最新评论
jtree02
在总结了数人的博客和自己的探索之下,终于实现,其中主要就是TreeCellRenderer这个接口的实现,
下面代码
用的Jcreator,需要在项目文件了加入image文件夹和图片文件。
Test.java
package myprojects.test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
public class Test extends JFrame implements TreeSelectionListener{
JButton addB, deleteB,addBS,addT;
JTree tree;
DefaultTreeModel treeModel;
DefaultMutableTreeNode leadSelection;
ImageIcon test;
JLabel label;
public Test() {
super("Tree Event Demo");
setSize(600,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
tree.setExpandsSelectedPaths(true);
tree.setEditable(true);
getContentPane( ).add(new JScrollPane(tree), BorderLayout.CENTER);
tree.addTreeSelectionListener(this);
MyTreeCellRenderer myCellRenderer = new MyTreeCellRenderer();
//设置叶子节点的图标
tree.setCellRenderer(myCellRenderer);
//按钮
addB = new JButton("Add a Child node");
addBS=new JButton("Add a Sibling node");
deleteB = new JButton("Delete a node");
addT=new JButton("Test");
JPanel buttonP = new JPanel( );
buttonP.add(addB);
buttonP.add(addBS);
buttonP.add(deleteB);
buttonP.add(addT);
getContentPane( ).add(buttonP, BorderLayout.SOUTH);
addB.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
if (leadSelection != null&&nodeName!=null) {
leadSelection.add(new DefaultMutableTreeNode(nodeName));
((DefaultTreeModel)tree.getModel( )).reload(leadSelection);
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node and input the nodename");
}
}
});
addBS.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
if (leadSelection != null&&leadSelection.getParent()!=null&&nodeName!=null) {
((DefaultMutableTreeNode)leadSelection.getParent()).add(new DefaultMutableTreeNode(nodeName));//该步骤改为先寻找parent然后加node
((DefaultTreeModel)tree.getModel( )).reload(leadSelection.getParent());
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node, input the nodename and insure the node is not the root");
}
}
});
deleteB.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
if (leadSelection != null) {
DefaultMutableTreeNode parent =
(DefaultMutableTreeNode) leadSelection.getParent( );
if (parent == null) {
JOptionPane.showMessageDialog(Test.this, "Can't delete root");
}
else {
parent.remove(leadSelection);
leadSelection = null;
((DefaultTreeModel)tree.getModel( )).reload(parent);
}
}
else {
JOptionPane.showMessageDialog(Test.this, "No Selection...");
}
}
});
addT.addActionListener(
new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
test=new ImageIcon("../image/class.PNG");
label=new JLabel();
label.setIcon(test);
label.setText(nodeName);
if (leadSelection != null&&nodeName!=null) {
leadSelection.add(new DefaultMutableTreeNode(label));
((DefaultTreeModel)tree.getModel( )).reload(leadSelection);
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node and input the nodename");
}
}
});
}
public void valueChanged(TreeSelectionEvent e) {
TreePath leadPath = e.getNewLeadSelectionPath( );
if (leadPath != null) {
leadSelection = (DefaultMutableTreeNode)leadPath.getLastPathComponent( );
}
}
public static void main(String args[]) {
//System.out.println("Starting Test...");
//Test mainFrame = new Test();
//mainFrame.setSize(400, 400);
//mainFrame.setTitle("Test");
//mainFrame.setVisible(true);
Test te = new Test( );
te.setVisible(true);
}
}
Ok,另外MyTreeCellRenderer类的代码如下MyTreeCellRenderer.java
package myprojects.test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row, boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
JLabel label = (JLabel)obj;
DefaultTreeCellRenderer tempCellRenderer = new DefaultTreeCellRenderer();
tempCellRenderer.setLeafIcon(label.getIcon());
return tempCellRenderer.getTreeCellRendererComponent(tree,label.getText(),selected,expanded,true,row,hasFocus);
}
return super.getTreeCellRendererComponent(tree,value,
selected,expanded,leaf,row,hasFocus);
}
}
整个类是gool实现的,我写了个Test用了一下而已,不过作为一个整体,理解起来比较容易。
http://blog.sina.com.cn/s/blog_47e3d38d01000716.html
JTree及JTable的一些“剖析”
1.JTree的显示
最近因为要使用JTree及JTable做一些图片的显示及操作,因为以前都是肤浅的用过,所以并为深入。现在遇到的问题如在JTree里面如何单独显示每个cell的图片,比如在JTable里面如何画出别的控件等!
在网寻求帮助,但效果并不是很好,所以自行研究了一翻,虽然并未象那些资深人士一般做出精辟的真正的剖析,但我相信我的“一些剖析”还是能帮助到一些正在,或者正要使用这两大swing控件的人。
首先来说下JTree,单就显示父节点,子节点的图片是比较简单的,我们用DefaultTreeCellRenderer这个类就能实现。调用setOpenIcon(), setCloseIcon(), setLeafIcon()三个方法,分别实现父节点打开的图片,父节点关闭的图片,以及叶节点的显示图片。然后在相应需要显示的JTree里面调用setCellRenderer(TreeCellRenderer x)即可。至于别的字体,背景色等都在DefaultTreeCellRenderer里面相应的set方面里面,大家可通过JDK自行寻找。
这上面说的方法是极为简单的实现图片的方法,一般也就足够了,但是如果你想在节点里面实现自己的控件或者每个cell都需要拥有自己图片如何操作呢?使用DefaultTreeCellRenderer是不能满足我们的要求的,至少我是没找到简便的方法!因为使用JTree的setCellRenderer(TreeCellRenderer x) 方法后,是使所有cell都使用实现了TreeCellRenderer接口的类,这里我们用的是DefaultTreeCellRenderer来进行显示的.
那么我们先来看看DefaultTreeCellRenderer是如何实现TreeCellRenderer这个接口的:
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel,
boolean expanded,
boolean leaf, int row,
boolean hasFocus) {
String stringValue = tree.convertValueToText(value, sel,
expanded, leaf, row, hasFocus);
this.tree = tree;
this.hasFocus = hasFocus;
setText(stringValue);
if(sel)
setForeground(getTextSelectionColor());
else
setForeground(getTextNonSelectionColor());
// There needs to be a way to specify disabled icons.
if (!tree.isEnabled()) {
setEnabled(false);
if (leaf) {
setDisabledIcon(getLeafIcon());
} else if (expanded) {
setDisabledIcon(getOpenIcon());
} else {
setDisabledIcon(getClosedIcon());
}
}
else {
setEnabled(true);
if (leaf) {
setIcon(getLeafIcon());
} else if (expanded) {
setIcon(getOpenIcon());
} else {
setIcon(getClosedIcon());
}
}
setComponentOrientation(tree.getComponentOrientation());
selected = sel;
return this;
}
以上的橙色部分就是DefaultTreeCellRenderer为节点设置图片的地方,这个类本就是继承JLabel并且实现的TreeCellRenderer接口,所以以上蓝色部分是把传来的value加到Label的文字部分,并且return的是this,也就是标签了。
至于getLeafIcon(),getClosedIcon(),getOpenIcon(),对应得到的值就是我们调用对应的set方法给的值.
了解到这些你是否有想法了?对了,那就是我们自己实现TreeCellRenderer接口。那么我们就能显示自己需要的图片及控件了。但是前提还有个问题需要我们了解,那就是我们的节点—DefaultMutableTreeNode;构造一个节点时可以传任意的一个类,因为构造函数是用Object类来接收的:public DefaultMutableTreeNode(Object userObject) 。所以我们可以直接传入需要的东西,比如我们需要图片加文字,就直接传入Label即可,然后让我们自己实现了TreeCellRenderer的类实现就行了。而不必担心象DefaultTreeCellRenderer一样,标签的Text来源于Node构造时传入的对象的.toString(),而图片来源于事先set的ImageIcon. 这样,我们的JTree就可以多样化了,想要什么东西就传入什么东西,而不必担心他显示不出来。
而我们即将实现的接口public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) ;
着色的形参value是个节点对象,那么这里就需要用到getUserObject()方法来获取我们构造DefaultMutableTreeNode时传入的对象,运用RTTI来识别类型,如果是我们希望的类型就做出处理,否则就象DefaultTreeCellRenderer一样,用默认的ImageIcon加上value.toString来显示.。哦,对了!节点的toString()是重写过的,return getUserObject().toString;这里解释一下一面误会!
一切准备工作搞定,以下就是实现接口的细节了,代码如下:
class MyTreeCellRenderer implements TreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row,boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
return (JLabel)obj;
}
if(obj instanceof JCheckBox) {
return (JCheckBox)obj;
}
if(obj instanceof JRadioButton) {
return (JRadioButton)obj;
}
label.setText(value.toString());
if (leaf)
label.setIcon(leafIcon);
else if (expanded)
label.setIcon(openIcon);
else
label.setIcon(closeIcon);
return label;
}
public void setOpenIcon (ImageIcon image) {
openIcon = image;
}
public ImageIcon getOpenIcon () {
return openIcon;
}
public void setClosedIcon(ImageIcon image) {
closeIcon = image;
}
public ImageIcon getClosedIcon() {
return closeIcon;
}
public void setLeafIcon(ImageIcon image) {
leafIcon = image;
}
public ImageIcon getLeafIcon() {
return leafIcon;
}
private JLabel label = new JLabel();
private boolean flag = true;
private ImageIcon openIcon = new ImageIcon(".\\src\\image\\open.png");
private ImageIcon closeIcon = new ImageIcon(".\\src\\image\\close.png");
private ImageIcon leafIcon = new ImageIcon(".\\src\\image\\buddy.gif");
}
这个类把TreeCellRenderer接口实现了,注意上面着色的部分,我们把自己需要用到的组件直接返回,这样就可以在给构造node的时候直接传过去了。至于一般的图文结合或者是不能识别的类型处理方式和DefaultTreeCellRenderer一样。但是最终实现是实现了,问题也有不少,比如我们选中node后颜色不会变化,让我们无法区分是否选择等等一系列问题,最重要的是如果添加的组件,如何进行组件的操作等!以下给出了解决方案!
其实实现UI细节比较烦琐,因为你传入的控件都有自己的paint()方法,这就说明你如果要实现细节那么必然要重写这些paint()方法来配合JTree显示,既然要重写这些方法那么你所传入的控件至少是从实现了paint()重写方法的类实例化而来,这就是烦琐之处。如果大家有兴趣可以参考DefaultTreeCellRenderer类来自己写这些方法!
我想也可以通过传来的控件一个个set属性也能达到目的,但是这效率就不是很高了。唯一方便的就不用从某个控件派生而来,把共有属性都写到一堆,也不唯是个好办法。
当然DefaultTreeCellRenderer类是继承的JLabel,而我当下要用的无非就是实现每个cell有自己图片而已,所以偷了一个懒,以下是我实现部分的源码。
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row, boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
JLabel label = (JLabel)obj;
DefaultTreeCellRenderer tempCellRenderer = new DefaultTreeCellRenderer();
tempCellRenderer.setLeafIcon(label.getIcon());
return tempCellRenderer.getTreeCellRendererComponent(tree,label.getText(),
selected,expanded,true,row,hasFocus);
}
return super.getTreeCellRendererComponent(tree,value,
selected,expanded,leaf,row,hasFocus);
}
}
目的只有一个,让实现了UI细节部分的DefaultTreeCellRenderer重用而已。这样,能实现都实现了,不能实现的也实现了,标签需要什么属性直接用tempCellRenderer的set方法即可!!虽然只有JLabel而已!呵呵。
至于如何操作控件我会放到JTable操作里面一起讲,因为他们都是实现了CellEditor接口,虽然一个是从TreeCellEditor派生,一个是从TableCellEditor派生!
下面代码
用的Jcreator,需要在项目文件了加入image文件夹和图片文件。
Test.java
package myprojects.test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
public class Test extends JFrame implements TreeSelectionListener{
JButton addB, deleteB,addBS,addT;
JTree tree;
DefaultTreeModel treeModel;
DefaultMutableTreeNode leadSelection;
ImageIcon test;
JLabel label;
public Test() {
super("Tree Event Demo");
setSize(600,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
tree.setExpandsSelectedPaths(true);
tree.setEditable(true);
getContentPane( ).add(new JScrollPane(tree), BorderLayout.CENTER);
tree.addTreeSelectionListener(this);
MyTreeCellRenderer myCellRenderer = new MyTreeCellRenderer();
//设置叶子节点的图标
tree.setCellRenderer(myCellRenderer);
//按钮
addB = new JButton("Add a Child node");
addBS=new JButton("Add a Sibling node");
deleteB = new JButton("Delete a node");
addT=new JButton("Test");
JPanel buttonP = new JPanel( );
buttonP.add(addB);
buttonP.add(addBS);
buttonP.add(deleteB);
buttonP.add(addT);
getContentPane( ).add(buttonP, BorderLayout.SOUTH);
addB.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
if (leadSelection != null&&nodeName!=null) {
leadSelection.add(new DefaultMutableTreeNode(nodeName));
((DefaultTreeModel)tree.getModel( )).reload(leadSelection);
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node and input the nodename");
}
}
});
addBS.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
if (leadSelection != null&&leadSelection.getParent()!=null&&nodeName!=null) {
((DefaultMutableTreeNode)leadSelection.getParent()).add(new DefaultMutableTreeNode(nodeName));//该步骤改为先寻找parent然后加node
((DefaultTreeModel)tree.getModel( )).reload(leadSelection.getParent());
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node, input the nodename and insure the node is not the root");
}
}
});
deleteB.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
if (leadSelection != null) {
DefaultMutableTreeNode parent =
(DefaultMutableTreeNode) leadSelection.getParent( );
if (parent == null) {
JOptionPane.showMessageDialog(Test.this, "Can't delete root");
}
else {
parent.remove(leadSelection);
leadSelection = null;
((DefaultTreeModel)tree.getModel( )).reload(parent);
}
}
else {
JOptionPane.showMessageDialog(Test.this, "No Selection...");
}
}
});
addT.addActionListener(
new ActionListener( ) {
public void actionPerformed(ActionEvent ae) {
String nodeName = JOptionPane.showInputDialog("New node name:");
test=new ImageIcon("../image/class.PNG");
label=new JLabel();
label.setIcon(test);
label.setText(nodeName);
if (leadSelection != null&&nodeName!=null) {
leadSelection.add(new DefaultMutableTreeNode(label));
((DefaultTreeModel)tree.getModel( )).reload(leadSelection);
}
else {
JOptionPane.showMessageDialog(Test.this, "Error! Please select a node and input the nodename");
}
}
});
}
public void valueChanged(TreeSelectionEvent e) {
TreePath leadPath = e.getNewLeadSelectionPath( );
if (leadPath != null) {
leadSelection = (DefaultMutableTreeNode)leadPath.getLastPathComponent( );
}
}
public static void main(String args[]) {
//System.out.println("Starting Test...");
//Test mainFrame = new Test();
//mainFrame.setSize(400, 400);
//mainFrame.setTitle("Test");
//mainFrame.setVisible(true);
Test te = new Test( );
te.setVisible(true);
}
}
Ok,另外MyTreeCellRenderer类的代码如下MyTreeCellRenderer.java
package myprojects.test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row, boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
JLabel label = (JLabel)obj;
DefaultTreeCellRenderer tempCellRenderer = new DefaultTreeCellRenderer();
tempCellRenderer.setLeafIcon(label.getIcon());
return tempCellRenderer.getTreeCellRendererComponent(tree,label.getText(),selected,expanded,true,row,hasFocus);
}
return super.getTreeCellRendererComponent(tree,value,
selected,expanded,leaf,row,hasFocus);
}
}
整个类是gool实现的,我写了个Test用了一下而已,不过作为一个整体,理解起来比较容易。
http://blog.sina.com.cn/s/blog_47e3d38d01000716.html
JTree及JTable的一些“剖析”
1.JTree的显示
最近因为要使用JTree及JTable做一些图片的显示及操作,因为以前都是肤浅的用过,所以并为深入。现在遇到的问题如在JTree里面如何单独显示每个cell的图片,比如在JTable里面如何画出别的控件等!
在网寻求帮助,但效果并不是很好,所以自行研究了一翻,虽然并未象那些资深人士一般做出精辟的真正的剖析,但我相信我的“一些剖析”还是能帮助到一些正在,或者正要使用这两大swing控件的人。
首先来说下JTree,单就显示父节点,子节点的图片是比较简单的,我们用DefaultTreeCellRenderer这个类就能实现。调用setOpenIcon(), setCloseIcon(), setLeafIcon()三个方法,分别实现父节点打开的图片,父节点关闭的图片,以及叶节点的显示图片。然后在相应需要显示的JTree里面调用setCellRenderer(TreeCellRenderer x)即可。至于别的字体,背景色等都在DefaultTreeCellRenderer里面相应的set方面里面,大家可通过JDK自行寻找。
这上面说的方法是极为简单的实现图片的方法,一般也就足够了,但是如果你想在节点里面实现自己的控件或者每个cell都需要拥有自己图片如何操作呢?使用DefaultTreeCellRenderer是不能满足我们的要求的,至少我是没找到简便的方法!因为使用JTree的setCellRenderer(TreeCellRenderer x) 方法后,是使所有cell都使用实现了TreeCellRenderer接口的类,这里我们用的是DefaultTreeCellRenderer来进行显示的.
那么我们先来看看DefaultTreeCellRenderer是如何实现TreeCellRenderer这个接口的:
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel,
boolean expanded,
boolean leaf, int row,
boolean hasFocus) {
String stringValue = tree.convertValueToText(value, sel,
expanded, leaf, row, hasFocus);
this.tree = tree;
this.hasFocus = hasFocus;
setText(stringValue);
if(sel)
setForeground(getTextSelectionColor());
else
setForeground(getTextNonSelectionColor());
// There needs to be a way to specify disabled icons.
if (!tree.isEnabled()) {
setEnabled(false);
if (leaf) {
setDisabledIcon(getLeafIcon());
} else if (expanded) {
setDisabledIcon(getOpenIcon());
} else {
setDisabledIcon(getClosedIcon());
}
}
else {
setEnabled(true);
if (leaf) {
setIcon(getLeafIcon());
} else if (expanded) {
setIcon(getOpenIcon());
} else {
setIcon(getClosedIcon());
}
}
setComponentOrientation(tree.getComponentOrientation());
selected = sel;
return this;
}
以上的橙色部分就是DefaultTreeCellRenderer为节点设置图片的地方,这个类本就是继承JLabel并且实现的TreeCellRenderer接口,所以以上蓝色部分是把传来的value加到Label的文字部分,并且return的是this,也就是标签了。
至于getLeafIcon(),getClosedIcon(),getOpenIcon(),对应得到的值就是我们调用对应的set方法给的值.
了解到这些你是否有想法了?对了,那就是我们自己实现TreeCellRenderer接口。那么我们就能显示自己需要的图片及控件了。但是前提还有个问题需要我们了解,那就是我们的节点—DefaultMutableTreeNode;构造一个节点时可以传任意的一个类,因为构造函数是用Object类来接收的:public DefaultMutableTreeNode(Object userObject) 。所以我们可以直接传入需要的东西,比如我们需要图片加文字,就直接传入Label即可,然后让我们自己实现了TreeCellRenderer的类实现就行了。而不必担心象DefaultTreeCellRenderer一样,标签的Text来源于Node构造时传入的对象的.toString(),而图片来源于事先set的ImageIcon. 这样,我们的JTree就可以多样化了,想要什么东西就传入什么东西,而不必担心他显示不出来。
而我们即将实现的接口public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) ;
着色的形参value是个节点对象,那么这里就需要用到getUserObject()方法来获取我们构造DefaultMutableTreeNode时传入的对象,运用RTTI来识别类型,如果是我们希望的类型就做出处理,否则就象DefaultTreeCellRenderer一样,用默认的ImageIcon加上value.toString来显示.。哦,对了!节点的toString()是重写过的,return getUserObject().toString;这里解释一下一面误会!
一切准备工作搞定,以下就是实现接口的细节了,代码如下:
class MyTreeCellRenderer implements TreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row,boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
return (JLabel)obj;
}
if(obj instanceof JCheckBox) {
return (JCheckBox)obj;
}
if(obj instanceof JRadioButton) {
return (JRadioButton)obj;
}
label.setText(value.toString());
if (leaf)
label.setIcon(leafIcon);
else if (expanded)
label.setIcon(openIcon);
else
label.setIcon(closeIcon);
return label;
}
public void setOpenIcon (ImageIcon image) {
openIcon = image;
}
public ImageIcon getOpenIcon () {
return openIcon;
}
public void setClosedIcon(ImageIcon image) {
closeIcon = image;
}
public ImageIcon getClosedIcon() {
return closeIcon;
}
public void setLeafIcon(ImageIcon image) {
leafIcon = image;
}
public ImageIcon getLeafIcon() {
return leafIcon;
}
private JLabel label = new JLabel();
private boolean flag = true;
private ImageIcon openIcon = new ImageIcon(".\\src\\image\\open.png");
private ImageIcon closeIcon = new ImageIcon(".\\src\\image\\close.png");
private ImageIcon leafIcon = new ImageIcon(".\\src\\image\\buddy.gif");
}
这个类把TreeCellRenderer接口实现了,注意上面着色的部分,我们把自己需要用到的组件直接返回,这样就可以在给构造node的时候直接传过去了。至于一般的图文结合或者是不能识别的类型处理方式和DefaultTreeCellRenderer一样。但是最终实现是实现了,问题也有不少,比如我们选中node后颜色不会变化,让我们无法区分是否选择等等一系列问题,最重要的是如果添加的组件,如何进行组件的操作等!以下给出了解决方案!
其实实现UI细节比较烦琐,因为你传入的控件都有自己的paint()方法,这就说明你如果要实现细节那么必然要重写这些paint()方法来配合JTree显示,既然要重写这些方法那么你所传入的控件至少是从实现了paint()重写方法的类实例化而来,这就是烦琐之处。如果大家有兴趣可以参考DefaultTreeCellRenderer类来自己写这些方法!
我想也可以通过传来的控件一个个set属性也能达到目的,但是这效率就不是很高了。唯一方便的就不用从某个控件派生而来,把共有属性都写到一堆,也不唯是个好办法。
当然DefaultTreeCellRenderer类是继承的JLabel,而我当下要用的无非就是实现每个cell有自己图片而已,所以偷了一个懒,以下是我实现部分的源码。
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean selected, boolean expanded,boolean leaf, int row, boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
if(obj instanceof JLabel) {
JLabel label = (JLabel)obj;
DefaultTreeCellRenderer tempCellRenderer = new DefaultTreeCellRenderer();
tempCellRenderer.setLeafIcon(label.getIcon());
return tempCellRenderer.getTreeCellRendererComponent(tree,label.getText(),
selected,expanded,true,row,hasFocus);
}
return super.getTreeCellRendererComponent(tree,value,
selected,expanded,leaf,row,hasFocus);
}
}
目的只有一个,让实现了UI细节部分的DefaultTreeCellRenderer重用而已。这样,能实现都实现了,不能实现的也实现了,标签需要什么属性直接用tempCellRenderer的set方法即可!!虽然只有JLabel而已!呵呵。
至于如何操作控件我会放到JTable操作里面一起讲,因为他们都是实现了CellEditor接口,虽然一个是从TreeCellEditor派生,一个是从TableCellEditor派生!
相关推荐
### 如何使用JTree:详解与实践 #### JTree简介 `JTree`是Java Swing中的一个组件,用于展示层次化的数据结构。它允许用户在应用程序中构建树形视图来表示目录结构、组织结构图等。`JTree`继承自`JComponent`类,...
在Java的Swing库中,`JTree`组件是一个用于展示层次数据的控件,它以树状结构显示数据。`jtree`标题所指的可能是关于如何在`JTree`中添加复选框(checkboxes)的功能。这通常是为了让用户能够多选树中的节点,进行...
在Java Swing库中,`JTree`是一个非常重要的组件,用于显示和操作树形数据结构。这个例子展示了如何实现一个可拖动节点的`JTree`,这在用户界面设计中是一个常见且实用的功能,特别是在需要展示层次结构信息时。`...
实现jTable和jTree的双向联动,点击jTree会选中jTable单元格,点击jTable会选中jTree节点。
在Java Swing库中,JTree和JTable是两个非常重要的组件,它们被广泛用于构建用户界面,特别是处理数据展示和交互。JTree用于显示层次结构的数据,而JTable则适用于二维表格形式的数据展现。 首先,我们来深入了解...
在Java Swing库中,`JTree`和`JTable`是两种非常重要的组件,用于创建用户界面。`JTree`通常用于展示层次化的数据结构,而`JTable`则适用于二维表格数据的显示和操作。本项目是关于如何在Java应用程序中结合使用这两...
在IT领域,尤其是在Web开发中,`JTree`是一个常用组件,它用于在用户界面中展示数据的层次结构,比如文件系统、组织架构等。在本案例中,我们讨论的是一个使用JavaScript实现的JTree,这通常是通过HTML、CSS和...
**JTree 深度解析** `JTree` 是Java Swing库中的一个重要组件,它用于在用户界面中显示树状数据结构。这个组件允许用户以图形化的方式浏览和操作层次结构的数据,例如文件系统目录、数据库结构或者组织结构图。在...
在Java Swing库中,JTree组件是一个非常有用的可视化控件,用于展示层次化的数据结构,如文件系统目录或组织结构图。这篇博文将探讨如何在Java应用程序中有效地使用JTree。 首先,理解JTree的基本概念至关重要。...
### Java组件之JTree使用详解 #### 一、引言 `JTree`是Java Swing中的一个重要组件,用于展示层次化的数据结构。它提供了一种直观的方式来表示具有层级关系的数据,例如文件系统的目录结构或者组织架构等。本文将...
**JTree的Doc文档详解** Java Swing库中的`JTree`组件是用于显示和操作树状数据结构的可视化工具。这个组件允许用户以图形化的方式查看层次化的信息,如文件系统目录、数据库结构或者应用程序的对象模型。在Java...
### JTree用法详解:Swing中的树状结构控件 在Java Swing中,`JTree`是一个非常重要的组件,用于展示层次结构的数据,如文件系统、组织结构图等。本文将详细介绍`JTree`的各种使用方法,包括如何创建、自定义外观、...
在IT领域,JTree是一种广泛使用的Java Swing组件,它允许用户以树形结构来展示数据。这个组件在GUI(图形用户界面)应用中特别常见,因为它能清晰地组织层次化的信息,比如文件系统目录、数据库结构或者项目组织。...
在Java编程中,`JTree`是Swing库中的一个组件,用于展示树形数据结构。这个组件在GUI(图形用户界面)应用中非常常见,因为它可以清晰地展示层次关系的数据,比如文件系统目录结构。在Java中动态实现二叉树,即在...
**JTree 2.0:构建直观的目录树视图** `JTree`是Java Swing库中的一个组件,用于在用户界面中展示层次结构数据,通常表现为目录树的形式。在`JTree2.0`版本中,这个组件得到了进一步的改进和增强,提供更丰富的功能...
在Java Swing中,JTree是一个非常重要的组件,用于展示层次结构的数据,通常以树状的形式显示。它在各种用户界面中都有广泛的应用,例如文件系统浏览、组织结构展示等。本教程将深入讲解如何使用JTree以及相关的操作...
而JTree则是一个Java库,它提供了一个可交互的树视图组件,常用于展示层次结构的数据。将HTML转换为JTree的过程主要是为了在Java应用程序中以树状结构展示HTML文档的结构。 要实现这个转换,我们需要以下步骤: 1....
### JTree的用法详解 #### 一、引言 `JTree` 是 Java Swing 库中的一个重要组件,用于在图形用户界面 (GUI) 中显示层次结构数据。它非常适合用来展示具有分层关系的信息,例如文件系统目录结构、组织结构等。 ####...
在Java Swing库中,JTree是一个非常有用的组件,它用于展示层次结构的数据,例如文件系统或组织结构。在你的项目中,你似乎正在探索如何在JTree的不同节点上显示特定的图片,这可以增强用户的视觉体验,使得界面更加...
JTree用法及JTree使用经验总结(吐血推荐) 1、初始化 2、三个经常使用的取值函数 3、根据node得到path:4、根据Path展开到该节点 5、根据path设定该节点选定 6、选中节点的方法 7、滚动到可见位置 8、给JTree添加右键...