2

In the program I'm writing, I have a JTree storing some objects of my own design. I made my own extension of DefaultTreeCellRenderer and overrode getTreeCellRendererComponent to return a JPanel with some buttons and things. What I found was that the buttons I added didn't act like buttons, which makes think that interaction with the components is being "stolen" by the tree cell. (If you click on the button, the container surrounding the button is also being clicked on, and the tree has its own response to being clicked.)

So my question is this:

If what I want is the basic functionality of a tree, plus some buttons, what approach should I use?

  • Continue on the same route; add a mouse listener of some kind to manually add the functionality to the button.
  • Continue on the same route; remove the existing mouse listener and add your own to achieve the right behavior.
  • Extend or implement a slightly different class or interface than you did - maybe not DefaultMutableTreeNodes, maybe not DefaultTreeCellRenderer, etc. - use the existing XXXX to do what you're trying to do.
  • Avoid using JTree; make your own, it's not that hard.

I'm leaning toward the last option - there's a decent chance I don't actually want the folding behavior of a tree anyway, so I may just make my own structure. However, even if I choose that option, I'd like to know what I should have done.

John P
  • 1,463
  • 3
  • 19
  • 39
  • 2
    don't re-invent the wheel ;-) Especially not if the main reason you are not satisfied with the existing wheel is that you don't - yet - know how to turn it. Plus the most probable outcome would be an edgy structure anyway ... – kleopatra Jul 25 '12 at 09:50
  • JTree is one of the most complicated components in the Swing API (with exception to the text components), don't get stressed if it takes some time to get working. Once you have it under control, the other components will seem simple in comparison – MadProgrammer Jul 25 '12 at 16:17

2 Answers2

4

You'll also need a TreeCellEditor, illustrated here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
3

Avoid using JTree; make your own, it's not that hard

I wish you good luck wit that ;-)

What is happening is that the components returned by the renderer are only used as a 'stamp'. So the JTree does not really contain the returned components, they are only painted. Hence no interaction with your button. It only looks like a button. It seems the JTree tutorial does not contain a real section on this, but it is basically the same concept as for tables, which is explained in the 'Renderers and editors' part of the tutorial.

That also explains why a typical renderer class extends JLabel and can simply use return this after it made customizations to itself, without affecting the other nodes in the tree. For example the source code of the DefaultTreeCellRenderer, which extends JLabel, contains

public Component getTreeCellRendererComponent(JTree tree, Object value,
                                              boolean sel,
                                              boolean expanded,
                                              boolean leaf, int row,
                                              boolean hasFocus) {
   //...
   setText(stringValue);
   //...
   return this;
}

How to fix this: create an editor as well, as suggested by @trashgod

Robin
  • 36,233
  • 5
  • 47
  • 99
  • Good points. `Outline`, illustrated [here](http://codereview.stackexchange.com/a/4447/6692), leverages the same pattern. – trashgod Jul 25 '12 at 10:05
  • @trashgod Not only on SO you have examples for everything, now you are going to start filling the other sites as well. Don't wanna know how much time you spent on those examples – Robin Jul 25 '12 at 10:11