Tree node icon dissappears when i click on it - java

/* when i am clicking the tree node (EX:WEBLOGIC is selected) the node icon disappears,but the other icons(Non selected) are coming.please help me out to solve this issue.This is a swing based program*/
class ColorRenderer extends DefaultTreeCellRenderer
{
public ColorRenderer()
{
super();
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
{
try
{
Component cell = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
RTGTreeNode treeNode = (RTGTreeNode) value;
GraphUniqueKeyDTO graphUniqueKeyDTO = treeNode.getGraphUniqueKeyDTO();
/*Default Icon not needed.*/
setIcon(null);
if (graphUniqueKeyDTO == null)
{
return cell;
}
String nodeName = treeNode.toString();
if (!leaf)
{
cell.setFont(NSColor.mediumPlainFont());
if (selected)
{
cell.setForeground(Color.black);
cell.setBackground(new Color(128, 0, 0));
}
else
{
Color color = treeNode.getNodeColor();
if (treeNode.getTreeViewToolTip() != null)
nodeName = treeNode.getTreeViewToolTip();
openIcon = treeNode.getImgIcon();
if(openIcon!=null){
setIcon(openIcon);
setLeafIcon(openIcon);
}
if(color == null)
cell.setForeground(NSColor.leftPaneGroupTitleColor());
else
cell.setForeground(color);
}
}
else
{
cell.setFont(NSColor.smallPlainFont());
if (selected)
{
cell.setForeground(Color.black);
cell.setBackground(new Color(128, 0, 0));
}
else
{
cell.setForeground(NSColor.leftPaneGraphTitleColor());
}
}
setToolTipText(nodeName);
JLabel currentCell = (JLabel) cell;
currentCell.setHorizontalAlignment(JLabel.CENTER);
return cell;
}
catch (Exception ex)
{
Log.errorLog("ColorRenderer", "getTreeCellRendererComponent", "", "", "Exception - " + ex);
return null;
}
}

A node in a tree can have a custom icon but most skins have an additional folder like icon next to those nodes in a tree that contain children. I think you mean the Folder icon next to the node disappears when you click on it. If the tree asks the model if it has children and the model returns true then the icon is displayed. When you click on the node and the children are not present the tree removes the icon.
This will happen if you did not implement the getChildren and isLeaf method or implemented isLeaf incorrectly. The isLeaf method tells the JTree UI to draw or not draw the folder icon. Also make sure setAsksAllowsChildren() is set the the correct value for your needs and getChildCount() returns the correct value for each node.

Related

I already have a checkbox in a Java Swing TreeNode. But how do I make it checkable?

Note: I am NOT asking how to put a checkbox in a JTree - previously, a confused moderator thought this is what I was asking. I already have the checkbox in the tree. I am asking what class or method controls the checkability of the checkbox...
In order to get a checkbox inside a Tree node, I read that you had to make a checkbox renderer, so I made one:
class CheckboxCellRenderer implements TreeCellRenderer {
final static Logger logger = LoggerFactory.getLogger(CheckboxCellRenderer.class);
JLabel firstNameLabel = new JLabel(" ");
JPanel renderer = new JPanel();
JCheckBox checkbox;
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
public CheckboxCellRenderer() {
super();
checkbox = new JCheckBox(firstNameLabel.getText(), false);
renderer.add(checkbox);
renderer.add(firstNameLabel);
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component returnValue = null;
firstNameLabel.setText(value.toString());
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
renderer.setEnabled(tree.isEnabled());
if(((DefaultMutableTreeNode) value).getLevel()==1){
returnValue = renderer;
}
}
if (returnValue == null) {
returnValue = defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
This creates the checkbox in the tree node. But for some reason this makes the checkbox uncheckable, and nothing happens when I click it. Why does creating the checkbox in the renderer "break" the checkbox? How do I make the checkbox checkable (i.e. it gets checked when I click the checkbox, and unchecked when I click it again)?
In order to be make a checkbox "checkable", it looks like you need an editor class. This can be demonstrated by commenting out the line "tree.setCellEditor(new CheckBoxNodeEditor(tree));" in the "CheckBox Node Tree Sample" that Abra posted, which makes the example "uncheckable".

How to set image icon to Jtree node on right side of label depends on Node value?

I have searched a lot but solutions that i got are not as per my need.I am showing multiple servers in tree structure.I want to set icon on right side of server(localhost) node when its value gets change.Please provide me a way to set icon.In following image localhost is server name. Its server node.
public class ServerInfo{
private Boolean isShotDetected =false;
public Boolean getIsShotDetected() {
return isShotDetected;
}
public void setIsShotDetected(Boolean isShotDetected) {
this.isShotDetected = isShotDetected;
}
}
class MyTreeCellRenderer extends DefaultTreeCellRenderer {
private Border border = BorderFactory.createEmptyBorder(2, 2, 2, 2);
#Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
JLabel label = (JLabel) super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row,
hasFocus);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
if (expanded) {
setFont(new Font("Arial", Font.BOLD, 13));
} else {
setFont(new Font("Arial", Font.PLAIN, 13));
}
if (node instanceof ServerNode) {
ServerInfo info = ((ServerNode) node).getMultiSite();
if (info.getIsShotDetected()) {
// label.setAlignmentX(SwingConstants.RIGHT);
label.setIcon(redBall);
}
}
label.setBorder(border);
return label;
}
}
Try following:
label.setHorizontalTextPosition(SwingConstants.TRAILING);
if (node instanceof ServerNode) {
ServerInfo info = ((ServerNode) node).getMultiSite();
if (info.getIsShotDetected()) {
label.setHorizontalTextPosition(SwingConstants.LEADING);
label.setIcon(redBall);
}
}

Changing JTree Node Icon dynamically

I have implemented a JTree using the DefaultTreeModel.I am storing Message type objects in the tree where I set the node icons initially according to a direction variable value of the Message. I can do this successfully using the below code.
tcBuilderTree = new JTree(treeModel);
tcBuilderTree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
tcBuilderTree.setCellRenderer(new DefaultTreeCellRenderer(){
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean isLeaf,
int row,
boolean focused) {
Component c = super.getTreeCellRendererComponent(tree, value,
selected, expanded, isLeaf, row, focused);
if(value instanceof CustomMessageTreeNode){
setIcon(((CustomMessageTreeNode)value).
getMessage().getMessageDirectionIcon());
}
return c;
}
});
//implementation of getMessageDirectionIcon()
public ImageIcon getMessageDirectionIcon(){
ImageIcon icon=null;
URL messageIconUrl;
if(msgDirection.equalsIgnoreCase("In")){
messageIconUrl = ToolBar.class.getResource
("/icons/arrowRight.png");
icon=new ImageIcon(messageIconUrl);
}
else if(msgDirection.equalsIgnoreCase("Out")){
messageIconUrl = ToolBar.class.getResource
("/icons/arrowLeft.png");
icon=new ImageIcon(messageIconUrl);
}
return icon;
}
Dynamically I want to let the user select the node and change its direction so that the node icon gets changed. I'm doing it through the foloowing code.
public void toggleDirection(){
CustomMessageTreeNode currentSelectedNode =
(CustomMessageTreeNode) tcBuilderTree.getLastSelectedPathComponent();
Message toggleMessage=currentSelectedNode.getMessage();
tcBuilderTree.setCellRenderer(new DefaultTreeCellRenderer(){
#Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean isLeaf,
int row,
boolean focused) {
Component c = super.getTreeCellRendererComponent(tree, value,
selected, expanded, isLeaf, row, focused);
if(value instanceof CustomMessageTreeNode){
String currentDirection=toggleMessage.getMsgDirection();
if(currentDirection.equalsIgnoreCase("In")){
toggleMessage.setMsgDirection("Out");
System.out.println("Direction changed as : Out");
setIcon(toggleMessage.getMessageDirectionIcon());
return c;
}
if(currentDirection.equalsIgnoreCase("Out")){
toggleMessage.setMsgDirection("In");
System.out.println("Direction changed as : In");
setIcon(toggleMessage.getMessageDirectionIcon());
return c;
}
}
return c;
}
});
}
This is my CustomMessageNode class.
public class CustomMessageTreeNode extends DefaultMutableTreeNode{
private Message message;
public CustomMessageTreeNode(String msgName){
super(msgName);
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
}
Once I change the direction by selecting the node the icon gets changed. But the issue happens whenever I click on some other node or somewhere in my JFrame the icon keeps on changing the direction. I debugged and made sure that the toggleDirection() function is called only once when I click the node and said to change the direction.
Please let me know why this happens and is there a better way to do this.What is the reason for the node icon to keep on changing when the user changes it once.

JComboBox: change one selection item to italic

I want to change one selection item in existing jcombobox (items are already added) to italic? Is there any way to do that?
I hope this one helps you :)
You just have to add the ListCellRenderer to your ComboBox.
class MyComboBoxRenderer extends JLabel
implements ListCellRenderer {
. . .
public ComboBoxRenderer() {
setOpaque(true);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
}
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
//Get the selected index. (The index param isn't
//always valid, so just use the value.)
int selectedIndex = ((Integer)value).intValue();
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
//Set the icon and text. If icon was null, say so.
ImageIcon icon = images[selectedIndex];
String pet = petStrings[selectedIndex];
setIcon(icon);
if (icon != null) {
setText(pet);
setFont(list.getFont()); //HERE YOU ALSO HAVE TO SET THE COLOR OR SOMETHING LIKE THAT
} else {
setUhOhText(pet + " (no image available)",
list.getFont());
}
return this;
}
. . .
}

