first commit

This commit is contained in:
Boris
2024-01-15 20:14:10 +00:00
commit 8c81ee28b7
3106 changed files with 474415 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
/**
* A GUI for the environment, with runtime controls.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class EnvironmentView extends JFrame
{
// The longest delay for the animation, in milliseconds.
private static final int LONGEST_DELAY = 1000;
// Colors for the different cell states.
private static final Color[] colors = {
Color.WHITE, // Alive
new Color(68, 100, 129), // Dead
new Color(204, 196, 72), // Dying
};
private GridView view;
private final Environment env;
private boolean running;
private int delay;
/**
* Constructor for objects of class EnvironmentView
* @param env
*/
public EnvironmentView(Environment env, int rows, int cols)
{
super("2D Cellular Automaton");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocation(20, 20);
this.env = env;
this.running = false;
setDelay(50);
setupControls();
setupGrid(rows, cols);
pack();
setVisible(true);
}
/**
* Setup a new environment of the given size.
* @param rows The number of rows.
* @param cols The number of cols;
*/
private void setupGrid(int rows, int cols)
{
Container contents = getContentPane();
view = new GridView(rows, cols);
contents.add(view, BorderLayout.CENTER);
}
/**
* Show the states of the cells.
*/
public void showCells()
{
Cell[][] cells = env.getCells();
if(!isVisible()) {
setVisible(true);
}
view.preparePaint();
for(int row = 0; row < cells.length; row++) {
Cell[] cellRow = cells[row];
int numCols = cellRow.length;
for(int col = 0; col < numCols; col++) {
int state = cellRow[col].getState();
view.drawMark(col, row, colors[state]);
}
}
view.repaint();
}
/**
* Set up the animation controls.
*/
private void setupControls()
{
// Continuous running.
final JButton run = new JButton("Run");
run.addActionListener(e -> {
if(!running) {
running = true;
try {
new Runner().execute();
}
catch(Exception ex) {
}
}
});
// Single stepping.
final JButton step = new JButton("Step");
step.addActionListener(e -> {
running = false;
env.step();
showCells();
});
// Pause the animation.
final JButton pause = new JButton("Pause");
pause.addActionListener(e -> running = false);
// Reset of the environment
final JButton reset = new JButton("Reset");
reset.addActionListener(e -> {
running = false;
env.reset();
showCells();
});
// Randomize the environment.
final JButton randomize = new JButton("Random");
randomize.addActionListener(e -> {
running = false;
env.randomize();
showCells();
});
Container contents = getContentPane();
// A speed controller.
final JSlider speedSlider = new JSlider(0, 100);
speedSlider.addChangeListener(e -> {
setDelay(speedSlider.getValue());
});
Container speedPanel = new JPanel();
speedPanel.setLayout(new GridLayout(2, 1));
speedPanel.add(new JLabel("Animation Speed", SwingConstants.CENTER));
speedPanel.add(speedSlider);
contents.add(speedPanel, BorderLayout.NORTH);
// Place the button controls.
JPanel controls = new JPanel();
controls.add(run);
controls.add(step);
controls.add(pause);
controls.add(reset);
controls.add(randomize);
contents.add(controls, BorderLayout.SOUTH);
}
/**
* Set the animation delay.
* @param speedPercentage (100-speedPercentage) as a percentage of the LONGEST_DELAY.
*/
private void setDelay(int speedPercentage)
{
delay = (int) ((100.0 - speedPercentage) * LONGEST_DELAY / 100);
}
/**
* Provide stepping of the animation.
*/
private class Runner extends SwingWorker<Boolean, Void>
{
@Override
/**
* Repeatedly single-step the environment as long
* as the animation is running.
*/
public Boolean doInBackground()
{
while(running) {
env.step();
showCells();
try {
Thread.sleep(delay);
}
catch(InterruptedException e) {
}
}
return true;
}
}
/**
* Provide a graphical view of a rectangular grid.
*/
@SuppressWarnings("serial")
private class GridView extends JPanel
{
private final int GRID_VIEW_SCALING_FACTOR = 10;
private final int gridWidth, gridHeight;
private int xScale, yScale;
private Dimension size;
private Graphics g;
private Image fieldImage;
/**
* Create a new GridView component.
*/
public GridView(int height, int width)
{
gridHeight = height;
gridWidth = width;
size = new Dimension(0, 0);
}
/**
* Tell the GUI manager how big we would like to be.
*/
@Override
public Dimension getPreferredSize()
{
return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
gridHeight * GRID_VIEW_SCALING_FACTOR);
}
/**
* Prepare for a new round of painting. Since the component
* may be resized, compute the scaling factor again.
*/
public void preparePaint()
{
if(! size.equals(getSize())) {
size = getSize();
fieldImage = view.createImage(size.width, size.height);
g = fieldImage.getGraphics();
xScale = size.width / gridWidth;
if(xScale < 1) {
xScale = GRID_VIEW_SCALING_FACTOR;
}
yScale = size.height / gridHeight;
if(yScale < 1) {
yScale = GRID_VIEW_SCALING_FACTOR;
}
}
}
/**
* Paint on grid location on this field in a given color.
*/
public void drawMark(int x, int y, Color color)
{
g.setColor(color);
g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);
}
/**
* The field view component needs to be redisplayed. Copy the
* internal image to screen.
*/
@Override
public void paintComponent(Graphics g)
{
if(fieldImage != null) {
Dimension currentSize = getSize();
if(size.equals(currentSize)) {
g.drawImage(fieldImage, 0, 0, null);
}
else {
// Rescale the previous image.
g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);
}
}
}
}
}