import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.net.URL; import java.util.logging.Logger; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.Outline; import org.netbeans.swing.outline.OutlineModel; import org.netbeans.swing.outline.RenderDataProvider; import org.netbeans.swing.outline.RowModel; public class OutlineSnippet extends JFrame { private static final long serialVersionUID = -3859337819345830500L; /** * So we can tell the leaf nodes from the non-leaf nodes. */ static class LeafDefaultMutableTreeNode extends DefaultMutableTreeNode { private static final long serialVersionUID = -968618064398030688L; public LeafDefaultMutableTreeNode(Object userObject) { super(userObject); } } public OutlineSnippet() { super("OutlineSnippet"); setLayout(new BorderLayout()); DefaultMutableTreeNode invisibleRootNode = new DefaultMutableTreeNode(); createNodes(invisibleRootNode); TreeModel treeMdl = new DefaultTreeModel(invisibleRootNode); RowModel rowMdl = new RowModel() { @Override public Class getColumnClass(int column) { return String.class; } @Override public int getColumnCount() { return 5; } @Override public String getColumnName(int column) { return "Column " + column; } @Override public Object getValueFor(Object node, int column) { // Only show information for leaf nodes of the tree if (node instanceof LeafDefaultMutableTreeNode) return "data " + column; else return ""; } @Override public boolean isCellEditable(Object node, int column) { return false; } @Override public void setValueFor(Object node, int column, Object value) { // Just ignore for now. } }; final RenderDataProvider rdp = new RenderDataProvider() { @Override public Color getBackground(Object o) { return Color.LIGHT_GRAY; } @Override public String getDisplayName(Object o) { return o.toString(); } @Override public Color getForeground(Object o) { return Color.BLUE; } @Override public Icon getIcon(Object o) { return OutlineSnippet.this.getIcon("asterisk.gif"); } @Override public String getTooltipText(Object o) { return o.toString(); } @Override public boolean isHtmlDisplayName(Object o) { return false; } }; final OutlineModel mdl = DefaultOutlineModel.createOutlineModel( treeMdl, rowMdl); final Outline outline = new Outline(); outline.setRootVisible(false); outline.setModel(mdl); outline.setRenderDataProvider(rdp); outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); outline.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { /* * The selected row expands and collapses with the tree part, * therefore one must use the model to figure out what is * selected. Here I get the tree node and just print out its * label. */ final int selectedRow = outline.getSelectedRow(); System.out.println("selected row=" + mdl.getValueAt(selectedRow, 0).toString()); } }); add(new JScrollPane(outline), BorderLayout.CENTER); pack(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame panel = new OutlineSnippet(); panel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); panel.setVisible(true); } }); } private void createNodes(DefaultMutableTreeNode root) { DefaultMutableTreeNode category; DefaultMutableTreeNode book; DefaultMutableTreeNode top = new DefaultMutableTreeNode( "The Java Series"); root.add(top); category = new DefaultMutableTreeNode("Books for Java Programmers"); top.add(category); book = new LeafDefaultMutableTreeNode( "The Java Tutorial: A Short Course on the Basics"); category.add(book); book = new LeafDefaultMutableTreeNode( "The Java Tutorial Continued: The Rest of the JDK"); category.add(book); book = new LeafDefaultMutableTreeNode( "The JFC Swing Tutorial: A Guide to Constructing GUIs"); category.add(book); category = new DefaultMutableTreeNode("Books for Java Implementers"); top.add(category); book = new LeafDefaultMutableTreeNode( "The Java Virtual Machine Specification"); category.add(book); book = new LeafDefaultMutableTreeNode("The Java Language Specification"); category.add(book); DefaultMutableTreeNode ruby = new DefaultMutableTreeNode( "The Ruby Series"); root.add(ruby); book = new LeafDefaultMutableTreeNode("The Ruby Way"); ruby.add(book); } public Icon getIcon(String imageSymbolicName) { final URL imgURL = getImageURL(imageSymbolicName); if (imgURL != null) { return new ImageIcon(imgURL, imageSymbolicName); } Logger.getAnonymousLogger().severe( "Unable to load an image named '" + imageSymbolicName + "'"); return null; } public URL getImageURL(String imageSymbolicName) { final String path = "/" + imageSymbolicName; final URL url = Object.class.getResource(path); if (url == null) { Logger.getAnonymousLogger().severe( "failed to get URL from getResource(" + path + ")"); } return url; } }