Package com.matis_digital.simulation.gui

Source Code of com.matis_digital.simulation.gui.MainWindow

package com.matis_digital.simulation.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.matis_digital.simulation.Constants;
import com.matis_digital.simulation.ParticleManager;
import com.matis_digital.simulation.gui.utils.Particle;

public class MainWindow extends JFrame implements Runnable
{
    private transient int                   screenWidth      = -1;
    private transient int                   screenHeight     = -1;
    private static final int                screenX          = 0;
    private static final int                screenY          = 0;
    public static final double              NANO_SECONDS     = 1E9;
    public static final double              MICRO_SECONDS    = 1E6;
    public static final double              MILLI_SECONDS    = 1E3;
    private static final long               serialVersionUID = 3796505324035585944L;
    private transient final ParticleManager _particles;
    public transient Thread                 loop             = null;
    private transient boolean               _rendered        = true;
    private transient int                   _renderCounter   = 0;
    private transient int                   _repaintCounter  = 0;
    private transient BufferedImage         _backBuffer;
    private transient Graphics2D            _bbGraphics;
    private transient long                  _renderTime;
    private transient long                  _repaintTime;
    private transient long                  _renderElapsed;
    private transient long                  _repaintElapsed;
    private boolean                         paused           = true;
    private boolean                         step             = false;
    private boolean                         trace            = false;
    private boolean                         info             = false;
    private boolean                         stats            = true;
    private transient double                renderFPS        = 50.0f;
    private transient double                repaintFPS       = 50.0f;
    private transient long                  renderDelayTime  = Math.round(NANO_SECONDS / renderFPS);
    private transient long                  repaintDelayTime = Math.round(NANO_SECONDS / repaintFPS);

