📄 ruleui.java
字号:
// Class RuleUIpackage 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 Consolepublic class RuleUI extends JPanel { // 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.Lsys intstance void getRulesFromUI() { // set l-system parameters // seed ls.l.seed = seedField.getText(); Lsys.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<ruleTable.getRowCount(); r++) { // if both not null if(ruleTable.getValueAt(r,0) != null && ruleTable.getValueAt(r,1) != null) // and both not zero length if(((String)(ruleTable.getValueAt(r,0))).length() > 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<ls.l.rules.size(); r++) { if(ls.l.code.b[p] == (((Rule)ls.l.rules.get(r)).pattern)) // replace! { newCode.addAll(((Rule)ls.l.rules.get(r)).replace); ruleApplied = true; // dont try to expand extra rules, that would be trouble break; } } if(!ruleApplied) // if no rule was found for this item { newCode.add(ls.l.code.b[p]); } p++; // increment p to go to the next // Cycle the progress bar to show thinking! // You're probably thinking.. "Hey.. this is such a waste of time, why // didn't you just use that nifty 'barber pole' auto-scrolling effect?" // Well, that's good stuff, and it's called "Indeterminate mode". However, // this capability seems to only exist in >= 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -