Class PlotPanel<P,A>

All Implemented Interfaces:
ActionListener, ImageObserver, MenuContainer, Serializable, EventListener

public class PlotPanel<P,A> extends JComponent implements ActionListener
Component which paints plot graphics for Topcat. This is the throbbing heart of the plot classes.

It is supplied at construction time with various objects capable of acquiring (presumably from a GUI) information required to specify a plot, and its replot method conceptually acquires all that information and prepares a plot accordingly. The plot is cached to an icon (probably an image) which is in turn painted by paintComponent. replot should therefore be called any time the plot information has changed, or may have changed.

In actual fact replot additionally expends a lot of effort to work out whether it can avoid doing some or all of the work required for the plot on each occasion, by caching and attempting to re-use the restults of various computational steps if they have not become outdated. The capability to do this as efficiently as possible drives quite a bit of the design of the rest of the plotting framework, in particular the requirement that a number of the objects determining plot content can be assessed for equality to tell whether they have changed materially since last time.

This component manages all the storage and caching of expensive (memory-intensive) resources: layer plans and data stores. Such resources should not be cached or otherwise held on to by long-lived reference elsewhere in the application.

This component also manages threading to get computation done in appropriate threads (and not on the EDT). At time of writing there are probably some improvements that can be made in that respect.

This component is an ActionListener - receiving any action will prompt a (potential) replot.

