我创建了一个图形程序,它采用用户输入的y或x截距形式方程,并绘制网格上的匹配线。它有效,但绘制线条的速度非常慢。在我使用用户的输入添加代码之前,它很快,所以我知道这部分的效率低下。我真的很感激,如果有人花一点时间浏览我的代码并给我一些关于如何让它运行得更快的建议/提示。
这是主要的Frame类的代码:
package src;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.Line2D;
import java.text.DecimalFormat;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
/*
* This class is responsible for making the program's frame
*/
public class MainFrame
{
public static int width = 1001;
public static int height = 1001;
public static String equation;
public static boolean drawLine = false;
//public static String equation;
public static void main(String[] args)
{
JFrame frame = new JFrame();
EquationConverter ec = new EquationConverter();
//These are the JPanels that put together the window
JPanel northPane = new JPanel();
JPanel southPane = new JPanel();
JPanel eastPane = new JPanel();
JPanel westPane = new JPanel();
Color panelColor = new Color(230, 230, 230);
JTextField textField = new JTextField();
//JTextPane textPane = new JTextPane();
//Set the window's layout
frame.setLayout(new BorderLayout());
//Create the grid panel
@SuppressWarnings("serial")
JPanel graphPane = new JPanel()
{
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
setPreferredSize(new Dimension(width, height));
setBackground(Color.white);
g2.setColor(Color.LIGHT_GRAY);
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = height;
//Draw horizontal lines
for (int i = 1; i <= 20; i++)
{
g2.drawLine(x1, y1, x2, y2);
x1 += width/20;
x2 = x1;
}
g2.drawLine(width-1, 0, width-1, height);
x1 = 0;
y1 = 0;
x2 = width;
y2 = 0;
//Draw vertical lines
for (int i = 1; i <= 20; i++)
{
g2.drawLine(x1, y1, x2, y2);
y1 += height/20;
y2 = y1;
}
g2.drawLine(0, height-1, width, height-1);
//Make the x and y axis lines bigger and
//a darker color than the grid lines
g2.setStroke(new BasicStroke(4));
g2.setColor(Color.black);
g2.drawLine(500, 0, 500, 1001);
g2.drawLine(0, 500, 1001, 500);
//Draw numbers along y axis
g2.setFont(new Font("defualt", Font.PLAIN, 20));
int sx = 475;
int sy = 60;
String si;
for (int i = 9; i >= -9; i--)
{
if (i != 0)
{
si = Integer.toString(i);
g2.drawString(si, sx, sy);
}
sy += 50;
}
sx = 40;
sy = 525;
//Draw numbers along the x axis
for (int i = -9; i <= 9; i++)
{
if (i != 0)
{
si = Integer.toString(i);
g2.drawString(si, sx, sy);
}
sx += 50;
}
if (drawLine == true)
{
double x = 0;
double y = 0;
String newEquation = "";
String finalEquation = "";
DecimalFormat df = new DecimalFormat("#.####");
g2.setColor(Color.red);
equation = textField.getText();
equation = equation.toLowerCase().replace(" ", "");
if (!equation.equals(""))
{
if (equation.charAt(0) == 'y' && equation.charAt(1) == '=')
{
equation = equation.substring(2);
newEquation = ec.editStr(equation, 'x');
//Draws lines using y intercept form
for (x = -10; x < 10; x+=0.0001)
{
//y = (x);
finalEquation = ec.replaceX(newEquation, df.format(x), 'x');
y = Double.parseDouble(ec.solveEquation(finalEquation));
g2.draw(new Line2D.Double(width/2+50*x, height/2-50*y,
width/2+50*x, height/2-50*y));
}
}
else if (equation.charAt(0) == 'x' && equation.charAt(1) == '=')
{
equation = equation.substring(2);
newEquation = ec.editStr(equation, 'y');
//Draws lines using x intercept form
for (y = -10; y < 10; y+=0.0001)
{
//x = (y);
finalEquation = ec.replaceX(newEquation, df.format(y), 'y');
x = Double.parseDouble(ec.solveEquation(finalEquation));
g2.draw(new Line2D.Double(width/2+50*x, height/2-50*y,
width/2+50*x, height/2-50*y));
}
}
}
}
else
{
drawLine = false;
}
}
};
//Settings for the graph panel
frame.add(graphPane, BorderLayout.CENTER);
graphPane.setBorder(BorderFactory.createLineBorder(Color.black));
//Settings for the north panel
frame.add(northPane, BorderLayout.NORTH);
northPane.setPreferredSize(new Dimension(1500, 30));
northPane.setBackground(panelColor);
//Settings for the south panel
southPane.add(textField);
textField.setPreferredSize(new Dimension(700, 80));
textField.setFont(new Font("default", Font.PLAIN, 60));
textField.setBorder(BorderFactory.createLineBorder(Color.black));
textField.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
drawLine = true;
graphPane.repaint();
}
});
//Settings for the east panel
frame.add(eastPane, BorderLayout.EAST);
westPane.setPreferredSize(new Dimension(247, 1500));
westPane.setBackground(panelColor);
//Settings for the west panel
frame.add(westPane, BorderLayout.WEST);
eastPane.setPreferredSize(new Dimension(247, 1500));
eastPane.setBackground(panelColor);
//Settings for the frame
frame.setTitle("Custom Graphs");
frame.setSize(1501, 1501);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
}
这是该类的代码,其中包含将用户的等式转换为字符串的方法,计算机可以使用该字符串来绘制该行:
package src;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
/*
* This class converts the user's equation for use by the computer
*/
public class EquationConverter
{
//This method adds multiplication signs at necessary points in the sting
protected String editStr(String str, char xOrY)
{
String newStr = str;
for (int i = 0; i < str.length(); i++)
{
//Adds a multiplicative sign between variables and digits
if (i != 0 && str.charAt(i) == xOrY && Character.isDigit(str.charAt(i-1)))
{
newStr = str.substring(0, i) + "*" + str.substring(i);
}
//Adds a multiplicative sign between parentheses
else if (i != 0 && str.charAt(i) == '(' && str.charAt(i-1) == ')')
{
newStr = str.substring(0, i) + "*" + str.substring(i);
}
str = newStr;
}
return newStr;
}
//This method replaces the character x with the numeric value of x
protected String replaceX(String str, String number, char xOrY)
{
String newStr = str;
for (int i = 0; i < str.length(); i++)
{
if (i == 0 && str.charAt(i) == xOrY)
{
if (str.length() == 1)
{
newStr = number;
}
else
{
newStr = number + str.substring(i+1);
}
}
else if (i != 0 && str.charAt(i) == xOrY)
{
//Add parentheses where there could be two minus signs
if (i+1 == str.length())
{
newStr = str.substring(0, i) + "(" + number + ")";
}
else
{
newStr = str.substring(0, i) + "(" + number + ")" + str.substring(i+1);
}
}
str = newStr;
}
return newStr;
}
//This method solves a string equation and returns the numeric value
protected String solveEquation(String str)
{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("javascript");
try
{
return engine.eval(str).toString();
}
catch (Exception e)
{
System.exit(0);
return "";
}
}
}