blob: dbb759c9c5e47e9406158d4cca55ff1a197a981f [file] [log] [blame]
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.poifs.poibrowser;
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.util.*;
/**
* <p>This is a {@link TreeCellRenderer} implementation which is able
* to render arbitrary objects. The {@link ExtendableTreeCellRenderer}
* does not do the rendering itself but instead dispatches to
* class-specific renderers. A class/renderer pair must be registered
* using the {@link #register} method. If a class has no registered
* renderer, the renderer of its closest superclass is used. Since the
* {@link ExtendableTreeCellRenderer} always has a default renderer
* for the {@link Object} class, rendering is always possible. The
* default {@link Object} renderer can be replaced by another renderer
* but it cannot be unregistered.</p>
*/
public class ExtendableTreeCellRenderer implements TreeCellRenderer
{
/**
* <p>Maps classes to renderers.</p>
*/
protected Map<Class<?>,TreeCellRenderer> renderers;
public ExtendableTreeCellRenderer()
{
renderers = new HashMap<Class<?>,TreeCellRenderer>();
register(Object.class, new DefaultTreeCellRenderer()
{
@Override
public Component getTreeCellRendererComponent
(JTree tree, Object value, boolean selectedCell,
boolean expanded, boolean leaf, int row, boolean hasCellFocus)
{
final String s = value.toString();
final JLabel l = new JLabel(s + " ");
if (selected)
{
Util.invert(l);
l.setOpaque(true);
}
return l;
}
});
}
/**
* <p>Registers a renderer for a class.</p>
**/
public void register(final Class<?> c, final TreeCellRenderer renderer)
{
renderers.put(c, renderer);
}
/**
* <p>Unregisters a renderer for a class. The renderer for the
* {@link Object} class cannot be unregistered.</p>
*/
public void unregister(final Class<?> c)
{
if (c == Object.class)
throw new IllegalArgumentException
("Renderer for Object cannot be unregistered.");
renderers.put(c, null);
}
/**
* <p>Renders an object in a tree cell depending of the object's
* class.</p>
*
* @see TreeCellRenderer#getTreeCellRendererComponent
*/
@Override
public Component getTreeCellRendererComponent
(final JTree tree, final Object value, final boolean selected,
final boolean expanded, final boolean leaf, final int row,
final boolean hasFocus)
{
final String NULL = "null";
TreeCellRenderer r;
Object userObject;
if (value == null)
userObject = NULL;
else
{
userObject = ((DefaultMutableTreeNode) value).getUserObject();
if (userObject == null)
userObject = NULL;
}
r = findRenderer(userObject.getClass());
return r.getTreeCellRendererComponent
(tree, value, selected, expanded, leaf, row,
hasFocus);
}
/**
* <p>Find the renderer for the specified class.</p>
*/
protected TreeCellRenderer findRenderer(final Class<?> c)
{
final TreeCellRenderer r = renderers.get(c);
if (r != null)
/* The class has a renderer. */
return r;
/* The class has no renderer, try the superclass, if any. */
final Class<?> superclass = c.getSuperclass();
if (superclass != null) {
return findRenderer(superclass);
}
return null;
}
}