/** Delegates to the EventBroadcaster for this model */ public final synchronized void addTableModelListener(TableModelListener l) { broadcaster.addTableModelListener (l); }
/** Delegates to the EventBroadcaster for this model */ public final synchronized void addTreeModelListener(TreeModelListener l) { broadcaster.addTreeModelListener (l); }
public boolean areMoreEventsPending() { return broadcaster.areMoreEventsPending(); }
/** Convenience method to fire a single table change to all listeners */ void fireTableChange (TableModelEvent e) { //Event may be null for offscreen info, etc. if (e == null) { return; } inMultiEvent = false; fireTableChange(e, getTableModelListeners()); }
/** Process a node insertion event from the user-supplied tree model * Order of operations: * <ol><li>Refire the same tree event with the OutlineModel we're * proxying as the source</li> * <li>Create one or more table model events (more than one if the * incoming event affects discontiguous rows) reflecting the effect * of the tree change</li> * <li>Call the method with the same signature as this one on the * layout cache, so it will update its state appropriately</li> * <li>Fire the generated TableModelEvent(s)</li></ol> */ public void treeNodesInserted(TreeModelEvent e) { assert SwingUtilities.isEventDispatchThread(); fireTreeChange (translateEvent(e), NODES_INSERTED); TableModelEvent[] events = translateEvent(e, NODES_INSERTED); getLayout().treeNodesInserted(e); fireTableChange(events); }
int row = getLayout().getRowForPath(path); boolean inClosedNode = !getLayout().isExpanded(path); if (inClosedNode) { case NODES_REMOVED : return new TableModelEvent[] { new TableModelEvent (getModel(), row, row, 0, TableModelEvent.UPDATE) }; boolean discontiguous = isDiscontiguous(e); blocks = getContiguousIndexBlocks(e, type == NODES_REMOVED); log ("discontiguous " + types[type] + " event", blocks.length + " blocks"); } else { blocks = new Object[] {e.getChildIndices()}; switch (type) { case NODES_CHANGED : result[i] = createTableChangeEvent (e, currBlock); break; case NODES_INSERTED : result[i] = createTableInsertionEvent (e, currBlock); break; case NODES_REMOVED : result[i] = createTableDeletionEvent (e, currBlock); break; default :
/** Process a structural change event from the user-supplied tree model. * This will result in a generic "something changed" * TableModelEvent being fired. */ public void treeStructureChanged(TreeModelEvent e) { assert SwingUtilities.isEventDispatchThread(); getLayout().treeStructureChanged(e); fireTreeChange (translateEvent(e), STRUCTURE_CHANGED); //If it's a structural change, we need to dump all our info about the //existing tree structure - it can be bogus now. Similar to JTree, //this will have the effect of collapsing all expanded paths. The //TreePathSupport takes care of dumping the layout cache's copy of //such data getTreePathSupport().clear(); //We will just fire a "Something happened. Go figure out what." event. fireTableChange (new TableModelEvent (getModel())); }
TableModelEvent result = null; log ("createTableDeletionEvent " + Arrays.asList(toArrayOfInteger(indices)), e); int row = getLayout().getRowForPath(path); if (row == -1) { Object[] children = getChildrenForIndices(e, indices); if (getTreePathSupport().isExpanded(childPath)) { getLayout().getVisibleChildCount(childPath); log (childPath + " has ", new Integer(visibleChildren)); getTreePathSupport().removePath(path); log ("firstRow", new Integer(firstRow)); log("Count removed is ", new Integer(countRemoved)); log("TableModelEvent: fromRow: ", new Integer(firstRow)); log(" toRow: ", new Integer(lastRow)); result = new TableModelEvent (getModel(), firstRow, lastRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);
/** Updates the layout to mark the descendants of the events path as also * expanded if they were the last it was expanded, then fires a table change. */ public void treeExpanded(TreeExpansionEvent event) { assert SwingUtilities.isEventDispatchThread(); log ("treeExpanded", event); //Mysterious how the event could be null, but JTree tests it //so we will too. if(event != null) { updateExpandedDescendants(event.getPath()); } log ("about to fire", pendingExpansionEvent); //Now fire a change on the owning row so its display is updated (it //may have just become an expandable node) TreePath path = event.getPath(); int row = getLayout().getRowForPath(path); TableModelEvent evt = new TableModelEvent (getModel(), row, row, 0, TableModelEvent.UPDATE); if (row == -1) { evt = new TableModelEvent(getModel()); } fireTableChange(new TableModelEvent[] {evt, pendingExpansionEvent}); pendingExpansionEvent = null; inProgressEvent = null; }
public void treeCollapsed(TreeExpansionEvent event) { assert SwingUtilities.isEventDispatchThread(); log ("treeExpanded", event); //FixedHeightLayoutCache tests if the event is null. //Don't know how it could be, but there's probably a reason... if(event != null) { TreePath path = event.getPath(); //Tell the layout about the change if(path != null && getTreePathSupport().isVisible(path)) { getLayout().setExpandedState(path, false); } } log ("about to fire", pendingExpansionEvent); //Now fire a change on the owning row so its display is updated (it //may have just become an expandable node) TreePath path = event.getPath(); int row = getLayout().getRowForPath(path); TableModelEvent evt = new TableModelEvent (getModel(), row, row, 0, TableModelEvent.UPDATE); fireTableChange(new TableModelEvent[] {evt, pendingExpansionEvent}); pendingExpansionEvent = null; inProgressEvent = null; }
/** Process a change event from the user-supplied tree model. This * method will throw an assertion failure if it receives any event type * other than TableModelEvent.UPDATE - the ProxyTableModel should never, * ever fire structural changes - only the tree model is allowed to do * that. */ public void tableChanged(TableModelEvent e) { assert SwingUtilities.isEventDispatchThread(); //The *ONLY* time we should see events here is due to user //data entry. The ProxyTableModel should never change out //from under us - all structural changes happen through the //table model. assert (e.getType() == e.UPDATE) : "Table model should only fire " + "updates, never structural changes"; fireTableChange (translateEvent(e)); }
/** * Change the label of the 'tree' column. * @param label New label for tree column. */ public void setNodesColumnLabel( String label ) { this.nodesColumnLabel = label; broadcaster.fireTableChange( new TableModelEvent( this, -1, -1, 0, TableModelEvent.HEADER_ROW ) ); }
/** Creates a new instance of DefaultOutlineModel. <strong><b>Note</b> * Do not fire table structure changes from the wrapped TableModel (value * changes are okay). Changes that affect the number of rows must come * from the TreeModel. */ protected DefaultOutlineModel(TreeModel treeModel, TableModel tableModel, boolean largeModel, String nodesColumnLabel) { this.treeModel = treeModel; this.tableModel = tableModel; if (nodesColumnLabel != null) { this.nodesColumnLabel = nodesColumnLabel; } layout = largeModel ? (AbstractLayoutCache) new FixedHeightLayoutCache() : (AbstractLayoutCache) new VariableHeightLayoutCache(); broadcaster = new EventBroadcaster (this); layout.setRootVisible(true); layout.setModel(this); treePathSupport = new TreePathSupport(this, layout); treePathSupport.addTreeExpansionListener(broadcaster); treePathSupport.addTreeWillExpandListener(broadcaster); treeModel.addTreeModelListener(broadcaster); tableModel.addTableModelListener(broadcaster); if (tableModel instanceof ProxyTableModel) { ((ProxyTableModel) tableModel).setOutlineModel(this); } }
/** Process a change event from the user-supplied tree model. * Order of operations: * <ol><li>Refire the same tree event with the OutlineModel we're * proxying as the source</li> * <li>Create one or more table model events (more than one if the * incoming event affects discontiguous rows) reflecting the effect * of the tree change</li> * <li>Call the method with the same signature as this one on the * layout cache, so it will update its state appropriately</li> * <li>Fire the generated TableModelEvent(s)</li></ol> */ public void treeNodesChanged(TreeModelEvent e) { assert SwingUtilities.isEventDispatchThread(); fireTreeChange (translateEvent(e), NODES_CHANGED); TableModelEvent[] events = translateEvent(e, NODES_CHANGED); getLayout().treeNodesChanged(e); fireTableChange(events); }
/** Fires multiple table model events, setting the inMultiEvent flag * as appropriate. */ private void fireTableChange (TableModelEvent[] e) { //Event may be null for offscreen info, etc. if (e == null || e.length==0) { return; } TableModelListener[] listeners = getTableModelListeners(); inMultiEvent = e.length > 1; try { for (int i=0; i < e.length; i++) { fireTableChange (e[i], listeners); if (i == e.length-1) { inMultiEvent = false; } } } finally { inMultiEvent = false; } }
/** Process a node removal event from the user-supplied tree model * Order of operations: * <ol><li>Refire the same tree event with the OutlineModel we're * proxying as the source</li> * <li>Create one or more table model events (more than one if the * incoming event affects discontiguous rows) reflecting the effect * of the tree change</li> * <li>Call the method with the same signature as this one on the * layout cache, so it will update its state appropriately</li> * <li>Fire the generated TableModelEvent(s)</li></ol> */ public void treeNodesRemoved(TreeModelEvent e) { assert SwingUtilities.isEventDispatchThread(); fireTreeChange (translateEvent(e), NODES_REMOVED); TableModelEvent[] events = translateEvent(e, NODES_REMOVED); getLayout().treeNodesRemoved(e); fireTableChange(events); }