You may want to be told when a dataset changes or new data is added to a DSS file. This can be accomplished using HecDssListener, a component of HecDssCatalog and inherited by HecDataManager and the other various DSS classes. HecDssListener can tell you 1) when the file has changed; 2) when your dataset has changed; 3) when records have been deleted; and 4) when records have been added.
The simplest implementation is listening for a file change. The class to be notified implements hec.event.HecDssListener as follows

public class myClass implements hec.event.HecDssListener{
…
	HecDssCatalog catalog = new HecDssCatalog("C:/temp/Sample7.dss");
	catalog.addHecDssListener(this);
}

//Add the method hecDssEventPerformed, which will be called when something in the file changes

public void hecDssEventPerformed(hec.event.HecDssEvent source) 
{
 //Do something here
}

//Be sure to remove the listener when complete.

public void done()
{
	catalog.removeHecDssListener(this);
}
JAVA


One may want to listen to changes to specific records. The listener is passed an array of pathnames to watch for changes for, or a pathname with wild characters that matches pathnames that you want to watch. (A wild character is a star at the end or beginning of a pathname part, but not within it. For example, "*Flow*" is valid, but "Flow*Out" is not.)


HecDssCatalog catalog = new HecDssCatalog("C:/temp/Sample7.dss");
catalog.addHecDssListener(this, "/*/*/Flow/*/1Hour/*/", HecDssEventType.RecordsChanged);
//or
catalog.addHecDssListener(this, myPathArray, HecDssEventType.RecordsChanged);

//When a change occurs, you can find out which of the records from your pathnames changed by calling getPathnames:
public void hecDssEventPerformed(hec.event. HecDssEventType source) 
{
Get the pathnames from (only) the records that have changed
String[] paths = catalog.getPathnames();

}
JAVA


Example: HecDssListener




import hec.event.HecDssEvent;
import hec.heclib.dss.*;

//  An example listening for  "Flow" records changed in the file
//
public class ExampleListener1 implements hec.event.HecDssListener
{	
	HecDssCatalog catalog;

	public static void main (String args[])  {
		new ExampleListener1();
	}
	
	public ExampleListener1()
	{	
		catalog = new HecDssCatalog("C:/temp/Sample7.dss");
		catalog.addHecDssListener(this, "/*/*/Flow/*/1Hour/*/", HecDssEventType.RecordsChanged);
	}

	public void hecDssEventPerformed(HecDssEventType source) 
	{
		String[] paths = catalog.getPathnames();
		if ((paths != null) && (paths.length > 0)) {			
			for (int i=0; i<paths.length; i++) {
				System.out.println("Record changed, pathname: " + paths[i]);									
			}  
		}
	}

	public void done()
	{
		catalog.removeHecDssListener(this);
	}

}

JAVA

As another example, you may want a plot of time series data to automatically update when new data for that dataset arrives or the data changes from a model compute.  To accomplish this, add a listener after you have read the data and created your plot.

public class myClass implements hec.event.HecDssListener

HecTimeSeries dssTimeSeries = new HecTimeSeries("C:/temp/Sample7.dss");

