V
Vincent H
Hi,
I'm experiencing a strange problem with the JTree. When updating the string presented by a node (i.e. making it longer
than the initial value) the tree is updated but the string is truncated. I'm using my own TreeModel and TreeCellRender.
The update is done via the TreeModel which triggers the TreeModelListeners' treeNodesChanged() method.
To show the problem I've made a small demo app. Its classes are attached. After starting it, and expanding all nodes you
can press the "Hit Me" button to see that one of the teams changes (but is not displayed correctly).
Anyone experience something similar? What am I doing wrong here?
Thanks,
Vincent
import java.awt.Color;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.JButton;
public class MainFrame extends JFrame implements TreeCellRenderer {
private MyOwnTreeModel treeModel = new MyOwnTreeModel();
private JLabel treeLabel = new JLabel();
private javax.swing.JPanel jContentPane = null;
private JScrollPane jScrollPane = null;
private JTree jTree = null;
private JButton jButton = null;
public static void main(String[] args) {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
public MainFrame() {
super();
initialize();
jTree.setModel(treeModel);
jTree.setCellRenderer(this);
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
MyTreeObject val = (MyTreeObject) value;
if (val.isChampion()) {
treeLabel.setText(val.getName() + " campione");
treeLabel.setForeground(Color.RED);
} else {
treeLabel.setText(val.getName());
treeLabel.setForeground(Color.BLACK);
}
return treeLabel;
}
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setViewportView(getJTree());
}
return jScrollPane;
}
private JTree getJTree() {
if (jTree == null) {
jTree = new JTree();
}
return jTree;
}
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setText("Hit me!");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
treeModel.makeOneChamp();
}
});
}
return jButton;
}
private void initialize() {
this.setSize(486, 320);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private javax.swing.JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new javax.swing.JPanel();
jContentPane.setLayout(new java.awt.BorderLayout());
jContentPane.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
jContentPane.add(getJButton(), java.awt.BorderLayout.SOUTH);
}
return jContentPane;
}
} // @jve:decl-index=0:visual-constraint="10,10"
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public class MyOwnTreeModel implements TreeModel {
private List listeners = new ArrayList();
private static int counter = 0;
private MyTreeObject rootObj = new MyTreeObject(" carot");
private MyTreeObject a = new MyTreeObject("a Sixers");
private MyTreeObject b = new MyTreeObject("b Lakers");
private MyTreeObject c = new MyTreeObject("c Suns");
private MyTreeObject d = new MyTreeObject("d Knicks");
private MyTreeObject e = new MyTreeObject("e Pacers");
private MyTreeObject f = new MyTreeObject("f Heat");
private MyTreeObject g = new MyTreeObject("g Bulls");
private MyTreeObject h = new MyTreeObject("h Jazz");
public MyOwnTreeModel() {
super();
rootObj.addChild(a);
a.addChild(c);
a.addChild(d);
a.addChild(e);
rootObj.addChild(b);
b.addChild(f);
b.addChild(g);
b.addChild(h);
}
public Object getRoot() {
return rootObj;
}
public int getChildCount(Object parent) {
return ((MyTreeObject)parent).getChildren().size();
}
public boolean isLeaf(Object node) {
if (getChildCount(node) == 0) {
return true;
}
return false;
}
public void addTreeModelListener(TreeModelListener l) {
listeners.add(l);
}
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l);
}
public Object getChild(Object parent, int index) {
return ((MyTreeObject)parent).getChildren().get(index);
}
public int getIndexOfChild(Object parent, Object child) {
String name = ((MyTreeObject)child).getName();
if (name.startsWith("a")) return 0;
if (name.startsWith("b")) return 1;
if (name.startsWith("c")) return 0;
if (name.startsWith("d")) return 1;
if (name.startsWith("e")) return 2;
if (name.startsWith("f")) return 0;
if (name.startsWith("g")) return 1;
if (name.startsWith("h")) return 2;
return -1;
}
public void valueForPathChanged(TreePath path, Object newValue) {
}
public void makeOneChamp() {
MyTreeObject champ = null;
MyTreeObject oldChamp = null;
if (counter == 0) {
champ = c;
oldChamp = h;
}
if (counter == 1) {
champ = d;
oldChamp = c;
}
if (counter == 2) {
champ = e;
oldChamp = d;
}
if (counter == 3) {
champ = f;
oldChamp = e;
}
if (counter == 4) {
champ = g;
oldChamp = f;
}
if (counter == 5) {
champ = h;
oldChamp = g;
}
champ.makeChampion(true);
oldChamp.makeChampion(false);
if (counter == 5) {
counter = 0;
} else {
counter++;
}
TreeModelEvent event = new TreeModelEvent(this, new Object[] { champ });
for (Iterator iterator = listeners.iterator(); iterator.hasNext() {
TreeModelListener l = (TreeModelListener) iterator.next();
l.treeNodesChanged(event);
}
}
}
import java.util.ArrayList;
import java.util.List;
public class MyTreeObject {
private String name;
private boolean isChampion = false;
private List children = new ArrayList();
public MyTreeObject(String name) {
this.name = name;
}
public void addChild(MyTreeObject child) {
children.add(child);
}
public List getChildren() {
return children;
}
public String getName() {
return name.substring(2);
}
public void makeChampion(boolean winner) {
isChampion = winner;
}
public boolean isChampion() {
return isChampion;
}
public String toString() {
return name;
}
}
I'm experiencing a strange problem with the JTree. When updating the string presented by a node (i.e. making it longer
than the initial value) the tree is updated but the string is truncated. I'm using my own TreeModel and TreeCellRender.
The update is done via the TreeModel which triggers the TreeModelListeners' treeNodesChanged() method.
To show the problem I've made a small demo app. Its classes are attached. After starting it, and expanding all nodes you
can press the "Hit Me" button to see that one of the teams changes (but is not displayed correctly).
Anyone experience something similar? What am I doing wrong here?
Thanks,
Vincent
import java.awt.Color;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.JButton;
public class MainFrame extends JFrame implements TreeCellRenderer {
private MyOwnTreeModel treeModel = new MyOwnTreeModel();
private JLabel treeLabel = new JLabel();
private javax.swing.JPanel jContentPane = null;
private JScrollPane jScrollPane = null;
private JTree jTree = null;
private JButton jButton = null;
public static void main(String[] args) {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
public MainFrame() {
super();
initialize();
jTree.setModel(treeModel);
jTree.setCellRenderer(this);
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
MyTreeObject val = (MyTreeObject) value;
if (val.isChampion()) {
treeLabel.setText(val.getName() + " campione");
treeLabel.setForeground(Color.RED);
} else {
treeLabel.setText(val.getName());
treeLabel.setForeground(Color.BLACK);
}
return treeLabel;
}
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setViewportView(getJTree());
}
return jScrollPane;
}
private JTree getJTree() {
if (jTree == null) {
jTree = new JTree();
}
return jTree;
}
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setText("Hit me!");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
treeModel.makeOneChamp();
}
});
}
return jButton;
}
private void initialize() {
this.setSize(486, 320);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private javax.swing.JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new javax.swing.JPanel();
jContentPane.setLayout(new java.awt.BorderLayout());
jContentPane.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
jContentPane.add(getJButton(), java.awt.BorderLayout.SOUTH);
}
return jContentPane;
}
} // @jve:decl-index=0:visual-constraint="10,10"
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public class MyOwnTreeModel implements TreeModel {
private List listeners = new ArrayList();
private static int counter = 0;
private MyTreeObject rootObj = new MyTreeObject(" carot");
private MyTreeObject a = new MyTreeObject("a Sixers");
private MyTreeObject b = new MyTreeObject("b Lakers");
private MyTreeObject c = new MyTreeObject("c Suns");
private MyTreeObject d = new MyTreeObject("d Knicks");
private MyTreeObject e = new MyTreeObject("e Pacers");
private MyTreeObject f = new MyTreeObject("f Heat");
private MyTreeObject g = new MyTreeObject("g Bulls");
private MyTreeObject h = new MyTreeObject("h Jazz");
public MyOwnTreeModel() {
super();
rootObj.addChild(a);
a.addChild(c);
a.addChild(d);
a.addChild(e);
rootObj.addChild(b);
b.addChild(f);
b.addChild(g);
b.addChild(h);
}
public Object getRoot() {
return rootObj;
}
public int getChildCount(Object parent) {
return ((MyTreeObject)parent).getChildren().size();
}
public boolean isLeaf(Object node) {
if (getChildCount(node) == 0) {
return true;
}
return false;
}
public void addTreeModelListener(TreeModelListener l) {
listeners.add(l);
}
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l);
}
public Object getChild(Object parent, int index) {
return ((MyTreeObject)parent).getChildren().get(index);
}
public int getIndexOfChild(Object parent, Object child) {
String name = ((MyTreeObject)child).getName();
if (name.startsWith("a")) return 0;
if (name.startsWith("b")) return 1;
if (name.startsWith("c")) return 0;
if (name.startsWith("d")) return 1;
if (name.startsWith("e")) return 2;
if (name.startsWith("f")) return 0;
if (name.startsWith("g")) return 1;
if (name.startsWith("h")) return 2;
return -1;
}
public void valueForPathChanged(TreePath path, Object newValue) {
}
public void makeOneChamp() {
MyTreeObject champ = null;
MyTreeObject oldChamp = null;
if (counter == 0) {
champ = c;
oldChamp = h;
}
if (counter == 1) {
champ = d;
oldChamp = c;
}
if (counter == 2) {
champ = e;
oldChamp = d;
}
if (counter == 3) {
champ = f;
oldChamp = e;
}
if (counter == 4) {
champ = g;
oldChamp = f;
}
if (counter == 5) {
champ = h;
oldChamp = g;
}
champ.makeChampion(true);
oldChamp.makeChampion(false);
if (counter == 5) {
counter = 0;
} else {
counter++;
}
TreeModelEvent event = new TreeModelEvent(this, new Object[] { champ });
for (Iterator iterator = listeners.iterator(); iterator.hasNext() {
TreeModelListener l = (TreeModelListener) iterator.next();
l.treeNodesChanged(event);
}
}
}
import java.util.ArrayList;
import java.util.List;
public class MyTreeObject {
private String name;
private boolean isChampion = false;
private List children = new ArrayList();
public MyTreeObject(String name) {
this.name = name;
}
public void addChild(MyTreeObject child) {
children.add(child);
}
public List getChildren() {
return children;
}
public String getName() {
return name.substring(2);
}
public void makeChampion(boolean winner) {
isChampion = winner;
}
public boolean isChampion() {
return isChampion;
}
public String toString() {
return name;
}
}