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.ComponentListenerThis class performs the drawing of the fractal, using a number of threads/runnables to compute the image in chunks.Each
Runnablehas 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 ofRunnables 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
Futurevalue used to count the number of completed runnables and cancel the tasks if needed. AnArrayListof 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 aLockandConditionis 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
MemoryImageSourcebacked 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.drawImageusingComponentimageUpdate()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 voidcomponentHidden(java.awt.event.ComponentEvent e)voidcomponentMoved(java.awt.event.ComponentEvent e)voidcomponentResized(java.awt.event.ComponentEvent e)voidcomponentShown(java.awt.event.ComponentEvent e)voidpaint(java.awt.Graphics g)voidrender()booleansetColorExpression(java.lang.String str)Parses a new expression for colorsbooleansetExpressionString(java.lang.String newString)Parses a new expressionvoidsetIterations(int iterations_in)Sets number of iterationsvoidshiftSelection(com.singularsys.jepexamples.applets.FractalCanvas.RegionListener regionListener)Responds to mouse drag events translates the scene.voidzoomIn(Complex mid)Zoom in the sceenvoidzoomOut()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:
paintin 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:
componentResizedin interfacejava.awt.event.ComponentListener
-
componentMoved
public void componentMoved(java.awt.event.ComponentEvent e)
- Specified by:
componentMovedin interfacejava.awt.event.ComponentListener
-
componentShown
public void componentShown(java.awt.event.ComponentEvent e)
- Specified by:
componentShownin interfacejava.awt.event.ComponentListener
-
componentHidden
public void componentHidden(java.awt.event.ComponentEvent e)
- Specified by:
componentHiddenin interfacejava.awt.event.ComponentListener
-
render
public void render()
-
-