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); } } }