Package uk.ac.starlink.topcat.plot2

## Class PlotPanel<P,​A>

- java.lang.Object
- - java.awt.Component
  - - java.awt.Container
    - - javax.swing.JComponent
      - - uk.ac.starlink.topcat.plot2.PlotPanel<P,​A>

- All Implemented Interfaces:
    `java.awt.event.ActionListener`, `java.awt.image.ImageObserver`, `java.awt.MenuContainer`, `java.io.Serializable`, `java.util.EventListener`

      public class PlotPanel<P,​A>
      extends javax.swing.JComponent
      implements java.awt.event.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:
    Serialized Form

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from class javax.swing.JComponent

      `javax.swing.JComponent.AccessibleJComponent`

    - ### Nested classes/interfaces inherited from class java.awt.Container

      `java.awt.Container.AccessibleAWTContainer`

    - ### Nested classes/interfaces inherited from class java.awt.Component

      `java.awt.Component.AccessibleAWTComponent, java.awt.Component.BaselineResizeBehavior, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy`

  - ### Field Summary

    - ### Fields inherited from class javax.swing.JComponent

      `listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW`

    - ### Fields inherited from class java.awt.Component

      `accessibleContext, BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT`

    - ### Fields inherited from interface java.awt.image.ImageObserver

      `ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH`

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---

    `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, Factory<uk.ac.starlink.ttools.plot2.Ganger<P,​A>> gangerFact, Factory<java.util.List<ZoneDef<P,​A>>> zonesFact, Factory<PlotPosition> posFact, uk.ac.starlink.ttools.plot2.paper.PaperTypeSelector ptSel, uk.ac.starlink.ttools.plot2.paper.Compositor compositor, ToggleButtonModel sketchModel, javax.swing.BoundedRangeModel progModel, ToggleButtonModel showProgressModel, ToggleButtonModel axisLockModel, ToggleButtonModel auxLockModel)`

    Constructor.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `actionPerformed​(java.awt.event.ActionEvent evt)` | Invokes replot.
    `void` | `addChangeListener​(javax.swing.event.ChangeListener listener, boolean allChanges)` | Adds a listener which will be messaged when the displayed plot changes.
    `void` | `clearData()` | Clears state to initial values, cancels any plots in progress, and disposes of potentially expensive memory assets.
    `javax.swing.Icon` | `createExportIcon​(boolean forceBitmap)` | Returns an icon corresponding to the current state of this panel.
    `GuiPointCloud` | `createGuiPointCloud​(int iz)` | Returns a point cloud that describes all the point positions included in a given zone for the most recent plot.
    `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.
    `uk.ac.starlink.ttools.plot2.data.DataStore` | `getDataStore()` | Returns the data store used in the most recent completed plot.
    `uk.ac.starlink.ttools.plot2.Gang` | `getGang()` | Returns zone arrangement gang for the most recently completed plot.
    `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.
    `java.awt.Rectangle` | `getOuterBounds​(PlotPosition plotpos)` | Returns the bounds to use for the plot icon.
    `uk.ac.starlink.ttools.plot2.PlotLayer[]` | `getPlotLayers​(int iz)` | Returns the plot layers painted in a given zone for the most recent completed plot.
    `uk.ac.starlink.ttools.plot2.task.PlotSpec<P,​A>` | `getPlotSpec()` | Returns the plot specification for the most recently completed plot.
    `uk.ac.starlink.ttools.plot2.ReportMap[]` | `getReports​(int iz)` | Returns the plot reports for a given zone generated by the most recent completed plot.
    `uk.ac.starlink.ttools.plot2.Surface` | `getSurface​(int iz)` | Returns the plot surface of a given zone for the most recent completed plot.
    `int` | `getZoneCount()` | Returns the number of zones in the most recently completed plot.
    `ZoneId` | `getZoneId​(int iz)` | Returns the zone ID of a given zone for the most recently completed plot.
    `int` | `getZoneIndex​(java.awt.Point pos)` | Returns the zone index for the surface whose data bounds enclose a given graphics position.
    `protected void` | `paintComponent​(java.awt.Graphics g)` | Paints the most recently cached plot icons.
    `void` | `removeChangeListener​(javax.swing.event.ChangeListener listener)` | Removes a listener previously added.
    `void` | `replot()` | Call this on the event dispatch thread to indicate that the plot inputs may have changed, to trigger a new plot.
    `void` | `setHighlights​(java.util.Map<uk.ac.starlink.ttools.plot2.SubCloud,​double[]> highlightMap)` | Sets a list of points which should be highlighted in the plot.
    `void` | `setNavDecoration​(uk.ac.starlink.ttools.plot2.Decoration navDec)` | Sets a decoration giving visual feedback for navigation gestures.
    `void` | `submitExtraAnnotator​(java.lang.Runnable annotator)` | Submits a runnable to run when the plot is not changing.
    `void` | `submitPlotAnnotator​(java.lang.Runnable annotator)` | Submits a runnable to run on the same queue as the plot itself.

    - ### Methods inherited from class javax.swing.JComponent

      `addAncestorListener, addNotify, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBaseline, getBaselineResizeBehavior, getBorder, getBounds, getClientProperty, getComponentGraphics, getComponentPopupMenu, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getFontMetrics, getGraphics, getHeight, getInheritsPopupMenu, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPopupLocation, getPreferredSize, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getUI, getUIClassID, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, hide, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingOrigin, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintImmediately, paintImmediately, paramString, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setComponentPopupMenu, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFocusTraversalKeys, setFont, setForeground, setInheritsPopupMenu, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update, updateUI`

    - ### Methods inherited from class java.awt.Container

      `add, add, add, add, add, addContainerListener, addImpl, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, getMousePosition, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusCycleRoot, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setLayout, transferFocusDownCycle, validate, validateTree`

    - ### Methods inherited from class java.awt.Component

      `action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getAccessibleContext, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, requestFocus, requestFocus, requestFocusInWindow, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setMixingCutoutShape, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### 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,
                           Factory<uk.ac.starlink.ttools.plot2.Ganger<P,​A>> gangerFact,
                           Factory<java.util.List<ZoneDef<P,​A>>> zonesFact,
                           Factory<PlotPosition> posFact,
                           uk.ac.starlink.ttools.plot2.paper.PaperTypeSelector ptSel,
                           uk.ac.starlink.ttools.plot2.paper.Compositor compositor,
                           ToggleButtonModel sketchModel,
                           javax.swing.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
        `gangerFact` - factory for defining how multi-zone plots are grouped
        `zonesFact` - acquires per-zone information
        `posFact` - supplier of plot position settings
        `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 Detail

    - #### actionPerformed

          public void actionPerformed​(java.awt.event.ActionEvent evt)

      Invokes replot.
      Specified by:
        `actionPerformed` in interface `java.awt.event.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​(java.lang.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​(java.lang.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

    - #### 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

    - #### getZoneIndex

          public int getZoneIndex​(java.awt.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

    - #### getZoneId

          public ZoneId getZoneId​(int iz)

      Returns the zone ID of a given zone for the most recently completed plot.
      Parameters:
        `iz` - zone index
      Returns:
        zone id

    - #### 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​(java.util.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​(java.awt.Graphics g)

      Paints the most recently cached plot icons.
      Overrides:
        `paintComponent` in class `javax.swing.JComponent`

    - #### getOuterBounds

          public java.awt.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​(javax.swing.event.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​(javax.swing.event.ChangeListener listener)

      Removes a listener previously added.
      Parameters:
        `listener` - plot change listener

    - #### createExportIcon

          public javax.swing.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