//Josiah Greenewald //DPS1 term project //12/8/03 //Import everything import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.*; import javax.swing.event.*; import java.awt.image.BufferedImage.*; import java.awt.Image.*; import javax.swing.border.EtchedBorder.*; import javax.swing.plaf.BorderUIResource.EtchedBorderUIResource.*; import javax.swing.border.AbstractBorder.*; import javax.swing.plaf.BorderUIResource.*; import javax.swing.BorderFactory.*; import javax.swing.border.*; import javax.swing.JMenuItem.*; import javax.swing.JMenu.*; import javax.swing.JComponent.*; import java.awt.image.*; import java.io.File.*; import java.io.*; import javax.imageio.*; import java.util.ArrayList.*; import java.util.AbstractList.*; import java.util.AbstractCollection.*; import java.util.Vector.*; import java.util.*; import javax.swing.*; import javax.swing.JWindow.*; import java.awt.Frame.*; import java.awt.Component.*; import java.awt.Window.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.awt.*; import java.util.*; //import java.awt.Graphics2D.*; //import java.awt.geom.Line2D.*; //import java.awt.geom.Line2D.Double.*; import java.awt.geom.*; //------------------------------------------------ public class DPSTermProject { //main method: set up the window public static void main(String[] args) { final TermProjectGUIFrame frame = new TermProjectGUIFrame(); //TermProjectSplash splash = new TermProjectSplash("splashScreen.jpg",frame, 500); //frame.splashAnim(frame, "splashScreen.jpg", 1000, 500); frame.splashAnim(frame, "splashScreen.jpg", 300, 6000); frame.init(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.show(); } } //------------------------------------------------- class TermProjectGUIFrame extends JFrame { //instance variables: private JComboBox examples; private JTextField axiom; private JSlider numIterations; private JSlider angle; //private JTextArea replacementRules; private JList replacementRules; private JTextArea alphabet; private JTextArea edit; private JTextArea rule; private String axiomText = ""; private int iterateNum = 1; private double angleVal; private String prodRuleF; private String prodRuleX; private String prodRuleY; private String prodRuleZ; private String prodRuleW; private String prodRulef; private String prodRuleR; private String prodRuleL; private String prodRuleA; private String prodRuleB; private String prodRuleH; private String prodRuleJ; private BufferedImage image; private JFileChooser chooser; public JColorChooser colorChooser; private File file; private String[] theRules; private TermProjectIsland2 imagePanel; private Color color; private JTextField stepField; private JTextField startHeadField; private Graphics g; private TermProjectLSystem2 lsystem; private String instruction; private TermProjectTurtle2 t; private int startY; private int startX; private JTextField angleField; //constructor public TermProjectGUIFrame() { setTitle("L-System Generator"); setSize(920, 740); theRules = new String[10]; //theRules[0] = ("Add a rule to replace the specified character in the axiom with the specified string"); colorChooser = new JColorChooser(); color = Color.WHITE; //color = colorChooser.getColor(); } public void buildGUI() { //build GUI and do all component actions:*********** final Container contentPane = getContentPane(); //examples comboboxand label:------------------------------- JLabel label1 = new JLabel("Examples:"); examples = new JComboBox(new Object[] { "New", "Tree 1", "Tree 2", "Tree 3", "Tree 4", "Tree 5", "Tree 6", "Koch's Snowflake", "Koch Curve 1", "Koch Curve 2", "Koch Curve 3", "Koch Curve 4", "Koch Curve 5", "Koch Curve 6", "Koch Curve 7", "Koch Curve 8", "FASS Curve 1", "FASS Curve 2", "FASS Curve 3", "Dagon", "Double Penrose", "Peanol", "Plant 1", "Plant 2", "Sierpinkski's Carpet", "Mason Sucks" }); //examples action: examples.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //have if statement and methods for each pattern to set the //variables and input controls to the specified settings. //treeExample = (String)examples.getSelectedItem(); //axiom.setText(Lsystem.getName(treeExample)); //MIGHT NEED TO SPECIFY STARTING POSITION AND HEADING FOR EACH CASE if(examples.getSelectedIndex() == 0) { //leave everything blank iterateNum = 0; angleVal = 0; axiomText = null; //prodRuleF = ""; //theRules[0] = ("Add a rule to replace the specified character in the axiom with the specified string"); for(int i=0; i<10;i++) theRules[i] = null; stepField.setText("0"); startHeadField.setText("0"); angleField.setText("0"); } else if(examples.getSelectedIndex() == 1) { //tree 1 iterateNum = 5; angleVal = 25.7; axiomText = "F"; prodRuleF = "F[+F]F[-F]F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("2.1"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 2) { //tree 2 iterateNum = 5; angleVal = 20; axiomText = "F"; prodRuleF = "F[+F]F[-F][F]"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("8"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 3) { //tree 3 iterateNum = 4; angleVal = 22.5; axiomText = "F"; prodRuleF = "FF-[-F+F+F]+[+F-F-F]"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("9"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 4) { //tree 4 iterateNum = 7; angleVal = 20; axiomText = "X"; prodRuleX = "F[+X]F[-X]+X"; prodRuleF = "FF"; theRules[0] = ("X => "+prodRuleX); theRules[1] = ("F => "+prodRuleF); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("2.1"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 5) { //tree 5 iterateNum = 7; angleVal = 25.7; axiomText = "X"; prodRuleX = "F[+X][-X]FX"; prodRuleF = "FF"; theRules[0] = ("X => "+prodRuleX); theRules[1] = ("F => "+prodRuleF); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("2"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 6) { //tree 6 iterateNum = 5; angleVal = 22.5; axiomText = "X"; prodRuleX = "F-[[X]+X]+F[+FX]-X"; prodRuleF = "FF"; theRules[0] = ("X => "+prodRuleX); theRules[1] = ("F => "+prodRuleF); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("6.5"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 7) { //Koch's SnowFlake iterateNum = 4; angleVal = 60; axiomText = "+F++F++F"; prodRuleF = "F-F++F-F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("5.3"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 8) { //koch curve 1 iterateNum = 4; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "FF-F-F-F-F-F+F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("3.5"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 9) { //koch curve 2 iterateNum = 4; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "FF-F-F-F-FF"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("6.2"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 10) { //koch curve 3 iterateNum = 3; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "FF-F+F-F-FF"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("23.5"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 11) { //koch curve 4 iterateNum = 4; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "FF-F--F-F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("6.2"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 12) { //koch curve 5 iterateNum = 5; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "F-FF--F-F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("5.8"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 13) { //koch curve 6 iterateNum = 4; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "F-F+F-F-F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("13.5"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 14) { //koch curve 7 iterateNum = 2; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "F+FF-FF-F-F+F+FF-F-F+F+FF+FF-F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("7.7"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 15) { //koch curve 8 iterateNum = 4; angleVal = 90; axiomText = "-F++F-"; prodRuleF = "F+F-F-F+F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("6.1"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 16) { //FASS CURVE 1 iterateNum = 2; angleVal = 90; axiomText = "F+F+F+F"; prodRuleF = "F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF"; prodRulef = "ffffff"; theRules[0] = ("F => "+prodRuleF); theRules[1] = ("f => "+prodRulef); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("7.8"); startHeadField.setText("270"); } else if(examples.getSelectedIndex() == 17) { //FASS CURVE 2 iterateNum = 4; angleVal = 60; axiomText = "L"; prodRuleL = "L+R++R-L--LL-R+"; prodRuleR = "-L+RR++R+L--L-R"; theRules[0] = ("L => "+prodRuleL); theRules[1] = ("R => "+prodRuleR); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("8.8"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 18) { //FASS CURVE 3 iterateNum = 2; angleVal = 90; axiomText = "-R"; prodRuleL = "LL-R-R+L+L-R-RL+R+LLR-L+R+LL+R-LR-R-L+L+RR-"; prodRuleR = "+LL-R-R+L+LR+L-RR-L-R+LRR-L-RL+L+R-R-L+L+RR"; theRules[0] = ("R => "+prodRuleR); theRules[1] = ("L => "+prodRuleL); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("20"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 19) { //DRAGON iterateNum = 10; angleVal = 90; axiomText = "L"; prodRuleL = "L+RF+"; prodRuleR = "-FL-R"; theRules[1] = ("R => "+prodRuleR); theRules[0] = ("L => "+prodRuleL); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("7.2"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 20) { //double penrose iterateNum = 3; angleVal = 36; axiomText = "[X][Y]++[X][Y]++[X][Y]++[X][Y]++[X][Y]"; prodRuleW = "YF++ZF----XF[-YF----WF]++"; prodRuleX = "+YF--ZF[---WF--XF]+"; prodRuleY = "-WF++XF[+++YF++ZF]-"; prodRuleZ = "--YF++++WF[+ZF++++XF]--XF"; theRules[0] = ("W => "+prodRuleW); theRules[1] = ("X => "+prodRuleX); theRules[2] = ("Y => "+prodRuleY); theRules[3] = ("Z => "+prodRuleZ); for(int i=4; i<10;i++) theRules[i] = null; stepField.setText("28"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 21) { //peanol iterateNum = 3; angleVal = 90; axiomText = "F-F-F-F"; prodRuleF = "F-F+F+F+F-F-F-F+F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("7.2"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 22) { //plant 1 iterateNum =2; angleVal = 12; axiomText = "F"; prodRuleF = "F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("60"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 23) { //plant 2 iterateNum =4; angleVal =14; axiomText = "Y"; prodRuleX = "X[-FFF][+FFF]FX"; prodRuleY = "YFX[+Y][-Y]"; theRules[0] = ("X => "+prodRuleX); theRules[1] = ("Y => "+prodRuleY); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("20"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 24) { //serpinskis carpet iterateNum = 4; angleVal = 90; axiomText = "F"; prodRuleF = "F+F-F-F-f+F+F+F-F"; prodRulef = "fff"; theRules[0] = ("F => "+prodRuleF); theRules[1] = ("f => "+prodRulef); for(int i=2; i<10;i++) theRules[i] = null; stepField.setText("6.2"); startHeadField.setText("0"); } else if(examples.getSelectedIndex() == 25) { //mason sucks iterateNum = 3; angleVal = 96; axiomText = "F-F-F-F-F-F-F-F-F-F-F-F-F-F-F"; prodRuleF = "FF-F-F-F-FF"; theRules[0] = ("F => "+prodRuleF); for(int i=1; i<10;i++) theRules[i] = null; stepField.setText("13"); startHeadField.setText("270"); } axiom.setText(axiomText); numIterations.setValue(iterateNum); angle.setValue((int)angleVal); replacementRules.setListData(theRules); redraw(); //CALL ALL METHODS TO BUILD THE SYSTEM } }); //textfield and label for axiom:-------------------------------- JLabel label2 = new JLabel("Axiom:"); axiom = new JTextField(axiomText); //axiom action: axiom.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { redraw(); } }); //slider for number of iterations------------------------ JLabel sliderLabel = new JLabel("Number of Iterations:"); numIterations = new JSlider(0, 10, 0); numIterations.setMajorTickSpacing(1); numIterations.setMinorTickSpacing(1); numIterations.setPaintTicks(true); numIterations.setPaintLabels(true); //numIterations slider action: numIterations.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { //redraw(); } }); //slider and label for the angle of rotation----------------------- JLabel angleLabel = new JLabel("Angle of Rotation:"); angle = new JSlider(-180, 180, 0); angle.setMajorTickSpacing(60); angle.setMinorTickSpacing(20); angle.setPaintTicks(true); angle.setPaintLabels(true); //action for angle slider angle.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { Math.toRadians(angle.getValue()); angleField.setText(String.valueOf(angle.getValue())); redraw(); } }); angleField = new JTextField(1); angleField.setText(String.valueOf(angle.getValue())); angleField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { angle.setValue(Integer.parseInt(angleField.getText())); } }); //color button and action:-------------------------- //this doesnt work b/c i cant get the image to update with the new color passed in JButton colorButton = new JButton("Choose Color"); colorButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { color = colorChooser.showDialog(imagePanel, "Choose a Color", Color.green); redraw(); } }); //alphabet text area--------------------------------- JLabel alphabetLabel = new JLabel("Alphabet:"); alphabet = new JTextArea(); alphabet.setBackground(Color.lightGray); alphabet.append(" F,L,R: forward, draw line\n"); alphabet.append(" f: forward, no line\n"); alphabet.append(" +: turn right by angle\n"); alphabet.append(" -: turn left by angle\n"); alphabet.append(" [: start a branch\n"); alphabet.append(" ]: end a branch"); alphabet.setEditable(false); //left side panel layout setup:---------------------------- JPanel westPanel = new JPanel(); GridBagLayout layout = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); westPanel.setLayout(layout); //layout for example label: c.anchor = GridBagConstraints.WEST; c.ipadx = 10; c.insets.left = 5; c.insets.right = 5; c.insets.top = 0; c.insets.bottom = 5; c.gridx = 0; c.gridy = 0; layout.setConstraints(label1, c); westPanel.add(label1); //layout for example c.anchor = GridBagConstraints.CENTER; c.insets.top = 0; c.insets.bottom = 20; c.gridx = 0; c.gridy = 1; layout.setConstraints(examples, c); westPanel.add(examples); //layout for axiom label c.anchor = GridBagConstraints.WEST; c.insets.top = 0; c.insets.bottom = 5; c.gridx = 0; c.gridy = 3; layout.setConstraints(label2, c); westPanel.add(label2); //layout for axiom c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets.top = 0; c.insets.bottom = 20; c.gridx = 0; c.gridy = 4; layout.setConstraints(axiom, c); westPanel.add(axiom); //layout for numIt slider label c.weightx = 0; c.fill = 0; c.insets.top = 0; c.insets.bottom = 5; c.gridx = 0; c.gridy = 6; layout.setConstraints(sliderLabel, c); westPanel.add(sliderLabel); //layout for numIt slider c.insets.top = 0; c.insets.bottom = 20; c.gridx = 0; c.gridy = 7; c.fill = GridBagConstraints.HORIZONTAL; layout.setConstraints(numIterations, c); westPanel.add(numIterations); //layout for angle slider label c.fill = 0; c.insets.top = 0; c.insets.bottom = 5; c.gridx = 0; c.gridy = 9; layout.setConstraints(angleLabel, c); westPanel.add(angleLabel); c.insets.left = 55; //c.insets.right = 20; c.anchor = GridBagConstraints.CENTER; c.insets.top = 0; c.insets.bottom = 5; c.gridx = 0; c.gridy = 9; layout.setConstraints(angleField, c); westPanel.add(angleField); //layout for angle slider c.anchor = GridBagConstraints.WEST; c.insets.left = 5; c.insets.right = 5; c.fill = GridBagConstraints.HORIZONTAL; c.insets.top = 0; c.insets.bottom = 20; c.gridx = 0; c.gridy = 11; layout.setConstraints(angle, c); westPanel.add(angle); //layout for color button c.fill = 0; c.anchor = GridBagConstraints.CENTER; c.insets.top = 0; c.insets.bottom = 20; c.gridx = 0; c.gridy = 12; layout.setConstraints(colorButton, c); westPanel.add(colorButton); //layout for alphabet label c.anchor = GridBagConstraints.CENTER; c.insets.top = 0; c.insets.bottom = 7; c.gridx = 0; c.gridy = 14; layout.setConstraints(alphabetLabel, c); westPanel.add(alphabetLabel); //layout for alphabet pane c.insets.top = 0; c.insets.bottom = 0; c.gridx = 0; c.gridy = 15; JScrollPane alphabetPane = new JScrollPane(alphabet); layout.setConstraints(alphabetPane, c); westPanel.add(alphabetPane); //this is only created once and the color is determined in its class so the initial color stays the same. //find out a way to set the color using the turtle class so it can be call from the create pattern button. imagePanel = new TermProjectIsland2(colorChooser.getColor()); imagePanel.repaint(); //bottom panel layout setup JPanel southPanel = new JPanel(); JPanel rulePanel = new JPanel(); JLabel rulesLabel = new JLabel("Replacement Rules:"); replacementRules = new JList(theRules); replacementRules.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); replacementRules.setFixedCellHeight(12); replacementRules.setFixedCellWidth(582); JScrollPane pane = new JScrollPane(replacementRules); JPanel replacePanel = new JPanel(); JLabel replaceLabel = new JLabel("Rule: "); rule = new JTextArea(1, 3); JScrollPane pane2 = new JScrollPane(rule); JLabel arrow = new JLabel("=>"); edit = new JTextArea(1, 45); JScrollPane pane3 = new JScrollPane(edit); replacePanel.add(replaceLabel); replacePanel.add(pane2); replacePanel.add(arrow); replacePanel.add(pane3); JButton addButton = new JButton("Add Rule"); addButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if((rule.getText() != "") && (edit.getText() != "")) { String putBack = (rule.getText() + "=>" + edit.getText()); for(int i=0;i<6;i++) { if(theRules[i] == null) { theRules[i] = putBack; rule.setText(""); edit.setText(""); break; } } replacementRules.setListData(theRules); } } }); JButton deleteButton = new JButton("Delete Rule"); deleteButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if(replacementRules.getSelectedValue() != null) { theRules[replacementRules.getAnchorSelectionIndex()] = null; replacementRules.clearSelection(); } } }); JButton modifyButton = new JButton("Modify Rule"); modifyButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if(replacementRules.getSelectedValue() != null) { String total = String.valueOf(replacementRules.getSelectedValue()); edit.setText(total.substring(4, total.length())); rule.setText(total.substring(0,1)); } } }); JButton createButton = new JButton("Create My Pattern"); createButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { redraw(); } }); FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT); southPanel.setLayout(flowLayout); GridBagLayout layout2 = new GridBagLayout(); GridBagConstraints c2 = new GridBagConstraints(); rulePanel.setLayout(layout2); c2.anchor = GridBagConstraints.WEST; c2.gridx = 0; c2.gridy = 0; c2.insets.top = 0; c2.insets.bottom = 3; layout2.setConstraints(rulesLabel, c2); rulePanel.add(rulesLabel); c2.fill = GridBagConstraints.VERTICAL; c2.insets.top = 0; c2.insets.bottom = 3; c2.gridx = 0; c2.gridy = 1; layout2.setConstraints(pane, c2); rulePanel.add(pane); c2.fill = GridBagConstraints.BOTH; c2.insets.left = 20; c2.insets.right = 10; c2.insets.top = 0; c2.insets.bottom = 0; c2.gridx = 2; c2.gridy = 1; layout2.setConstraints(createButton, c2); rulePanel.add(createButton); c2.fill = GridBagConstraints.HORIZONTAL; c2.insets.left = 20; c2.insets.right = 5; c2.insets.top = 0; c2.insets.bottom = 60; c2.gridx = 1; c2.gridy = 1; layout2.setConstraints(addButton, c2); rulePanel.add(addButton); c2.insets.top = 15; c2.insets.bottom = 19; c2.gridx = 1; c2.gridy = 1; layout2.setConstraints(deleteButton, c2); rulePanel.add(deleteButton); c2.insets.top = 55; c2.insets.bottom = 0; c2.gridx = 1; c2.gridy = 1; layout2.setConstraints(modifyButton, c2); rulePanel.add(modifyButton); c2.fill = GridBagConstraints.HORIZONTAL; c2.insets.right = 0; c2.insets.left = 0; c2.anchor = GridBagConstraints.WEST; c2.insets.top = 2; c2.insets.bottom = 2; c2.gridx = 0; c2.gridy = 2; layout2.setConstraints(rule, c2); layout2.setConstraints(replacePanel, c2); rulePanel.add(replacePanel); southPanel.add(rulePanel); GridBagLayout layout3 = new GridBagLayout(); JPanel northPanel = new JPanel(); GridBagConstraints c4 = new GridBagConstraints(); northPanel.setLayout(layout3); JPanel menuPanel = new JPanel(); FlowLayout menuLayout = new FlowLayout(FlowLayout.LEFT); menuPanel.setLayout(menuLayout); JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenuItem exit= new JMenuItem("Exit"); exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { try { System.exit(0); } catch(Exception e) { System.out.print(e); } } }); fileMenu.add(exit); JMenu helpMenu = new JMenu("Help"); JMenuItem about = new JMenuItem("About"); about.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "This was created by Josiah Greenewald", "About", JOptionPane.PLAIN_MESSAGE); } }); helpMenu.add(about); JMenuItem instructions = new JMenuItem("Instructions"); helpMenu.add(instructions); menuBar.add(fileMenu); menuBar.add(helpMenu); menuPanel.add(menuBar); c4.gridx = 0; c4.gridy = 0; c4.insets.right = 300; c4.insets.left = 0; layout3.setConstraints(menuPanel, c4); northPanel.add(menuPanel); JPanel stepPanel = new JPanel(); c4.gridx = 1; c4.gridy = 0; c4.insets.right = 10; c4.insets.left = 50; layout3.setConstraints(stepPanel, c4); //stepPanel.setBorder(BorderFactory.createEtchedBorder()); JLabel stepLabel = new JLabel("Step Size:"); stepField = new JTextField(3); stepField.setText("0"); stepField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { redraw(); } }); JScrollPane pane4 = new JScrollPane(stepField); stepPanel.add(stepLabel); stepPanel.add(pane4); northPanel.add(stepPanel); JPanel startHeadPanel = new JPanel(); c4.gridx = 2; c4.gridy = 0; c4.insets.right = 150; c4.insets.left = 0; layout3.setConstraints(startHeadPanel, c4); //startHeadPanel.setBorder(BorderFactory.createEtchedBorder()); JLabel startHeadLabel = new JLabel("Start Heading (0 = North):"); startHeadField = new JTextField(3); startHeadField.setText("0"); startHeadField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { redraw(); } }); JScrollPane pane7 = new JScrollPane(startHeadField); startHeadPanel.add(startHeadLabel); startHeadPanel.add(pane7); northPanel.add(startHeadPanel); contentPane.setLayout(new BorderLayout()); westPanel.setBorder(BorderFactory.createEtchedBorder()); contentPane.add(northPanel, BorderLayout.NORTH); northPanel.setBorder(BorderFactory.createEtchedBorder()); contentPane.add(westPanel, BorderLayout.WEST); contentPane.add(southPanel, BorderLayout.SOUTH); southPanel.setBorder(BorderFactory.createEtchedBorder()); contentPane.add(imagePanel, BorderLayout.CENTER); imagePanel.setBorder(BorderFactory.createEtchedBorder()); } //other methods------------------------------------ public String getAxiom() { return axiom.getText(); } public int getNumIterations() { return numIterations.getValue(); } public double getAngle() { return (double)angle.getValue(); } public void redraw() { lsystem = new TermProjectLSystem2(getAxiom(), getRules()); instruction = lsystem.createString(getNumIterations()); t = new TermProjectTurtle2(imagePanel, getAngle(), getStep(), getStartHead()); t.drawInstructions(instruction); //if(colorChooser.getColor() != null) //color = colorChooser.getColor(); imagePanel.repaint(); imagePanel.validate() ; } public double getStartHead() { return Double.parseDouble(startHeadField.getText()); } public double getStep() { return Double.parseDouble(stepField.getText()); } public Vector getRules() { Vector result = new Vector(); for(int i=0;i<6;i++) { result.add(theRules[i]); } return result; } public void init() { buildGUI(); } public void splashAnim(JFrame frame, String fileName, int sleepTime, int stayTime) { final int pauseTime = sleepTime; final String fileName2 = fileName; final JFrame frame2 = frame; final int stayTime2 = stayTime; Runnable wait2 = new Runnable() { public void run() { try { Thread.sleep(pauseTime); TermProjectSplash splash3 = new TermProjectSplash(fileName2,frame2, stayTime2); } catch(Exception e) { e.printStackTrace(); // can catch InvocationTargetException // can catch InterruptedException } } }; Thread splashThread2 = new Thread(wait2, "SplashThread2"); splashThread2.start(); } } //------------------------------------------------------------ //class for the splash screen class TermProjectSplash extends JWindow { public TermProjectSplash(String filename, Frame f, int waitTime) { super(f); JLabel l = new JLabel(new ImageIcon(filename)); getContentPane().add(l, BorderLayout.CENTER); pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension labelSize = l.getPreferredSize(); setLocation(screenSize.width/2 - (labelSize.width/2)+ 50, screenSize.height/2 - (labelSize.height/2)-70); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { setVisible(false); dispose(); } }); final int pause = waitTime; final Runnable closerRunner = new Runnable() { public void run() { setVisible(false); dispose(); } }; Runnable waitRunner = new Runnable() { public void run() { try { Thread.sleep(pause); SwingUtilities.invokeAndWait(closerRunner); } catch(Exception e) { e.printStackTrace(); } } }; setVisible(true); Thread splashThread = new Thread(waitRunner, "SplashThread"); splashThread.start(); } } //------------------------------------------------------------- //Class for the L-System class TermProjectLSystem2 { public String axiom; public Vector productions; public TermProjectLSystem2(String axiom2, Vector productions2) { axiom = axiom2; productions = productions2; } public String createString(int detail) { if (detail == 0) { return new String(axiom); } else { String result = new String(); String part = createString(detail - 1); for(int i=0; i < part.length(); i++) { boolean productionIsFound = false; for(int j=0; ((j < productions.size()) && (!productionIsFound)); j++) { String currentProd = (String)productions.elementAt(j); if(currentProd != null) { if (currentProd.charAt(0) == part.charAt(i)) { productionIsFound = true; String replace = currentProd.substring(5); result = result + replace; } } } if (!productionIsFound) { result = result + part.charAt(i); } } return result; } } } //------------------------------------------------------------ //class for the Panel that draws the lines class TermProjectIsland2 extends JPanel { private Color color; private Vector lineContainer; private double startX; private double startY; public TermProjectIsland2(Color c) { color = c; lineContainer = new Vector(); setPreferredSize(new Dimension(700, 500)); } public void paint(Graphics g) { super.paint(g); g.setColor(Color.black); //g.setBackground(Color.black); g.fillRect(0, 0, getWidth(), getHeight()); //g.setColor(color); g.setColor(Color.WHITE); g.setPaintMode(); g.translate(getWidth()/8, 0); //g.translate(frame.getAngle //g.scale(getWidth(), getHeight()); for (int i=0; i < lineContainer.size(); i++) { Line line = (Line)lineContainer.elementAt(i); //Line2D.Double line = (Line2D.Double) lineContainer.elementAt(i); g.drawLine((int)(line.x1 - startX + 2.0), (int)(line.y1 - startY + 2.0), (int)(line.x2 - startX + 2.0), (int)(line.y2 - startY + 2.0)); //g.draw(line); } } public void update(Graphics g) { super.update(g); paint(g); } //set the container of lines to be the container that is passed in. also make it so the the whole image gets displayed on the panel public void setLineContainer(Vector newLineContainer) { lineContainer = newLineContainer; if (newLineContainer.size() > 0) { Line firstLine = (Line)newLineContainer.elementAt(0); startX = firstLine.minX(); startY = firstLine.minY(); for(int i=1; i < newLineContainer.size(); i++) { Line currentLine = (Line)newLineContainer.elementAt(i); if (currentLine.minX() < startX) { startX = currentLine.minX(); } if (currentLine.minY() < startY) { startY = currentLine.minY(); } } } } } //------------------------------------------------------------------------------- //turtle class that has the methods to move the turlte and interpret the instructions class TermProjectTurtle2 { public class State { public double x; public double y; public double angle; public State(double x, double y, double angle) { this.x = x; this.y = y; this.angle = angle; } } public Vector turtleLines; public State position; public double step; public double pivot; public TermProjectIsland2 turtlePicture; private Stack stack; private Color color2; public TermProjectTurtle2(TermProjectIsland2 panel, double pivot, double step, double startHead) { //turtlePicture = new TermProjectIsland2(color); turtlePicture = panel; int centerX = turtlePicture.getWidth()/2; int centerY = turtlePicture.getHeight()/2; State p = new State(centerX, centerY, Math.toRadians(startHead + 270)); setState(p); this.pivot = Math.toRadians(pivot); this.step = step; stack = new Stack(); } //draw the instructions public void drawInstructions(String instruction) { turtleLines = new Vector(); stack.removeAllElements(); startOver(); for(int i=0; i < instruction.length(); i++) { char c = instruction.charAt(i); if ((c == 'F') || (c == 'R') || (c == 'L')) moveDraw(); else if (c == 'f') move(); else if (c == '-') turnRight(); else if (c == '+') turnLeft(); else if (c == '[') stack.push(new State(position.x, position.y, position.angle)); else if (c == ']') { if(!stack.empty()) setState((State) stack.pop()); } } turtlePicture.setLineContainer(turtleLines); turtlePicture.repaint(); } //set current state private void setState(State p) { position = p; } //starting position private void startOver() { position.x = (turtlePicture.getWidth() / 2); position.y = (turtlePicture.getHeight() / 2); } private void turnDegrees(double degrees) { position.angle += degrees; } private void turnRight() { turnDegrees(pivot); } private void turnLeft() { turnDegrees(-1.0 * pivot); } public void setColor(Color c) { color2 = c; } private void move() { position.x = position.x + step * Math.cos(position.angle); position.y = position.y + step * Math.sin(position.angle); } private void moveDraw() { double oldX, oldY; // save the turtle's current coordinates oldX = position.x; oldY = position.y; // move the turtle move(); // draw the line connecting the new and old coordinates turtleLines.add(new Line(oldX, oldY, position.x, position.y)); } } //-------------------------------------------------------------------------- //class to make a line...for some reason Line2D.Double would not work for me...I couldnt get it to display so I created my own line class class Line { public double x1; public double y1; public double x2; public double y2; public Line(double beginX, double beginY, double endX, double endY) { x1 = beginX; y1 = beginY; x2 = endX; y2 = endY; } public double minX() { if(x1 < x2) { return (x1); } else { return (x2); } } public double minY() { if(y1 < y2) { return (y1); } else { return (y2); } } }