// // SSCellImpl.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.ss; import java.rmi.RemoteException; import java.util.Vector; import visad.*; import visad.formula.*; import visad.util.DataUtility; /** * A VisAD Cell which updates an SSCell * when one of its Data objects change. */ public class SSCellImpl extends CellImpl { /** * VisAD Data object representing boolean true. */ public static final Real TRUE = new Real(1.0); /** * VisAD Data object representing boolean false. */ public static final Real FALSE = new Real(0.0); /** * SSCellData that this cell updates when its data changes. */ private SSCellData cellData; /** * Data reference that this cell monitors for changes. */ private DataReferenceImpl ref; /** * Name of the linked SSCell. */ private String cellName; /** * Variable name of the linked data. */ private String varName; /** * Errors generated from computing the linked data. */ private String[] errors; /** * Formula manager for the linked SSCell. */ private FormulaManager fm; /** * Flag marking whether this cell has finished initializing. */ private boolean inited = false; /** * Whether this cell should broadcast data changes. */ private int skipNotify = 1; // skip notify from initial doAction() call /** * Whether this cell should check for updated data computation errors. */ private int skipErrors = 0; /** * Constructs an SSCellImpl. */ public SSCellImpl(SSCellData cellData, DataReferenceImpl ref, String varName, boolean checkErrors) throws VisADException, RemoteException { this.cellData = cellData; this.ref = ref; cellName = cellData.ssCell.getName(); this.varName = varName; fm = cellData.ssCell.getFormulaManager(); inited = false; if (!checkErrors) skipNextErrors(); addReference(ref); } /** * Returns whether this cell has finished initializing. */ public boolean isInited() { return inited; } /** * Returns the errors relevant to the linked data. */ String[] getErrors() { return errors; } /** * Disables broadcasting of data changes during next data update. */ void skipNextNotify() { skipNotify++; } /** * Disables detection of errors during next data update. */ void skipNextErrors() { skipErrors++; } /** * Invoked when linked data changes. */ public synchronized void doAction() { // get new data Data data = ref.getData(); // broadcast new errors, if any if (skipErrors == 0) { cellData.setErrors(fm.getErrors(varName), true, false); } else skipErrors--; if (data != null) { // update cell display cellData.ssCell.updateDisplay(true); // add data's ScalarTypes to FormulaManager variable registry Vector v = new Vector(); try { DataUtility.getScalarTypes(new Data[] {data}, v, false, true); } catch (VisADException exc) { if (BasicSSCell.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (BasicSSCell.DEBUG) exc.printStackTrace(); } int len = v.size(); for (int i=0; i<len; i++) { ScalarType st = (ScalarType) v.elementAt(i); if (st instanceof RealType) { RealType rt = (RealType) st; try { fm.setThing(rt.getName(), VRealType.get(rt)); } catch (VisADException exc) { if (BasicSSCell.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (BasicSSCell.DEBUG) exc.printStackTrace(); } } } // notify linked cells of data change if (skipNotify == 0) { try { cellData.ssCell.sendMessage(BasicSSCell.UPDATE_DATA, varName, data); } catch (RemoteException exc) { if (BasicSSCell.DEBUG) exc.printStackTrace(); } } else skipNotify--; } else cellData.ssCell.updateDisplay(); // update dependencies for all cells cellData.ssCell.updateDependencies(); // broadcast data change event cellData.ssCell.notifySSCellListeners( SSCellChangeEvent.DATA_CHANGE, varName); inited = true; } }