我想利用java画一个棋盘格,完成了,但是测试的时候有点不够满意。就是我是在paint()方法中画的,每次更新都会有repaint()。这时候会重复调用paint方法,也就是棋盘要被画很多遍,虽然图像不会改变,感觉很别扭。有没有方法可以只画一次棋盘。

解决方案 »

  1.   

    以下是绘制表盘的代码  2D做的:import java.awt.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.util.Date;import javax.swing.JFrame;
    import javax.swing.JPanel;public class TimeDemo extends JFrame{
    private JPanel pan;
    private double r1=160,r2=165,rm1=158,rm2=167,hr=100,mr=130,sr=167;
    public TimeDemo(){
    super("Time demo");
    this.setBounds(200,200,410,430);
    getMinLab();

    pan=new MyPanel();
    this.add(pan);

    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    MyThread th=new MyThread();
    th.setDaemon(true);
    th.start();

    }

    public static void main(String[] args) {
    new TimeDemo();
    }

    class MyPanel extends JPanel{
    public void paint(Graphics g){
    g.clearRect(0,0,this.getWidth(),this.getHeight());
    Graphics2D g2=(Graphics2D)g;

    BasicStroke bs=null;

    // String num[]={"1","2","3","4","5","6","7","8","9","10","11","12"};
    //       打开抗锯齿
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            Line2D line[]=getMinLab();
            for(int i=0;i<line.length;i++){
             bs=new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(bs);
             if(i%5==0){
             bs=new BasicStroke(4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(bs);
            
             }
             g2.draw(line[i]);
            }
            
            //计算时针
            Date date=new Date();
            int s=date.getSeconds();
            
            double m=date.getMinutes()+s/60.0;
            
            double h=date.getHours()+m/60.0;
            System.out.println(h);
            
            double hy=Math.sin(Math.PI/6*(h%12-3))*hr+200;
            double hx=Math.cos(Math.PI/6*(h%12-3))*hr+200; 
            bs=new BasicStroke(6,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(bs);
            Line2D.Double hline=new Line2D.Double(200,200,hx,hy);
            g2.draw(hline);
    //       计算分针
            double my=Math.sin(Math.PI/30*(m-15))*mr+200;
            double mx=Math.cos(Math.PI/30*(m-15))*mr+200; 
            bs=new BasicStroke(4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(bs);
            Line2D.Double mline=new Line2D.Double(200,200,mx,my);
            g2.draw(mline);
    //   计算秒针
            double sy=Math.sin(Math.PI/30*(s-15))*sr+200;
            double sx=Math.cos(Math.PI/30*(s-15))*sr+200; 
            bs=new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(bs);
            Line2D.Double sline=new Line2D.Double(200,200,sx,sy);   
            g2.draw(sline);
            
            //画表盘
            
            Ellipse2D.Double el=new Ellipse2D.Double(10,10,380,380);
            g2.draw(el);
    }
    }

    public Line2D[] getMinLab(){
    Line2D[] lineM=new Line2D[60];

    for(int i=0;i<lineM.length;i++){
    double x1,y1,x2,y2;
    double b1 = Math.sin(Math.PI / 30 * i);
    double b2 = Math.cos(Math.PI / 30 * i);
    if (i % 5 != 0) {
    y1 = b1 * r1 + 200;
    y2 = b1 * r2 + 200;
    x1 = b2 * r1 + 200;
    x2 = b2 * r2 + 200;
    } else {
    y1 = b1 * rm1 + 200;
    y2 = b1 * rm2 + 200;
    x1 = b2 * rm1 + 200;
    x2 = b2 * rm2 + 200;
    }

    lineM[i]=new Line2D.Double(x1,y1,x2,y2);


    // System.out.println(i+"-------("+x1+","+y1+"),("+x2+","+y2+")");
    }

    return lineM;
    }

    class MyThread extends Thread{
    public void run(){
    while(true){
    pan.repaint();
    try {
    this.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }

    // public void refresh(){
    // pan.repaint();
    // this.validate();
    // }}
      

  2.   

    建议楼主可以采用双缓冲技术,应用BufferedImage类,把要画的图像先放入这个类中,在从这个类读到画板上。我最近在看的一本JAVA游戏编程书采用的就是这种方法。
      

  3.   

    我想到到一个方法:设定一个flag=ture,当读完一遍之后就设为FALSE。在要只读一遍的图上加上if语句就ok。
    谢谢大家,我有时间再看看各楼的观点吧!