嗨,我目前正在做最后一年的项目;我需要开发一个算法可视化工具。我需要满足用户定义的算法;这是动画用户在我的工具中提供的文本编辑器中键入的算法。
我正在使用 Java Compiler API 来编译用户键入并保存的代码。我的工具提供了一组用户可以在他/她的算法中使用的类。
例如:
myArray(这个类由我的工具提供)
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
public class myArray extends JComponent {
int size = 0;
int count = 0;
int[]hold;
Thread th;
public myArray(int[]arr)//pass user array as parameter
{
//th = new Thread();
size=arr.length;
hold = arr;//make a copy of the array so as to use later in swap operation
}
public int length()
{
return hold.length;
}
public void setAccessibleContext(AccessibleContext accessibleContext) {
this.accessibleContext = accessibleContext;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
this.setPreferredSize(new Dimension(360,100));
for(int i=1; i<=size; i++)
{
g2d.drawRect((i*30), 30, 30, 50);
}
for(int i=1; i<=size; i++)
{
g2d.drawString(Integer.toString(hold[i-1]), (i*30)+15, 30+25);
}
}
public void set(int i, int j)//position of the two elements to swap in the array
{
try {
th.sleep(2000);//sleep before swapping because else user won't see original array since it would swap and then sleep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int temp = hold[i];
hold[i] = hold[j];
hold[j] = temp;
hold[i]=j;
this.repaint();//can use eapint with a class that extends JPanel
}
public void swap(int i, int j)//position of the two elements to swap in the array
{
try {
th.sleep(2000);//sleep before swapping because else user won't see original array since it would swap and then sleep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int temp = hold[i];
hold[i] = hold[j];
hold[j] = temp;
this.repaint();//can use eapint with a class that extends JPanel
}
public int get(int pos)
{
return hold[pos];
}
}
这是我的 GUI 的一部分,它将导致编译:
JavaCompiler jc = null;
StandardJavaFileManager sjfm = null;
File javaFile = null;
String[] options = null;
File outputDir = null;
URL[] urls = null;
URLClassLoader ucl = null;
Class clazz = null;
Method method = null;
Object object = null;
try
{
jc = ToolProvider.getSystemJavaCompiler();
sjfm = jc.getStandardFileManager(null, null, null);
File[] files = new File[1];
//files[0] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/myArray.java");
//files[1] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/Tool.java");
files[0] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/userDefined.java");
// getJavaFileObjects’ param is a vararg
Iterable fileObjects = sjfm.getJavaFileObjects(files);
jc.getTask(null, sjfm, null, null, null, fileObjects).call();
// Add more compilation tasks
sjfm.close();
options = new String[]{"-d", "C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project"};
jc.getTask(null, sjfm, null, Arrays.asList(options), null, fileObjects).call();
outputDir = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project");
urls = new URL[]{outputDir.toURL()};
ucl = new URLClassLoader(urls);
clazz = ucl.loadClass("userDefined");
method = clazz.getMethod("user", null);
object = clazz.newInstance();
Object ob = method.invoke(object, null);
}
这是一个用户定义算法(userDefined.java)的例子:
import java.awt.*;
import javax.swing.*;
public class userDefined
{
public void user()
{
int [] numArr = {1,3,1,-1,5,-5,0,7,12,-36};
myArray myArray = new myArray(numArr);
JFrame frame = new JFrame("Rectangles");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(360, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.add(myArray);
for (int i=myArray.length(); i>1; i--)
{
for (int j=0; j<i-1; j++)
{
if (myArray.get(j) > myArray.get(j+1))
{
myArray.swap(j, j+1);
}
}
}
}
}
我遇到的问题是,如果我尝试像上面那样使用反射;我只得到一个不显示动画的白色窗口)但只在最后显示结果。
但是,如果我使用它而不是反射(并在 userDefined.java 中将方法 void user() 更改为 static void main(string args)):
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if(compiler.run(null, null, null, "userDefined.java") != 0) {
System.err.println("Could not compile.");
System.exit(0);
}
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java "+"userDefined");
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
它提供了第一次编译后我将 myArray 类放在与 userDefined.java 相同的文件夹中。在这种情况下,我可以看到动画正确发生。
如何使用反射来调用 main 方法而不是使用类的实例。请我真的需要一些帮助。谢谢!