sim.app.lsystem.RuleUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
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