【问题标题】:while loop loops just once - javawhile 循环只循环一次 - java
【发布时间】:2015-03-18 17:13:33
【问题描述】:

为什么我的 while 循环只循环一次?它应该循环 99 次。 Thread.sleep 方法可以打破这个循环或 repaint 吗?你能帮我解决这个问题吗?它没有显示任何错误。我正在使用 netbeans。

Licznik.java:

    import javax.swing.JApplet;

public class Licznik extends JApplet {
    @Override
    public void init() {
        setSize(900,900);
        PanelLicznik pl=new PanelLicznik();
    add(pl);
    } 
}

PanelLicznik.java:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.*;
import java.awt.geom.Line2D;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class PanelLicznik extends JPanel implements Runnable
{
    int srodek = 450;
    Image bg;
    int a = 400, t = 0, v = 0, i = 0;
    double x = 152, y = 756;
    public PanelLicznik() {  
       Thread watek1 = new Thread(this);
       watek1.start();
    }

    @Override
    public Dimension getPreferredSize() { 
        return new Dimension(900, 900); 
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g; 
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        bg = new ImageIcon(this.getClass().getResource("s.gif")).getImage();
        g2.drawImage(bg,0,0,null); 
        Line2D wsk = new Line2D.Double(srodek,srodek,x,y);
        g2.setColor(new Color(255,255,255));
        g2.setStroke(new BasicStroke(15.0f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER));
        g2.draw(wsk);
    }

    @Override
    public void run() {
      t = 3;
      v = 100; 
      i = 0
      while(i < v){
         try{  
            Thread.sleep(100);
         } 
         catch(Exception ek) {}
         double stopien = 231.4 - ((360*v)/280);
         double radSek = Math.toRadians(stopien);
         x = srodek + (a * Math.cos(radSek));   
         y = srodek - (a * Math.sin(radSek));
         repaint();
         i++;
      }
    }
 }

重绘

public void repaint() {
    repaint(0, 0, 0, width, height);
}

/**
 * Repaints the component.  If this component is a lightweight
 * component, this results in a call to <code>paint</code>
 * within <code>tm</code> milliseconds.
 * <p>
 * <b>Note</b>: For more information on the paint mechanisms utilitized
 * by AWT and Swing, including information on how to write the most
 * efficient painting code, see
 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
 *
 * @param tm maximum time in milliseconds before update
 * @see #paint
 * @see #update(Graphics)
 * @since JDK1.0
 */
public void repaint(long tm) {
    repaint(tm, 0, 0, width, height);
}

/**
 * Repaints the specified rectangle of this component.
 * <p>
 * If this component is a lightweight component, this method
 * causes a call to this component's <code>paint</code> method
 * as soon as possible.  Otherwise, this method causes a call to
 * this component's <code>update</code> method as soon as possible.
 * <p>
 * <b>Note</b>: For more information on the paint mechanisms utilitized
 * by AWT and Swing, including information on how to write the most
 * efficient painting code, see
 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
 *
 * @param     x   the <i>x</i> coordinate
 * @param     y   the <i>y</i> coordinate
 * @param     width   the width
 * @param     height  the height
 * @see       #update(Graphics)
 * @since     JDK1.0
 */
public void repaint(int x, int y, int width, int height) {
    repaint(0, x, y, width, height);
}

/**
 * Repaints the specified rectangle of this component within
 * <code>tm</code> milliseconds.
 * <p>
 * If this component is a lightweight component, this method causes
 * a call to this component's <code>paint</code> method.
 * Otherwise, this method causes a call to this component's
 * <code>update</code> method.
 * <p>
 * <b>Note</b>: For more information on the paint mechanisms utilitized
 * by AWT and Swing, including information on how to write the most
 * efficient painting code, see
 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
 *
 * @param     tm   maximum time in milliseconds before update
 * @param     x    the <i>x</i> coordinate
 * @param     y    the <i>y</i> coordinate
 * @param     width    the width
 * @param     height   the height
 * @see       #update(Graphics)
 * @since     JDK1.0
 */
public void repaint(long tm, int x, int y, int width, int height) {
    if (this.peer instanceof LightweightPeer) {
        // Needs to be translated to parent coordinates since
        // a parent native container provides the actual repaint
        // services.  Additionally, the request is restricted to
        // the bounds of the component.
        if (parent != null) {
            if (x < 0) {
                width += x;
                x = 0;
            }
            if (y < 0) {
                height += y;
                y = 0;
            }

            int pwidth = (width > this.width) ? this.width : width;
            int pheight = (height > this.height) ? this.height : height;

            if (pwidth <= 0 || pheight <= 0) {
                return;
            }

            int px = this.x + x;
            int py = this.y + y;
            parent.repaint(tm, px, py, pwidth, pheight);
        }
    } else {
        if (isVisible() && (this.peer != null) &&
            (width > 0) && (height > 0)) {
            PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
                                          new Rectangle(x, y, width, height));
            SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e);
        }
    }
}

【问题讨论】:

  • 您的i 是全局的,您永远不会重置它。
  • 除了表单变量重置问题,Thread.sleep() 可能是个问题:*.com/questions/4917383/…

标签: java loops while-loop


【解决方案1】:

while之前重置i

v = 100;
i = 1; // if you want 99 times
while (i<v) { ...

注意:尽量不要使用这样的全局值,因为你必须一直跟踪变量的值。尽可能使用局部变量。

局部变量:

  int ax = 100; 
  int bx = 1;
  while(bx < ax){
     try{  
        Thread.sleep(100);
     } 
     catch(Exception ek) {}
     double stopien = 231.4 - ((360*v)/280);
     double radSek = Math.toRadians(stopien);
     x = srodek + (a * Math.cos(radSek));   
     y = srodek - (a * Math.sin(radSek));
     repaint();
     bx++;
  }

【讨论】:

  • 或者更好的是,将i也设为方法的局部变量。
  • 我添加了它,它仍然循环一次:(
  • 向我们展示方法repaint()。我怀疑你在repaint() 中做了一些修改i 的事情。否则将v = 100; i = 1;替换为int ax = 100; int bx = 1;,并在循环中适当替换vi,看看它是否仍然只循环一次。
  • 我将其更改为 ax 和 bx 并没有帮助。我不明白你显示重绘是什么意思。我什么都没做
  • 你确定 repaint() 没有改变?我正在尝试查看循环还会中断的其他地方,并且到目前为止看不到任何其他问题。