package iiuf.swing; import java.awt.Point; import java.awt.FlowLayout; import java.awt.Component; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.util.ArrayList; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.ImageIcon; import javax.swing.JScrollPane; import javax.swing.JScrollBar; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeModelEvent; import javax.swing.tree.TreePath; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import iiuf.util.EventListenerList; /** Horizontal aligned buttons representing a path. (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class ButtonTreePathView extends JPanel implements TreeModelListener { private TreePath path; private EventListenerList listeners = new EventListenerList(); private int startDisplay; private TreeModel model; public ButtonTreePathView(TreeModel model) { this(null, model); } public ButtonTreePathView(TreePath path, TreeModel model) { ((FlowLayout)getLayout()).setAlignment(FlowLayout.LEFT); if(path != null) setPath(path); setModel(model); } public void treeNodesChanged(TreeModelEvent e) { Component[] cmps = getComponents(); for(int i = 0; i < cmps.length; i++) ((JButton)cmps[i]).setText(path.getPathComponent(i).toString()); } public void treeNodesRemoved(TreeModelEvent e) { if(e.getTreePath().getPathComponent(0) != path.getPathComponent(0)) return; setPath(shortestCommonPath(path, e.getTreePath())); } public void treeStructureChanged(TreeModelEvent e) { setPath(shortestCommonPath(path, e.getTreePath())); } public void treeNodesInserted(TreeModelEvent e) {} private TreePath shortestCommonPath(TreePath p1, TreePath p2) { TreePath result = new TreePath(p1.getPathComponent(0)); for(int i = 1; i < Math.min(p1.getPathCount(), p2.getPathCount()); i++) if(p1.getPathComponent(i) != p2.getPathComponent(i)) break; else result = result.pathByAddingChild(p1.getPathComponent(i)); return result; } public void setModel(TreeModel model_) { if(model != null) model.removeTreeModelListener(this); model = model_; if(model != null) model.addTreeModelListener(this); } public TreeModel getModel() { return model; } public void addChangeListener(ChangeListener listener) { listeners.add(ChangeListener.class, listener); } public void addChangeListener(ChangeListener listener, boolean weak) { listeners.add(ChangeListener.class, listener, weak); } public void removeChangeListener(ChangeListener listener) { listeners.remove(ChangeListener.class, listener); } public void setPath(TreePath path) { if(path == null) return; setPath(path, path.getPathCount() < startDisplay); } public void setPath(TreePath path_, boolean lastIsLimit) { if(path_ == null) return; if(path_.equals(path)) return; path = path_; removeAll(); Object[] p = path.getPath(); if(lastIsLimit) startDisplay = p.length - 1; for(int i = startDisplay; i < p.length; i++) { final int iterator = i; JButton button = Swing.newButton(p[iterator].toString(), new ActionListener() { int idx = iterator; public void actionPerformed(ActionEvent e) { synchronized(ButtonTreePathView.this) { Object[] pOld = path.getPath(); Object[] pNew = new Object[idx + 1]; for(int j = 0; j < pNew.length; j++) pNew[j] = pOld[j]; path = new TreePath(pNew); while(getComponentCount() > idx + 1 - startDisplay) remove(idx + 1 - startDisplay); } fireChangeEvent(new ChangeEvent(ButtonTreePathView.this)); validate(); repaint(); } }); button.setIcon(Resource.RIGHTARROW); button.setHorizontalTextPosition(button.LEADING); add(button); } if(getParent().getParent() instanceof JScrollPane) { getParent().getParent().validate(); JScrollBar sb = ((JScrollPane)getParent().getParent()).getHorizontalScrollBar(); sb.setValue(sb.getMaximum()); repaint(); } else { validate(); repaint(); } fireChangeEvent(new ChangeEvent(this)); } protected void fireChangeEvent(ChangeEvent e) { ChangeListener[] ls = (ChangeListener[])listeners.getListeners(ChangeListener.class); for(int i = 0; i < ls.length; i++) ls[i].stateChanged(e); } public TreePath getPath() { return path; } public int getInvisiblePathLength() { return startDisplay; } public TreeNode getViewRoot() { return (TreeNode)path.getPathComponent(startDisplay); } } /* $Log: ButtonTreePathView.java,v $ Revision 1.1 2002/07/11 12:09:52 ohitz Initial checkin Revision 1.5 2001/01/14 13:21:13 schubige Win NT update Revision 1.4 2001/01/12 08:26:20 schubige TJGUI update and some TreeView bug fixes Revision 1.3 2001/01/03 15:23:50 schubige graph stuff beta Revision 1.2 2000/10/10 16:32:12 schubige Added subtree display to TreeView, fixed some bugs Revision 1.1 2000/10/03 08:39:38 schubige Added tree view and contect menu stuff */