uk.ac.starlink.topcat.plot2
Class PlotPanel<P,A>

java.lang.Object
  extended by java.awt.Component
      extended by java.awt.Container
          extended by javax.swing.JComponent
              extended by uk.ac.starlink.topcat.plot2.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:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class javax.swing.JComponent
JComponent.AccessibleJComponent
 
Nested classes/interfaces inherited from class java.awt.Container
Container.AccessibleAWTContainer
 
Nested classes/interfaces inherited from class java.awt.Component
Component.AccessibleAWTComponent, Component.BaselineResizeBehavior, Component.BltBufferStrategy, Component.FlipBufferStrategy
 
Field Summary
 
Fields inherited from class javax.swing.JComponent
accessibleContext, 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
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
PlotPanel(uk.ac.starlink.ttools.plot2.PlotType 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<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, BoundedRangeModel progModel, ToggleButtonModel showProgressModel, ToggleButtonModel axisLockModel, ToggleButtonModel auxLockModel)
          Constructor.
 
Method Summary
 void actionPerformed(ActionEvent evt)
          Invokes replot.
 void addChangeListener(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.
 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.
 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 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(Point pos)
          Returns the zone index for the surface whose data bounds enclose a given graphics position.
protected  void paintComponent(Graphics g)
          Paints the most recently cached plot icons.
 void removeChangeListener(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(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(Runnable annotator)
          Submits a runnable to run when the plot is not changing.
 void submitPlotAnnotator(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, getAccessibleContext, 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, getUIClassID, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, 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, transferFocusBackward, 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, 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, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, hide, 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, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setName, setSize, setSize, show, show, size, toString, transferFocus, 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 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<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,
                 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(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

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


Copyright © 2003-2018 CCLRC: Council for the Central Laboratory of the Research Councils. All Rights Reserved.