TreeCellRenderer in Linux

A

Abs

Hi!

I'm trying to get my swing app to work in both Windows and Linux. Right
now, it works in Windows, but in Linux (Mandrake) it returns a
ClassCastException in the getTreeCellRendererComponent() method in my
custom TreeCellRenderer. My app shows a filesystem tree.


public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {

String name=fsv.getSystemDisplayName(((FileNode)value).getFile());
// CLASSCASTEXCEPTION HERE


super.getTreeCellRendererComponent(tree, name, selected, expanded,
leaf, row, hasFocus);
setText(name);
setIcon(fsv.getSystemIcon(((FileNode)value).getFile()));
return this;
}




I don't know why the FileNode class cast throws a ClassCastException in
Linux but not in Windows. Here is the code for the FileNode class:


public class FileNode extends DefaultMutableTreeNode {

private FileSystemView fsv=FileSystemView.getFileSystemView();

public FileNode(String name) {
setUserObject(new File(name));
}

public FileNode(File file) {
setUserObject(file);
}

public boolean getAllowsChildren() {
return isDirectory();
}

public boolean isLeaf() {
return !isDirectory();
}

public File getFile() {
return (File)getUserObject();
}

public boolean isDirectory() {
File file = getFile();
return fsv.isTraversable(file).booleanValue();
}


}




Can anyone help me, please ? Is FileSystemView broken in Linux ? I'm
using 1.4.2 in both Windows (the full JSDK) and Linux (the JRE).
 
P

Paul Lutus

Abs said:
Hi!

I'm trying to get my swing app to work in both Windows and Linux. Right
now, it works in Windows, but in Linux (Mandrake) it returns a
ClassCastException in the getTreeCellRendererComponent() method in my
custom TreeCellRenderer. My app shows a filesystem tree.


