Thread.sleep(x)不会做它必须做的事情

时间:2013-12-21 22:57:52

标签: java multithreading swing

我编写了一个可以打开所有枢轴的立方体代码。 现在我尝试用Thread.sleep放入一个循环,但每次重新绘制它只是给我半个立方体或什么都没有(它有点闪烁和摇摇欲坠)。

也许它不起作用,因为我的笔记本电脑太慢了,但我不认为是这种情况。

以下是代码:

import java.awt.*;
import javax.swing.*;

public class Würfel1 extends JApplet {

Container container;
Dimension Screen = new Dimension(400,400);
double c[] = new double[8];
double wx = 90; double wy = 90; double wz = 90;

public Würfel1() {
    init();
}

public void init() {
    this.setSize(Screen);
    container = this.getContentPane();
}

public void paint(Graphics g) {
    super.paint(g);
    drawcube(g);
    wx = wx - 2;
    wy = wy + 1;
    wz = wz + 3;

    try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}

    repaint();
}

private void drawcube(Graphics g) {
    /*
     * Punkt links oben vorne
     */
    int xStart = 100;
    int yStart = 100;

    /*
     * Breite, Höhe und Länge des Körpers
     */
    int b = 200;
    int h = 200;
    int l = 200;

    /*
     * Winkel der X-, Y- und Z-Achse des Körpers
     */
//      int wx = 90;
//      int wy = 90;
//      int wz = 90;

    /*
     * Mittelpunkt des Körpers
     */
    int x = xStart + b/2;
    int y = yStart + h/2;

    /*
     * erzeugt die Grundwerte für den Winkel 90,90,90
     */
    double xfield[] = {(-b/2),(b/2),(b/2),(-b/2),(-b/2),(b/2),(b/2),(-b/2)};
    double yfield[] = {(-h/2),(-h/2),(h/2),(h/2),(-h/2),(-h/2),(h/2),(h/2)};
    double zfield[] = {(l/2),(l/2),(l/2),(l/2),(-l/2),(-l/2),(-l/2),(-l/2)};

    /*
     *  verändert die Werte unter Berücksichtigung der Winkel
     */
    for (int i = 0; i < 8; i++)
    {
        double newx,newy,newz;

        newy = yfield[i] * Math.cos(Math.PI*(90-wx)/180) - zfield[i] * Math.sin(Math.PI*(90-wx)/180);
        newz = yfield[i] * Math.sin(Math.PI*(90-wx)/180) + zfield[i] * Math.cos(Math.PI*(90-wx)/180);
        yfield[i] = newy;
        zfield[i] = newz;

        newx = xfield[i] * Math.cos(Math.PI*(90-wy)/180) - zfield[i] * Math.sin(Math.PI*(90-wy)/180);
        newz = xfield[i] * Math.sin(Math.PI*(90-wy)/180) + zfield[i] * Math.cos(Math.PI*(90-wy)/180);
        xfield[i] = newx;
        zfield[i] = newz;

        newx = xfield[i] * Math.cos(Math.PI*(90-wz)/180) - yfield[i] * Math.sin(Math.PI*(90-wz)/180);
        newy = xfield[i] * Math.sin(Math.PI*(90-wz)/180) + yfield[i] * Math.cos(Math.PI*(90-wz)/180);
        xfield[i] = newx;
        yfield[i] = newy;
    }

    for (int i = 0; i < 8; i++) {
        c[i] = 1;
    }

    /*
     * Malt die Linien des Körpers
     */
    DrawPolygon(0,1,2,3,xfield,yfield,x,y,g,1);
    DrawPolygon(6,5,4,7,xfield,yfield,x,y,g,2);
    DrawPolygon(5,1,0,4,xfield,yfield,x,y,g,3);
    DrawPolygon(3,2,6,7,xfield,yfield,x,y,g,4);
    DrawPolygon(2,1,5,6,xfield,yfield,x,y,g,5);
    DrawPolygon(4,0,3,7,xfield,yfield,x,y,g,6);

}

public void DrawPolygon(int a, int s, int d, int f, double[] xfield, double yfield[],int b,int h,Graphics g,int c) {
    if((xfield[a] - xfield[s]) * (yfield[d] - yfield[s])
              - (yfield[a] - yfield[s]) * (xfield[d] - xfield[s]) > 0) {
                // |j->i x j->k| > 0

                int xCoords[] = {(int)(xfield[a])+b,(int)(xfield[s])+b,
                                 (int)(xfield[d])+b,(int)(xfield[f])+b};
                int yCoords[] = {(int)(yfield[a])+h,(int)(yfield[s])+h,
                                 (int)(yfield[d])+h,(int)(yfield[f])+h};
                Color color = new Color(0,0,0);
                if (c == 1) color = new Color(255,0,0);
                if (c == 2) color = new Color(255,255,0);
                if (c == 3) color = new Color(0,255,0);
                if (c == 4) color = new Color(0,255,255);
                if (c == 5) color = new Color(0,0,255);
                if (c == 6) color = new Color(255,0,255);

                g.setColor(color);
                g.fillPolygon(xCoords, yCoords, 4);
    }
}

public static void main(String[] args) {
    new Würfel1();
}
}

我使用了这个想法,因为我在另一个代码中看到了它,但是Polygon是用一个名为buffer的图像绘制的(我真的不知道这是什么) 我也使用JApplet,因为它更容易使用JFrame,我添加我的JPanel。

我最近的尝试是用

替换try [...] catch代码
        ActionListener action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            repaint();
        }
    };
    new Timer(100,action).start();

但由于某种原因,它只是加快了我的applet并仍然遇到了问题。 我已经读过其他问题,他们遇到了类似的问题,但我没有找到解决我的方法来解决这个问题的答案。

我现在更改了正常的绘图[...]并将我的立方体放在图像上: ...首先在drawcube方法中位于顶部

    // Double-Buffering
    if (buffer==null) {
        buffer=createImage(this.getSize().width, this.getSize().height);
        gBuffer=(Graphics2D)buffer.getGraphics();
    }
    gBuffer.clearRect(0,0, this.getSize().width, this.getSize().height);

    // Antialiasing
    gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

...下一个引用是在drawcube的末尾设置的

    g.drawImage(buffer,0,0,this);

...我还必须更改fillPoly方法(这很明显)

                gBuffer.setColor(color);
                gBuffer.fillPolygon(xCoords, yCoords, 4);

...我在init方法中放了一个计时器 - 现在几乎正常工作

public void init() {
    this.setSize(Screen);
    ActionListener action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            repaint();
        }
    };
    new Timer(100,action).start();
}

1 个答案:

答案 0 :(得分:7)

不要:

  1. 在绘画方法中使用Thread.sleep()。这将阻止Event Dispatch Thread并阻止Swing响应事件

  2. 从painting()方法中调用repaint()。这将导致无限循环

  3. 覆盖paint()以进行自定义绘制。 Custom Painting是通过覆盖JPanel(或JComponent)的paintComponent(...)方法完成的。然后将面板添加到小程序。

  4. 执行:

    1. 使用Swing Timer来安排动画。