Save This Page
Home » openjdk-7 » net.sourceforge » jbird » [javadoc | source]
    1   /*
    2   	J-Bird net/sourceforge/jbird/Ticker.java
    3   
    4   	Copyright 2001, 2002, 2003  Dick Repasky
    5   */
    6   package net.sourceforge.jbird;
    7   
    8   import java.awt.Button;
    9   import java.awt.Color;
   10   import java.awt.Frame;
   11   import java.awt.GridBagConstraints;
   12   import java.awt.GridBagLayout;
   13   import java.awt.Insets;
   14   import java.awt.Panel;
   15   import java.awt.event.ActionListener;
   16   import java.awt.event.ActionEvent;
   17   import java.io.IOException;
   18   import java.lang.ref.WeakReference;
   19   import java.sql.Date;
   20   import java.sql.ResultSet;
   21   import java.sql.SQLException;
   22   import java.text.Collator;
   23   import java.text.CollationKey;
   24   import java.text.MessageFormat;
   25   import java.util.ResourceBundle;
   26   
   27   import net.sourceforge.jbird.JTextEditor;
   28   import net.sourceforge.jbird.SpeciesNameIface;
   29   import net.sourceforge.jbird.awt.AVQueue;
   30   import net.sourceforge.jbird.iface.IntarrayListener;
   31   import net.sourceforge.jbird.iface.IntegerListener;
   32   import net.sourceforge.jbird.iface.IntegerListenerList;
   33   import net.sourceforge.jbird.iface.LogListener;
   34   
   35   /**
   36     * Panel that performs ticking for AddEditTicks.
   37     * @author Dick Repasky
   38     *
   39   */
   40   
   41   public class Ticker extends Panel {
   42   
   43      protected Button tickbutton;
   44      protected Button annotatebutton;
   45      protected Button untickbutton;
   46   					/** @since J-Bird 0.1.1 */
   47      protected Button displaybutton;
   48   
   49      private Insets inset		= new Insets(5,5,5,5);
   50   
   51      protected int	 currentregion		= -1;
   52      protected int	 currenttrip		= -1;
   53      protected Date  currentripdate	= null;
   54      protected int[] currentobservers	= null;
   55      protected String[] currentobsnames	= null;
   56      protected int	 currentspecies		= -1;
   57   
   58   			// listeners for passively receiving events
   59      protected TickRegionListener regionlistener	= new TickRegionListener();
   60      protected TickTripListener   triplistener	= new TickTripListener();
   61      protected TickObserverListener observerlistener = new TickObserverListener();
   62      protected TickSpeciesListener specieslistener   = new TickSpeciesListener();
   63   
   64      protected IntegerListenerList specieslisteners = new IntegerListenerList();
   65   
   66   			// interface for actively obtaining species names
   67      protected SpeciesNameIface speciessource = null;
   68   
   69      protected AVQueue gratifyqueue;
   70      protected String[] gratifyitem = new String[3];
   71   
   72   						// result messages
   73      private String lifemessage;
   74      private String regmessage;
   75      private String tripmessage;
   76      private String alreadymessage;
   77      private String failmessage;
   78      private String untickmessage;
   79      private String nottickdmessage;
   80   
   81      private JbirdDB dbase;
   82      private JBirdOptions jbirdoptions;
   83   						/** @since J-Bird 0.1.1 */
   84      private ResourceBundle progres;
   85      private Frame owningframe;
   86      private ObserverChooser observerchooser;
   87      private LogListener log;
   88   
   89      protected JTextEditor texteditor;
   90   
   91   				// variables used to
   92   				// keep track of notes
   93   				// values initialized to -1
   94   				// -1 always indicates nothing stored
   95   				// -2 indicates that species is ticked
   96   				//    but no note exists for it
   97   
   98   				// Array of note indices for observers
   99   				// Contains note corresponding
  100   				// to same index of currentobservers
  101      private int[] currentnotes;
  102   				// Array of note indices that
  103   				// corresponds to rows in
  104   				// the matrix that follows it
  105      private int[] noteidx;
  106      				// Matrix that describes observers
  107   				// that are associated with notes
  108   				// rows - note (corresponds to noteidx
  109   				// columns - contain vector of user
  110   				// 	indices
  111      private int[][] noteobservers;
  112   
  113      private WeakReference reportref;
  114   
  115   				/** Used to record time of calls to popupImage.
  116   				    Set to current time to prevent odd things
  117   				    from happening when differences are 
  118   				    recast to int. 
  119   				    @since J-Bird 0.1.1 */
  120      private long lastcall = System.currentTimeMillis();	
  121   				    
  122   
  123      /**
  124        * Big cheat. Pass the observerchooser so that I can get
  125        * the names. IndexedListChooser should have a mechanism
  126        * for providing both to listeners.
  127        *
  128      */
  129   
  130      public Ticker(JbirdDB db, ResourceBundle rb, 
  131   		JBirdOptions jo, LogListener logger, Frame owner,
  132   		ObserverChooser oc) {
  133   
  134   	dbase = db;
  135   	jbirdoptions = jo;
  136   	progres = rb;
  137   	owningframe = owner;
  138   	log = logger;
  139   	observerchooser = oc;
  140   
  141      	lifemessage = rb.getString("Life_tick_for");
  142      	regmessage  = rb.getString("Region_tick_for");
  143   	tripmessage = rb.getString("Trip_tick_for");
  144   	alreadymessage = rb.getString("Already_ticked_for");
  145   	failmessage = rb.getString("Tick_failed");
  146   	untickmessage = rb.getString("Untick_for");
  147   	nottickdmessage = rb.getString("Not_ticked");
  148      	tickbutton = new Button(rb.getString("Tick"));
  149      	untickbutton = new Button(rb.getString("Untick"));
  150   	annotatebutton = new Button(rb.getString("TickAnnotate"));
  151   	displaybutton = new Button(rb.getString("DisplayTicks"));
  152   
  153   	GridBagLayout gridbag = new GridBagLayout();
  154   	GridBagConstraints c = new GridBagConstraints();
  155   	c.insets = inset;
  156   	setLayout(gridbag);
  157   
  158   	c.gridwidth = 1;
  159   	c.gridheight = 1;
  160   	c.gridx = 0;
  161   	c.gridy = 0;
  162   
  163   	add(tickbutton, c);
  164   
  165   	c.gridx = 2;
  166   	add(annotatebutton, c);
  167   
  168   	c.gridx = 3;
  169   	add(untickbutton, c);
  170   
  171   	c.gridx = 4;
  172   	add(displaybutton, c);
  173   
  174   	checkStatus();
  175   
  176      	TickButtonListener tickbuttonlistener = new TickButtonListener();
  177   	tickbutton.addActionListener(tickbuttonlistener);
  178   	
  179      	UnTickButtonListener untickbuttonlistener = new UnTickButtonListener();
  180   	untickbutton.addActionListener(untickbuttonlistener);
  181   	
  182   	annotatebutton.addActionListener(new AnnotateButtonListener());
  183   	displaybutton.addActionListener(new DisplayButtonListener());
  184   
  185   	gratifyqueue = new AVQueue(3000, owner);
  186      }
  187   
  188   	/**
  189   	  * Return currently selected species, which should be -1
  190   	  * no species is selected.
  191   	  * @since J-Bird 0.1.4
  192   	  *
  193   	*/
  194   
  195      public final int getSelectedSpecies() {
  196   	return currentspecies;
  197      }
  198   
  199      private final void checkStatus() {
  200   	if (currentregion == -1 || currenttrip == -1 ||
  201   	    currentobservers == null || currentobservers.length == 0 ||
  202   	    currentspecies == -1) {
  203   		tickbutton.setEnabled(false);
  204   		untickbutton.setEnabled(false);
  205   		annotatebutton.setEnabled(false);
  206   	} else {
  207   		tickbutton.setEnabled(true);
  208   		untickbutton.setEnabled(true);
  209   		annotatebutton.setEnabled(true);
  210   	}
  211      }
  212   
  213      class TickRegionListener implements IntarrayListener {
  214   	public void receiveIntarray(int[] intarray) {
  215   		if (intarray == null || intarray.length == 0) {
  216   			currentregion = -1;
  217   		} else {
  218   			currentregion = intarray[0];
  219   		}
  220   		checkStatus();
  221   	}
  222      }
  223   
  224      public final IntarrayListener passRegionListener() {
  225   	return regionlistener;
  226      }
  227   
  228      class TickTripListener implements IntarrayListener {
  229   	public void receiveIntarray(int[] intarray) {
  230   		if (intarray == null || intarray.length == 0) {
  231   			currenttrip = -1;
  232   			currentripdate = null;
  233   		} else {
  234   			currenttrip = intarray[0];
  235   			currentripdate = 
  236   				dbase.getTripDate(currenttrip);
  237   		}
  238   		checkStatus();
  239   	}
  240      }
  241   
  242      public final IntarrayListener passTripListener() {
  243   	return triplistener;
  244      }
  245   
  246      class TickObserverListener implements IntarrayListener {
  247   	public void receiveIntarray(int[] intarray) {
  248   		currentobservers = (int[])intarray.clone();
  249   		currentobsnames = 
  250   			     observerchooser.picklist.getSelectedItems();
  251   		checkStatus();
  252   	}
  253      }
  254   
  255      public IntarrayListener passObserverListener() {
  256   	return observerlistener;
  257      }
  258   
  259      class TickSpeciesListener implements IntegerListener {
  260   	public void receiveInteger (int intvalue) {
  261   		currentspecies = intvalue;
  262   		checkStatus();
  263   	}
  264      }
  265   
  266      public final IntegerListener passSpeciesListener() {
  267   	return specieslistener;
  268      }
  269   
  270   
  271      /**
  272        * Tick current species for current observers.
  273        * 
  274        * Logs attempts to retick species
  275        *
  276      */
  277   
  278      private final void tickSpecies () {
  279   	tickSpecies(currentobservers, currentobsnames, true);
  280      }
  281   
  282      /**
  283        * Tick current species for current observers.
  284        *
  285        * Logs attempts to tick again as indicated.
  286        *
  287      */
  288   
  289      private final void tickSpecies (boolean logalready) {
  290   	tickSpecies(currentobservers, currentobsnames, logalready);
  291      }
  292   
  293   
  294      /**
  295        * Tick identified observers.  
  296        * <p>
  297        * Called from updateNotes.
  298        *
  299      */
  300   
  301      private final void tickSpecies (int[] obsnos, String[] obsnames,
  302   		boolean logalready) {
  303           int i;
  304   	for (i = 0; i < obsnos.length; i++ ) {
  305   		tickObserver(obsnos[i], obsnames[i], logalready);
  306   	}
  307   	if (! hasFocus()) requestFocus();
  308      }
  309   
  310      private final void tickObserver(int observer, String obsname,
  311   		boolean logalready) {
  312   	int ticktype = dbase.tickType(currentregion, currenttrip, 
  313   			currentripdate, observer, currentspecies);
  314   	Object[] oba = new Object[1];
  315   	oba[0] = obsname;
  316   	String logmessage = null;
  317   	switch (ticktype) {
  318   		case 0:
  319   							// already ticked
  320   			if (logalready) {
  321   			   logmessage = MessageFormat.format(alreadymessage,
  322   					oba);
  323   			   log.trace(logmessage);
  324   			   alreadyTicked();
  325   			}
  326   			return;
  327   		case 1:
  328   							// trip tick
  329   			logmessage = MessageFormat.format(tripmessage,
  330   					oba);
  331   			newTripTick();
  332   			break;
  333   		case 2:
  334   							// region tick
  335   			logmessage = MessageFormat.format(regmessage, oba);
  336   			newRegionTick(logmessage);
  337   			break;
  338   		case 3:
  339   							// life tick
  340   			logmessage = MessageFormat.format(lifemessage, 
  341   					oba);
  342   			newLifeTick(logmessage);
  343   			break;
  344   		default:
  345   							// internal error
  346   			log.popupError(MessageFormat.format(failmessage, 
  347   						oba), false);
  348   			return;
  349   	}
  350   	int rc = dbase.tickSpecies(currenttrip, observer, currentspecies);
  351   	if (rc == 1) {
  352   	   log.trace(logmessage);
  353   	} else {
  354   	   log.popupError(MessageFormat.format(failmessage, oba), false);
  355   	}
  356      }
  357   
  358      private final void untickSpecies() {
  359           int i;
  360   	Object[] oba = new Object[1];
  361   	for (i = 0; i < currentobservers.length; i++ ) {
  362   		String oname = currentobsnames[i];
  363   		oba[0] = oname;
  364   		int rc = dbase.untickSpecies(currenttrip,
  365   			currentobservers[i], currentspecies);
  366   		if (rc >= 1) {
  367   		   log.trace(MessageFormat.format(untickmessage, oba));
  368   		} else if (rc == 0) {
  369   		   log.trace(MessageFormat.format(nottickdmessage, oba));
  370   		} else {
  371   		   log.trace(MessageFormat.format(failmessage, oba));
  372   		}
  373   	}
  374   	if (! hasFocus()) requestFocus();
  375      }
  376   
  377      class TickButtonListener implements ActionListener {
  378   	public void actionPerformed(ActionEvent a) {
  379   		Color fg = tickbutton.getForeground();
  380   		Color bg = tickbutton.getBackground();
  381   		tickbutton.setForeground(bg);
  382   		tickbutton.setBackground(fg);
  383   		tickSpecies();
  384   		tickbutton.setForeground(fg);
  385   		tickbutton.setBackground(bg);
  386   	}
  387      }
  388   
  389      class UnTickButtonListener implements ActionListener {
  390   	public void actionPerformed(ActionEvent a) {
  391   		Color fg = untickbutton.getForeground();
  392   		Color bg = untickbutton.getBackground();
  393   		untickbutton.setForeground(bg);
  394   		untickbutton.setBackground(fg);
  395   		untickSpecies();
  396   		untickbutton.setForeground(fg);
  397   		untickbutton.setBackground(bg);
  398   	}
  399      }
  400   
  401      class AnnotateButtonListener implements ActionListener {
  402   	public void actionPerformed(ActionEvent a) {
  403   		Color fg = annotatebutton.getForeground();
  404   		Color bg = annotatebutton.getBackground();
  405   		annotatebutton.setForeground(bg);
  406   		annotatebutton.setBackground(fg);
  407   		tickAndAnnotateSpecies();
  408   		annotatebutton.setForeground(fg);
  409   		annotatebutton.setBackground(bg);
  410   	}
  411      }
  412    
  413      class DisplayButtonListener implements ActionListener {
  414   	public void actionPerformed(ActionEvent a) {
  415   		Color fg = displaybutton.getForeground();
  416   		Color bg = displaybutton.getBackground();
  417   		displaybutton.setForeground(bg);
  418   		displaybutton.setBackground(fg);
  419   		displayTicks();
  420   		displaybutton.setForeground(fg);
  421   		displaybutton.setBackground(bg);
  422   	}
  423      }
  424   
  425      private final void newLifeTick(String message) {
  426   	boolean gratify = false;
  427   	gratifyitem[0] = null;
  428   	gratifyitem[1] = null;
  429   	gratifyitem[2] = null;
  430   	if (jbirdoptions.lifepopup) {
  431   	   String file = jbirdoptions.lifeimage;
  432   	   if (file != null) {
  433   		gratifyitem[0] = message;
  434   		gratifyitem[1] = file;
  435   		gratify = true;
  436   	   } 
  437   	}
  438   	if (jbirdoptions.lifesound) {
  439   	   String file = jbirdoptions.lifesoundbite;
  440   	   if (file != null) {
  441   		gratifyitem[2] = file;
  442   		gratify = true;
  443   	   }
  444   	} else {	// play trip tick if trip ticks are played
  445   		if (jbirdoptions.ticksound) {
  446   	   		String file = jbirdoptions.ticksoundbite;
  447   	   		if (file != null) {
  448   				gratifyitem[2] = file;
  449   				gratify = true;
  450   			}
  451   		}
  452   	}
  453   	if (gratify) {
  454   		gratifyqueue.add(gratifyitem);
  455   	}
  456      }
  457   
  458      private final void newRegionTick(String message) {
  459   	boolean gratify = false;
  460   	gratifyitem[0] = null;
  461   	gratifyitem[1] = null;
  462   	gratifyitem[2] = null;
  463   	if (jbirdoptions.regionpopup) {
  464   	   String file = jbirdoptions.regionimage;
  465   	   if (file != null) {
  466   		gratifyitem[0] = message;
  467   		gratifyitem[1] = file;
  468   		gratify = true;
  469   	   }
  470   	}
  471   	if (jbirdoptions.regionsound) {
  472   	   String file = jbirdoptions.regionsoundbite;
  473   	   System.out.println("trip region should play sound");
  474   	   if (file != null) {
  475   		gratifyitem[2] = file;
  476   		gratify = true;
  477   	   }
  478   	} else {	// play trip tick if trip ticks are played
  479   		if (jbirdoptions.ticksound) {
  480   	   		String file = jbirdoptions.ticksoundbite;
  481   	   		if (file != null) {
  482   				gratifyitem[2] = file;
  483   				gratify = true;
  484   			}
  485   		}
  486   	}
  487   	if (gratify) {
  488   		gratifyqueue.add(gratifyitem);
  489   	}
  490      }
  491   
  492      private final void newTripTick() {
  493   	if (jbirdoptions.ticksound) {
  494   	   String file = jbirdoptions.ticksoundbite;
  495   	   if (file != null) {
  496   		gratifyitem[0] = null;
  497   		gratifyitem[1] = null;
  498   		gratifyitem[2] = file;
  499   		gratifyqueue.add(gratifyitem);
  500   	   }
  501   	}
  502      }
  503   
  504   	/**
  505   	  * Play error sound if options allow it.
  506   	  * @since J-Bird 0.1.2
  507   	  *
  508   	*/
  509   
  510      private final void alreadyTicked() {
  511   	if (jbirdoptions.errorsound) {
  512   	   String file = jbirdoptions.errorsoundbite;
  513   	   if (file != null) {
  514   		gratifyitem[0] = null;
  515   		gratifyitem[1] = null;
  516   		gratifyitem[2] = file;
  517   		gratifyqueue.add(gratifyitem);
  518   	   }
  519   	}
  520      }
  521   
  522      private final void tickAndAnnotateSpecies() {
  523   	System.out.println("pressed Tick / Annotate");
  524   	// tick those puppies
  525   	tickSpecies(false);	// false to not report repeat ticks in log
  526   	getNoteIndices();
  527   	checkMissingNotes();
  528   	//printNoteIndices();
  529   	updateNotes();
  530   	if (! hasFocus()) requestFocus();
  531      }
  532   
  533   	/**
  534   	  * -1's in currentnotes array indicate that no note was
  535   	  * present for a species and that the species was not ticked.
  536   	  * File entries for these observers in the matrix noteobservers.
  537   	  *
  538   	*/
  539   
  540      private final void checkMissingNotes() {
  541   	int maxi = currentnotes.length;
  542   	int i;
  543   	for (i = 0; i < maxi; i++) {
  544   		if (currentnotes[i] == -1) {
  545   			if (jbirdoptions.individualnotes == false) {
  546   				System.out.println("checkMissingNotes: calling fileObserver");
  547   				fileObserver(-2, currentobservers[i]);
  548   			} else {
  549   				System.out.println("checkMissingNotes: calling fileObserverForceNew");
  550   				fileObserverForceNew(-2, currentobservers[i]);
  551   			}
  552   		}
  553   	}
  554      }
  555   
  556      private final void printNoteIndices() {
  557   	System.out.println("printNoteIndices");
  558   	if (currentnotes == null) {
  559   		System.out.println("currentnotes == null");
  560   		return;
  561   	}
  562   	int i;
  563   	for (i = 0; i < currentnotes.length; i++) {
  564   		System.out.println("number " + i + 
  565   		   "\tcurrentnotes= " + currentnotes[i]);
  566   	}
  567   	for (i = 0; i < noteidx.length; i++) {
  568   		System.out.println("number " + 
  569   					i + 
  570   					"\tnoteidx = " + 
  571   					noteidx[i]);
  572   		int j = 0;
  573   		// following commented out for debugging.
  574   		// while (j < currentnotes.length && noteobservers[i][j] >= 0) {
  575   		while (j < currentnotes.length) {
  576   			System.out.println("\t\tobserver = " +
  577   				noteobservers[i][j]);
  578   			j++;
  579   		}
  580   	}
  581      }
  582   
  583      /* When this routine exits the following should exist
  584   	currentnotes[] - for each observer contains the
  585   			 note index 
  586   			 -1 if note the species is not already ticked
  587   				for the observer and if no note is present
  588   			 -2 if the species is already ticked but no note
  589   				exists
  590      */
  591   
  592      private final void getNoteIndices() {
  593   	currentnotes = null;
  594   	noteidx = null;
  595   	noteobservers = null;
  596   	
  597   	currentnotes = new int[currentobservers.length];
  598   	noteidx = new int[currentobservers.length];
  599   	noteobservers = new int[currentobservers.length]
  600   			       [currentobservers.length];
  601   	initializeNoteInfo();		// everything to -1
  602   	ResultSet noters = dbase.getNoteInfo(currenttrip,
  603   				currentobservers, currentspecies);
  604   	if (noters == null) {
  605   		return;
  606   	}
  607   	try {
  608   		noters.beforeFirst();
  609   		int idxobs = 0;
  610   		int idxnote = 0;
  611   		while (noters.next()) {
  612   			int obsnum = noters.getInt("Observer");
  613   			int notenum = noters.getInt("NoteNo");
  614   			if (noters.wasNull() || notenum == 0) {
  615   				notenum = -2;	// tick but no note
  616   			}
  617   			fileNote(notenum, obsnum);
  618   			if (notenum != -2 || 
  619   			    jbirdoptions.individualnotes == false) {
  620   				System.out.println("calling fileObserver");
  621   				fileObserver(notenum, obsnum);
  622   			} else {
  623   				System.out.println("calling fileObserverForceNew");
  624   				fileObserverForceNew(notenum, obsnum);
  625   			}
  626   		}
  627   		System.out.println("getNoteIndices: finished extracting");
  628   	}
  629   	catch (SQLException e) {
  630   		dbase.unanticipatedError("Ticker.getNoteIndices: " +
  631   			e.getMessage());
  632   		currentnotes = null;
  633   		noteidx = null;
  634   		noteobservers = null;
  635   		return;
  636   	}
  637   	finally {
  638   		dbase.closeSqlQuery(noters);
  639   	}
  640   	System.out.println("getNoteIndices: normal return");
  641   	return;
  642      }
  643   
  644      /**
  645        * Set all values to -1
  646        *
  647      */
  648   
  649      private final void initializeNoteInfo() {
  650   	int len = currentobservers.length;
  651   	int i,j;
  652   	for (i = 0; i < len; i++) {
  653   		currentnotes[i] = -1;
  654   		noteidx[i] = -1;
  655   		for (j = 0; j < len; j++) {
  656   			noteobservers[i][j] = -1;
  657   		}
  658   	}
  659      }
  660   
  661      /**
  662        * Stow the note number that is associated with an
  663        * observer
  664        *
  665      */
  666   
  667      private final void fileNote(int noteno, int observer) {
  668   	int i = 0;
  669   	while (observer != currentobservers[i]) {
  670   		i ++;
  671   	}
  672   	currentnotes[i] = noteno;
  673      }
  674   
  675      /**
  676        * Stow an observer that is associated with a note
  677        *
  678      */
  679   
  680      private final void fileObserver(int noteno, int observer) {
  681    
  682   	// first look up the note
  683   	int i = 0;
  684   	while (noteno != noteidx[i] && noteidx[i] != -1) {
  685   		i ++;
  686   	}
  687   	if (noteidx[i] == -1) {		// note not seen previously
  688   		noteidx[i] = noteno;
  689   		noteobservers[i][0] = observer;
  690   		return;
  691   	}
  692   	int j = 0;
  693   	while (noteobservers[i][j] != -1 && noteobservers[i][j] !=
  694   		observer) {
  695   		j ++;
  696   	}
  697   	noteobservers[i][j] = observer;
  698      }
  699   
  700      /**
  701        * Stow an observer that is associated with a note, but
  702        * force the use of a new row in the matrix even if
  703        * a row already exists for the specified note number.
  704        * <p>
  705        * This routine is used only when the note number is -2
  706        * indicating that there is not really a note.  It is used
  707        * to make places in the matrix for notes that must be
  708        * created in the data base.  For example, if none of the
  709        * observers has a note and if options call for each observer
  710        * to have a note.  In the final matrix all rows will be
  711        * associated with note -2 and will have only one column.
  712        * The column value will be that of one observer.
  713      */
  714   
  715      private final void fileObserverForceNew(int noteno, int observer) {
  716    
  717   		// first find the next unclaimed note holder
  718   	int i = 0;
  719   	while (noteidx[i] != -1) {
  720   		i ++;
  721   	}
  722   		// file the info
  723   	noteidx[i] = noteno;
  724   	noteobservers[i][0] = observer;
  725   	return;
  726      }
  727   
  728      private final void updateNotes() {
  729   
  730   	int i = 0;
  731   	String notes = null;
  732   	Collator col = Collator.getInstance();
  733   	while (i < noteidx.length && noteidx[i] != -1) {
  734   	   if (noteidx[i] > 0) {	// note exists
  735   		notes = dbase.getNoteText(noteidx[i]);
  736   	   } else {			// new note
  737   		notes = "<html>\n<head>\n</head>\n<body>\n</body>\n</html>\n";
  738   	   }
  739   				// checksum for detecting change
  740   	   CollationKey keycheck = col.getCollationKey(notes);
  741   				// observer numbers and names
  742   				// associated with note
  743              int[] trimmedobs = clipIntArray(noteobservers[i]);
  744   	   String[] trimmednames = correspondingNames(trimmedobs);
  745   				// be sure editor is ready
  746   	   texteditor.join();
  747   	   texteditor.setText(notes);
  748   	   texteditor.setTitle(buildEditorTitle(trimmednames));
  749   	   texteditor.setVisible(true); // this should block
  750   	   if (texteditor.getDisposition() == 1) { // user clicked save
  751   		System.out.println("updateNotes: user clicked save");
  752   		boolean emptydoc = texteditor.isDocumentEmpty();
  753   		String updatednotes = texteditor.getText();
  754   		CollationKey newkey = col.getCollationKey(updatednotes);
  755   		if (newkey.compareTo(keycheck) != 0) {  // note changed
  756   		   if (emptydoc) {           // delete  note
  757   		      dbase.unlinkNDeleteSpeciesNote(currenttrip, 
  758   				currentspecies,
  759                                   trimmedobs);
  760   		   } else if (noteidx[i] > -1) { // update  note
  761   		      dbase.updateNoteText(noteidx[i], updatednotes);
  762   		   } else {		     // add new note
  763   		      int newnumb = dbase.addNewNote(updatednotes);
  764   		      if (newnumb > -1) {
  765   			 dbase.linkSpeciesNote(currenttrip,
  766   				currentspecies,
  767   				trimmedobs,
  768   				newnumb);
  769   		      } else {
  770   		      	dbase.unanticipatedError("updateNotes: failed to " +
  771   				"obtain new note");
  772   		      }
  773   		   }
  774   		}
  775   	   }
  776   	   i += 1;
  777   	}
  778      }
  779   
  780      /**
  781        * Extract leading non-negative values from an array and
  782        * return them in a new array that contains no negative trailing       
  783        * elements.
  784        *
  785      */
  786   
  787      private final int[] clipIntArray(int[] arra) {
  788   	int maxi = 0;
  789   	while (maxi < arra.length && arra[maxi] >= 0) {
  790   		maxi ++;
  791   	}
  792   	int[] answer = new int[maxi];
  793   	int i;
  794   	for (i = 0; i < maxi; i++) {
  795   		answer[i] = arra[i];
  796   	}
  797   	return answer;
  798      }
  799   
  800      /**
  801        * Return a string array of names that correspond
  802        * to observer numbers in the argument.
  803        *
  804      */
  805   
  806      private final String[] correspondingNames(int[] obsnos) {
  807   	int len = obsnos.length;
  808   	String[] answer = new String[len];
  809   	int i;
  810   	int j;
  811   	for (i = 0; i < len; i++) {
  812   		boolean found = false;
  813   		j = 0;
  814   		while (!found && j < currentobservers.length) {
  815   			if (obsnos[i] == currentobservers[j]) {
  816   				found = true;
  817   				answer[i] = currentobsnames[j];
  818   			}
  819   			j ++;
  820   		}
  821   		if (! found) {
  822   			answer[i] = "";
  823   		}
  824   	}
  825   	return answer;
  826      }
  827   
  828      protected void setJTextEditor(JTextEditor ed) {
  829   	texteditor = ed;
  830      }
  831   
  832      protected JTextEditor getJTextEditor() {
  833   	return texteditor;
  834      }
  835   
  836      protected void setSpeciesSource(SpeciesNameIface iface) {
  837   	speciessource = iface;
  838      }
  839   
  840      protected String buildEditorTitle(String[] names) {
  841   			// start with species name
  842   	String[] specname = speciessource.getSpeciesName();
  843   	StringBuffer sb = new StringBuffer()
  844   				.append(specname[0])
  845   				.append(":");
  846   
  847   			// add observer names
  848   	for (int i = 0; i < names.length; i++) {
  849   		sb.append(" ")
  850   		  .append(names[i]);
  851   	}
  852   	
  853   	return sb.toString();
  854      }
  855   
  856   	/** 
  857   	  * Display trip ticks in browser. Invoked by listener
  858   	  * when the "Display ticks" button has been pushed.
  859   	  * @since J-Bird 0.1.1
  860   	  *
  861   	*/
  862   
  863      private final void displayTicks() {
  864   
  865   					// build reporter if necessary
  866   	TripReporter reporter = null;
  867   
  868   	if (reportref != null) {
  869   		reporter = (TripReporter)reportref.get();
  870   	}
  871   	if (reporter == null) {
  872   		try {
  873   			reporter = new TripReporter(dbase, jbirdoptions, progres);
  874   		}
  875   		catch(IOException e) {
  876   			dbase.oneParmMsg(5, "FailDisplayTicks", e.getMessage());
  877   			displaybutton.setEnabled(false);
  878   			return;
  879   		}
  880   		reporter.setTripInfo(false);
  881   		reporter.setTripNotes(false);
  882   		reporter.setCounts(true);
  883   		reporter.setObservers(true);
  884   		reporter.setSpeciesNotes(true);
  885   		reportref = new WeakReference(reporter);
  886   	}
  887   	reporter.setCommonNames(!jbirdoptions.scientificnames);
  888   	reporter.setCommonList(jbirdoptions.commonnamelist);
  889   	try {
  890   		reporter.writeReportToBrowser(currenttrip);
  891   	}
  892   	catch (Exception e) {
  893   		dbase.oneParmMsg(5, "FailDisplayTicks", e.getMessage());
  894   	}
  895   
  896   	reporter = null;
  897      }
  898   
  899   }

Save This Page
Home » openjdk-7 » net.sourceforge » jbird » [javadoc | source]