0

こんにちは、私は現在、最終年度のプロジェクトを行っています。アルゴリズムの視覚化ツールを開発する必要があります。ユーザー定義のアルゴリズムに対応する必要があります。これは、ツールで提供されているテキスト エディターでユーザーが入力したアルゴリズムをアニメーション化することです。

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 と同じフォルダーに配置することを条件とします。この場合、アニメーションが正しく行われていることがわかります。

クラスのインスタンスを使用する代わりに、リフレクションを使用してメイン メソッドを呼び出す方法を教えてください。これについて本当に助けが必要です。ありがとう!

4

1 に答える 1

4

あなたはスイングの最初のルールに違反/誤用しています: EDT (イベントディスパッチスレッド) でのみスイングコンポーネントにアクセスします。

main メソッドを使用してプログラムを開始すると、その規則に違反しています。これはたまたま機能しますが、あらゆる種類の奇妙な効果をもたらす可能性があります。これは理論的な警告ではありません。私に起こったことであり、良くありません。

コードからのリフレクションを使用して実行する場合、EDT にいる可能性が最も高いため、GUI が再度更新される前にアルゴリズムが完全に実行されます (これは EDT でも発生します)。そのため、アルゴリズムの最終結果のみが表示されます。

これを行う正しい方法は次のとおりです: 別のスレッドでアルゴリズムを実行し、SwingUtilities.invokeAndWait または SwingUtilities.invokeLater を使用して、myArray コンポーネントへのすべての変更が EDT で発生することを確認します。

于 2011-02-23T13:15:34.020 に答える