http://community.csdn.net/Expert/topic/3898/3898082.xml?temp=.9454157

解决方案 »

  1.   

    肯定要用多线程的,用一个单独的线程来计算,另外设一个定时器,比如是100ms,则每到100ms设一个重绘标志。计算线程每个计算循环均判断这个标志,如果设位,则将已计算好的值传递过去,再调用repaint()重绘窗口,同时将重绘标志复位。这样,就能达到每100ms根据计算结果自动在屏幕上画图了。
      

  2.   

    实现 MouseMotionListener 接口,
      

  3.   

    从你的程序来看,问题的重点不在于计算太慢,也不在于所谓的线程问题,实际上是你画线的步长太短了,如果按照你贴的程序中inch=0.01d来算,画完整个曲线要循环2万次,如果inch=0.001d的话就更夸张,需要循环20万次,你想一下执行20万次draw()方法,生成20万个Line2D对象能快得了么。
    如果只是想在屏幕上显示一下的话,用0.1的步长就足够了。画出的图形和用0.001为步长值所画出来的看起来是一样的。
      

  4.   

    又仔细看了一下,在你的程序里用
    gg.draw(new Line2D.Double(px,py,px,py));来画图,这实际上是一个点一个点的画图了,不应该这么写。把程序改成这样:
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    Graphics2D gg = (Graphics2D) g; //将坐标原点移动到ShowPanel的中心点
    double tpx = this.getWidth() / 2;
    double tpy = this.getHeight() / 2;
    gg.translate(tpx, tpy); gg.setColor(Color.red);

    double py0 = Double.MIN_VALUE;
    double startx = -100.0d;
    while (startx <= 100.0d) {
    double px = startx;
    double py = a * px * px + b * px + c;
    py = (-1) * py / 50;
    if (py0 != Double.MIN_VALUE) {
    gg.draw(new Line2D.Double(px-Demo.inch, py0, px, py));
    }
    py0 = py;
    startx += Demo.inch;
    }
    }即使用步长值inch=10d; 画出来的图形也已经很平滑了。
      

  5.   

    我找到原因了!原来 swing 里的轻量级组件根本不支持这种递增似的画图!(swing 开发组真可恶) 哈哈!
    改用awt的Frame 和Panel 就OK了!下面是我改好的程序,与大家分享。不过仍有个小问题,不知为什么有时画一遍就OK,有时却画两遍,还请大家帮忙!!!下面这个是主程序:package graphtools;
    import java.awt.*;
    import java.awt.event.*;
    /**
     * @DarkLord
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class PlotGraph { public static void main(String[] args) {
    Plotable[] function={
    new YiYuan(1.0d,0.0d,-400.0d,50.0d),
    new YiYuan(-1.0d,0.0d,+400.0d,50.0d),
    new Sin(50.0d,30.0d),
    new Sin(-50.0d,30.0d)
    };
    Color[] color={Color.red,Color.green,Color.blue,Color.cyan};
    final PlotPanel pp=new PlotPanel(function,color,-100.0d,100.0d,0.01d);
    final Frame f=new Frame("Ploting Mathematic Graph");
    f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0);
    }
    });
    f.add(pp);
    f.pack();
    EventQueue.invokeLater(new Runnable(){
    public void run(){
    f.setVisible(true);
    pp.startPlot();
    }
    });
    }

    private static class YiYuan implements Plotable{
    private double a;
    private double b;
    private double c;
    private double d;

    YiYuan(double a,double b,double c,double d){
    this.a=a;
    this.b=b;
    this.c=c;
    this.d=d;
    }
    public double valueAt(double x){
    return (a*x*x+b*x+c)/d;
    }
    }
    private static class Sin implements Plotable{
    private double a;
    private double b;

    Sin(double a,double b){
    this.a=a;
    this.b=b;
    }
    public double valueAt(double x){
    return a*Math.sin(x/b);
    }
    }
    }
    下面是画板代码:package graphtools;import java.awt.*;
    import java.util.*;
    import java.awt.geom.*;
    /**
     * @DarkLord
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class PlotPanel extends Panel {
    private final double start;
    private final double end;
    private final double pace;
    private Dimension size;
    private final Color[] color;
    private final Plotable[] function;
    private final java.util.List[] list;
    private int pointPainted=0;

    public PlotPanel(Plotable[] plotFunction,Color[] color,double start,double end,double pace){
    this.start=start;
    this.end=end;
    this.pace=pace;
    this.function=plotFunction;
    this.color=color;
    list=new ArrayList[plotFunction.length];
    for(int i=0;i<list.length;i++)
    list[i]=new ArrayList();
    }
    public Dimension getPreferredSize() {
            return new Dimension(600,500);
        }

    public void startPlot(){
    EventQueue.invokeLater(new Runnable(){
    public void run(){
    double step=getStart();
    int count=1;
    while(step<=getEnd()){
    double x=step;
    for(int i=0;i<list.length;i++){
    double y=(-1)*function[i].valueAt(x);
    list[i].add(new Point2D.Double(x,y));
    }

    if(++count%100==0)
    repaint();
    step+=pace;
    }
    }
    });
    }
    public void plotPoint(Graphics2D gg,Color color,java.util.List ls,int i){
    gg.setColor(color);
    Point2D.Double p=(Point2D.Double)ls.get(i);
    gg.draw(new Line2D.Double(p,p));
    }
    public void plotPoints(Graphics2D gg,int i){
    for(int j=0;j<list.length;j++)
    plotPoint(gg,color[j],list[j],i);
    pointPainted++;
    }
    public void plotAxis(Graphics2D gg,Color color){
    gg.setColor(color);
    Line2D linex=new Line2D.Double(-200.0,0.0,200.0,0.0);
    Line2D liney=new Line2D.Double(0.0,200.0,0.0,-200.0);
    Line2D l1=new Line2D.Double(200.0,0.0,195.0,5.0);
    Line2D l2=new Line2D.Double(200.0,0.0,195.0,-5.0);
    Line2D l3=new Line2D.Double(0.0,-200.0,-5.0,-195.0);
    Line2D l4=new Line2D.Double(0.0,-200.0,5.0,-195.0);
    gg.draw(linex);
    gg.draw(liney);
    gg.draw(l1);
    gg.draw(l2);
    gg.draw(l3);
    gg.draw(l4);
    gg.drawString("x",195,15);
    gg.drawString("y",-15,-190);
    gg.draw3DRect(-210,-210,420,420,true);
    }
    public double getStart(){
    return start;
    }
    public double getEnd(){
    return end;
    }

    public void paint(Graphics g){
    Graphics2D gg=(Graphics2D)g;
    size=getSize();
    gg.translate(size.width/2,size.height/2);
    plotAxis(gg,Color.black);
    for(int j=0;j<list[0].size()-1;j++)
    plotPoints(gg,j);

    }
    public void update(Graphics2D gg){
    for(int j=pointPainted;j<list[0].size()-1;j++)
    plotPoints(gg,j);
    }
    }
    下面是Plotable接口代码:package graphtools;/**
     * @DarkLord
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public interface Plotable {
    public double valueAt(double x);
    }