Class FractalCanvas
- java.lang.Object
-
- java.awt.Component
-
- java.awt.Container
-
- javax.swing.JComponent
-
- javax.swing.JPanel
-
- com.singularsys.jepexamples.applets.FractalCanvas
-
- All Implemented Interfaces:
java.awt.event.ComponentListener
,java.awt.image.ImageObserver
,java.awt.MenuContainer
,java.io.Serializable
,java.util.EventListener
,javax.accessibility.Accessible
public class FractalCanvas extends javax.swing.JPanel implements java.awt.event.ComponentListener
This class performs the drawing of the fractal, using a number of threads/runnables to compute the image in chunks.Each
Runnable
has is own local version of Jep, and its own copy of the expression. These are set during construction of the runnable.Jep localJep = new Jep(new LightWeightComponentSet(jep)); ImportationVisitor iv = new ImportationVisitor(localJep); Node localExpression = iv.deepCopy(expression); Complex localC = new Complex(0, 0); // A single mutable value Complex localZ = new Complex(0, 0); localJep.addVariable("c", localC); localJep.addVariable("z", localZ);
These are copies are used in the main evaluation loop.
localC.set(x, y); localZ.set(0, 0); int count = 0; while (count < iterations && localZ.abs2() < 4.0) { localZ.set((Complex) localJep.evaluate(localExpression)); count++; }
Scheduling of threads is managed by a ThreadPoolExecutor with 10 threads
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
When a new image is needed a set ofRunnable
s is created and sent to the executor.try { for (int i = 0; i < nDivisions; ++i) { for (int j = 0; j < nDivisions; ++j) { Runnable blockRunner = new CalcBlockRunnable(i * wid, j * high, wid, high); Future<Integer> future = executor.submit(blockRunner, wid * high); synchronized (futures) { futures.add(future); } } } } catch (RejectedExecutionException ex) { System.out.println("Rejected execution " + ex.toString()); } catch (JepException ex) { System.out.println(ex); }
Each of these has a
Future
value used to count the number of completed runnables and cancel the tasks if needed. AnArrayList
of these futures is kept. If the screen needs to be redrawn before every task is finished then they are killed by first callingfuture.cancel(true)
and then purging them withexecutor.purge()
.An additional thread is used to collect statistics about completed tasks. A
ConcurrentLinkedDeque<Integer>
is used to send messages to this queue, and aLock
andCondition
is used to wake this thread when there is a new message.ConcurrentLinkedDeque<Integer> reportQueue = new ConcurrentLinkedDeque<Integer>(); Reporter reporter = new Reporter(); Thread reportThead = new Thread(reporter, "ReportThread"); reportThead.start(); // Lock for reporter private Lock lock = new ReentrantLock(); // Condition to signal when the reportQueue has data private Condition notEmpty = lock.newCondition();
Messages are sent to this queue using
lock.lock(); reportQueue.add(nItts); notEmpty.signal(); lock.unlock();
And the report thread waits for messages
lock.lock(); while(true) { while(reportQueue.isEmpty()) { notEmpty.awaitUninterruptibly(); } Integer itts = reportQueue.pollFirst(); ... }
The image is created using a
MemoryImageSource
backed by a shared pixel array.int[] pixels = new int[dimensions.width * dimensions.height]; MemoryImageSource source = new MemoryImageSource(dimensions.width, dimensions.height, pixels, 0, dimensions.width); source.setAnimated(true); Image outImage = Toolkit.getDefaultToolkit().createImage(source);
The pixels are simply set by the runnable
pixels[index] = Color.getRGB()
and when an entire block is finished image consumers are informed usingsource.newPixels(rect.x,rect.y,rect.width,rect.height )
. The paint method simply uses theGraphic.drawImage
usingComponent
imageUpdate()
callback method to paint more of the image as it becomes available.public void paint(Graphics g) { g.drawImage(outImage, 0, 0, this); }
- See Also:
- Serialized Form
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class javax.swing.JPanel
javax.swing.JPanel.AccessibleJPanel
-
Nested classes/interfaces inherited from class javax.swing.JComponent
javax.swing.JComponent.AccessibleJComponent
-
-
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 FractalCanvas(java.lang.String initialExpression, Fractal parent)
Constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
componentHidden(java.awt.event.ComponentEvent e)
void
componentMoved(java.awt.event.ComponentEvent e)
void
componentResized(java.awt.event.ComponentEvent e)
void
componentShown(java.awt.event.ComponentEvent e)
void
paint(java.awt.Graphics g)
void
render()
boolean
setColorExpression(java.lang.String str)
Parses a new expression for colorsboolean
setExpressionString(java.lang.String newString)
Parses a new expressionvoid
setIterations(int iterations_in)
Sets number of iterationsvoid
shiftSelection(com.singularsys.jepexamples.applets.FractalCanvas.RegionListener regionListener)
Responds to mouse drag events translates the scene.void
zoomIn(Complex mid)
Zoom in the sceenvoid
zoomOut()
Zoom out the scene.-
Methods inherited from class javax.swing.JPanel
getAccessibleContext, getUI, getUIClassID, paramString, setUI, updateUI
-
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, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, hide, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingOrigin, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, 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
-
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, 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
-
FractalCanvas
public FractalCanvas(java.lang.String initialExpression, Fractal parent)
Constructor.
-
-
Method Detail
-
setExpressionString
public boolean setExpressionString(java.lang.String newString)
Parses a new expression- Returns:
- true on successful parse
-
setColorExpression
public boolean setColorExpression(java.lang.String str)
Parses a new expression for colors- Returns:
- true on successful parse
-
setIterations
public void setIterations(int iterations_in)
Sets number of iterations- Parameters:
iterations_in
-
-
paint
public void paint(java.awt.Graphics g)
- Overrides:
paint
in classjavax.swing.JComponent
-
shiftSelection
public void shiftSelection(com.singularsys.jepexamples.applets.FractalCanvas.RegionListener regionListener)
Responds to mouse drag events translates the scene.
-
zoomIn
public void zoomIn(Complex mid)
Zoom in the sceen- Parameters:
mid
- midpoint of the new scene
-
zoomOut
public void zoomOut()
Zoom out the scene.
-
componentResized
public void componentResized(java.awt.event.ComponentEvent e)
- Specified by:
componentResized
in interfacejava.awt.event.ComponentListener
-
componentMoved
public void componentMoved(java.awt.event.ComponentEvent e)
- Specified by:
componentMoved
in interfacejava.awt.event.ComponentListener
-
componentShown
public void componentShown(java.awt.event.ComponentEvent e)
- Specified by:
componentShown
in interfacejava.awt.event.ComponentListener
-
componentHidden
public void componentHidden(java.awt.event.ComponentEvent e)
- Specified by:
componentHidden
in interfacejava.awt.event.ComponentListener
-
render
public void render()
-
-