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 bypaintComponent
.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
-
-
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
-
-
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 fromcreateGuiPointCloud(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
-
-
-
-
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 typestoreFact
- data store factory implementationsurfFact
- surface factorygangerFact
- factory for defining how multi-zone plots are groupedzonesFact
- acquires per-zone informationposFact
- supplier of plot position settingsptSel
- rendering policycompositor
- compositor for composition of transparent pixelssketchModel
- model to decide whether intermediate sketch frames are posted for slow plotsprogModel
- progress bar model for showing plot progressshowProgressModel
- model to decide whether data scan operations are reported to the progress bar modelaxisLockModel
- model to determine whether axis auto-rescaling should be inhibitedauxLockModel
- 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 interfacejava.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 bycreateGuiPointCloud
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 fromcreateGuiPointCloud(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 classjavax.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. TheallChanges
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 listenerallChanges
- 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
-
-