Two Type of Nodes in a Single Check Box Node Tree

I need to render Two type of nodes in a single tree.
Parent nodes and Leaf nodes.
I also need to edit both of them .
The CheckBoxNodeRender is as follows :
public JCheckBox leafRenderer;
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);
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());
System.err.println("Leaf Value = "+node.getText());
leafRenderer.setSelected(node.isSelected());
}
}
returnValue = leafRenderer;
}
else {
// For the Parent Node
leafRenderer.setText(value.toString());
leafRenderer.setSelected(selected);
returnValue = leafRenderer;
}
return returnValue;
}
And the Editor is as follows :
public boolean isCellEditable(EventObject event) {
//All cells are editable
return true;
}
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() {
public void itemStateChanged(ItemEvent itemEvent) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
};
if (editor instanceof JCheckBox) {
((JCheckBox) editor).addItemListener(itemListener);
}
return editor;
}
I have been facing a unique problem here .
When i select the parent node and select some other node , the value of the other node gets set for the parent node.
Any leads ?
What mistake am i doing here ?
It looks like you have your customized TreeCellEditor reusing components returned from your customized TreeCellRenderer, is that correct? That seems like a bad practice to me. The default JLabel-based implementation of TreeCellRenderer uses a single JLabel for rendering a large tree - so even if the tree has 1,000 nodes, only one JLabel instance is needed. If you're reusing this component when displaying your editor, this will result in graphical anomalies.
My recommendation would be to change your TreeCellEditor implementation to return a different component than the one being used for your TreeCellRenderer.

Categories