@@ -0,0 +1,1601 @@
+package com.annimon.jecp.se;%0D%0A%0D%0Aimport com.annimon.jecp.ApplicationListener;%0D%0Aimport java.awt.Dimension;%0D%0Aimport java.awt.Graphics;%0D%0Aimport java.awt.image.BufferedImage;%0D%0Aimport javax.swing.JPanel;%0D%0A%0D%0A/**%0D%0A *%0D%0A * @author aNNiMON%0D%0A */%0D%0Apublic class JecpPaintPanel extends JPanel %7B%0D%0A    %0D%0A    private final ApplicationListener listener;%0D%0A    private final DrawingThread thread;%0D%0A    private final BufferedImage image;%0D%0A    private final JecpGraphics graphics;%0D%0A    %0D%0A    public JecpPaintPanel(ApplicationListener listener, int width, int height) %7B%0D%0A        this.listener = listener;%0D%0A        setFocusable(true);%0D%0A        setPreferredSize(new Dimension(width, height));%0D%0A        %0D%0A        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);%0D%0A        graphics = new JecpGraphics(image.getGraphics());%0D%0A        %0D%0A        thread = new DrawingThread();%0D%0A        thread.keepRunning = true;%0D%0A        thread.start();%0D%0A    %7D%0D%0A    %0D%0A    @Override%0D%0A    protected void paintComponent(Graphics g) %7B%0D%0A        super.paintComponent(g);%0D%0A        listener.onPaint(graphics);%0D%0A        g.drawImage(image, 0, 0, null);%0D%0A    %7D%0D%0A    %0D%0A    private class DrawingThread extends Thread %7B%0D%0A%0D%0A        private boolean keepRunning = true;%0D%0A%0D%0A        @Override%0D%0A        public void run() %7B%0D%0A            while (keepRunning) %7B%0D%0A                listener.onUpdate();%0D%0A                repaint();%0D%0A                try %7B%0D%0A                    Thread.sleep(5L);%0D%0A                %7D catch (InterruptedException ex) %7B%0D%0A                    Thread.currentThread().interrupt();%0D%0A                %7D%0D%0A            %7D%0D%0A        %7D%0D%0A    %7D%0D%0A%7D

Add JecpPaintPanel SE