All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.app.lsystem.RuleUI Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  Copyright 2006 by Daniel Kuebrich
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

// Class RuleUI
package sim.app.lsystem;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import sim.util.gui.*;

// This class becomes the Rules pane of the Console

public class RuleUI extends JPanel
    {
    private static final long serialVersionUID = -8650952120231540392L;
    // components
    JButton buttonGo = new JButton("Calculate");
    JButton buttonCancel = new JButton("Cancel");
    JButton buttonSave = new JButton("Save");
    JButton buttonLoad = new JButton("Load");
    JButton buttonHelp = new JButton("Help");

    // put the table in its own scroll pane, as the console is not too big
    JTable ruleTable = new JTable(20,2);
    JScrollPane scrollPane = new JScrollPane(ruleTable);
    
    JProgressBar calcProgress = new JProgressBar(0,100);
    
    JTextField seedField = new JTextField("F-F-F-F", 10);
    JTextField stepField = new JTextField("3", 3);
    
    // help panel (see very end of the init() function for elaboration on this)
    JPanel helpPanel = new JPanel();
    
    // references to sim with ui, sim state
    LSystemWithUI lsui;
    LSystem ls;
    
    // so that we can update the draw settings tab also
    DrawUI dui;
    
    // for calculation thread
    int steps=0;                // expansions
    Runnable calcRunnable;
    Thread calcThread;
    Object lock = new Object();
    boolean stop = false;
    
    // returns the frame that should be used as the parent frame for dialogs
    public Frame getFrame()
        {
        Component c = this;
        
        while(c.getParent() != null)
            c = c.getParent();
        
        return (Frame)c;
        }
    
    
    // this is currently used only by buttonGo
    // it takes the currently entered data for rules and sends it to the LSystem.LSystemData intstance
    void getRulesFromUI()
        {
        // set l-system parameters
            
        // seed
        ls.l.seed = seedField.getText();
        LSystemData.setVector(ls.l.code, ls.l.seed);
        // expansions
        ls.l.expansions = Integer.valueOf(stepField.getText()).intValue();
        
        // erase old rules
        ls.l.rules.clear();
        
        // build new rule list
        for(int r=0; r 0 && ((String)(ruleTable.getValueAt(r,0))).length() > 0)
                    ls.l.rules.add( new Rule( (byte)(((String)(ruleTable.getValueAt(r,0))).
                                substring(0,1).charAt(0)), (String)ruleTable.
                            getValueAt(r,1)) );
            }
        
        // set # of expansions
        steps = Integer.valueOf(stepField.getText()).intValue();
        }
    
    
    // constructor
    public RuleUI(LSystemWithUI nLsui, DrawUI nDui)
        {
        lsui = nLsui;
        ls = (LSystem)lsui.state;
        dui = nDui;
        
        try
            {
            init();
            }
        catch (Exception e)
            {
            e.printStackTrace();
            }
        }
    
    
    
    public void init()
        {
        // This runnable calculates the expansions of the L-system when the "Calculate"
        // button is pushed.  Because it runs in a separate thread, it can conveniently 
        // be cancelled, and updates a JProgressBar to show that it is still thinking.
        calcRunnable = new Runnable()
            {
            public void run()
                {
                int h=0; //number of expansions
                int p=0; //position in original code
                int r=0; //rule check index
                boolean ruleApplied = false; // has a rule been applied to this symbol yet
                
                // Speed... Make a new ByteList and copy into there
                // instead of inserting into the old one and shifting the elements over...
                // Also, I have not written an insert function, so this is a double bonus.
                ByteList newCode;
                newCode = new ByteList(ls.l.code.b.length);
                
                // main expanion loop
                while(true)
                    {
                    // stop if external stop requested
                    // this occurrs when the cancel button is pressed
                    synchronized(lock)
                        {
                        if(stop)
                            break;
                        }
                    
                    // stop if enough expansions have been completed
                    if(h >= steps)
                        break;
                    
                    // else keep expanding
                    ruleApplied = false;        // reset this
                    
                    for(r=0; r= 1.4...
                    if(p%100 == 0)
                        {
                        SwingUtilities.invokeLater(
                            new Runnable()
                                {
                                public void run()
                                    {
                                    int i = calcProgress.getValue();
                                    if(i < 100)
                                        i++;
                                    else
                                        i = 0;
                                    
                                    calcProgress.setValue(i);
                                    }
                                }
                            );
                        }
                     
                    // an expansion has been completed
                    // hurray
                    if(p >= ls.l.code.length)
                        {
                        p = 0;
                        h++;
                        ls.l.code = newCode;
                        newCode = new ByteList(ls.l.code.length);
                        }
                    }
                // end main expansion loop

                // on successful end, enable calculate and disable cancel buttons
                SwingUtilities.invokeLater(
                    new Runnable()
                        {
                        public void run()
                            {
                            buttonGo.setEnabled(true);
                            buttonCancel.setEnabled(false);
                            calcProgress.setValue(0);
                            calcProgress.setString("Done!");
                            }
                        }
                    );
            
                }// end run
            };
        
        // buttonGo calculates the expansions of the rules from the given seed
        buttonGo.addActionListener(new ActionListener()
            {
            public void actionPerformed(ActionEvent e)
                {
                getRulesFromUI();
                
                // now we will begin..
                calcProgress.setString("Calculating...");
                
                // expand
                // in a separate thread
                stop = false;
                calcThread = new Thread(calcRunnable);
                calcThread.start();
                
                // juggle buttons
                buttonCancel.setEnabled(true);
                buttonGo.setEnabled(false);
                }
            });
                
        // buttonCancel stops an expansion being processed (started by buttonGo "Calculate")
        buttonCancel.addActionListener(new ActionListener()
            {
            public void actionPerformed(ActionEvent e)
                {
                synchronized(lock)
                    {
                    // let the thread stop on its own...
                    stop = true;
                    }
                
                // but wait for it
                try
                    {
                    calcThread.join();
                    }
                catch (Exception ex)
                    {
                    ex.printStackTrace();
                    }
                
                // reset buttons
                calcProgress.setValue(0);
                calcProgress.setString("Cancelled");
                buttonCancel.setEnabled(false);
                buttonGo.setEnabled(true);
                }
            });
        
        
        // buttonSave saves the current seed, rules, draw settings, and expansions
        // Saves the data after a Calculate has been executed.. so if you
        // Enter data A
        // then Calculate
        // then Enter data B
        // then save, you will be saving data A.
        // so be careful!
        buttonSave.addActionListener(new ActionListener()
            {
            public void actionPerformed(ActionEvent e)
                {
                try
                    {

                    JOptionPane.showMessageDialog( getFrame(), 
                        "IF you have changed the settings since the last time you calculated the L-system,
"+ "the L-system you save will be the one last calculated--not the current data!" ); // show save dialog FileDialog fd = new FileDialog(getFrame(), "Save Current L-System Settings As", FileDialog.SAVE); fd.setFile("Untitled.lss"); fd.setVisible(true);; // on cancel, return if(fd.getFile() == null) return; // else do the thing File outputFile = new File(fd.getDirectory(), fd.getFile()); FileOutputStream outputFileStream = new FileOutputStream(outputFile); java.util.zip.GZIPOutputStream g = new java.util.zip.GZIPOutputStream( new BufferedOutputStream(outputFileStream)); ObjectOutputStream out = new ObjectOutputStream(g); out.writeObject(ls.l); // now need to do a little dance with the GZIPOutputStream to write // this stuff out correctly -- see sim.engine.SimState.writeToCheckpoint(OutputStream) // for more info out.flush(); g.finish(); g.flush(); out.close(); } catch (Exception ex) { ex.printStackTrace(); } } }); // buttonLoad loads the file's seed, rule, and expansions buttonLoad.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { // show load dialog FileDialog fd = new FileDialog(getFrame(), "Open L-System Settings File (.lss)", FileDialog.LOAD); fd.setFile("*.lss"); fd.setVisible(true);; // on cancel, return if(fd.getFile() == null) return; File inputFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream inputFileStream = new FileInputStream(inputFile); ObjectInputStream in = new ObjectInputStream( new java.util.zip.GZIPInputStream(new BufferedInputStream(inputFileStream))); ls.l = (LSystemData)in.readObject(); in.close(); // change UI fields to reflect newly loaded settings // seed seedField.setText(ls.l.seed); // # expansions stepField.setText(String.valueOf(ls.l.expansions)); // line size dui.distField.setText(String.valueOf(ls.l.segsize)); // angle... has been stored in radians, so un-radian it dui.angleField.setText(String.valueOf(ls.l.angle*180/Math.PI)); // x, y // --- unneccessary now that Display2D options do this //dui.xField.setText(String.valueOf(ls.l.x)); //dui.yField.setText(String.valueOf(ls.l.y)); // rules // first clear table for(int t=0; t




© 2015 - 2025 Weber Informatics LLC | Privacy Policy