Since:
12 Mar 2013
Author:
Mark Taylor
See Also:
  • Constructor Details

    • PlotPanel

      public PlotPanel(uk.ac.starlink.ttools.plot2.PlotType<P,A> plotType, uk.ac.starlink.ttools.plot2.data.DataStoreFactory storeFact, uk.ac.starlink.ttools.plot2.SurfaceFactory<P,A> surfFact, Supplier<PlotContent<P,A>> contentSupplier, uk.ac.starlink.ttools.plot2.paper.PaperTypeSelector ptSel, uk.ac.starlink.ttools.plot2.paper.Compositor compositor, ToggleButtonModel sketchModel, BoundedRangeModel progModel, ToggleButtonModel showProgressModel, ToggleButtonModel axisLockModel, ToggleButtonModel auxLockModel)
      Constructor. Factories to gather various information required for the plot are passed in. These are interrogated when a (possibly) new plot is triggered.

      Information flow is, or should be, one way - this component reads the data and the plot does not have side-effects on its constituent components, since passing information both ways generally leads to a lot of confusion. In fact as currently written one GUI compoent, the AxisController, is passed in and can be affected. It would be better to sanitize that.

      A progress bar model is used so that progress can be logged whenever a scan through the data of one or several tables is under way. An alternative would be to pass a JProgressBar itself, so that a new model could be inserted every time a new progress operation started. That would actually be easier to use, but doing it this way makes it more obvious if multiple progress operations are happening concurrently, which as it stands they should not be.

      Parameters:
      plotType - plot type
      storeFact - data store factory implementation
      surfFact - surface factory
      contentSupplier - supplier for plot content
      ptSel - rendering policy
      compositor - compositor for composition of transparent pixels
      sketchModel - model to decide whether intermediate sketch frames are posted for slow plots
      progModel - progress bar model for showing plot progress
      showProgressModel - model to decide whether data scan operations are reported to the progress bar model
      axisLockModel - model to determine whether axis auto-rescaling should be inhibited
      auxLockModel - model to determine whether aux range auto-rescaling should be inhibited
  • Method Details

    • actionPerformed

      public void actionPerformed(ActionEvent evt)
      Invokes replot.
      Specified by:
      actionPerformed in interface ActionListener
    • replot

      public void replot()
      Call this on the event dispatch thread to indicate that the plot inputs may have changed, to trigger a new plot. The plot will be regenerated and painted at a later stage if required. This method is fairly cheap to call if the plot has not in fact changed.
    • submitExtraAnnotator

      public void submitExtraAnnotator(Runnable annotator)
      Submits a runnable to run when the plot is not changing. If the plot changes while it's in operation, it will be cancelled. The supplied runnable should watch for thread interruptions. Such runnables are notionally run on a different queue than the one doing the plot.
      Parameters:
      annotator - runnable, typically for annotating the plot in some sense
    • submitPlotAnnotator

      public void submitPlotAnnotator(Runnable annotator)
      Submits a runnable to run on the same queue as the plot itself. If the plot changes while it's in operation, it will be cancelled. The supplied runnable should watch for thread interruptions. Such runnables are notionally run on the same queue as the one doing the plot, so will only run when a plot is complete. They should use a GuiDataStore such as the one used by createGuiPointCloud method so that progress is logged as appropriate.
      Parameters:
      annotator - runnable to run on the plot queue
    • getDataStore

      public uk.ac.starlink.ttools.plot2.data.DataStore getDataStore()
      Returns the data store used in the most recent completed plot.
      Returns:
      data store
    • getGanger

      public uk.ac.starlink.ttools.plot2.Ganger<P,A> getGanger()
      Returns the ganger used for the most recently completed plot.
      Returns:
      ganger
    • getGang

      public uk.ac.starlink.ttools.plot2.Gang getGang()
      Returns zone arrangement gang for the most recently completed plot.
      Returns:
      zone gang
    • getZoneCount

      public int getZoneCount()
      Returns the number of zones in the most recently completed plot.
      Returns:
      zone count
    • getZoneControllers

      public List<ZoneController<P,A>> getZoneControllers()
      Returns the list of ZoneControllers used in the most recently completed plot.
      Returns:
      nzone-element list of zone controllers
    • getZoneIndex

      public int getZoneIndex(Point pos)
      Returns the zone index for the surface whose data bounds enclose a given graphics position. If the position is not within the data bounds of any displayed plot surface, -1 is returned.
      Parameters:
      pos - graphics position to query
      Returns:
      zone index, or -1
    • getSurface

      public uk.ac.starlink.ttools.plot2.Surface getSurface(int iz)
      Returns the plot surface of a given zone for the most recent completed plot.
      Parameters:
      iz - zone index
      Returns:
      plot surface
    • getPlotLayers

      public uk.ac.starlink.ttools.plot2.PlotLayer[] getPlotLayers(int iz)
      Returns the plot layers painted in a given zone for the most recent completed plot.
      Parameters:
      iz - zone index
      Returns:
      plot layers
    • getReports

      public uk.ac.starlink.ttools.plot2.ReportMap[] getReports(int iz)
      Returns the plot reports for a given zone generated by the most recent completed plot. The array elements correspond to those of the plot layers array.
      Parameters:
      iz - zone index
      Returns:
      per-layer plot reports
    • getPlotSpec

      public uk.ac.starlink.ttools.plot2.task.PlotSpec<P,A> getPlotSpec()
      Returns the plot specification for the most recently completed plot.
      Returns:
      plot specification
    • createGuiPointCloud

      public GuiPointCloud createGuiPointCloud(int iz)
      Returns a point cloud that describes all the point positions included in a given zone for the most recent plot. This contains all the points from all the subsets requested for plotting, including points not visible because they fell outside the plot surface. Iterating over the points described by the returned point cloud, when using the DataStore available from it, takes care of progress updates and thread interruptions.
      Parameters:
      iz - zone index
      Returns:
      positions in most recent plot
    • createPartialGuiPointCloud

      public GuiPointCloud createPartialGuiPointCloud(int iz)
      Returns a point cloud like that from createGuiPointCloud(int) but for partial positions - ones for which data positions will have one or more missing (NaN) coordinates.
      Parameters:
      iz - zone index
      Returns:
      partial positions in most recent plot
      See Also:
      • SubCloud.createPartialSubClouds(uk.ac.starlink.ttools.plot2.PlotLayer[], boolean)
    • getLatestSurface

      public uk.ac.starlink.ttools.plot2.Surface getLatestSurface(int iz)
      Returns the best guess for the plot surface of a given zone which will be displayed next. It may in fact be the surface for a plot which is currently being calculated.
      Parameters:
      iz - zone index
      Returns:
      most up-to-date plot surface
    • clearData

      public void clearData()
      Clears state to initial values, cancels any plots in progress, and disposes of potentially expensive memory assets.
    • setHighlights

      public void setHighlights(Map<uk.ac.starlink.ttools.plot2.SubCloud,double[]> highlightMap)
      Sets a list of points which should be highlighted in the plot. This overwrites any previously set highlights map, and triggers a replot. These highlights will be retained for as long as the given data specs are visible.
      Parameters:
      highlightMap - sequence of data positions labelled by SubCloud
    • setNavDecoration

      public void setNavDecoration(uk.ac.starlink.ttools.plot2.Decoration navDec)
      Sets a decoration giving visual feedback for navigation gestures. This decoration will overwrite any previously set value, and will be retained until overwritten with a null value. This method triggers a repaint, but not a replot; the data graphics are assumed to be unaffected.
      Parameters:
      navDec - navigation decoration, or null to erase it
    • paintComponent

      protected void paintComponent(Graphics g)
      Paints the most recently cached plot icons.
      Overrides:
      paintComponent in class JComponent
    • getOuterBounds

      public Rectangle getOuterBounds(PlotPosition plotpos)
      Returns the bounds to use for the plot icon. This includes axis decorations etc, but excludes component insets.
      Parameters:
      plotpos - plot position including explicit settings for external dimensions (padding not used here)
      Returns:
      plot drawing bounds
    • addChangeListener

      public void addChangeListener(ChangeListener listener, boolean allChanges)
      Adds a listener which will be messaged when the displayed plot changes. The allChanges parameter indicates what plot changes are of interest; if false, then only changes to the plot axes and layers will be notified, but if true then decoration changes (legend and navigation indicators) will trigger a notification as well.
      Parameters:
      listener - plot change listener
      allChanges - true to get all changes, false for only substantial changes
    • removeChangeListener

      public void removeChangeListener(ChangeListener listener)
      Removes a listener previously added.
      Parameters:
      listener - plot change listener
    • createExportIcon

      public Icon createExportIcon(boolean forceBitmap)
      Returns an icon corresponding to the current state of this panel. This method executes quickly, but the returned icon's paintIcon method might take time. The returned value is immutable, and its behaviour is not affected by subsequent changes to this panel.
      Parameters:
      forceBitmap - true to force bitmap output of vector graphics, false to use default behaviour
      Returns:
      icon