我正在使用CustomCellRenderer来显示JTree的节点以显示具有节点的图像 如下所示: -
class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus){
super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
JLabel label = (JLabel) this ;
label.setIcon( new ImageIcon("white.png") ) ;
return this;
}
}
我的要求是在某些外部操作上更改节点的图像。 我正在尝试重新加载JTree的模型,但它的工作方式如下所示: -
public void actionPerformed(ActionEvent ae) {
DefaultTreeModel model = (DefaultTreeModel) tree.getModel() ;
JLabel label = (JLabel) tree.getCellRenderer() ;
System.out.println(label.getIcon()); //displaying white.png
label.setIcon( new ImageIcon("black.gif") ) ;
model.reload() ;
}
我做错了什么??????
答案 0 :(得分:1)
将您的Icon作为字段添加到渲染器类。
更改此字段的值并重新绘制JTree。
class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
ImageIcon rendererIcon;
public void setRendererIcon(ImageIcon myIcon){
this.rendererIcon = myIcon;
};
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus){
super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
JLabel label = (JLabel) this ;
label.setIcon( rendererIcon ) ;
return this;
}
}
修改:解释
在您的情况下,更改模型毫无用处。用于显示每个节点的图标是渲染器的一部分。
JTree的渲染器对象不必强制为JComponent
。当代码调用JComponent
时,它必须是一个提供getTreeCellRendererComponent
的对象。
在你的情况下,将getCellRenderer()转换为JLabel只是运气,因为DefaultTreeCellRenderer
的默认实现是JLabel
的扩展。
事实上,由于渲染器本身调用了setIcon,因此getIcon方法为您提供放入渲染器的最后一个图标是正常的。
完整代码工作:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeCellRenderer;
public class TestJTree {
private static ImageIcon iconWhite = new ImageIcon("white.jpg");
private static ImageIcon iconBlack = new ImageIcon("black.jpg");;
public static void main(String[] args) {
TestJTree me = new TestJTree();
me.process();
}
private void process() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initGui();
}
});
}
protected void initGui() {
JFrame frame = new JFrame("Test JTree");
frame.setContentPane(new JPanel(new BorderLayout()));
final JTree tree = new JTree();
frame.getContentPane().add(tree);
final CustomTreeCellRenderer renderer = new CustomTreeCellRenderer();
renderer.setRendererIcon(iconWhite);
tree.setCellRenderer(renderer);
JPanel panelButtons = new JPanel();
JButton buttonWhite = new JButton("");
buttonWhite.setIcon(iconWhite);
JButton buttonBlack = new JButton("");
buttonBlack.setIcon(iconBlack);
buttonBlack.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
renderer.setRendererIcon(iconBlack);
tree.repaint();
}
});
panelButtons.add(buttonBlack);
panelButtons.add(buttonWhite);
frame.getContentPane().add(panelButtons,BorderLayout.SOUTH);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
@SuppressWarnings("serial")
private static class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
ImageIcon rendererIcon;
public void setRendererIcon(ImageIcon myIcon){
this.rendererIcon = myIcon;
};
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus){
Component ret = super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
JLabel label = (JLabel) ret ;
label.setIcon( rendererIcon ) ;
return ret;
}
}
}
答案 1 :(得分:1)
几点:
actionPerformed
等方法从表中抓取渲染器并修改它并不常见。您应该注意渲染器是共享的,因此您将影响使用该渲染器的列中的所有单元格Icon
期间在渲染器实例上设置了actionPerformed
,也始终会通过getTreeCellRendererComponent
方法访问渲染器以进行绘画,并且您始终将图标设置为“white.png”,所以你永远不会得到“black.gif”来显示。您拥有的选项是在actionPerformed
方法中在模型上设置状态,然后在getTreeCellRendererComponent
内,您可以在模型中查询要显示的图标。
例如:
public void actionPerformed(ActionEvent ae) {
MyCustomTreeModel model = (MyCustomTreeModel) tree.getModel() ;
...
model.setMyState(state); //set the state based on the action
}
渲染器中的:
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus)
{
MyCustomTreeModel model = (MyCustomTreeModel) tree.getModel();
....
setIcon(model.getMyIconBasedOnTheStateISetInActionPerformed());
return this;
}