    public MainWindow()
    {
        super();
        screenWidth = 1920 * 1;
        screenHeight = 1030;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setUndecorated(true);
        setTitle("Simulation_02");
        setSize(screenWidth, screenHeight);
        setLocationRelativeTo(null);
        setVisible(true);
        _backBuffer = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB);
        _bbGraphics = (Graphics2D) _backBuffer.getGraphics();
        _particles = ParticleManager.getInstance(Constants.PARTICLES, this);
        addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_SPACE)
                {
                    paused = !paused;
                }
                else if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                {
                    requestKill();
                }
                else if (e.getKeyCode() == KeyEvent.VK_PERIOD)
                {
                    step = true;
                    paused = true;
                }
                else if (e.getKeyCode() == KeyEvent.VK_T)
                {
                    trace = !trace;
                }
                else if (e.getKeyCode() == KeyEvent.VK_I)
                {
                    info = !info;
                }
                else if (e.getKeyCode() == KeyEvent.VK_S)
                {
                    stats = !stats;
                }
                else if (e.getKeyCode() == KeyEvent.VK_Q)
                {
                    renderFPS = Math.max(10.0, renderFPS - 10.0f);
                }
                else if (e.getKeyCode() == KeyEvent.VK_W)
                {
                    renderFPS = Math.min(500.0, renderFPS + 10.0f);
                }
                else if (e.getKeyCode() == KeyEvent.VK_E)
                {
                    repaintFPS = Math.max(10.0, repaintFPS - 10.0f);
                }
                else if (e.getKeyCode() == KeyEvent.VK_R)
                {
                    repaintFPS = Math.min(100.0, repaintFPS + 10.0f);
                }
                renderDelayTime = Math.round(NANO_SECONDS / renderFPS);
                repaintDelayTime = Math.round(NANO_SECONDS / repaintFPS);
            }
        });
    }

    @Override
    public void run()
    {

        final Thread thisThread = Thread.currentThread();
        while ((loop == thisThread) && (_particles.size() >= 1))
        {

            final long startTime = System.nanoTime();
            if (paused == false || step == true)
            {
                _renderCounter++;
                _particles.animate();
                step = false;
            }
            _rendered = false;

            repaint();
            // waitForPaint();
            final long stopTime = System.nanoTime();
            final long elepsedTime = stopTime - startTime;
            final long delta = renderDelayTime - elepsedTime;
            /* Cap at FPS */
            final long waitTime = (long) Math.max(delta, 0);
            try
            {
                Thread.sleep((long) (waitTime / MICRO_SECONDS));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            _renderTime = elepsedTime + waitTime;
            _renderElapsed = elepsedTime;
        }
        System.out.println("Render counter: " + _renderCounter);
        if (loop != null)
        {
            requestKill();
        }
        while (loop == thisThread)
        {
            _rendered = false;
            repaint();
            waitForPaint();
        }
        dispose();
    }

    private void requestKill()
    {
        final boolean isPaused = paused;
        paused = true;
        final int result = JOptionPane.showConfirmDialog(this, "Terminate simulation?");
        if (result == JOptionPane.YES_OPTION)
        {
            loop = null;
        }
        paused = isPaused;
    }

    @Override
    public void paint(Graphics g)
    {
        if (_rendered == false)
        {
            final long startTime = System.nanoTime();
            if (_particles != null)
            {
                _bbGraphics.clearRect(getDisplayX(), getDisplayY(), getDisplayWidth(), getDisplayHeight());
                if (trace == true)
                {
                    for (int idx = 0; idx < _particles.size(); idx++)
                    {
                        final Particle particle = _particles.get(idx);
                        particle.drawTrace(_bbGraphics);
                    }
                }
                for (int idx = 0; idx < _particles.size(); idx++)
                {
                    final Particle particle = _particles.get(idx);
                    particle.draw(_bbGraphics, false);
                    if (info == true)
                    {
                        final FontRenderContext frc = _bbGraphics.getFontRenderContext();
                        final String infoString = particle.toString();
                        final Rectangle2D rect = _bbGraphics.getFont().getStringBounds(infoString, frc);
                        double x = particle.x;
                        double y = particle.y;
                        if (x < getDisplayX())
                        {
                            x = getDisplayX();
                        }
                        if ((x + rect.getWidth()) > getDisplayWidth())
                        {
                            x = getDisplayWidth() - rect.getWidth();
                        }
                        if (y < getDisplayY())
                        {
                            y = getDisplayY() + rect.getHeight();
                        }
                        if ((y + rect.getHeight()) > getDisplayHeight())
                        {
                            y = getDisplayHeight();
                        }
                        _bbGraphics.setPaint(particle.getColor());
                        _bbGraphics.drawString(infoString, (int) x, (int) y);
                    }
                }
            }
            if (stats == true)
            {
                renderStats(_bbGraphics);
            }
            // It is best to dispose() a Graphics object when done with it.
            g.drawImage(_backBuffer, getDisplayX(), getDisplayY(), getDisplayWidth(), getDisplayHeight(), null);
            final long stopTime = System.nanoTime();
            final long elepsedTime = stopTime - startTime;
            final long delta = repaintDelayTime - elepsedTime;
            final long waitTime = (long) Math.max(delta, 0);
            synchronized (this)
            {
                _rendered = true;
                notify();
            }
            try
            {
                Thread.sleep((long) (waitTime / MICRO_SECONDS));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            _repaintTime = elepsedTime + waitTime;
            _repaintElapsed = elepsedTime;
            _repaintCounter++;
        }
    }

    @Override
    public void update(Graphics g)
    {
        paint(g);
    }

    private void waitForPaint()
    {
        synchronized (this)
        {
            while (_rendered == false)
            {
                try
                {
                    wait();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    private void renderStats(final Graphics2D g)
    {
        int y = 20;
        g.setColor(Color.YELLOW);
        g.drawString("Render cycles: " + _renderCounter, 20, y);
        y += 20;
        g.drawString("Render Elapsed(ms) : " + String.format("%.5g", _renderElapsed / MICRO_SECONDS), 20, y);
        y += 20;
        g.drawString("Render FPS : " + String.format("%.5g", NANO_SECONDS / _renderTime), 20, y);
        y += 20;
        g.drawString("Repaint count: " + _repaintCounter, 20, y);
        y += 20;
        g.drawString("Repaint Elapsed(ms): " + String.format("%.5g", _repaintElapsed / MICRO_SECONDS), 20, y);
        y += 20;
        g.drawString("Repaint FPS: " + String.format("%.5g", NANO_SECONDS / _repaintTime), 20, y);
        y += 20;
        g.drawString("Particles left: " + String.valueOf(_particles.size()), 20, y);
        y += 20;
        g.drawString("Pause [space]: " + (paused ? "true" : "false"), 20, y);
        y += 20;
        g.drawString("Step [period]: " + (step ? "true" : "false"), 20, y);
        y += 20;
        g.drawString("Stats [s]: " + (stats ? "true" : "false"), 20, y);
        y += 20;
        g.drawString("Info [i]: " + (info ? "true" : "false"), 20, y);
        y += 20;
        g.drawString("Trace [t]: " + (trace ? "true" : "false"), 20, y);
        y += 20;
        g.drawString("RenderFPS [<< q, w >>]: " + String.format("%.5g", renderFPS), 20, y);
        y += 20;
        g.drawString("RepaintFPS [<< e, r >>]: " + String.format("%.5g", repaintFPS), 20, y);
    }

    public int getDisplayWidth()
    {
        return screenWidth;
    }

    public int getDisplayHeight()
    {
        return screenHeight;
    }

    public int getDisplayX()
    {
        return screenX;
    }

    public int getDisplayY()
    {
        return screenY;
    }

}
TOP

Related Classes of com.matis_digital.simulation.gui.MainWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.