timeSeriesContainer.fullName = "//SACRAMENTO/TEMP-MAX/11Jul1877 - 30Jun2009/1DAY/OBS/";

       int status = dssTimeSeries.read(timeSeriesContainer, true);

       hec.gfx2d.G2dDialog plot = PlotDialogFactory.getPlotDialogCreator().createPlotDialog(…          plot.setVisible(true);           

dssTimeSeries.addHecDssListener(this);


Add a function to remove the listener when the plot is closed.


final ExampleListener listener = this;

plot.addWindowListener(new WindowAdapter() {

   public void windowClosing(WindowEvent e) {

          dssTimeSeries.removeHecDssEventListener(listener);

          dssTimeSeries.close();

   }

       });


Then add the method hecDssEventPreformed to update your plot when your dataset changes


       public void hecDssEventPerformed(hec.event.HecDssEventType source) {

              int status = dssTimeSeries.read(timeSeriesContainer, true);

              if (status == 0) {

                     timeSeriesDataSet.setData(timeSeriesContainer);

              }

       }

      

In this example, the listener will only watch for your dataset changing, not others.  Remember, you want only one dataset for one HecTimeSeries object.  Create additional HecTimeSeries objects for other datasets.



Example: Updating Plots with HecDssListener



import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;

import hec.gfx2d.G2dData;
import hec.gfx2d.PlotDialogFactory;
import hec.gfx2d.TimeSeriesDataSet;
import hec.heclib.dss.*;
import hec.io.TimeSeriesContainer;

//  An example where you are listening to a data set to
//  determine if you need to refresh a plot
//
public class ExampleListener2 implements hec.event.HecDssListener
{	
	TimeSeriesContainer timeSeriesContainer;
	TimeSeriesDataSet timeSeriesDataSet;
	HecTimeSeries dssTimeSeries;

	public static void main (String args[])  {
		new ExampleListener1();
	}
	
	public ExampleListener2()
	{	
		dssTimeSeries = new HecTimeSeries("C:/temp/Sample7.dss");
		timeSeriesContainer = new TimeSeriesContainer();
		//  You can specify the entire dataset (over time) by using a "*" (time will be searched for)
		//  timeSeriesContainer.fullName = "//SACRAMENTO/TEMP-MAX/*/1DAY/OBS/";
		//  But using the actual dates is much faster (no searching needed)
		timeSeriesContainer .setName("//SACRAMENTO/TEMP-MAX/11Jul1877 - 30Jun2009/1DAY/OBS/");		
		int status = dssTimeSeries.read(timeSeriesContainer, true);
		if (status != 0) return;

		//  Show in a plot		
		timeSeriesDataSet = new TimeSeriesDataSet(timeSeriesContainer);
		Vector<G2dData> dataVec = new Vector<G2dData>();	
		dataVec.add(timeSeriesDataSet);
		hec.gfx2d.G2dDialog plot = PlotDialogFactory.getPlotDialogCreator().createPlotDialog(null,
 									timeSeriesContainer.fullName, false, dataVec);
		plot.setVisible(true);
		
		dssTimeSeries.addHecDssListener(this);
		final ExampleListener1 listener = this;
		plot.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				dssTimeSeries.removeHecDssListener(listener);
				dssTimeSeries.close();
			}
		});
				
		//  This happens somewhere else in your program
	/*	try { Thread.sleep(10000);}
		catch (Exception ignore){}
		HecTimeSeries ts = new HecTimeSeries("C:/temp/Sample7.dss");		
		TimeSeriesContainer tsc  = new TimeSeriesContainer();
		tsc .setName("//SACRAMENTO/TEMP-MAX/01Jan1960/1DAY/OBS/");
		status = ts.read(tsc, true);
		tsc.values[50] = 135.0;
		//  this will fire the event
		status = ts.write(tsc);
	*/		
	}

	
 
public void hecDssEventPerformed(hec.event.HecDssEventType source) 
	{
		//  If you want to know the change type:
		//  int changeType = source.getChangeType();
		//  Since we specified the dataset (pathnames), only those
		//  will be listened for (and notified when they are changed)
		int status = dssTimeSeries.read(timeSeriesContainer, true);
		if (status == 0) {
			//  When you change TimeSeriesDataSet, that will tell the plot to refresh
			timeSeriesDataSet.setData(timeSeriesContainer);
		}		
	}
}
 
 

JAVA

 

The DSS listener will listen for the following events:

public enum  HecDssEventType{

    Undefined(0),

    FileChanged(1),

    RecordsChanged(2),

    RecordsDeleted(3),

    RecordsAdded(4);


If you want to listen for any change in the file, you can add a listener to a HecDssCatalog object with no pathnames given, or explicitly with a requested change type of FileChanged, e.g.,

                        dataManager.addHecDssListener(this, HecDssEventType.FileChanged);

If you want to know when any records have been added to the file, use a requested change type of RecordsAdded, e.g.,

                        dataManager.addHecDssListener(this, HecDssEventType.RecordsAdded);

This will notifiy you when a record has been added, but it won’t tell you what that pathname is.  If you wish to know which specific records changed, you can use HecDssCatalog’s  whatChanged() method, discussed in the next session.  You can set a start point before you add the listener, then ask the catalog to tell you which records changed.  You can check a changed record’s version number to see if it is new (version 1 is new).

Each time you add a DSS listener, a thread is created to watch the file.  You must remove the listener when you are done to stop that thread.

                        dssTimeSeries.removeHecDssListener(this);


Example: HecDssListener listening for new records


import hec.event.HecDssEventType;
import hec.heclib.dss.*;

//  An example listening for new "Flow" records added to the file
//
public class ExampleListener3 implements hec.event.HecDssListener
{	
	HecDataManager dataManager;

	public static void main (String args[])  {
		new ExampleListener3();
	}
	
	public ExampleListener3()
	{	
		dataManager = new HecDataManager("C:/temp/Sample7.dss");
		//  We are only interested in hourly flow records
		dataManager.addHecDssListener(this, "/*/*/Flow/*/1Hour/*/", HecDssEventType.RecordsAdded);
	}

	public void hecDssEventPerformed(HecDssEventType source) 
	{
		String[] paths = dataManager.getPathnames();
		if ((paths != null) && (paths.length > 0)) {
			for (int i=0; i<paths.length; i++) {
				System.out.println("New record added, pathname: " + paths[i]);					
			}  
		}
	}

	public void done()
	{
		dataManager.removeHecDssListener(this);
	}

}

 

JAVA