public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {

String name=fsv.getSystemDisplayName(((FileNode)value).getFile());
// CLASSCASTEXCEPTION HERE

The class cast exception may be taking place in the called class, not this
one. You didn't list the stack trace, aso we cannot tell.
I don't know why the FileNode class cast throws a ClassCastException in
Linux but not in Windows.

Different compilers perhaps. But the location of the error is in the stack
trace you didn't provide.
 
O

oscarc

Paul said:
Abs wrote:




The class cast exception may be taking place in the called class, not this
one. You didn't list the stack trace, aso we cannot tell.




Different compilers perhaps. But the location of the error is in the stack
trace you didn't provide.

Here it is:

Exception in thread "main" java.lang.ClassCastException
at
cityslide.viewer.view.IconTreeCellRenderer.getTreeCellRendererCompone
nt(IconTreeCellRenderer.java:40)
at
javax.swing.plaf.basic.BasicTreeUI$NodeDimensionsHandler.getNodeDimen
sions(Unknown Source)
at
javax.swing.tree.AbstractLayoutCache.getNodeDimensions(Unknown Source
)
at
javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.updatePrefer
redSize(Unknown Source)
at
javax.swing.tree.VariableHeightLayoutCache.updateNodeSizes(Unknown So
urce)
at
javax.swing.tree.VariableHeightLayoutCache.invalidateSizes(Unknown So
urce)
at javax.swing.plaf.basic.BasicTreeUI.setCellRenderer(Unknown
Source)
at
javax.swing.plaf.basic.BasicTreeUI$PropertyChangeHandler.propertyChan
ge(Unknown Source)
at
javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(Unkno
wn Source)
at
javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(Unkno
wn Source)
at javax.swing.JComponent.firePropertyChange(Unknown Source)
at javax.swing.JTree.setCellRenderer(Unknown Source)
at cityslide.viewer.view.ExplorerView.init(ExplorerView.java:72)
at cityslide.viewer.view.ExplorerView.<init>(ExplorerView.java:42)
at cityslide.viewer.view.MainFrame.<init>(MainFrame.java:47)
at MainApplication.main(MainApplication.java:38)
 
P

Paul Lutus

oscarc said:
Here it is:

Exception in thread "main" java.lang.ClassCastException
at
cityslide.viewer.view.IconTreeCellRenderer.getTreeCellRendererCompone
nt(IconTreeCellRenderer.java:40)

Okay, you have to make sure the required and provided classes are in
agreement. You can use "instanceof" and/or assertions to test for this,
thus avoiding or handling this specific runtime error. For example, "value"
must be a FileNode, nothing else will do. Is it always a FileNode object?
Test using "instanceof" before allowing the problem line to execute.

Also, trace the code that calls this method. Make sure it always provides
the required object type.
 
C

Christian Kaufhold

Abs said:
I'm trying to get my swing app to work in both Windows and Linux. Right
now, it works in Windows, but in Linux (Mandrake) it returns a
ClassCastException in the getTreeCellRendererComponent() method in my
custom TreeCellRenderer. My app shows a filesystem tree.
[...]

String name=fsv.getSystemDisplayName(((FileNode)value).getFile());
// CLASSCASTEXCEPTION HERE


super.getTreeCellRendererComponent(tree, name, selected, expanded,
leaf, row, hasFocus);

I don't know why the FileNode class cast throws a ClassCastException in
Linux but not in Windows. Here is the code for the FileNode class:

It probably fails because 'value' is not a FileNode.

Try finding out what it is instead (getClass().getName()).

public class FileNode extends DefaultMutableTreeNode {

private FileSystemView fsv=FileSystemView.getFileSystemView();

Is it really necessary to store the same FileSystemView in each node
instead of, for example, the TreeModel?




Christian
 
A

Abs

Christian said:
It probably fails because 'value' is not a FileNode.

Try finding out what it is instead (getClass().getName()).

I've put this line in my code:

System.out.println(value.getClass());

Windows returns my class: FileNode
Linux returns its parent class: DefaultMutableTreeNode

This is weird!!!!!! Why does one OS add nodes to my JTree as FileNodes
and the other add them as DefaultMutableTreeNodes ?

Is it really necessary to store the same FileSystemView in each node
instead of, for example, the TreeModel?

No, it's not necessary, my code sucks, I know :)
 
A

Abs

Paul said:
Okay, you have to make sure the required and provided classes are in
agreement. You can use "instanceof" and/or assertions to test for this,
thus avoiding or handling this specific runtime error. For example, "value"
must be a FileNode, nothing else will do. Is it always a FileNode object?
Test using "instanceof" before allowing the problem line to execute.

I've put this line in my code:

System.out.println(value.getClass());

then,

Windows returns my class: FileNode
Linux returns its parent class: DefaultMutableTreeNode

Is there a coherent reason for this to happen ?
Also, trace the code that calls this method. Make sure it always provides
the required object type.

I've traced my code and every node is added to the JTree as a FileNode,
not as a DefaultMutableTreeNode.

I don't understand anything, the exact same compiled classes work in
Windows but not in Linux.
 
P

Paul Lutus

Abs wrote:

/ ...
Windows returns my class: FileNode
Linux returns its parent class: DefaultMutableTreeNode

This is weird!!!!!! Why does one OS add nodes to my JTree as FileNodes
and the other add them as DefaultMutableTreeNodes ?

Good question. But, since you haven't posted the calling code, we can only
guess.

Also, it isn't two different operating systems. They're both Java, and Java
*should* hide the differences between the two underlying platforms. The
reason the difference exists may be because you are using two different
versions of Java (bad idea if avoidable) or the calling code is simply not
the same.

You can always force a solution through a combination of tree ascending and
casting, but that is a hack, a band-aid. It would be better to use the same
version of Java on both platforms.
 
P

Paul Lutus

Abs said:
I've put this line in my code:

System.out.println(value.getClass());

then,

Windows returns my class: FileNode
Linux returns its parent class: DefaultMutableTreeNode

Is there a coherent reason for this to happen ?

Post the version outputs for both platforms (Linux and Windows).

$ java -version

Also, is the source identical on both platforms?
I've traced my code and every node is added to the JTree as a FileNode,
not as a DefaultMutableTreeNode.

On both platforms, in all cases? If this were true, the error would not come
up, since you are casting the provided object as a FileNode. So it is not
true.
I don't understand anything, the exact same compiled classes work in
Windows but not in Linux.

Run all your tests on both platforms. Throw an exception and trace the stack
if anything but a FileNode appears in the problem area. Find out where the
errant call originates.

IMHO this is most likely a version difference between Windows and Java.
 
A

Abs

Paul said:
Abs wrote:

/ ...




Good question. But, since you haven't posted the calling code, we can only
guess.

Is this what you need ?

FileTree explorertree=new FileTree();
explorertree.setBorder(BorderFactory.createEmptyBorder());
explorertree.setCellRenderer(new IconTreeCellRenderer());

explorertree.addTreeSelectionListener(new
ExplorerTreeSelectionController(this));
explorertree.addTreeWillExpandListener(new
ExplorerTreeExpansionController(this));

explorertree.setModel(new FileTreeModel());
explorertree.setSelection(folder);

--

FileTree extends JTree
FileTreeModel extends DefaultTreeModel

Also, it isn't two different operating systems. They're both Java, and Java
*should* hide the differences between the two underlying platforms. The
reason the difference exists may be because you are using two different
versions of Java (bad idea if avoidable) or the calling code is simply not
the same.

I'm using 1.4.2 in both systems (The JSDK in win and the JRE in linux),
but I don't remember the exact subversion in windows. This is the
-version output in linux:

java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)
 
C

Christian Kaufhold

Abs said:
Is this what you need ?

In general, something compilable would be better.
FileTree explorertree=new FileTree();
explorertree.setBorder(BorderFactory.createEmptyBorder());
explorertree.setCellRenderer(new IconTreeCellRenderer());

explorertree.addTreeSelectionListener(new
ExplorerTreeSelectionController(this));
explorertree.addTreeWillExpandListener(new
ExplorerTreeExpansionController(this));

explorertree.setModel(new FileTreeModel());
explorertree.setSelection(folder);

You first set the renderer, only then your model (why are you extending
JTree, DefaultTreeModel?). Therefore, initially FileTree will probably
(as you do not show the code, it is not clear) have a default model
containing DefaultMutableTreeNodes, and, depending on the LAF imple-
mentation is, might already query the renderer to calculate some
dimensions.

First set your model (or even set it initially, in the FileTree con-
structor) and then the renderer.


Christian
 
A

Abs

Paul said:
Post the version outputs for both platforms (Linux and Windows).

$ java -version

Also, is the source identical on both platforms?

I compile the source in win using Eclipse and run the same .class files
in win and linux
On both platforms, in all cases? If this were true, the error would not come
up, since you are casting the provided object as a FileNode. So it is not
true.

I'm using the same source in both platforms, like I said earlier I
compile it in win and run the compiled result in win (no problems) and
linux (with problems)
Run all your tests on both platforms. Throw an exception and trace the stack
if anything but a FileNode appears in the problem area. Find out where the
errant call originates.

IMHO this is most likely a version difference between Windows and Java.

I run 1.4.2 in both platforms. Maybe eclipse optimizes the compiled
result and linux doesn't like it.
 
P

Paul Lutus

Abs said:
Is this what you need ?

FileTree explorertree=new FileTree();
explorertree.setBorder(BorderFactory.createEmptyBorder());
explorertree.setCellRenderer(new IconTreeCellRenderer());

explorertree.addTreeSelectionListener(new
ExplorerTreeSelectionController(this));
explorertree.addTreeWillExpandListener(new
ExplorerTreeExpansionController(this));

explorertree.setModel(new FileTreeModel());
explorertree.setSelection(folder);

--

FileTree extends JTree
FileTreeModel extends DefaultTreeModel



I'm using 1.4.2 in both systems (The JSDK in win and the JRE in linux),
but I don't remember the exact subversion in windows. This is the
-version output in linux:

java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

Now post the version output from Windows. And (a precaution) avoid having
more than one Java version installed at a time -- this is a time-honored
way to run a different version than you think you are running.
 
P

Paul Lutus

Abs said:
I compile the source in win using Eclipse and run the same .class files
in win and linux

Same class files? Okay, then, post the output of:

java -version

from the Windows platform.
I'm using the same source in both platforms, like I said earlier I
compile it in win and run the compiled result in win (no problems) and
linux (with problems)

What compiler is being used to compile the code? This may be a case where
the compiler expects a target runtime engine that is not being provided.
I run 1.4.2 in both platforms. Maybe eclipse optimizes the compiled
result and linux doesn't like it.

That should not matter if the runtime engines are the same. Make sure you do
not have multiple Java versions installed on either platform, this could
produce a case in which a different engine is running the code than you
think.
 
A

Abs

Christian said:
You first set the renderer, only then your model (why are you extending
JTree, DefaultTreeModel?). Therefore, initially FileTree will probably
(as you do not show the code, it is not clear) have a default model
containing DefaultMutableTreeNodes, and, depending on the LAF imple-
mentation is, might already query the renderer to calculate some
dimensions.

First set your model (or even set it initially, in the FileTree con-
structor) and then the renderer.

YES! It was exactly that. I've set an empty FileTreeModel in the
FileTree constructor and now the app works flawlessly in linux. Thank
you very much both of you for the answers, Christian and Paul. It seems
same version JVMs in different platforms don't behave the same.
 
A

Abs

Paul said:
That should not matter if the runtime engines are the same. Make sure you do
not have multiple Java versions installed on either platform, this could
produce a case in which a different engine is running the code than you
think.

Thank you for your answers, Paul. Following Christian's recommendations,
I've set an empty FileTreeModel in the FileTree constructor and now the
app works flawlessly in linux. It seems same version JVMs in different
platforms don't behave the same.
 
C

Christian Kaufhold

Abs said:
YES! It was exactly that. I've set an empty FileTreeModel in the
FileTree constructor and now the app works flawlessly in linux. Thank
you very much both of you for the answers, Christian and Paul. It seems
same version JVMs in different platforms don't behave the same.

It probably only has to do with the current LookAndFeel (or even whether
the JTree has variable or fixed row heights?) and nothing with the platform.



Christian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

TreeCellRenderer does not work? 2
change icon in jtree 0
TreeCellRenderer 2
Jtree renderers 0
ploblem in jcheckbox 0
checkbox ploblem pls help!! 15
[SWING] Problem with JTree 2
Downloading a file in Linux 9

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top