package com.igormaznitsa.elife;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JOptionPane;
import com.igormaznitsa.elife.WorldModel.Cell;
/**
* The class describes the main form of the application
*
* @author Igor Maznitsa (igor.maznitsa@igormaznitsa.com)
* @version 1.00
*/
public class MainForm extends javax.swing.JFrame implements Runnable, ActionListener {
private WorldModel elifeWorldModelInstance;
/** Creates new form MainForm */
public MainForm() {
try {
elifeWorldModelInstance = new WorldModel(64, 64);
} catch (Throwable _thr) {
_thr.printStackTrace();
JOptionPane.showMessageDialog(null, "Fatal error [" + _thr.getMessage() + ']', "Fatal error", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
initComponents();
buttonClearAll.addActionListener(this);
buttonAbout.addActionListener(this);
elifeModelViewerComponent.addActionListener(this);
elifeModelViewerComponent.setWorldModel(elifeWorldModelInstance);
final Thread startThread = new Thread(this);
startThread.setDaemon(true);
startThread.start();
setVisible(true);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
toggleButtonProcess = new javax.swing.JToggleButton();
buttonClearAll = new javax.swing.JButton();
delaySlider = new javax.swing.JSlider();
elifeModelViewerComponent = new com.igormaznitsa.elife.ElifeModelViewer();
buttonAbout = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("E-Life v.1.00");
toggleButtonProcess.setText("Process");
toggleButtonProcess.setToolTipText("When the button is pressed the world will be alive");
buttonClearAll.setText("Clear all");
buttonClearAll.setToolTipText("Clear all cells on the world field");
delaySlider.setFont(new java.awt.Font("Arial", 0, 10)); // NOI18N
delaySlider.setMajorTickSpacing(500);
delaySlider.setMaximum(2000);
delaySlider.setMinimum(100);
delaySlider.setMinorTickSpacing(100);
delaySlider.setPaintLabels(true);
delaySlider.setPaintTicks(true);
delaySlider.setSnapToTicks(true);
delaySlider.setToolTipText("The slider allows you to choose the delay between iterations of the world life. The value of the slider in milliseconds.");
delaySlider.setBorder(javax.swing.BorderFactory.createTitledBorder("Delay between iterations (in milliseconds)"));
delaySlider.setRequestFocusEnabled(false);
javax.swing.GroupLayout elifeModelViewerComponentLayout = new javax.swing.GroupLayout(elifeModelViewerComponent);
elifeModelViewerComponent.setLayout(elifeModelViewerComponentLayout);
elifeModelViewerComponentLayout.setHorizontalGroup(
elifeModelViewerComponentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 412, Short.MAX_VALUE)
);
elifeModelViewerComponentLayout.setVerticalGroup(
elifeModelViewerComponentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 268, Short.MAX_VALUE)
);
buttonAbout.setText("About");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(elifeModelViewerComponent, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(delaySlider, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(toggleButtonProcess)
.addComponent(buttonClearAll))
.addComponent(buttonAbout))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonAbout, buttonClearAll, toggleButtonProcess});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(toggleButtonProcess)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(buttonClearAll)
.addGap(47, 47, 47)
.addComponent(buttonAbout))
.addComponent(elifeModelViewerComponent, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(delaySlider, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonAbout;
private javax.swing.JButton buttonClearAll;
private javax.swing.JSlider delaySlider;
private com.igormaznitsa.elife.ElifeModelViewer elifeModelViewerComponent;
private javax.swing.JToggleButton toggleButtonProcess;
// End of variables declaration//GEN-END:variables
@Override
public void run() {
try {
while (true) {
if (toggleButtonProcess.isSelected()) {
long time = System.currentTimeMillis();
elifeWorldModelInstance.processIteration();
elifeModelViewerComponent.repaint();
time = System.currentTimeMillis() - time;
final int delayTime = delaySlider.getValue();
if (time < delayTime) {
Thread.sleep(delayTime - time);
}
} else {
Thread.sleep(300);
}
}
} catch (Throwable _thr) {
_thr.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e == null) {
return;
}
final Object actionSource = e.getSource();
if (actionSource == null) {
return;
}
if (actionSource.equals(elifeModelViewerComponent)) {
if (toggleButtonProcess.isSelected()) {
// pressed
toggleButtonProcess.setSelected(false);
} else {
// stopped
final MouseEvent mouseEvent = elifeModelViewerComponent.getLastMouseEvent();
if (mouseEvent == null) {
return;
}
Point p_cellcoord = elifeModelViewerComponent.coordToCell(mouseEvent.getX(), mouseEvent.getY());
if (p_cellcoord == null) {
return;
}
boolean lg_set = mouseEvent.getButton() == MouseEvent.BUTTON1;
Cell p_cell = elifeWorldModelInstance.getCellAt(p_cellcoord.x, p_cellcoord.y);
if (lg_set) {
if (p_cell == null) {
elifeWorldModelInstance.createCell(p_cellcoord.x, p_cellcoord.y, 0);
}
} else {
if (p_cell != null) {
elifeWorldModelInstance.removeCell(p_cell);
}
}
elifeModelViewerComponent.repaint();
}
} else if (actionSource.equals(buttonClearAll)) {
if (toggleButtonProcess.isSelected()) {
// pressed
toggleButtonProcess.setSelected(false);
return;
} else if (elifeWorldModelInstance != null) {
elifeWorldModelInstance.clearAll();
}
elifeModelViewerComponent.repaint();
} else if (actionSource.equals(buttonAbout)) {
if (toggleButtonProcess.isSelected()) {
// pressed
toggleButtonProcess.setSelected(false);
}
final AboutDialog dialog = new AboutDialog(this, true);
dialog.setVisible(true);
}
}
}